自动化利器 Ansible – 从了解到应用

本文说明

本系列使用 ansible 2.9.27 版本来说明和汇总相关信息。

cat /etc/system-release
Red Hat Enterprise Linux Server release 7.8 (Maipo)
#
uname -a
Linux test01 3.10.0-1160.36.2.el7.x86_64 #1 SMP Wed Jul 21 11:57:15 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
#
ansible --version  # ansible版本
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/vipxf/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
#
yum info ansible  # 包信息
Loaded plugins: fastestmirror, product-id, search-disabled-repos, subscription-manager
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
Loading mirror speeds from cached hostfile
Installed Packages
Name        : ansible
Arch        : noarch
Version     : 2.9.27
Release     : 1.el7
Size        : 103 M
Repo        : installed
Summary     : SSH-based configuration management, deployment, and task execution system
URL         : http://ansible.com
License     : GPLv3+
Description : Ansible is a radically simple model-driven configuration management,
            : multi-node deployment, and remote task execution system. Ansible works
            : over SSH and does not require any software or daemons to be installed
            : on remote nodes. Extension modules can be written in any language and
            : are transferred to managed machines automatically.

#

独立章节索引

Ansible 概念介绍

Ansible是自由开源的配置和自动化工具。

主要特点

- 无客户端模式(agentless),无侵入性,只需在主控端部署Ansible环境,被控端无需做任何操作
- 丰富的内置模块满足绝大部分场景需求,调用特定模块可以完成特定任务
- 基于Python研发,支持API及自定义模块,二次开发相对容易
- 默认使用SSH协议和节点进行通信
- 强大的playbook机制,配置语法使用yaml和Jinja模板语言,便于配置管理和实现复杂功能
- 具有幂等性,自动跳过没有变化的部分,也就是一个操作执行一次和多次的结果相同
- 对云计算平台和大数据提供了支持

Ansible 使用模式

- 结合CMDB:通过CMDB下发指令调用Ansible完成相关操作
- API调用:远程调用Ansible提供丰富的API接口
- Ad-Hoc命令:直接通过Ad-Hoc命令集执行相关操作,多用于非固化需求、临时性操作和二次开发接口调用的场景
- playbook执行:运行Playbook按序执行任务集

自动化利器 Ansible - 从了解到应用

Ansible由控制主机对被管节点的操作方式为 Ad-Hoc 和 Playbook。

  • Ad-Hoc模式使用单个模块,支持批量执行单条命令。
  • Playbook模式是Ansible主要管理方式,Playbook通过多个Task集合完成一类功能,可以简单地把 Playbook理解为通过组合多条Ad-Hoc操作的配置文件。

Ansible 架构及流程

自动化利器 Ansible - 从了解到应用
Ansible 主要由五部分组成
- Ansible      Ansible核心
- Modules      包括核心模块和自定义模块
- Plugins      插件,对模块功能的补充,包含连接插件、邮件插件等
- Playbooks    剧本,定义任务的配置文件
- Inventory    定义管理主机的清单

ansible 命令执行过程
1. Ansible加载配置文件,默认为/etc/ansible/ansible.cfg
2. Ansible读取Inventory文件(默认为/etc/ansible/hosts),获取管理主机列表及相关变量信息
3. 根据参数调用对应配置和模块,产生临时py文件
4. 通过SSH方式传输到目标主机(默认为~/.ansible/tmp目录)
5. 设置临时py文件的执行权限,执行操作并返回结果
6. 删除临时py文件并退出

Ansible 基础信息

Ansible 主要目录

配置文件目录
/etc/ansible/
- ansible.cfg  # Ansible 主配置文件
- hosts  # Inventory,定义目标主机清单的文件
- roles  # 角色目录,用于定义角色

执行文件目录
/usr/bin/

Lib库依赖目录
/usr/lib/python2.7/site-packages/ansible

Help文档目录
/usr/share/doc/ansible-2.9.27/

Ansible模块目录
/usr/share/ansible/
- collections  # 目录
- plugins      # 插件模块目录
- roles        # 角色模块目录

Ansible 配置文件

默认Ansible配置文件存放在 /etc/ansible/ansible.cfg

