date: 2021-01-22title: ansible模块使用 #标题
tags: ansible模块 #标签
categories: ansible # 分类

记录一些常用的模块用法,不太详细,只是在以后忘记语法时翻出来看看。

ansible常用指令

serial——滚动更新

默认情况下,Ansible将尝试并行管理playbook中所有的机器。对于滚动更新用例,可以使用serial关键字定义Ansible一次应管理多少主机:

  1. - name: test play
  2. hosts: webservers
  3. serial: 2 # 也可以写百分比,但如果是三个机器,写 serial: "50%",则一次只能在一台机器上执行。
  4. gather_facts: False
  5. tasks:
  6. - name: task one
  7. comand: hostname
  8. - name: task two
  9. command: hostname

在上面的例子中,如果我们在“WebServers”组中有4个主机,后面2个主机等到前面2个主机执行完后执行:

  1. PLAY [webservers] ****************************************
  2. TASK [task one] ******************************************
  3. changed: [web2]
  4. changed: [web1]
  5. TASK [task two] ******************************************
  6. changed: [web1]
  7. changed: [web2]
  8. PLAY [webservers] ****************************************
  9. TASK [task one] ******************************************
  10. changed: [web3]
  11. changed: [web4]
  12. TASK [task two] ******************************************
  13. changed: [web3]
  14. changed: [web4]
  15. PLAY RECAP ***********************************************
  16. web1 : ok=2 changed=2 unreachable=0 failed=0
  17. web2 : ok=2 changed=2 unreachable=0 failed=0
  18. web3 : ok=2 changed=2 unreachable=0 failed=0
  19. web4 : ok=2 changed=2 unreachable=0 failed=0

—list-hosts

查看playbok中的执行主机列表,ansible命令也支持 —list-hosts 选项。

  1. $ ansible-playbook -i hosts test.yml --list-hosts

查看每个成员所在的分组

一个IP可能在多个分组中。

  1. $ ansible all -a "echo {{group_names|to_json}}" # to_json为解决unicode问题

查看分组列表

也就是一共多少分组。

  1. $ ansible x.x.x.x -a "echo {{groups|list|to_json}}" # x.x.x.x是ansible包含的任意一个主机IP,也可以写 all

查看所有分组以及下面的主机

  1. $ ansible-inventory --list

-C 测试执行效果

仅仅是测试,并不会真正的执行。

  1. $ ansible-playbook -i hosts -C test.yml

ansible模块使用 - 图1

ansible-doc 查询模块使用

  1. $ ansible-doc -s script
  2. - name: Runs a local script on a remote node after transferring it
  3. script:
  4. chdir: # Change into this directory on the remote node before running the script.
  5. cmd: # Path to the local script to run followed by optional arguments.
  6. creates: # A filename on the remote node, when it already exists, this step will *not* be run.
  7. decrypt: # This option controls the autodecryption of source files using vault.
  8. executable: # Name or path of a executable to invoke the script with.
  9. free_form: # Path to the local script file followed by optional arguments.
  10. removes: # A filename on the remote node, when it does not exist, this step will *not* be run.

优化ansible执行策略

ansible的任务执行,是并发操作,默认开启5个进程执行,可以执行-f 定义并发进程数。
ansible默认5个并发进程,如果控制主机比较多,例如20个主机,那么会并行执行5台主机,只有这5台主机全部执行完一次任务,再继续下一批的5台执行任务,如果其中一台执行完任务,那么它默认也会等待那四台主机完成,然后再5台并行执行任务,这样的话,就会影响执行效率。

如果目标主机的网络稳定性不好,开启的进程就会一直等待最后一个任务执行完成,才继续下一个任务。

在使用playbook文件中,可以指定 strategy: free,表示异步执行,尽快切换到下一台主机(只要有一台主机执行任务完成,不会等待其他主机完成后再去执行其他主机),默认为linear。
如下:

  1. - hosts: test1
  2. become: yes
  3. become_user: root
  4. become_method: sudo
  5. gather_facts: no
  6. strategy: free # 增加此行

接下来是模块相关的语法,可以参考下解释更详细些更全面些的博文:ansible常用模块

get_url

