Linux架构29 ansible playbook任务标签,复用文件,忽略错误,错误处理,滚动执行
默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务,Ansible的标签(tag)功能可以给单独任务甚至整个playbook打上标签,
然后利用这些标签来指定要运行playbook中的个别任务,或不执行指定的任务。
1.对一个task打一个标签 2.对一个task打多个标签 3.对多个task打一个标签
#对一个task打一个标签 - name: Config Nginx Server copy: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: - { src: "/root/nginx.conf", dest: "/etc/nginx/" } - { src: "/root/wordpress.conf", dest: "/etc/nginx/conf.d" } notify: restart_nginx #触发器判断上面的文件是否发生改变 tags: reload_nginx #对一个task打多个标签 - name: Config Nginx Server copy: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: - { src: "/root/nginx.conf", dest: "/etc/nginx/" } - { src: "/root/wordpress.conf", dest: "/etc/nginx/conf.d" } notify: restart_nginx #触发器判断上面的文件是否发生改变 tags: - reload_nginx - reconfig_nginx #对多个name打一个标签 - name: Config Nginx Server copy: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: - { src: "/root/nginx.conf", dest: "/etc/nginx/" } - { src: "/root/wordpress.conf", dest: "/etc/nginx/conf.d" } notify: restart_nginx #触发器判断上面的文件是否发生改变 tags: - reload_nginx - reconfig_nginx - name: Tar PHP and Wordpress Package unarchive: src: "{{ item.src }}" dest: "{{ item.dest }}" with_items: - { src: "/root/php.tar.gz", dest: "/tmp/" } - { src: "/root/blog.tar.gz", dest: "/" } notify: restart_nginx tags: reload_nginx
#查看所有的标签 [root@m01 web]# ansible-playbook lnmp.yml --list-tags playbook: lnmp.yml play #1 (all): all TAGS: [] TASK TAGS: [] play #2 (web01): web_01 TAGS: [] TASK TAGS: [reload_nginx] play #3 (db01): db01 TAGS: [] TASK TAGS: [] #指定标签执行name的内容 [root@m01 web]# ansible-playbook lnmp.yml -t reload_nginx #指定多个标签执行name的内容 [root@m01 web]# ansible-playbook lnmp.yml -t reload_nginx #指定多个标签执行name的内容 [root@m01 web]# ansible-playbook lnmp.yml -t reload_nginx,reconfig_nginx #排除标签执行其他name (跳过标签名字为chown_dir) [root@m01 web]# ansible-playbook lnmp.yml --skip-tags chown_dir
#执行所有打标签的task
[root@ubuntu ~]# ansible-playbook tags.yaml -t tagged
#执行所有未打标签的task
[root@ubuntu ~]# ansible-playbook tags.yaml -t untagged
#跳过所有没有tag的task
[root@ubuntu ~]# ansible-playbook tags.yaml -t untagged
在之前写playbook的过程中,我们发现,写多个playbook没有办法一键执行,这样我们还要单个playbook挨个去执行,很鸡肋。
所以在playbook中有一个功能,叫做include用来动态调用task任务列表。
[root@m01 web]# vim install_nginx.yml - name: Install Nginx Server yum: name: nginx state: present [root@m01 web]# vim config_nginx.yml - name: Config Nginx copy: src: /root/wordpress.conf dest: /etc/nginx/conf.d/ notify: reload_nginx [root@m01 web]# vim main.yml - hosts: web01 tasks: # 从上到下执行 - include_tasks: ./install_nginx.yml - include_tasks: ./config_nginx.yml handlers: - name: reload_nginx systemed: name: nginx state: restarted #执行 [root@m01 web]# ansible-playbook main.yml
[root@m01 web]# vim main.yml - import_playbook: ./lnp.yml - import_playbook: ./mariadb.yml #执行 [root@m01 web]# ansible-playbook main.yml
- name: Get PHP Install Status shell: "rpm -qa | grep php" ignore_errors: yes #获取状态,加上忽略错误(否则非0报错,不往下执行) register: get_php_install_status #调用变量结果,rc值不等于0时执行安装命令 - name: Install PHP Server shell: "yum localinstall -y /tmp/*.rpm" when: get_php_install_status.rc != 0 #rc就是$?返回
当task执行失败时,playbook将不再继续执行,包括如果在task中设置了handler也不会被执行。
但是我们可以采取强制措施...
如果在主机上的执行的任务失败时,则此任务对应的处理程序不再运行
此时可以通过force_handlers: yes实现,即使notify对应的响应任务执行失败,仍继续执行noftify对应的处理程序(即使任务失败了也要调用notify触发handlers)
force_handlers与tasks同层级
- name: httpd hosts: web force_handlers: yes tasks: - name: install httpd yum: name: httpd state: present notify: - start httpd handlers: - name: start httpd service: name: httpd state: started
#当被控端没有发生实际改变时,可以使用changed_when将状态强行变绿 - hosts: web01 tasks: - name: Get PHP Install Status shell: "rpm -qa | grep php" ignore_errors: yes register: get_php_install_status changed_when: false # 把状态黄色变为绿色
#查nginx配置是否正确 - hosts: web01 tasks: - name: Check Nginx Server shell: /usr/sbin/nginx -t register: check_nginx changed_when: - ( check_nginx.stdout.find('successful')) #判断输出有没有successful,没有就结束不继续执行后面的操作 - false - name: ...
滚动执行
默认情况下, ansible 从上到下执行,如果一个 playbook 中有多个 task,在有多台远程主机的情况下,
需要在所有远程主机上执行完当前的 task 之后才执行下一个 task,如果主机过多,或者需要执行的task 比较消耗时间,
则会导致所有主机都处于一个执行中状态。
默认是从上往下执行,先在 A,B,C 三台主机上执行 Task-1,再在三台主机上执行 Task-2
默认是水平执行(如设置并发fork,即一个任务多少台机器并发执行) #修改ansible并发数 [root@rocky ~]# vim /etc/ansible/ansible.cfg forks=5
[root@ubuntu ~]# cat forks.yaml --- #forks - hosts: group tasks: - name: task-1 debug: msg=task-1 - name: task-2 debug: msg=task-2 [root@ubuntu ~]# ansible-playbook forks.yaml PLAY [group1] *************************************************************** TASK [task-1] *************************************************************** ok: [10.0.0.166] => { "msg": "task-1" } ok: [10.0.0.157] => { "msg": "task-1" } TASK [task-2] *************************************************************** ok: [10.0.0.166] => { "msg": "task-2" } ok: [10.0.0.157] => { "msg": "task-2" } 滚动执行,深度优先(一台台机器执行完所有任务,执行完的机器就能使用了) [root@ubuntu ~]# cat serial.yaml --- #forks - hosts: group1 serial: 1 #每次在一台机上执行完所有task,可以写成百分比,如 "20%" 先执行 20% 的 主机 tasks: - name: task-1 debug: msg=task-1 - name: task-2 debug: msg=task-2 [root@ubuntu ~]# ansible-playbook serial.yaml PLAY [group1] *************************************************************** TASK [task-1] *************************************************************** ok: [10.0.0.166] => { "msg": "task-1" } TASK [task-2] *************************************************************** ok: [10.0.0.166] => { "msg": "task-2" } PLAY [group1] *************************************************************** TASK [task-1] *************************************************************** ok: [10.0.0.157] => { "msg": "task-1" } TASK [task-2] *************************************************************** ok: [10.0.0.157] => { "msg": "task-2" }
run_once 只执行一次
利用 run_once 指令可以让 task 只执行一次,而非在所有被控主机都执行。
[root@ubuntu ~]# cat run_once-1.yaml --- #run_once-1 - hosts: rocky tasks: - name: task-1 debug: msg=task-1 - name: task-2 debug: msg=task-2 run_once: true