常见参数
inventory = /etc/ansible/hosts     # 主机清单inventory文件的位置
library = /usr/share/ansible       # 存放Ansible模块的目录,支持用":"隔开多个目录
forks = 5                          # 并发连接数,默认为5
remote_port = 22                   # 连接主机节点的端口,默认为22端口,建议修改
host_key_checking = False          # 是否检查SSH主机的密钥,值为True/False
timeout = 60                       # SSH连接的超时时间,单位为秒
log_path = /var/log/ansible.log    # 存储ansible日志的文件(默认不开启)

Ansible 执行文件

$ ll /usr/bin/*ansible*  # 相关执行文件
lrwxrwxrwx 1 root root    20 Mar 17  2022 /usr/bin/ansible -> /usr/bin/ansible-2.7
lrwxrwxrwx 1 root root    20 Mar 17  2022 /usr/bin/ansible-2 -> /usr/bin/ansible-2.7
-rwxr-xr-x 1 root root  5933 Jan 16  2022 /usr/bin/ansible-2.7
lrwxrwxrwx 1 root root     7 Mar 17  2022 /usr/bin/ansible-config -> ansible
-rwxr-xr-x 1 root root 13432 Jan 16  2022 /usr/bin/ansible-connection
lrwxrwxrwx 1 root root    28 Mar 17  2022 /usr/bin/ansible-console -> /usr/bin/ansible-console-2.7
lrwxrwxrwx 1 root root    28 Mar 17  2022 /usr/bin/ansible-console-2 -> /usr/bin/ansible-console-2.7
lrwxrwxrwx 1 root root     7 Mar 17  2022 /usr/bin/ansible-console-2.7 -> ansible
lrwxrwxrwx 1 root root    24 Mar 17  2022 /usr/bin/ansible-doc -> /usr/bin/ansible-doc-2.7
lrwxrwxrwx 1 root root    24 Mar 17  2022 /usr/bin/ansible-doc-2 -> /usr/bin/ansible-doc-2.7
lrwxrwxrwx 1 root root     7 Mar 17  2022 /usr/bin/ansible-doc-2.7 -> ansible
lrwxrwxrwx 1 root root    27 Mar 17  2022 /usr/bin/ansible-galaxy -> /usr/bin/ansible-galaxy-2.7
lrwxrwxrwx 1 root root    27 Mar 17  2022 /usr/bin/ansible-galaxy-2 -> /usr/bin/ansible-galaxy-2.7
lrwxrwxrwx 1 root root     7 Mar 17  2022 /usr/bin/ansible-galaxy-2.7 -> ansible
lrwxrwxrwx 1 root root     7 Mar 17  2022 /usr/bin/ansible-inventory -> ansible
lrwxrwxrwx 1 root root    29 Mar 17  2022 /usr/bin/ansible-playbook -> /usr/bin/ansible-playbook-2.7
lrwxrwxrwx 1 root root    29 Mar 17  2022 /usr/bin/ansible-playbook-2 -> /usr/bin/ansible-playbook-2.7
lrwxrwxrwx 1 root root     7 Mar 17  2022 /usr/bin/ansible-playbook-2.7 -> ansible
lrwxrwxrwx 1 root root    25 Mar 17  2022 /usr/bin/ansible-pull -> /usr/bin/ansible-pull-2.7
lrwxrwxrwx 1 root root    25 Mar 17  2022 /usr/bin/ansible-pull-2 -> /usr/bin/ansible-pull-2.7
lrwxrwxrwx 1 root root     7 Mar 17  2022 /usr/bin/ansible-pull-2.7 -> ansible
lrwxrwxrwx 1 root root    26 Mar 17  2022 /usr/bin/ansible-vault -> /usr/bin/ansible-vault-2.7
lrwxrwxrwx 1 root root    26 Mar 17  2022 /usr/bin/ansible-vault-2 -> /usr/bin/ansible-vault-2.7
lrwxrwxrwx 1 root root     7 Mar 17  2022 /usr/bin/ansible-vault-2.7 -> ansible
$

Ansible 常见模块

Ansible基于模块工作,本身没有批量部署的能力。
可以理解为Ansilbe提供了框架来运行具备批量部署能力的指定功能模块。

通过 ansilbe-doc 命令查看模块帮助信息,类似man命令
ansible-doc -l                  # List available plugins
ansible-doc -l | grep "copy"    # 查找名称包含copy字符的模块
ansible-doc        # 显示模块的说明信息
ansible-doc -s     # Show playbook snippet for specified plugin(s)

常见模块
## command     在指定主机上执行命令(默认模块),不支持变量、管道、重定向等shell特性
## ping        测试指定主机连接性
## shell       在指定主机上执行命令或运行脚本,打开远程主机的shell进程的一个子shell运行命令,支持shell的变量、管道、重定向等特性
## script      调用本地脚本在远程主机执行
## stat        获取文件信息
## setup       主机系统信息,收集facts
## copy        复制文件到远程主机的指定位置
## fetch       复制指定主机的文件到本地
## get_url     在远程主机下载指定的url地址,支持文件校验
## file        设置文件属性
## cron        设置计划任务
## group       管理用户组
## user        管理用户
## service     管理服务状态
## yum         管理程序包
## hostname    管理主机名称

## git         代码及版本管理
## B           后台管理
## assemble    文件组装,可以将多份配置文件组装成一份配置文件
## ini         ini文件管理模块
## url         web请求,发送HTTP协议请求并得到返回的状态码
## apt         APT包管理模块

Ansible 命令讲解

Ansible 命令集

以下所有命令均可使用-h参数获取帮助信息
ansible               # Define and run a single task 'playbook' against a set of hosts  # 常用命令
ansible-config        # View ansible configuration.

ansible-console       # REPL console for executing Ansible tasks.  # 交互式工具,相当linux中的shell,不常用
ansible-doc           # plugin documentation tool  # 查询模块的文档说明,类似linux中的man,常用命令
ansible-galaxy        # Perform various Role and Collection related operations.

ansible-inventory     # Show Ansible inventory information, by default it uses the inventory script JSON format
ansible-playbook      # Runs Ansible playbooks, executing the defined tasks on the targeted hosts.  # 执行系列任务,类似linux中的sh,常用命令
ansible-pull          # pulls playbooks from a VCS repo and executes them for the local host
ansible-vault         # encryption/decryption utility for Ansible data files

Ansible 常用命令集

常用命令集

ansible
Ansible指令的核心部分,主要用于执行ad-hoc命令,也就是单条命令
默认使用command模块,默认的使用模块可以在ansible.cfg中进行定义

ansible-doc
用于查看模块信息,
参数 -l 列出可用的插件
参数 -s 用于查看指定模块的用法,例如"ansible-doc -s shell"

ansible-playbook
读取playbook文件内容并执行定义的任务
对于固化的需求通常采用playbook方式定义和实现

ansible-vault
主要应用于包含敏感信息的场景,可以加密和解密敏感信息
经过加密后的playbook,编辑时需要输入事先设定的密码才能打开
使用 --ask-vault-pass 参数执行加密后的playbook文件

ansible-config
查看ansible的配置
参数 list 打印所有配置参数,参数 view 查看配置文件
结合 grep 使用可以获取具体配置信息,例如"ansible-config view |grep -v "#" |grep host_key_checking"

Ansible ad-hoc命令

ansible  [-f forks] [-m module_name] [-a args]
      命令生效的主机: //all

常用选项  通过 ansible -h 命令获取详细信息
-v                    # 输出详细执行过程信息  verbose mode (-vvv for more, -vvvv to enable connection debugging)
-i inventory_file     # 指定inventory文件,默认为/etc/ansible/hosts
-f forks              # 指定并发线程数(一次处理多少个主机),默认5个线程
-m module_name        # 指定执行使用的模块
-M directory          # 指定模块存放路径,默认为/usr/share/ansible
-a args               # 指定模块参数
-l hosts_ip           # 限定主机(只在限定主机上执行任务)

--become-method BECOME_METHOD    # 提权方法,默认为sudo,一般为su
--become-user BECOME_USER        # 切换用户,默认为root
-K, --ask-become-pass            # 请求提权密码

--list-hosts        # 列出此次的主机列表,但不做任何改变
--syntax-check      # 语法检查
-C, --check         # 检验可能的错误,但不做任何改变

主机名文件保留
- "-t"或"--tree"选项可以将ansible的执行结果按主机名保存在指定目录下的文件中
- 使用"-t"选项可以将第一次执行的结果按主机名保存在文件中, 此后即使不使用"-t"选项也能提升执行速度

命令示例
ansible 192.168.56.3 -a 'hostname'  # 默认使用command模块(不支持变量、管道等)
ansible 192.168.56.3 -m command -a 'hostname'
ansible Test --list  # 列出Test组所有的主机列表

ansible Test:Test2 -m ping  # 通过ping模块检查Test组和Test2组的主机是否存活
ansible Test:!Test2 -m ping  # 在Test组但不在Test2组的主机
ansible Test:&Test2 -m ping  # 同时存在Test组和Test2组的主机
ansible Tes* -m ping  # 组名开头为Tes的主机

ansible all -m shell -a 'hostname && date'  # 通过shell模块在所有主机试行shell命令
ansible all -f 10 -m shell -a 'hostname && date;cat /etc/system-release'  # shell模块支持变量、管道、if判断等复杂命令

部分参数如果不指定,将采用ansible.cfg中的设置值,或者采用原始默认值。

自动化利器 Ansible - 从了解到应用

Ansible ad-hoc常用命令

ping        测试指定主机连接性
ansible ta -m ping
ansible -i /etc/ansible/hosts ta -m ping  #  指定inventory文件

command     在指定主机上执行命令(默认模块),不支持变量、管道、重定向等shell特性
ansible ta -m command -a "chdir=/home/ ls ./"  # 在远程主机上切换到home目录执行ls命令

shell       在指定主机上执行命令或运行脚本,打开远程主机的shell进程的一个子shell运行命令,支持shell的变量、管道、重定向等特性
ansible ta -m shell -a 'hostname && date;cat /etc/system-release'  # 支持变量、管道、if判断等复杂命令
ansible ta -m shell -a "echo 'this is a test' > test.txt" -C  # 验证可能的错误,但不做任何改变
ansible ta -m shell -a 'echo "123456"|passwd --stdin root' -K  # 更改root密码

script      调用本地脚本在远程主机执行,但只能执行脚本,不能调用其他指令,且不支持管道命令
ansible ta -m script -a "/home/vipxf/test.sh"
ansible ta -m script -a "removes=/home/vipxf/test.sh /home/vipxf/test2.sh" -o  # 如果远程主机上test.sh文件存在就执行本地脚本test2.sh,否则就不执行
ansible ta -m script -a "creates=/home/vipxf/test.sh /home/vipxf/test2.sh" -o  # 如果远程主机上test.sh文件存在就不执行本地脚本test2.sh,否则就执行

raw         类似shell,支持管道命令,可用于没有python环境的远程主机
ansible ta -m raw -a "cd /home;pwd"

stat        获取文件信息
ansible ta -m stat -a "path=/etc/ansible/hosts"

setup       系统信息,收集facts
ansible ta -m setup
ansible ta -m setup | grep "xxx"  # 获取主机所有facts然后结合grep命令过滤
ansible ta -m setup -a "filter=ansible_os_family"  # 通过filter参数来查看指定信息
ansible ta -m setup -a 'filter="*mem*"' --tree ./facts  # 通过filter参数查看指定信息并按主机名保存到facts目录

copy        复制文件到远程主机的指定位置
ansible ta -m copy -a "src=/etc/hosts dest=~/test.hosts mode=664 owner=vipxf group=vipxf"  # 复制本地文件到远程主机并设置权限
ansible ta -m copy -a "content="this is a test" dest=~/test.hosts mode=664 owner=vipxf group=vipxf"  # 在远程主机创建指定内容文件并设置权限

fetch       复制指定主机的文件到本地
ansible ta -m fetch -a "src=~/testfile.txt dest=~/"  # 将在指定目录下创建对应IP文件夹来存放文件,保留了原目录结构

get_url     在远程主机下载网络文件,支持文件校验
ansible ta -m get_url -a "url=http://172.20.5.3/pub/soft/docker/docker-19.03.9.tgz dest=~/ mode=655 owner=vipxf"  # 下载文件到远程主机指定目录并设置权限

file        设置文件属性
ansible ta -m file -a "path=~/testfile.txt mode=755 owner=vipxf group=vipxf"  # 更新文件属性
ansible ta -m file -a "path=~/testfile.txt state=touch mode=644"  # 创建文件
ansible ta -m file -a "path=~/testfile.txt state=absent"  # 删除文件
ansible ta -m file -a "path=~/testdir mode=755 state=directory"  # 创建目录

cron        设置计划任务
ansible ta -m cron -a "minute=0 hour=22 job='/home/vipxf/testcron.sh' name='test cron'"  # 创建计划任务
ansible ta -m cron -a "name='test cron' state=absent"  # 删除计划任务

group       管理用户组
ansible ta -b --become-user root --become-method su -m group -a "name=test system=yes" --ask-become-pass  # 创建用户组
ansible ta -b --become-user root --become-method su -m group -a "name=test state=absent" --ask-become-pass  # 删除用户组

user        管理用户
ansible ta -b --become-user root --become-method su -m user -a "name=test system=yes group=test password=pw@123" -K  # 创建用户
ansible ta -b --become-user root --become-method su -m user -a "name=test state=absent force=yes" -K  # 删除用户

service     管理服务
ansible ta -b --become-user root --become-method su -m service -a "name=sshd enabled=yes state=started" -K  # 启动httpd服务并且不设置开机启动
ansible ta -b --become-user root --become-method su -m service -a "name=sshd state=stopped" -K  # 停止httpd服务并且不设置开机启动

yum         管理程序包
ansible ta -b --become-user root --become-method su -m yum -a "name=httpd state=present" -K  # 安装包,也可以将state设为installed
ansible ta -b --become-user root --become-method su -m yum -a "name=httpd state=latest disable_gpg_check=no" -K  # 关闭完整性校验,安装最新版包
ansible ta -b --become-user root --become-method su -m yum -a "name=httpd state=absent" -K  # 卸载包,也可以将state设为removed
ansible ta -b --become-user root --become-method su -m yum -a "name=nginx state=latest enablerepo=local" -K  # 启用本地yum源安装最新版软件包

hostname    管理主机名称
ansible ta -b --become-user root --become-method su -m hostname -a "name=test" --ask-become-pass  # 更改远程主机名

Ansible 变量使用

  • Ansible的变量名仅能由字母、数字和下划线组成,且只能以字母开头。
  • Python关键字和playbook关键字都不能作为有效的变量名。
  • Ansible的变量可以被定义在playbook、inventory、yaml格式文件、角色和命令行中,也可以将任务的输出定义为变量。

Ansible 自定义变量

方式1:在Inventory中为主机或组定义专用变量
[groupname]
192.168.56.1 variable_name=value
[groupname:vars]
variable_name=value
[all:vars]
ansible_ssh_port="2222"

方式2:在playbook中通过关键字vars或vars_files定义变量
vars:
  - var_name: value
  - var_name: value
vars_files:
  - ./external_vars.yml  # 变量文件内容遵循yml格式

方式3:在playbook中把任务的输出通过关键字register定义为变量,然后用于其他任务
tasks:
    - name: test
      shell: /usr/bin/foo
      register: foo_result

方式4:在playbook中使用变量,执行palybook时通过命令行传递变量,通过"-e"或"--extra-vars"参数传递的变量优先级更高
ansible-playbook test.yml --extra-vars "hosts=Test user=anliven"

方式5:指定主机角色时通过 roles 传递变量,并在角色内通过 var_name 调用
roles:
  - { role: ROLE_NAME, var: value, ...}

Ansible 系统变量

远程主机的系统信息统称为facts
facts信息是JSON格式的数据结构,ansible_facts是最上层,可以使用 ansible_facts 变量查看所有内容
此外默认情况下使用 ansible_ 前缀可以将一些fact作为顶级变量访问
通过 setup 模块可以查看指定主机的所有facts信息,通过使用filter参数来查看指定信息

ansible  -m setup  # 查看指定主机的facts信息
ansible ta -m setup | grep "xxx"  # 获取主机所有facts然后结合grep命令过滤
ansible ta -m setup -a "filter=ansible_os_family"  # 通过filter参数来查看指定信息
ansible ta -m setup -a 'filter="*mem*"' --tree ./facts  # 通过filter参数查看指定信息并按主机名保存到facts目录

Ansible 引用变量

普通变量
通过 {{ var_name }} 方式引用

关键字register或系统fact变量
- 返回结果集通常是嵌套yaml或者json的数据结构
- 通过  {{ var_name.stdout }}  或 {{ ansible_facts["eth0"]["ipv4"]["address"] }} 的方式引用

Ansible 变量优先级

优先级
1. 命令行中定义的变量(用-e或--extra-vars定义的变量)
2. 在Inventory中定义的连接变量(比如:ansible_ssh_user)
3. 普通变量(命令行转换、play中的变量、included的变量、role中的变量等)
4. 在Inventory中定义的其他变量
5. Facts变量

Ansible 清单定义

Ansible 主机清单(Inventory)

Ansible通过Inventory(可管理的主机集合)对远端服务器或者主机进行统一操作和管理,默认将主机列在一个文本文件中,这个文件称为Inventory文件。

  • 默认的路径和文件为: /etc/ansible/hosts
  • 可以通过ANSIBLE_HOSTS环境变量、ansible.cfg文件中inventory参数来指定,或者运行ansible和ansible-playbook时使用-i参数临时指定
  • 可以有多个 inventory 文件,也可以通过 Dynamic Inventory 动态生成
  • inventory文件为 INI文件格式,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中
  • 组名建议使用”_”来连接字符,例如”aaa_bbb_ccc”

Ansible Inventory文件

192.168.56.1    # 未分组
test.example.com
127.0.0.1 ansible_connection=local  # 直接访问本地主机,而不是通过SSH

[Test]  # 已分组名称
192.168.56.1
192.168.56.2
192.168.56.[3:4]  # 通过列表方式通配地址
192.168.56.[5:6]  # 多个通配地址
anliven-[a:d].example.com  # 通配主机域名

[Test:vars]  # 定义组变量
ansible_ssh_user="anliven"
ansible_ssh_pass="anliven"
ansible_ssh_port="22"

[Test2]  # 在分组中指定变量
192.168.56.[1:2] ansible_ssh_user=anliven ansible_ssh_pass=Anliven
192.168.56.[3:4] ansible_ssh_user=anliven ansible_ssh_pass=Anliven
192.168.56.[3:4]

[Test3]  # 在分组中切换root用户
192.168.56.[1:2] ansible_ssh_port="22" ansible_ssh_user="anliven" ansible_ssh_pass="anliven"  ansible_become_pass="Anliven"

[Temp]
192.168.56.1:2222  # 指定端口
192.168.56.2 http_port=8080 var1=test1 var2=test2   # 定义主机时为其添加主机变量以便于在playbook中使用

[Temp:vars]
ansible_ssh_user="anliven"
ansible_ssh_pass="anliven"

[TestGroup:children]  # 嵌套组,TestGroup为名称,其他为固定格式
Test1
Test2
Test3

[TestGroup:vars]  # 嵌套组的变量只能在ansible-playbook中使用
var1="test1"
var2="123"

[all:vars]  # 类似全局变量,对inventory文件中所有节点都有效
ansible_ssh_port="22"

Ansible Inventory内置参数

Ansible Inventory文件中可使用的行为参数

自动化利器 Ansible - 从了解到应用

可以在ansible.cfg中的[defaults]部分更改一些Inventory行为参数的默认值

自动化利器 Ansible - 从了解到应用

Ansible Dynamic Inventory

  • 动态Inventory也就是Ansible所有的Inventory文件里面的主机列表和变量信息都支持从外部拉取,例如CMDB等。
  • 避免主机列表不准确和频繁大量的手动更新的问题
  • 也可以通过设置ansible.cfg文件中的inventory参数为一个可执行脚本,将CMDB等其他系统的主机信息同步至Ansible中。
  • 对动态Inventory脚本的参数和输出必须遵循格式规则

Ansible Inventory分割

通过Inventory分割满足如下需要

  • 按不同业务/系统分割成的多个Inventory文件
  • 同时使用常规Inventory文件和动态Inventory脚本

实现方式

  • 配置ansible.cfg文件的hostfile参数,指定放置inventory文件目录作为Inventory,Ansible将合并目录里所有文件为一个完整的Inventory
  • 也可以在命令行中使用-i命令来指定特定的Inventory文件
[defaults]

hostfile = /etc/ansible/inventory  # 指定目录作为Inventory

Ansible 剧本执行

Ansible Playbook 基础介绍

剧本(Playbook) 是 ansible 用于配置,部署,和管理被控节点的剧本。

  • playbook类似Linux的shell脚本,用于实现和管理大量的、规律的、复杂的操作任务
  • playbook方便代码和配置的重用、移植性好,同时也易于管理

Playbook格式

playbook文件由YMAL语言编写,需遵循yaml格式要求
  1. 第一行以 "---" 开始,表明YMAL文件的开始(非playbook强制要求,没有也能通过语法检查)
  2. 列表元素以"-"开头,后面带有一个空格,然后元素内容
  3. 对象的键与值以":"和一个空格来分隔
  4. 相同层次内容必须保持相同的缩进和对齐,否则会报错
  5. 在同一行中,"#" 之后的内容表示注释
  6. 文件名应该以.yml或.yaml结尾

编写完成后可以通过 --syntax-check 子命令检查语法错误
ansible-playbook --syntax-check sample.yaml

Playbook组成

  • 一个Playbook可以包括一个或多个Play。
  • 一个Play由Host的无序集合与Task的有序列表组成。
  • 每一个Task仅由一个模块构成。
    自动化利器 Ansible - 从了解到应用
play
- 一个Playbook包括一个或多个Play
- 一个Play由Host的无序集合与Task的有序列表组成

目标定义部分:host
- 执行playbook的主机信息

变量定义部分:variable
- 执行playbook需要的变量
- 设置的ansible配置变量,例如gather_facts

任务定义部分:tasks & module
- 在目标主机执行的任务列表和调用的模块
- Play的主体部分,Task列表中的各任务按次序逐个在Hosts中的指定主机上执行
- 每一个Task仅由一个模块构成
- 建议为每一个Task设置一个Name,便于在运行Playbook时从输出结果辨别task信息
- Ansible的自带模块Command模块和Shell模块无需使用key=value格式,可以直接编写要执行的命令

触发器定义部分:handlers
- task执行完成后需要调用的任务,通常结合关键字notify
- 由通知者进行的Notify,如果没有被Notify,则Handlers不会执行,如果被Notify了,则Handlers被执行
- 不管有多少个通知者进行了Notify,等到Play中的所有Task都执行完成之后,Handlers也只会被执行一次
- 实质上也是Task的列表

Ansible Playbook 示例

[root@test01 ansible-test]# pwd
/root/ansible-test
[root@test01 ansible-test]#
[root@test01 ansible-test]# ll
total 4
drwxr-xr-x 2 root root  24 Oct 17 09:47 conf
-rw-r--r-- 1 root root 922 Oct 14 11:24 sample.yaml
[root@test01 ansible-test]#
[root@test01 ansible-test]# tree
.
├── conf
│   └── httpd.conf
└── sample.yaml

1 directory, 2 files
[root@test01 ansible-test]#
[root@test01 ansible-test]# cat conf/httpd.conf
MaxClients        {{ maxClients }}
Listen        {{ httpd_port }}
[root@test01 ansible-test]#
[root@test01 ansible-test]# cat sample.yaml
- hosts: ta
  remote_user: vipxf
  gather_facts: no
  vars:
    - package: vim
  tasks:
    - name: install vim
      yum: name={{ package }} state=latest
    - name: install configuration file
      become: yes
      become_method: su
      become_flags: "-"
      become_user: root
      template: src=/root/ansible-test/conf/httpd.conf dest=/root/test-template.conf
      notify:
      - check-hostname-date
    - name: copy file
      copy: src=/root/ansible-test/conf/httpd.conf dest=/home/vipxf/test-copy.conf
  handlers:
    - name: check-hostname-date
      shell: hostname && date
      ignore_errors: True
- hosts: ta
  remote_user: vipxf
  gather_facts: no
  become: yes
  become_method: su
  become_flags: "-"
  become_user: root
  vars:
    - newgroup: testgroup
    - newuser: testuser
  tasks:
    - name: create new group
      group: name={{ newgroup }} system=yes
    - name: create new user
      user: name={{ newuser }} group=testgroup system=yes
[root@test01 ansible-test]#
[root@test01 ansible-test]# cat /etc/ansible/hosts
[ta]
172.20.8.247 ansible_ssh_port=2222 ansible_ssh_user=vipxf ansible_ssh_pass=Anliven09!

[ta:vars]
httpd_port=80 maxClients=10
[root@test01 ansible-test]#

Ansible playbook 示例说明

- hosts: ta  # 指定执行指定任务的主机,可以通过一个或多个由冒号分隔主机组
  remote_user: vipxf  # 指定在远程主机执行任务的用户,也能用在task中
  gather_facts: no
  vars:
    - package: vim
  tasks:  # 任务列表,在指定主机上按顺序执行各任务
    - name: install vim  # 每个任务的名称,用于输出执行结果
      yum: name={{ package }} state=latest
    - name: install configuration file
      become: yes
      become_method: su
      become_flags: "-"
      become_user: root
      template: src=/root/ansible-test/conf/httpd.conf dest=/root/test-template.conf
      notify:  # 此任务状态为changed时采取的操作,在handlers中定义
      - check-hostname-date
    - name: copy file
      copy: src=/root/ansible-test/conf/httpd.conf dest=/home/vipxf/test-copy.conf
  handlers:  # 触发器,在被指定任务通知和所有任务完成的情况下只执行一次,实质上也是按序执行的任务列表
    - name: check-hostname-date
      shell: hostname && date
      ignore_errors: True  # 如果命令或脚本的退出码不为零,使用ignore_errors来忽略错误信息

- hosts: ta  # playbook文件可以有多个play
  remote_user: vipxf
  gather_facts: no
  become: yes
  become_method: su
  become_flags: "-"
  become_user: root
  vars:
    - newgroup: testgroup
    - newuser: testuser
  tasks:
    - name: create new group
      group: name={{ newgroup }} system=yes
    - name: create new user
      user: name={{ newuser }} group=testgroup system=yes

相关命令

Ansible具有幂等性,会自动跳过没有变化的部分
建议使用绝对路径来执行playbook的yaml文件
语法检查 和 预测试 不能保证结果绝对正确,实际的运行测试是有必要的
特别注意yml文件的内容格式(空格、缩进)、特殊字符等,必要时重写重建

## 检查内容语法错误
ansible-playbook --syntax-check sample.yaml
## 预测试(不改变目标主机的任何设置)
ansible-playbook --check sample.yaml --ask-become-pass
ansible-playbook -C sample.yaml --ask-become-pass

- name: test-root
  hosts: ta
  remote_user: vipxf
  gather_facts: no
  become: yes
  become_user: root
  become_method: su
  become_flags: "-"
  vars:
    ansible_become_pass: "{{ root_pass_input }}"
  tasks:
    - name: test
      shell: date && sleep 3
      ignore_errors: True
[root@test01 ansible-test]#
[root@test01 ansible-test]# ansible-playbook  test-temp.yaml -e root_pass_input=redhat

PLAY [test-root] **************************************************************************************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************************************************************************************
changed: [172.20.8.247]

PLAY RECAP ********************************************************************************************************************************************************************************************************************
172.20.8.247               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@test01 ansible-test]#

3 – Ansible 简单的复用方式

通过关键字include可以实现简单的代码复用。

在playbook中,Include 指令可以跟task 混合在一起使用
  - tasks:
      - include: tasks/foo.yml  # 引用配置文件

参数化的include
  - tasks:
      - include: aaa.yml user=anliven  # 引用配置文件的同时传入变量
      - include: bbb.yml pwd=P@ssw0rd

4 – Ansible task通知多个handlers任务

通过关键字listen为handlers中的一个或多个触发器任务指定主题,task就可以按主题名进行通知。
触发顺序按照handler定义的先后顺序执行。

`yaml

Original: https://www.cnblogs.com/anliven/p/16859401.html
Author: Anliven
Title: 自动化利器 Ansible – 从了解到应用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/799335/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球