下载一个url,功能相当于wget。

  1. - get_url:
  2. url: http://mirrors.aliyun.com/repo/epel-7.repo # 下载的url
  3. dest: /etc/yum.repos.d/ # 保存目录
  4. url_username: # 在需要验证时提供的用户名
  5. url_password: # 在需要进行验证时提供的密码
  6. mode: 0440 # 下载后的文件权限

service

控制服务的启停,等同于systemctl指令。

  1. - name: Enable firewalld
  2. service:
  3. name: firewalld
  4. state: started # 服务的状态可选值:reloaded, restarted, started, stopped
  5. enabled: yes # 是否开启自启,可选值:yes、no

user 和group模块

创建或删除用户、组,根据state来指定动作。

  1. - name: create user
  2. user:
  3. name: "{{ item}}"
  4. state: absent # present:添加用户;absent:删除用户
  5. remove: yes # 该选项只针对absent,表示是否删除用户相关的家目录。
  6. with_items: # 定义用户列表
  7. - testuser1
  8. - testuser2

如果是多个元素,比如创建用户时要指定用户所在组:

  1. - name: create group
  2. group: # group模块就在这里也展示了
  3. name: "{{ item }}"
  4. state: present
  5. with_items:
  6. - groupx1
  7. - groupx2
  8. - name: create user
  9. user:
  10. name: "{{ item.name }}"
  11. group: "{{ item.group }}" # 指定用户所属组,该组必须存在
  12. state: present
  13. with_items: # 定义多个元素
  14. - {name: 'userx1',group: 'groupx1'}
  15. - {name: 'userx2',group: 'groupx2'}

交互式创建用户的playbook

  1. [root@nginx ansible]# cat a.yml
  2. - name: test
  3. hosts: test1
  4. gather_facts: false
  5. vars_prompt:
  6. - name: "user_name" # 准备接受用户名
  7. prompt: "Enter user name" # 提示语句
  8. private: no # 用户输入的信息可以显示在屏幕上
  9. - name: "user_password" # 准备接受用户密码
  10. prompt: "Enter user password" # 提示语句
  11. encrypt: "sha512_crypt" # encrypt关键字表示对用户输入的信息进行哈希, “sha512_crypt”表示使用sha512算法对用户输入的信息进行哈希
  12. confirm: yes # 提示第二次输入确认密码
  13. tasks:
  14. - name: create user
  15. user:
  16. name: "{{user_name}}"
  17. password: "{{user_password}}"

copy 模块

copy模块用于拷贝目录或文件到受控端,若要将受控端的文件拷贝至ansible本机,则需使用 synchronize模块。

  1. # src可以指定为ansible主机上的绝对路径,也可以直接指定文件名,但需提前将文件放置 roles/file 目录下
  2. copy:
  3. src: /usr/local/{{ item }}
  4. dest: /usr/local/
  5. with_items:
  6. - a.sh
  7. - b.sh

file模块

file模块创建目录

  1. - name: Create directory
  2. file:
  3. path: "{{ item }}"
  4. state: directory # directory表示创建目录;link:创建软链接;absent:删除目录
  5. mode: 0777 # 目录权限
  6. with_items:
  7. - /usr/local/nginx
  8. - /usr/src/nginx

file模块创建软链接:

  1. - name: “创建一个软链接”
  2. file:
  3. src: /usr/src/nginx # 源目录
  4. dest: /home/nginx # 链接目录
  5. state: link
  6. mode: 0755

file模块也可以用来只设置权限,只需要指定path和mode两个选项即可。

unarchive解压模块

  1. - name: "解压一个包文件"
  2. unarchive:
  3. src: /usr/local/src/nginx-1.2.4.tar.gz # 指定要解压的压缩包(可以写绝对路径,也可把包放在file目录下,直接写包名),也可以指定为一个url
  4. copy: no # 当指定的src为一个url时,copy选项必须为no,默认为yes
  5. dest: /usr/local/src # 解压后的路径(客户端的路径)
  6. owner: lv # 解压后的属主
  7. group: lv # 解压后的属组
  8. list_files: yes # 如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的x
  9. mode: 0700 # 解压后的权限
  10. creates: /home # 幂等性相关设置,creates表示如果指定的目录存在,则不执行该模块

synchronize模块

