优化ansible执行playbook速度

ansible对应版本信息

# ansible --version

ansible 2.9.27

  config file = /root/ansible/ansible.cfg

  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']

  ansible python module location = /usr/lib/python3.11/site-packages/ansible

  executable location = /usr/bin/ansible

  python version = 3.11.4 (main, Sep 20 2023, 00:00:00) [GCC 12.3.1 (openEuler 12.3.1-15.oe2309)]

  1. 查找playbook中耗时task

可以通过启用timer, profile_roles, profile_tasks回调插件

# cat ansible.cfg

[defaults]

inventory = /root/ansible/inventory

roles_path = /root/ansible/roles

remote_user = root

host_key_checking = False

gathering = explicit

ansible_python_interpreter=/usr/bin/python3

forks=50

interpreter_python = auto_legacy_silent

callback_whitelist = timer, profile_roles, profile_tasks

[privilege_escalation]

become=True

become_method=sudo

become_user=root

become_ask_pass=False

[ssh_connection]

ssh_args = -o ControlMaster=auto -o ControlPersist=60s

 执行playbook会出书任务执行耗时统计

PLAY RECAP *********************************************************************************************************************************************************************************************************************************

servera                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

serverb                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Wednesday 17 January 2024  17:08:12 +0800 (0:00:30.809)       0:00:30.854 *****

===============================================================================

copy ------------------------------------------------------------------- 30.82s

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

total ------------------------------------------------------------------ 30.82s

Wednesday 17 January 2024  17:08:12 +0800 (0:00:30.809)       0:00:30.854 *****

===============================================================================

copy a.conf -----------------------------------------------------------------------------

2.禁用fact gathering

playbook中的默认会执行fact gathering 任务,该任务主要是收集节点信息和生成对应节点信息的环境变量。如果后边任务没有用到这些变量可以禁用该任务。

ansible.cfg中配置

gathering = explicit

YML中配置禁用

 gather_facts: False 

3.配置并行度

[defaults] 

forks=50

或者

ansible-playbook test.yaml --forks 50

4.优化ssh配置

建立ssh连接是一个在后台运行的相对较慢的过程。当 playbook 中有更多任务并且执行任务的托管节点更多时,全局执行时间会显着增加。

ControlMaster

允许与远程主机ssh链接共用。这可以节省 ssh连接初始过程的时间,因为后续链接请求将使用第一个 ssh连接来执行任务。

ControlPersist

指示 ssh在后台保持空闲连接打开的时间。

[ssh_connection] 

ssh_args = -o ControlMaster=auto -o ControlPersist=60s

5.动态环境中禁用主机密钥检查

[defaults] 

host_key_checking = False

默认情况下,Ansible 检查并验证 SSH 主机密钥,以防止服务器欺骗和中间人攻击。这也很消耗时间。

6.Use pipelining

当 Ansible 使用 SSH 时,后台会建立多个ssh链接,用于复制文件、脚本和其他执行命令可以通过启用管道参数(默认情况下禁用)来减少 ssh连接数

# ansible.cfg

pipelining = True

7.Use execution strategies

默认情况下,Ansible 会等待每个主机完成一个任务,然后再转到下一个任务,这称为线性策略。如果您对任务或托管节点没有依赖关系,则可以将策略更改为 free,这允许 Ansible 在托管主机上执行任务直到任务结束,而无需等待其他主机完成其任务:

- hosts: production servers

strategy: free

tasks:

8.异步任务

当任务执行时,Ansible 会等待其完成,然后再关闭与受管节点的连接。 当您的任务执行时间较长(例如磁盘备份、包安装等)时,这可能会成为瓶颈,因为它会增加全局执行时间。 如果以下任务不依赖于这个长时间运行的任务,您可以使用异步模式和适当的轮询间隔来告诉 Ansible 不要等待并继续执行下一个任务:

---

- name: mkfs

  hosts: nodes

  tasks:    

    - name: mkfs

      shell: "mkfs -f /dev/sda1"

      async: 120 # Maximum allowed time in Seconds

      poll: 05 # Polling Interval in Seconds

9.任务合并

安装软件包尽量放到一个任务中

#下边安装三个软件包,分别在2个任务中执行

- name: Install httpd

  yum:

name: httpd

state: present

- name: Install mysql

    yum:

name: mysql

state: present

 #2个软件包可以放在一个循环任务中执行

- name: Install Pacakages

yum:

    name: "{{ item }}"

    state: present

  loop:

    - httpd

    - mysql

 #更好方式是

- name: Install httpd and mysql

    yum:

    name:

      - httpd

      - mysql

    state: present

10.避免使用copy同步目录

当您有多个文件要复制到同一目录中时,请同步模块,而不是使用多个复制模块或循环:

- name: Copy data

  synchronize:

    src: /opt/data

    dest: /opt/data

11.模板使用

您可以使用多个 lineinfile 和 blockinfile 任务来管理和配置单个文件。 这种方法创建了一个很长的剧本。 当存在配置偏差时,您必须使用不同的正则表达式编辑此 lineinfile 任务。 但是,您可以使用 Jinja2 模板创建任意级别的复杂文件,并使用模板模块(或过滤器)来配置受管节点。

Your Jinja2 template: nginxd.conf.j2

# nginx configuration for wp-test

server {

    root /var/www/{{ website_root_dir }};

    index index.php index.html index.htm;

    server_name {{ website_name }}.com www.{{ website_name }}.com;

    access_log /var/log/nginx/access_{{ website_name }}-com.log;

    error_log /var/log/nginx/error_{{ website_name }}-com.log;

......

    ssl_certificate /etc/letsencrypt/live/{{ website_name }}.com/fullchain.pem; # managed by Certbot

    ssl_certificate_key /etc/letsencrypt/live/{{ website_name }}.com/privkey.pem; # managed by Certbot

    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

模板模块将变量(代码 {{ website_root_dir }})替换为剧本中提供的值:

---

- name: Configure the nginx Web Server

  hosts: web_servers

  become: True

  vars:

    website_name: myawesomeblog

    website_root_dir: /var/www/myawesomeblogdata

  tasks:

    - name: Copy nginx configuration

      template:

        src: nginxd.conf.j2

        dest: /etc/nginx/sites-enabled/{{ website_name }}.conf

12.尽量使用内部接口,避免使用shell和commad

您可以使用 Ansible shell 或命令模块来运行基本的 Linux 命令。 强烈建议您使用适当的模块,并在最坏的情况下使用这些 shell/命令模块。 shell(或命令)模块将简单地执行命令而不进行任何验证,并且大多数时候,您需要处理幂等性和错误检查。例如,下面的第一个任务(使用 shell)只是覆盖文件的内容,而不检查或验证,但第二个任务(使用复制模块)仅在需要时更改文件,并且它还更新目标文件的权限和所有权 。

    - name: Create file using shell module

      shell: 'echo "Hello" > /tmp/foo.conf'

      

    - name: Create file with permission using file module

      ansible.builtin.copy:

        content: "Hello"

        dest: /tmp/foo.conf

        owner: root

        group: root

        mode: '0644'

13.语法优化

在剧本中使用适当的模块和模块参数可以节省大量时间并避免复杂化。

你可能感兴趣的:(ansible,ansible)