Ansible 高级特性详解
Ansible 高级特性详解
本地任务执行 (local_action)
当需要在 Ansible 控制节点本地执行某个任务而非远程被控节点时,可以使用 local_action。这在某些初始化或准备阶段非常有用,例如在远程服务启动前等待 SSH 端口可用。
- name: 等待 SSH 服务启动
wait_for:
port: 22
host: "{{ inventory_hostname }}"
search_regex: OpenSSH
connection: local
任务委托 (delegate_to)
delegate_to 允许您将一个任务的执行委托给其他主机,即使该任务的目标主机是另一组服务器。这适用于需要在特定管理服务器上执行的操作,例如在 Nagios 服务器上启用告警,或在 DNS 服务器上修改记录。
- name: 为 Web 服务器启用告警
hosts: webservers
tasks:
- name: 启用告警
nagios:
action: enable_alerts
service: web
host: "{{ inventory_hostname }}"
delegate_to: nagios.example.com
任务暂停 (wait_for 模块)
在某些情况下,任务需要等待特定条件满足才能继续执行,例如等待某个端口启动或文件出现。wait_for 模块可用于实现这一目的。
常用参数包括:
port: 监听的端口号。delay: 轮询检查的间隔时间(秒)。host: 要检查的主机地址。path: 要检查的文件路径。state: 期望的状态(如 'started', 'absent', 'drained')。timeout: 等待的超时时间(秒)。search_regex: 在文件内容或端口响应中搜索的正则表达式。exclude_hosts: 排除检查的主机列表。
# 等待 8080 端口启动
- name: 等待 8080 端口监听
wait_for:
port: 8080
state: started
# 等待 8000 端口启动,每 10 秒检查一次
- name: 等待 8000 端口启动 (每 10 秒检查)
wait_for:
port: 8000
delay: 10
state: started
# 等待 /tmp/foo 文件存在
- name: 等待 /tmp/foo 文件存在
wait_for:
path: /tmp/foo
state: present
# 等待 /tmp/foo 文件存在且包含 "completed"
- name: 等待 /tmp/foo 文件存在并包含 "completed"
wait_for:
path: /tmp/foo
state: present
search_regex: completed
# 等待 /var/lock/file.lock 文件被删除
- name: 等待 /var/lock/file.lock 文件被删除
wait_for:
path: /var/lock/file.lock
state: absent
滚动更新 (serial 和 max_fail_percentage)
serial 指令限制了在同一时间段内并行执行任务的主机数量,非常适合负载均衡场景下的滚动更新。max_fail_percentage 则定义了允许的最大失败主机比例,超过此比例时整个 Playbook 将停止执行。
- name: 滚动更新后端服务器
hosts: myhosts
serial: 1 # 每次只在一台主机上执行
max_fail_percentage: 25 # 允许最多 25% 的主机失败
tasks:
# ... 摘除主机、更新、添加主机的任务 ...
serial 的值可以是整数(表示并行主机数)或百分比(表示并行主机占总数的百分比)。
一次性执行 (run_once)
当某个任务只需要执行一次,即使它应用于多个主机时,可以使用 run_once: true。这对于执行数据库迁移等仅需一次的操作非常有用。它也可以与 local_action 或 delegate_to 结合使用,指定在控制节点或特定服务器上执行。
# 在控制节点上只执行一次任务
- name: 本地执行一次性任务
command: /opt/my-custom-command
connection: local
run_once: true
# 在指定主机上执行一次性任务
- name: 在指定主机上执行一次性迁移
command: /opt/run_migrations
run_once: true
delegate_to: app.a1-61-105.dev.unp
设置环境变量 (environment)
environment 关键字允许您为任务设置环境变量,这对于需要特定环境变量才能运行的命令或脚本非常有用,例如设置代理或 AWS 凭证。
- name: 上传文件到 AWS S3
hosts: test
tasks:
- name: 安装 AWS CLI
pip:
name: awscli
state: present
- name: 上传文件到 S3
shell: aws s3 put-object --bucket=my-test-bucket --key={{ ansible_hostname }}/fstab --body=/etc/fstab --region=eu-west-1
environment:
AWS_ACCESS_KEY_ID: "YOUR_ACCESS_KEY"
AWS_SECRET_ACCESS_KEY: "YOUR_SECRET_KEY"
环境变量也可以存储在变量中:
- hosts: all
vars:
proxy_settings:
http_proxy: "http://proxy.example.com:8080"
https_proxy: "http://proxy.bos.example.com:8080"
tasks:
- name: 安装 cobbler
apt:
name: cobbler
state: installed
environment: proxy_settings
交互式提示 (vars_prompt)
vars_prompt 用于在 Playbook 执行过程中向用户请求输入信息,例如敏感数据或动态参数。private: yes 会隐藏用户的输入。
- hosts: demo2.example.com
remote_user: root
vars_prompt:
- name: network_user
prompt: "请输入您的网络用户名:"
private: yes
- name: network_password
prompt: "请输入您的网络密码:"
private: yes
tasks:
- name: 显示用户名
debug:
var: network_user
- name: 显示密码 (隐藏)
debug:
var: network_password
Tags (标签)
Tags 允许您为 Playbook 中的特定任务打上标签,以便在执行时仅运行带有特定标签的任务。这对于大型 Playbook 的灵活管理至关重要。
为任务打标签
在任务定义中添加 tags 关键字,后面跟标签名。
- name: 安装 Apache
yum:
name: httpd
state: present
tags:
- install_httpd
- name: 启动 Apache
service:
name: httpd
state: started
tags:
- start_httpd
执行指定标签的任务
ansible-playbook your_playbook.yml --tags="start_httpd"
一次执行多个标签的任务
ansible-playbook your_playbook.yml --tags="install_httpd,start_httpd"
排除指定标签的任务
ansible-playbook your_playbook.yml --skip-tags="install_httpd"
查看 Playbook 中的所有标签
ansible-playbook your_playbook.yml --list-tags
定义多个标签
可以使用列表或逗号分隔的方式为任务指定多个标签。
tags:
- install
- webserver
为 Play 指定标签
为整个 Play 指定标签会将其应用于该 Play 中的所有任务。
- name: 配置 Web 服务器
hosts: all
tags:
- httpd
tasks:
# ... 任务 ...
Ansible 内置标签
always: 无论如何都会执行的任务,除非使用--skip-tags=always。never: 除非使用--tags=never,否则不会执行的任务。tagged: 与--tags一起使用,执行所有打了标签的任务(不包括never)。untagged: 与--tags或--skip-tags一起使用,处理未打标签的任务。