此模块用于主机间互相拷贝文件或目录。

  1. - name: 将客户端的/tmp/目录下的a.shb.sh拷贝至ansible主机的/data/目录下
  2. synchronize:
  3. src: /tmp/{{ item }}
  4. dest: /data/
  5. mode: pull
  6. with_items:
  7. - a.sh
  8. - b.sh
  9. # 注意:指定的路径后面带 / 和不带 / 是有差别的
  10. # 带 / 表示此目录下的所有东西,不带 / 是指整个目录
  11. - name: ansible主机的/tmp目录下的所有文件和目录都拷贝至客户端的/data/目录下
  12. synchronize:
  13. src: /tmp/
  14. dest: /data/
  15. delete: yes # 默认情况下会保留 dest 端有,而 src 端没有的文件。可以通过 delete 参数设置为 yes 来删除 dest 端多余的文件。
  16. - name: ansible上的tmp目录拷贝至受控端上,并改名为 /dat 目录(主要是来比较 / 和不带 / 的区别)
  17. synchronize:
  18. src: /tmp
  19. dest: /dat
  20. delete: yes
  21. - name: ansible主机上的/tmp/目录下所有文件拷贝至客户端,并删除dest有,而src没有的文件>
  22. ,通过rsync_opts 指定 /tmp/a/b 这个目录不拷贝到客户端
  23. synchronize:
  24. src: /tmp/
  25. dest: /data/
  26. delete: yes
  27. rsync_opts: --exclude=a/b
  28. # 当远程节点为ServerB的时候,将ServerA的文件夹传输到ServerB上:
  29. - hosts: ServerB
  30. tasks:
  31. - name: Transfer file from ServerA to ServerB
  32. synchronize:
  33. src: /path/on/server_a
  34. dest: /path/on/server_b
  35. delegate_to: ServerA
  36. # 当远程节点为ServerA的时候,将ServerA的文件夹传输到ServerB上:
  37. - hosts: ServerA
  38. tasks:
  39. - name: Transfer file from ServerA to ServerB
  40. synchronize:
  41. src: /path/on/server_a
  42. dest: /path/on/server_b
  43. mode: pull
  44. delegate_to: ServerB

yum模块

yum模块中的state可选值如下:

  • present | installed:只是保证已经安装了所需的软件包,如果没有安装,则安装最新版本。
  • latest:如果没有安装则安装最新版本,如果安装了,则更新到最新版本。
  • absent | removed:删除指定的包。

默认state的值为absent。

yum模块中可以通过enablerepo(启用某个仓库),download_only(仅仅下载而不安装)、download_dir(如果设置了download_only,则可以通过此选项来指定下载目录。)

  1. # 安装epel源
  2. - name: install epel repo
  3. yum:
  4. name: epel-release
  5. state: latest
  6. # 以组的形式安装
  7. - name: install "Development tools"
  8. yum:
  9. name: "@Development tools" # 以组的形式安装,相当于grouplinstall
  10. state: present
  11. - name: upgrade all packages
  12. yum:
  13. name: "*"
  14. state: latest
  15. # 老版本的一次指定多个软件包,需要使用循环列表,在2.11版本后,推荐使用列表来定义多个软件包
  16. - name: install packages
  17. yum:
  18. name: "{{ item }}"
  19. state: latest
  20. with_items:
  21. - nginx
  22. - httpd
  23. # 仅下载多个软件包,不安装
  24. - name: download_only software
  25. yum:
  26. name: ['nginx', 'httpd', 'redis'] # 通过列表的形式来指定多个软件包
  27. download_only: yes
  28. download_dir: /usr/local/src/

script模块

  1. # 在受控机的/tmp/目录下执行ansible本机相应role目录下的file目录下的 a.sh 和 b.sh 两个脚本
  2. # 脚本路径也可以写ansible本机上的绝对路径
  3. - name: 指定目录下执行多个脚本
  4. script:
  5. cmd: '{{ item }}'
  6. args:
  7. chdir: /tmp/
  8. with_items: # 下面的两个脚本需放在相应role下的file目录中
  9. - a.sh
  10. - b.sh
  11. # 可以按照如下指定为ansible主机上的绝对路径
  12. # with_items:
  13. # - /root/ansible/c.sh
  14. # - /root/ansible/d.sh