accelerate
对于使用ansible 1.5 及以后版本的用户,加速模式只在如下状况下有用处:html
(A) 管理红帽企业版 Linux 6 或者更早的那些依然使用 paramiko 的版本 python
(B) 像在文档中描述的那样:没法在 TTYs 中使用 sudo.web
#只需在你的 play 中添加 accelerate: true 便可使用加速模式: --- - hosts: all accelerate: true tasks: - name: some task command: echo {{ item }} with_items: - foo - bar - baz #若是你但愿改变 Ansible 用于加速模式的端口,你只需添加 accelerated_port 选项: --- - hosts: all accelerate: true # default port is 5099 accelerate_port: 10000 #accelerate_port 选项也一样能经过指定环境变量 ACCELERATE_PORT 或者在你的 ansible.cfg 中配置: [accelerate] accelerate_port = 5099
async
poll
async_status
默认状况下playbook中的任务执行时会一直保持链接,直到该任务在每一个节点都执行完毕.有时这是没必要要的,好比有些操做运行时间比SSH超时时间还要长.docker
解决该问题最简单的方式是一块儿执行它们,而后轮询直到任务执行完毕.shell
你也能够对执行时间很是长(有可能遭遇超时)的操做使用异步模式.json
为了异步启动一个任务,能够指定其最大超时时间以及轮询其状态的频率.vim
若是你没有为 poll 指定值,那么默认的轮询频率是10秒钟:安全
--- - hosts: all remote_user: root tasks: - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec command: /bin/sleep 15 async: 45 poll: 5
async 并无默认值,若是你没有指定 async 关键字,那么任务会以同步的方式运行,这是Ansible的默认行为.服务器
另外,若是你不须要等待任务执行完毕,你能够指定 poll 值为0而启用 “启动并忽略”app
--- - hosts: all remote_user: root tasks: - name: simulate long running op, allow to run for 45 sec, fire and forget command: /bin/sleep 15 async: 45 poll: 0
对于要求排它锁的操做,若是你须要在其以后对同一资源执行其它任务,那么你不该该对该操做使用”启动并忽略”.好比yum事务.
--forks
参数值过大会更快的触发异步任务.也会加快轮询的效率.
当你想对 “启动并忽略” 作个变种,改成”启动并忽略,稍后再检查”,你可使用如下方式执行任务:
--- # Requires ansible 1.8+ - name: 'YUM - fire and forget task' yum: name=docker-io state=installed async: 1000 poll: 0 register: yum_sleeper - name: 'YUM - check on fire and forget task' async_status: jid={{ yum_sleeper.ansible_job_id }} register: job_result until: job_result.finished retries: 30
若是 async:
值过小,可能会致使 “稍后检查” 任务执行失败,由于 async_status::
的临时状态文件还未被写入信息,而”稍后检查”任务就试图读取此文件.
--check
--diff
--limit
当以 --check
参数来运行 ansible-playbook 时,将不会对远程的系统做出任何更改.
相对的,任何带有检测功能的模块(这几乎包含了全部的主要核心模块,但这不要求全部的模块都需支持.) 只要支持 ‘检测模式’ 将会报告它们会作出什么改变而不是直接进行改变.其余不支持检测模式的模块将既不响应也不提出相应的报告.
检测模式只是一种模拟.若是你的playbook是以先前命令的执行结果做为条件的话,那它可能对你就没有什么大用处了. 可是对于基于一次一节点的基础配置管理的使用情形来讲是颇有用.
Example: ansible-playbook foo.yml --check
有时候你甚至会想在检测模式中执行一个任务.为了达到这样的效果, 你须要在相应的任务上使用 always_run 子句.跟 when 子句同样,它的值是一个 Jinja2 表达式. 在一个简单的例子中,布尔值也会表达为一个适当的 YAML 值.
Example: tasks: - name: this task is run even in check mode command: /something/to/run --even-in-check-mode always_run: yes
友情提示,带有 when 子句的任务会返回false,该任务将会被跳过,即便它还被添加了会返回true的 always_run 子句.
对 ansible-playbook 来讲 --diff
选项与 --check
(详情参下)配合使用效果奇佳,不过它也能够单独使用.当提供了相应的标识后,当远程系统上任何模板文件的变化时,ansible-playbook CLI 将会报告文件上任何文本的变化 (或者,若是使用了 --check
参数,将报告会发生的变化.).由于 diff 特性会产生大量的输出结果,因此它在一次检测一个主机时使用为佳,如:
ansible-playbook foo.yml --check --diff --limit foo.example.com
serial
因为设计初衷是做为多用户,Anisible很擅长在某一个主机上表明另外一个作事,或者参考远程主机作一些本地工做.
这个特性对于架设连续实现某些设施或者无缝滚动升级,这里你可能会提到负载均衡或者监控系统.
更多的特性容许调试事情完成的顺序,和设置一批窗口,来肯定多少机器在一次中滚动更新.
默认来讲,Anisble 能够试图参考某一个play来并行操做全部主机.对于滚动更新案例,你可使用’‘serial’’ 关键词来定义Ansible在一个特定时间同时控制多少主机:
- name: test play hosts: webservers serial: 3
在上面的例子,若是咱们有100台主机,3 台主机定义在组’webservers’ 能够在下面3个主机开始以前彻底完成
这个’‘serial’’ 关键词在Ansible 1.8 之后能够被定义为百分数,用来定义每一次操做一个play中百分之多少主机:
- name: test play hosts: websevers serial: "30%"
若是主机数不能被passes数量整除,最后的pass将会包含提醒信息,无论多小的百分比,每一个pass的主机数必定会大于等于1.
默认来讲,Ansible 会持续执行,只要在一个组中还有主机没有宕机.
在有些状况下,例如以前提到的滚动更新,也许理想的状况是当一个失败数上限达到时,主动宕掉这个play.
为了达到这个目的,在 1.3版本中,你能够设置最大失败半分比:
- hosts: webservers max_fail_percentage: 30 serial: 10
在上面的例子中,若是在10个服务器中若是多余3个,其它的play就会主动宕掉.这个百分比必须被超过,不只仅是相等.
例如若是serial值呗设置为4,而且你但愿任务主动在2个系统失败时候放弃.那么这个百分比应该设置为49而不是50.
delegate_to
local_action
若是你想参考其它主机来在一个主机上执行一个任务,咱们就可使用’delegate_to’关键词在你要执行的任务上.
这个对于把节点放在一个负载均衡池里面活着从里面移除很是理想. 这个选项也对处理窗口中断很是有用. 使用’serial’关键词来控制必定数量的主机也是一个好想法:
--- - hosts: webservers serial: 5 tasks: - name: take out of load balancer pool command: /usr/bin/take_out_of_pool {{ inventory_hostname }} delegate_to: 127.0.0.1 - name: actual steps would go here yum: name=acme-web-stack state=latest - name: add back to load balancer pool command: /usr/bin/add_back_to_pool {{ inventory_hostname }} delegate_to: 127.0.0.1
--- # ... tasks: name: take out of load balancer pool local_action: command /usr/bin/take_out_of_pool {{ inventory_hostname }} # ... name: add back to load balancer pool local_action: command /usr/bin/add_back_to_pool {{ inventory_hostname }}
A common pattern is to use a local action to call ‘rsync’ to recursively copy files to the managed servers. Here is an example:
--- # ... tasks: - name: recursively copy files from management server to target local_action: command rsync -a /path/to/files {{ inventory_hostname }}:/path/to/target/
connection
在本地使用playbook有时候比ssh远程使用更加有用.能够经过把playbook放在crontab中,来确保一个系统的配置,能够颇有用.
在OS installer 中运行一个playbook也颇有用.例如Anaconda kickstart.
要想在本地运行一个play,能够直接设置”host:” 与 “hosts:127.0.0.1”, 而后使用下面的命令运行:
ansible-playbook playbook.yml --connection=local
或者,一个本地链接也能够做为一个单独的playbook play应用在playbook中, 即使playbook中其余的plays使用默认远程 链接以下:
- hosts: 127.0.0.1 connection: local
run_once
有时候你有这样的需求,在一个主机上面只执行一次一个任务.这样的配置能够配置”run_once”来实现:
--- # ... tasks: # ... - command: /opt/application/upgrade_db.py run_once: true # ...
这样能够添加在”delegat_to”选项对中来定义要执行的主机:
- command: /opt/application/upgrade_db.py run_once: true delegate_to: web01.example.org
当”run_once” 没有和”delegate_to”一块儿使用,这个任务将会被清单指定的第一个主机.
在一组被play制定主机.例如 webservers[0], 若是play指定为 “hosts: webservers”.
这个方法也很相似,虽然比使用条件更加简单粗暴,以下事例:
- command: /opt/application/upgrade_db.py when: inventory_hostname == webservers[0]
environment
你彻底有可能遇到一些更新包须要经过proxy才能正常获取,或者甚至一部分包须要经过proxy升级而另一部分包则不须要经过proxy.
或者可能你的某个脚本须要调用某个环境变量才能正常运行.
Ansible 使用 ‘environment’ 关键字对于环境部署的配置很是简单容易,下面是一个使用案例:
- hosts: all remote_user: root tasks: - apt: name=cobbler state=installed environment: http_proxy: http://proxy.example.com:8080
environment 也能够被存储在变量中,像以下方式访问:
- hosts: all remote_user: root # here we make a variable named "proxy_env" that is a dictionary vars: proxy_env: http_proxy: http://proxy.example.com:8080 tasks: - apt: name=cobbler state=installed environment: proxy_env
虽然上面只展现了 proxy 设置,但其实能够同时其实支持多个设置. 大部分合合乎逻辑的地方来定义一个环境变量均可以成为 group_vars 文件,示例以下:
--- # file: group_vars/boston ntp_server: ntp.bos.example.com backup: bak.bos.example.com proxy_env: http_proxy: http://proxy.bos.example.com:8080 https_proxy: http://proxy.bos.example.com:8080
ignore_errors
failed_when
fail
change_when
Ansible 一般默认会确保检测模块和命令的返回码.
有时一条命令会返回 0 但那不是报错.有时命令不会老是报告它 ‘改变’ 了远程系统.
本节描述了 如何将 Ansible 处理输出结果和错误处理的默认行为改变成你想要的.
一、忽略错误命令
一般状况下, 当出现失败时 Ansible 会中止在宿主机上执行.有时候,你会想要继续执行下去.为此 你须要像这样编写任务:
- name: this will not be counted as a failure command: /bin/false ignore_errors: yes
注意上面的系统仅仅处理那个特定的任务,因此当你在使用一个未定义的变量时, Ansible 仍然会报 错,须要使用者进行处理.
二、控制对失败的定义
假设一条命令的错误码毫无心义,只有它的输出结果能告诉是你什么出了问题,好比说字符串 “FAILED” 出 如今输出结果中.
在 Ansible 1.4及以后的版本中提供了以下的方式来指定这样的特殊行为:
- name: this command prints FAILED when it fails command: /usr/bin/example-command -x -y -z register: command_result failed_when: "'FAILED' in command_result.stderr"
三、覆写返回结果
当一个 shell或命令或其余模块运行时,它们每每都会在它们认为其影响机器状态时报告 “changed” 状态,
tasks: - shell: /usr/bin/billybass --mode="take me to the river" register: bass_result changed_when: "bass_result.rc != 2" # this will never report 'changed' status - shell: wall 'beep' changed_when: False
tags
若是你有一个大型的 playbook,那可以只运行其中特定部分的配置而无需运行整个 playbook 将会颇有用.
plays 和 tasks 都因这个理由而支持 “tags”
tasks: - yum: name={{ item }} state=installed with_items: - httpd - memcached tags: - packages - template: src=templates/src.j2 dest=/etc/foo.conf tags: - configuration
若是你只想运行一个很是大的 playbook 中的 “configuration” 和 “packages”,你能够这样作:
ansible-playbook example.yml --tags "configuration,packages"
另外一方面,若是你只想执行 playbook 中某个特定任务 以外 的全部任务,你能够这样作:
ansible-playbook example.yml --skip-tags "notification"
你一样也能够对 roles 应用 tags:
roles: - { role: webserver, port: 5000, tags: [ 'web', 'foo' ] }
你一样也能够对基本的 include 语句使用 tag:
- include: foo.yml tags=web,foo
--start-at
--step
若是你想从指定的任务开始执行playbook,可使用``–start-at``选项:
ansible-playbook playbook.yml --start-at="install packages"
以上命令就会在名为”install packages”的任务开始执行你的playbook.
咱们也能够经过``–step``选项来交互式的执行playbook:
ansible-playbook playbook.yml --step
这样ansible在每一个任务前会自动中止,并询问是否应该执行该任务.
好比你有个名为``configure ssh``的任务,playbook执行到这里会中止并询问:
Perform task: configure ssh (y/n/c):
“y”回答会执行该任务,”n”回答会跳过该任务,而”c”回答则会继续执行剩余的全部任务而再也不询问你.
ansible-vault
--ask-vault-pass
--vault-password-file
Ansible 1.5的新版本中, “Vault” 做为 ansible 的一项新功能可将例如passwords,keys等敏感数据文件进行加密,
而非存放在明文的 playbooks 或 roles 中. 这些 vault 文件能够分散存放,也能够集中存放.
经过`ansible-vault` 来编辑文件,常常用到的命令如 –ask-vault-pass , –vault-password-file .
你能够在 ansible.cfg 中定义密码文件所在位置,这个选项就不须要在命令行中指定标志了.
vault 能够加密任何 Ansible 使用的结构化数据文件. 甚至能够包括:
“group_vars/” 或 “host_vars/” inventory 变量,
“include_vars” 或 “vars_files” 加载的变量,
经过 ansible-playbook 命令行使用 “-e @file.yml” 或 “-e @file.json” 命令传输的变量文件,
role变量,
全部默认的变量均可以被 vault 加密.
由于 Ansible tasks, handlers等都是数据文件, 全部的这些都可以被 vault 加密. 若是你不喜欢你使用的变量被泄漏,你能够将整个 task 文件部分加密.
不过,这个工做量比较大并且可能给你的同事带来不便哦 !
执行以下命令,建立加密文件:
ansible-vault create foo.yml
首先你将被提示输出密码, 通过Vault加密过的文件如需查看需同时输入密码后才能进行.
提供密码后, 工具将加载你定义的 $EDITOR 的编辑工具默认是 vim, 一旦你关闭了编辑会话框,生成后的文件将会是加密文件.
默认加密方式是 AES (基于共享密钥)
编辑加密文件,使用 ansible-vault edit . 该命令会先加密文件为临时文件并容许你编辑这个文件,当完成编辑后会保存回你所命名的文件并删除临时文件:
ansible-vault edit foo.yml
若是你但愿加密一个已经存在的文件,使用 ansible-vault encrypt . 该命令也可同时批量操做多个文件:
ansible-vault encrypt foo.yml bar.yml baz.yml=
若是不但愿继续加密一个已经加密过的文件,经过 ansible-vault decrypt 你能够永久解密. 命令将解密并保存到硬盘上,这样你不用再使用 ansible-vault edit 来编辑文件了:
ansible-vault decrypt foo.yml bar.yml baz.yml
Available since Ansible 1.8
若是你不但愿经过编辑的方式来查看文件, ansible-vault view 能够知足你的须要:
ansible-vault view foo.yml bar.yml baz.yml
执行 vault 加密后的playbook文件,最少须要提交以下两个标志之一. 交互式的指定 vault 的密码文件:
ansible-playbook site.yml --ask-vault-pass
该提示被用来解密(仅在内存中)任何 vault 加密访问过的文件. 目前这些文件中全部的指令请求将被使用相同的密码加密.
另外,密码也能够定义在一个文件或者一个脚本中,可是须要 Ansible 1.7 以上的版本才能支持.
当使用该功能时,必定要确认密码文件的权限是安全的,以确保没有人能够随意访问或者变动密码文件:
ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt ansible-playbook site.yml --vault-password-file ~/.vault_pass.py
密码存储一行一个
若是你使用的是脚本而不是普通文件,确保脚本是可执行的,这样密码能够输出至标准设备.若是你的脚本须要提示输入数据,那提示能够被发送到标准错误.
若是你是从持续集成系统(例如Jenkins)中使用 Ansible 的话上面的这种状况你会用的到.
(–vault-password-file 参数能够在 Ansible-Pull(拉取配置而非推送配置) 命令中被使用,尽管这将须要分发keys到对应的节点上,
因此 ,了解这些隐性问题后 – vault 更倾向使用 push 方式)