18.ansible delegate_to

1. 场景介绍

在对一组服务器 server_group1 执行操作过程中,需要在另外一台机器 A 上执行一个操作,比如在 A 服务器上添加一条 hosts 记录,这些操作必须要在一个 playbook 联动完成。也就是是说 A 服务器这个操作与 server_group1 组上的服务器有依赖关系。Ansible 默认只会在定义好的一组服务器上执行相同的操作,这个特性对于执行批处理是非常有用的。但如果在这过程中需要同时对另外 1 台机器执行操作时,就需要用到 Ansible 的任务委派功能(delegate_to)。使用 delegate_to 关键字可以委派任务到指定的机器上运行。在 playbook 的操作如下:

- name: add host record 
  shell: 'echo "192.168.1.100 test.xyz.com" >> /etc/hosts'

 - name: add host record to center server 
  shell: 'echo "192.168.1.100 test.xyz.com " >> /etc/hosts'
  delegate_to: 192.168.1.1

任务委派功能还可以用于以下场景:

  • 在部署之前将一个主机从一个负载均衡集群中删除;
  • 当你要对一个主机做改变之前去掉相应 dns 的记录;
  • 当在一个存储设备上创建 iscsi 卷的时候;
    *当使用外的主机来检测网络出口是否正常的时候。

2. 委托(delegate)

通过"delegate_to", 用户可以把某一个任务放在委托的机器上执行.

- 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

上面的task会在跑ansible的机器上执行, “delegate_to: 127.0.0.1” 可以用local_action来代替

  tasks:

  - name: take out of load balancer pool
    local_action: command /usr/bin/take_out_of_pool {{ inventory_hostname }}
示例: 滚动更新代码 nginx负载均衡配置

剧本执行要求设置

- hosts: "{{ Server }}"
  serial: 1
  roles:
    - code_update 

task任务

- name: 1. Push New Code
  unarchive:
    src: "html-{{ Version }}.tar.gz"
    dest: /data/
    owner: www
    group: www
  tags: t1
- name: 2. Remove The Service
  replace:
    regexp: "server {{ ansible_default_ipv4.address }}"
    path: /etc/nginx/conf.d/slb.conf
    replace: "#server {{ ansible_default_ipv4.address }}" 
  delegate_to: localhost
  notify: Reload_Nginx

- meta: flush_handlers

- name: 3. Remove Html Directory link
  file: 
    path: /data/html
    state: absent

- name: 4. Create Html Directory link
  file:
    src: "/data/html-{{ Version }}"
    path: /data/html
    state: link
    owner: www
    group: www

- name: 4. Test Web Info
  shell: 
    cmd: echo "{{ ansible_default_ipv4.address.split('.')[-1] }}" >> /data/html/index.html

- name: test 30s
  shell:
    cmd: sleep 20s  

- name: 5. Create The Service
  replace:
    regexp: "#server {{ ansible_default_ipv4.address }}"
    path: /etc/nginx/conf.d/slb.conf
    replace: "server {{ ansible_default_ipv4.address }}"
  delegate_to: localhost
  notify: Reload_Nginx

- meta: flush_handlers

- name: 6. Find Site Directory Number > 5
  shell:
    cmd: 'ls -d /data/html* |wc -l'
  register: Html_Site_Number
  tags: t2

- name: 7. Remove Old Site Directory 
  shell: 
    cmd: "rm -rf $(ls  -td  /data/html*|xargs -n1|sed  '1,5d'|xargs) "
  when: Html_Site_Number.stdout > '4'
  tags: t2

触发器

- name: Reload_Nginx
  command:
    cmd: nginx -s reload 
  delegate_to: localhost

3. 委托者的facts

默认情况下, 委托任务的facts是inventory_hostname中主机的facts, 而不是被委托机器的facts. 在ansible 2.0 中, 设置delegate_facts为true可以让任务去收集被委托机器的facts.

- hosts: app_servers
  tasks:
    - name: gather facts from db servers
      setup:
      delegate_to: "{{item}}"
      delegate_facts: True
      with_items: "{{groups['dbservers'}}"

该例子会收集dbservers的facts并分配给这些机器, 而不会去收集app_servers的facts

4. run_once

通过run_once: true来指定该task只能在某一台机器上执行一次. 可以和delegate_to 结合使用

- command: /opt/application/upgrade_db.py
  run_once: true
  delegate_to: web01.example.org

指定在"web01.example.org"上执行这
如果没有delegate_to, 那么这个task会在第一台机器上执行

posted @ 2022-10-19 14:24  老夫聊发少年狂88  阅读(176)  评论(0编辑  收藏  举报