1、ansible 功能和特性
- 模块化:调用特定的模块完成特定任务,支持自定义模块,可使用任何编程语言写模块(账号,软件等)。ansible 模块非常多,大约3000多个,但常用也就二三十个左右。
- Paramiko(python对ssh的实现),PyYAML,Jinja2(模板语言)三个关键模块
- 基于Python语言实现,软件是用python开发的。
- 部署简单,基于python和SSH(默认已安装),agentless 无需客户端、无需代理不依赖PKI(无需ssl)
- 安全,基于OpenSSH
- 幂等性:一个任务执行1遍和执行n遍效果一样。不因重复执行带来意外情况。注意:此特性非绝对
- 支持playbook编排任务,YAML格式,编排任务,支持丰富的数据结构 剧本演员要按照 系统按照你规定的方式去执行命令
- 较强大的多层解决方案 role
2、 ansible 组成
INVENTORY 主机清单
:Ansible需要管理的主机的清单,要把IP地址 填写到 /etc/anaible/hosts文件中。MODULES 功能模块
:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义。PLUGINS 补充功能
:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用API 应用接口
:供第三方程序调用的应用程序编程接口 信息交互共享
3、ansible 安装
js
`yum 安装:`
yum install epel-release.noarch -y
yum install ansible -y
`查看版本:`
[root@7-3 ~]# ansible --version
ansible 2.9.27
`查看配置文件:`
[root@7-3 ~]# rpm -qc ansible
/etc/ansible/ansible.cfg //这个基本上不需要改
/etc/ansible/hosts //主机清单,很重要⭐
ansible软件,不需要手动打开或者关闭,当使用时会自动起,使用完毕,软件会自动关。
4、配置文件
文件类型 | 对应路径 |
---|---|
主配置文件 | /etc/ansible/ansible.cfg⭐ |
主机清单 | /etc/ansible/hosts⭐ |
存放角色的目录 | /etc/ansible/roles/ |
4.1 主配置文件
js
vim /etc/ansible/ansible.cfg //内容基本不需要改动
4.2 主机清单 inventory⭐⭐
ansible的主要功能在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory 主机清单文件中将其 分组
js
*****参数详细说明:
ansible_ssh_host //将要连接的远程主机名
ansible_ssh_port //修改端口号
192.168.1.100:2222 //指定非默认端口
js
vim /etc/ansible/hosts //hosts清单决定了,可以管理哪些服务器
[web] //组名
192.168.125.120 //主机号
192.168.125.130
[db] //第二个组名
192.168.125.130 //主机号可以重复
192.168.125.140
[all] //组名也可以嵌套
web
db
192.168.125.[100:105] //连续的主机,100到105之间的IP
4.3 ssh免密登录⭐
ansible的原理 是使用ssh协议,所以需要设置 ssh免密登录,那么如何设置免密登录呢?
- 关闭验证信息:
js
`方法一:`
vim /etc/ssh/ssh_config
35 StrictHostKeyChecking no //第35行,删除注释;并将ask改为no
`方法二:`
vim /etc/ansible/ansible.cfg
71 host_key_checking = False
//开启71行的ansible的不验证即可,去掉注释
谁主动,谁是客户端。
- 免密登录:(临时性)
js
[root@7-1 ~]# ssh-keygen //一直回车就行
[root@7-1 ~]# cd .ssh/
[root@7-1 ~]# ssh-copy-id -i id_rsa.pub 192.168.125.130 //需要输入一次密码
[root@7-1 .ssh]# ssh 192.168.125.130
Last login: Mon Jun 24 15:17:54 2024 from 192.168.125.100 //实现免密登录
小拓展1:
js
ansible web -m ping
命令 组名 指定模块 ping模块
上面命令执行之前一定要先设置免密登录!!!因为密码不同 无法一起管理!!!
小拓展2:passwd命令,可以修改当前用户的密码
5、ansible 工具⭐⭐
| 工具类型 | 对应路径 |
|-------------------------------------|---------------------------|---------------------------|
| 主程序,临时命令执行工具 | /usr/bin/ansible |
| 查看配置文档,模块功能查看工具,相当于`ansible-doc -l | grep 关键字 具体模块名字` | /usr/bin/ansible-doc⭐ |
| 定制自动化任务,编排剧本工具,相当于bash | /usr/bin/ansible-playbook |
小拓展:ansible-doc使用方法
js
ansible-doc 模块名
ansible-doc yum | grep -i -A 20 example //查看yum模块的模板,并过滤出后面20行
5.1 ansible 语法和选项⭐
ansible语法格式:
js
ansible <host-pattern> [-m module_name] [-a args]
命令 主机或者清单中的组 -m 指定模块 -a 执行的任务(模块语法)
选项:
选项 | 含义 |
---|---|
-k | 使用密码验证(不建议使用) |
-m | 指定模块, 默认为command,也可以修改默认模块 |
-a | 执行的命令(模块语法) ,临时性的命令、一次性任务 |
--version | 显示版本 |
-v | 显示详细过程 |
--list-hosts | 显示主机列表,可简写 --list |
-h,--help | 帮助 |
-C, --check | 检查,并不执行 |
-T, --timeout=TIMEOUT | 执行命令的超时时间,默认10s |
-u, --user=REMOTE_USER | 执行远程执行的用户,默认root |
-b, --become | 代替旧版的sudo 切换 |
--become-user=USERNAME | 指定sudo的runas用户,默认为root vim /etc/sudoers 用户权限 |
-K, --ask-become-pass | 提示输入sudo时的口令 |
-f FORKS, --forks FORKS | 指定并发同时执行ansible任务的主机数 |
示例:
js
`支持通配符:`
ansible all -m ping //all 代表所有主机
ansible "*" -m ping //*也代表所有主机,等价于ansible all -m ping
ansible 192.168.125.* -m ping //192.168.125.0段
ansible "192.168.125.120 192.168.125.130" -m ping
`或关系:`
ansible 'web:accp' --list-hosts //冒号代表 或
hosts (4):
192.168.91.101
192.168.91.102
192.168.91.103
192.168.91.105
`并且关系:`
ansible "web:&accp" --list-hosts //:&代表且,在web里,并且在accp里
[WARNING]: No hosts matched, nothing to do
hosts (0):
`逻辑非:`
ansible 'web:!accp' --list-hosts //:!非 在web里,但是不在accp里
hosts (2):
192.168.91.101
192.168.91.102
`正则表达式:`
ansible "websrvs:dbsrvs" -m ping
ansible "~(k|a).*" -m ping
例子:
ansible 'kube*:etcd:!127.0.0.1' -a reboot && reboot //除了本机,在kube开头的组或者etcd组里的,进行重启
`-f 并行执行:`
ansible all -a "sleep 3" -f1
ansible all -a "sleep 3" -f4 //4个一起执行
5.2 ansible 执行原理:
7-1下发指令给7-2和7-3,会生成一个python脚本。然后通过ssh返回给客户端,客户端执行脚本
js
*****ansible命令执行过程
1. 加载自己的配置文件,默认/etc/ansible/ansible.cfg
#[root@node1 ~]# ansible all -a "sleep 100" -f4 //休眠100秒,并行执行4个
#cd /root/.ansible/tmp //临时文件夹
2. 加载自己对应的模块文件,如:command
3. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
4. 给文件+x执行
5. 执行并返回结果
6. 删除临时py文件,退出
5.3 命令执行结果的颜色
- 绿色:执行成功,并且不需要做改变的操作
- 黄色:执行成功,并且对目标主机做变更
- 红色 :执行失败
如何自定义颜色:
js
vim /etc/ansible/ansible.cfg
[colors]
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
5.4 ansible-doc⭐⭐⭐
查看配置文档,模块功能查看工具。
js
[root@7-3 ~]# ansible-doc -l //查看所有支持的模块
[root@7-3 ~]# ansible-doc -l |wc -l
3387
[root@7-3 ~]# ansible-doc -l |grep ^ping //过滤以ping开头的模块
ping
pingdom
[root@7-3 ~]# ansible-doc ping //查看ping模块怎么使用
6、模块⭐⭐⭐⭐⭐
js
官网文档:模块如何使用
https://docs.ansible.com/ansible/2.9/modules/list_of_all_modules.html
先声明前提条件:
js
[root@7-1 ~]# vim /etc/ansible/hosts //在7-1上设置的主机清单,那么7-1就是 主节点
[web]
192.168.125.120 //下面这些都是 从节点,也称为远程主机
192.168.125.130
[cxk]
192.168.125.140
192.168.125.150
6.1 command 模块
- 功能:
- command 是默认模块, 可以省略不写
- 在从节点上生效
- 此模块不具有幂等性
- 不支持通配符、正则、重定向,如 $VARNAME < >| ; & 等
示例:
js
例1:
ansible web -m command -a 'hostname' //web是组名;-m command是默认模块,可以省略;-a执行指令
例2:
ansible web -a 'touch /opt/ky36' //在web组里创建空文件
192.168.125.130 | CHANGED | rc=0 >>
192.168.125.120 | CHANGED | rc=0 >>
例3:
ansible web -a "echo 123 > /opt/123" //command模块 不支持重定向
192.168.125.130 | CHANGED | rc=0 >>
123 > /opt/123
192.168.125.120 | CHANGED | rc=0 >>
123 > /opt/123 //执行的结果:相当于把echo后面的内容,全部打印下来
6.2 shell 模块
-
功能:
- shell模块 是加强版的command
- 支持各种符号,比如:*,$, > 重定向
- 此模块不具有幂等性
- 也是在从节点上生效
示例:
js
例1:
[root@7-1 ~]# ansible web -m shell -a "echo 123 > /data/123" //-m 指定shell模块,就可以实现重定向
192.168.125.130 | CHANGED | rc=0 >>
192.168.125.120 | CHANGED | rc=0 >>
`7-2验证:`
[root@7-2 data]# tree
.
└── 123
0 directories, 1 file
小拓展:修改默认模块⭐
js
[root@7-1 ~]# vim /etc/ansible/ansible.cfg
113 # default module name for /usr/bin/ansible
114 module_name = shell
//修改完,也不需要重启。
6.3 script 脚本模块
-
功能:
- 执行脚本
- 从节点上生效。 运行脚本,无需执行权限。
- 此模块不具有幂等性
示例:
js
例1:
[root@7-1 data]# vim script.sh
#! /bin/bash
mkdir /data/abc
[root@7-1 data]# ansible web -m script -a "/data/script.sh" //脚本运行在7-1上面,生效在web组对应的主机上
7-2验证:
[root@7-2 data]# ls
abc //已经创建了abc文件夹
6.4 copy ⭐⭐
功能:主到从。 也就是由 主节点,复制到从节点
关键字:
参数 | 含义 |
---|---|
src | 源文件路径,如果没有指明绝对路径,就默认为当前路径 |
dest | 文件落地路径,从节点的路径 |
owner | 属主 |
group | 属组 |
mode | 权限 |
backup | backup=yes,意思为如果复制时有同名文件,会先备份再复制 |
content | 相当于echo,后面跟的是 文本内容 |
示例:
js
例1:
[root@7-1 data]# ansible web -m copy -a "src=/etc/fstab dest=/data/ owner=root group=zhangsan mode=644"
7-2验证:
[root@7-2 data]# ll
总用量 4
-rw-r--r--. 1 root zhangsan 541 6月 24 16:20 fstab
例2:
[root@7-1 data]# ansible web -m copy -a "content='hello world\n' dest=/data/hello" //content='hello world\n',hello world是一句话,\n是换行
验证:
[root@7-2 data]# cat hello
hello world
例3:
`加不加/`:
ansible web -m copy -a "src=/etc dest=/opt"
ansible web -m copy -a "src=/etc/ dest=/opt"
etc后面,不加/,类似于追加。意思为连着/etc一起复制,也就是/opt/etc/...
etc后面,加/,类似于改名。 意思为只复制/etc下一级的文件,也就是/opt/...
小拓展:
js
install命令的功能=cp+chmod+chown
6.5 get_url 模块
功能:用于将文件从http、https或ftp下载到被管理机节点(从节点)上。
关键字:
参数 | 含义 |
---|---|
url⭐ | 指明下载路径。下载文件的URL,支持HTTP,HTTPS或FTP协议 |
dest⭐ | 目标路径(绝对路径)。如果目标是一个目录,就用服务器上面文件的名称,如果目标设置了名称就用目标设置的名称 |
force | 如果force=yes,dest不是目录,将每次下载文件,如果内容改变,替换文件; 如果force=no,则只有在目标不存在时才会下载该文件 |
owner | 属主 |
group | 属组 |
mode | 权限 |
示例:
js
ansible web -m get_url -a "url=https://nginx.org/download/nginx-1.18.0.tar.gz dest=/data"
6.6 fetch 模块
功能:
- 从到主。 远程主机(从节点)提取文件,至ansible的主控端(服务端)
- 与copy相反, 目前不支持目录。
关键字:
参数 | 含义 |
---|---|
src | 从节点 的源地址 |
dest | 主节点 的目的地址 |
copy与fetch的区别:
- copy:主到从
- fetch:从到主。这种需求的一般是拷贝日志。
示例:打包日志
js
例1:
ansible web -m fetch -a "src=/var/log/messages dest=/data/" //src是从节点的源地址,dest是主节点的目的地址。
主节点7-1验证:
[root@7-1 data]# tree
.
├── 192.168.125.120
│ └── var
│ └── log
│ └── messages
├── 192.168.125.130
│ └── var
│ └── log
│ └── messages
6.7 file 模块
功能:设置文件属性,创建软链接等
参数 | 含义 | 选项 |
---|---|---|
path | 指定文件路径 | ------ |
state⭐ | 文件状态 | touch 新建、absent 删除、hard 硬连接、link 软链接 |
recurse | 递归 | yes |
src | 源文件 | ------ |
owner | 属主 | ------ |
group | 属组 | ------ |
mode | 权限 | ------ |
示例:
js
例1:
[root@7-1 data]# ansible web -m file -a "path=/data/0624 state=touch" //web组对应的主机新建/data/0624文件夹
验证:
[root@7-2 data]# ls
0624
例2:
[root@7-1 data]# ansible web -m file -a "path=/data/0624 state=absent" //absent 删除0624文件夹
6.8 stat 模块
功能:检查文件或文件系统的状态,相当于判断
关键字:
参数 | 含义 |
---|---|
path | 文件(对象)的绝对路径 |
exists | 判断是否存在 |
isuid | 调用 用户的ID与所有者ID是否匹配 |
示例:
js
ansible web -m stat -a 'path=/data/' //查看是否存在
6.9 unarchive 解压缩⭐⭐
功能:解压缩
常见参数:
参数 | 含义 | 选项 |
---|---|---|
copy | 当copy=yes 时,为主到从 。由主节点的压缩包,传给从节点,并解压; 当copy=no 时,为从到从。由从节点的压缩包,传给从节点,并解压。 | yes(默认)、no |
remote_src(与上面的copy相反) | 当yes 时,为从到从 。 当no 时,为主到从。 | yes(默认)、no |
src | 源路径。可以是主节点的路径,也可以是从节点的路径。 | 如果是从节点上的路径,则需要设置copy=no |
dest | 从节点上的目标路径 | ------ |
mode | 设置解压缩后的文件权限 | ------ |
示例:
js
例1:
ansible web -m unarchive -a "src=/data/a.tar.gz dest=/mnt/" //把主节点的a.tar.gz传给从节点的/mnt下面,并且解压缩。主到从是copy=yes,可以省略
例2:
ansible web -m unarchive -a "src=/mnt/a.tar.gz dest=/data/ copy=no" //从节点中的压缩文件,解压到/data文件夹下。
6.10 archive 压缩⭐⭐
功能:打包压缩 保存在被管理节点(从节点)
对远端机器 进行压缩
示例:
js
例1:
ansible web -m archive -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2 owner=wang mode=0644'
例2:
ansible web -m archive -a "src=/var/log/ dest=/data/alllog.gz" //此时压缩文件是在web组中的主机里
ansible web -m fetch -a "src=/data/alllog.gz dest=/data/" //把web组的压缩包拷到本机,可以再用tar xf进行解压
6.11 hostname 管理主机名
功能:管理主机名 一般不使用此模块
js
ansible 192.168.91.102 -m hostname -a 'name=node3'
//一般不使用此模块,不然会造成 所有主机名一致
6.12 cron 计划任务模块
功能:计划任务
支持时间:minute,hour,day,month,weekday
关键字:
js
name 会生成一行注释,也就是对应的标题
job 执行的命令
示例:
js
例1:
ansible web -m cron -a "minute=30 hour=9 day=10 name=mysql job=/data/a.sh" //web组中新建计划任务
验证:
[root@7-2 data]# crontab -l //查看计划任务
#Ansible: mysql
30 9 10 * * /data/a.sh
例2:
ansible web -m cron -a "name=mysql state=absent" //删除计划任务
6.13 yum 安装、卸载⭐⭐
管理软件包:安装、卸载
关键字:
参数 | 含义 |
---|---|
name | 不可或缺的参数,用于指定需要管理的软件包。 |
state | 用于指定软件包的状态。 安装:installed、present 安装最新版本:latest 卸载:absent、removed |
update_cache | 强制更新yum的缓存 |
conf_file | 指定远程yum安装时所依赖的配置文件(安装本地已有的包)。 |
disable_pgp_check | 是否禁止GPG checking,只用于presentor latest。 |
disablerepo | 临时禁止使用yum库。 只用于安装或更新时。 |
enablerepo | 临时使用的yum库。只用于安装或更新时 |
注意:卸载软件,卸载的不彻底,卸载不掉依赖环境
示例:
js
例1:
ansible web -m yum -a "name=httpd state=present" //安装httpd软件
例2:
ansible web -m yum -a "name=httpd state=absent" //卸载httpd软件
6.14 yum_repository 模块
功能:建立yum仓库模块
关键字:
参数 | 含义 | 备注 |
---|---|---|
name | 必不可少的参数,用于指定要操作的唯一的仓库ID。 | 对应".repo"配置的"中括号"内的仓库ID。 |
baseurl | 此参数用于设置"yum"仓库的baseurl。 | ------ |
description | 描述。此参数用于设置仓库的注释信息 | 对应".repo"配置的"name字段" |
file | 此参数用于设置仓库的配置文件名称,即设置".repo"配置文件的文件名前缀,在不使用此参数的情况下,默认以"name"参数的仓库ID作为".repo"配置文件的文件名前缀,同一个".repo" 配置文件中 可以存在多个 yum 源。 | ------ |
enabled | 此参数用于设置是否激活对应的 yum 源,此参数默认值为 yes,表示启用对应的 yum 源,设置为 no 表示不启用对应的 yum 源。 | |
gpgcheck | 此参数用于设置是否开启 rpm 包验证功能,默认值为 no,表示不启用包验证,设置为 yes 表示开启包验证功能。 | |
gpgcakey | 当 gpgcheck 参数设置为 yes 时,需要使用此参数指定验证包所需的公钥。 | |
state | 默认值为 present。 当值设置为 absent 时,表示删除对应的 yum 源。 | present、absent |
示例:
js
ansible web -m yum_repository -a "name=cxk baseurl=file:///mnt gpgcheck=no file=cxk.repo description=epel"
6.15 service 管理服务⭐
功能:管理服务。比如启动、停止、重启
关键字:
参数 | 选项 | 含义 |
---|---|---|
name | ------ | 指定需要操作的服务名称,比如 nginx |
state | started、stopped、restarted、reloaded(注意单词状态都是 过去时) | 指定服务的状态 |
enabled | enabled=yes:开机启动 enabled=no:不开机启动 | 指定是否将服务设置为开机 启动项 |
示例:
js
例1:
ansible web -m service -a "name=httpd state=started enabled=yes" //开启httpd,并且开机就启动
例2:
ansible web -m service -a "name=firewalld state=stopped enabled=no" //关闭防火墙。注意stopped中间有两个p
6.16 mount 挂载
功能:挂载和卸载文件系统。
这个是临时挂载,一般不使用这个。
6.17 user 管理用户⭐⭐
功能:管理用户
关键字:
参数 | 含义 | 选项 |
---|---|---|
comment | 用户的描述信息 | ------ |
name | 指定用户名 | ------ |
createhome | 是否创建家目录 | yes、no |
force | 强制删除,当state=absent时,等价于userdel | ------ |
state | 不能创建,只能删除 | absent |
home | 指定用户家目录 | ------ |
shell | 指定默认的shell,不能与前面的家目录冲突 | ------ |
system | 创建系统用户,不能与uid冲突 | yes、no |
uid | 指定用户的uid | ------ |
group | 指定基本组 | ------ |
groups | 指定附加组 | ------ |
示例:
js
例1:
ansible web -m user -a "name=cxk comment='this is cxk' uid=666 system=yes"
例2:
ansible web -m user -a "name=cxk state=absent" //删除cxk用户
[root@7-2 ~]# id cxk
id: cxk: no such user
小拓展1:shell的类型有哪些?
js
[root@7-2 ~]# cat /etc/shells //默认的shell类型是bash
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
小拓展2:普通用户和系统用户
- 系统用户的uid是1-999
- 普通用户的uid是1000以上。
6.18 lineinfile 替换
多行替换的话,只会替换最后一行。建议使用replace模块
关键字:
参数 | 含义 |
---|---|
path | 指定要操作的文件路径 |
regexp | 正则,旧字符 |
line | 新字符 |
state | state=absent 删除对应的文本 |
backup | 是否在修改文件之前对文件进行备份 |
create | 当要操作的文件并不存在时,是否创建对应的文件 |
insertafter | 将文本插入到"指定的行"之后 |
insertbefore | 将文本插入到"指定的行"之前 |
示例:
js
例1:
ansible web -m lineinfile -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen.*' line='Listen 8080'" //Listen注意首字母是大写,小写的话会在最后默认添加一行
6.19 replace 替换(多行)⭐⭐
功能:基于正则进行匹配和替换。类似于sed
与lineinfile 对比:
- lineinfile:只替换多行中的最后一行
- replace:多行全部替换
关键字:
参数 | 含义 |
---|---|
path | 指定要操作的文件路径 |
regexp | 正则,旧字符 |
replace | 新字符 |
示例:
js
例1:
ansible web -m replace -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen 8080' replace='Listen 80'"
6.20 setup 模块
功能:用来收集主机的系统信息。
filter是标准写法,后面跟的是变量
js
ansible all -m setup
ansible all -m setup -a "filter=ansible_nodename"
ansible all -m setup -a "filter=ansible_hostname"
ansible all -m setup -a "filter=ansible_domain"
ansible all -m setup -a "filter=ansible_memtotal_mb"
ansible all -m setup -a "filter=ansible_memory_mb" //内存
ansible all -m setup -a "filter=ansible_memfree_mb"
ansible all -m setup -a "filter=ansible_os_family"
ansible all -m setup -a "filter=ansible_distribution_major_version"
ansible all -m setup -a "filter=ansible_distribution_version"
ansible all -m setup -a "filter=ansible_processor_vcpus" //cpu
ansible all -m setup -a "filter=ansible_all_ipv4_addresses" //ip
ansible all -m setup -a "filter=ansible_architecture"
ansible all -m setup -a "filter=ansible_uptime_seconds"
ansible all -m setup -a "filter=ansible_processor*"
ansible all -m setup -a 'filter=ansible_env'
7、playbook 任务剧本⭐⭐⭐⭐⭐
7.1 playbook 组成
js
vim ~/.vimrc
set ai //换行时自动对齐
set ts=2 //一个tab键等于2个空格
注意:playbook不支持tab键,不允许tab键和空格混用。
三种常见的数据格式:
- XML:Extensible Markup Language,可扩展标记语言,可用于数据交换和配置,不适合两台主机之间传递信息。tomcat
- JSON:JavaScript Object Notation, JavaScript 对象表记法,主要用来数据交换或配置,不支持注释
- YAML: YAML Ain't Markup Language YAML 不是一种标记语言, 主要用来配置,大小写敏感,可读性好,不支持tab,yaml 也是最常用的格式。
xml、json、yaml 三种格式之间可以相互转换
7.1.1 playbook 特点
-
playbook 剧本由 一个或多个"play" 组成的列表
如play1 play2 play3
-
play 的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的任务角色。task是任务,可以有多个任务
-
task实际是调用ansible的一个模块,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作
-
Playbook 文件是采用YAML语言编写的
7.1.2 YAML语言规则
- 在单一文件第一行,用连续三个连字号"-" 开始,还有选择性的连续三个点号( ... )用来表示文件的结尾
- 缩进必须是统一的,不能空格和tab混用
- 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
- YAML文件内容是区别大小写的,key/value的值均需大小写敏感
- YAML文件扩展名通常为yml或yaml
7.2 playbook 命令
js
playbook 语法格式:
ansible-playbook <.yaml文件> [选项]
选项 | 含义 |
---|---|
--list-hosts |
列出运行任务的主机 |
--list-tags |
列出tag 标签 |
--list-tasks |
列出task 任务列表 |
--limit |
指定运行的主机。比如主机列表中,写了多台机器,但是只想针对主机列表中 特定的机器执行 |
-i INVENTORY |
指定主机清单文件,通常一个项对应一个主机清单文件 |
--start-at-task START_AT_TASK |
从指定task开始执行,而非从头开始,START_AT_TASK为任务的name |
-v | 显示过程 |
检查语法的命令:
js
ansible-playbook --syntax-check
ansible-playbook -C 加脚本名字 //空跑,也可以检查语法
小拓展1:redo和undo
js
yum history redo 5 //重新执行 编号为5的 历史命令
yum history undo 8 //尝试撤销 编号为8的 历史命令
小拓展2: 在vim编辑器中,J(大j)命令, 可以将两行合成一行
7.3 playbook 组件⭐⭐
组件名 | 含义 |
---|---|
hosts | 指定了在哪些机器上执行任务 |
remote_user | 以谁的身份运行,不写的话,默认是root |
tasks | 任务列表,你要做哪些事情 |
gather_facts | 是否收集主机信息。默认是收集yes,可以设置为no。 |
7.3.1 hosts
hosts: playbook 中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中。
js
one.example.com one.example.com:two.example.com 192.168.1.50
192.168.1.*
Websrvs:dbsrvs //或者,两个组的并集W
ebsrvs:&dbsrvs //与,两个组的交集
webservers:!dbsrvs //在websrvs组,但不在dbsrvs组
示例:
js
- hosts: websrvs:appsrvs
7.3.2 remote_user
remote_user: 可用于host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务。
此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
yaml
- hosts: websrvs
remote_user: root
tasks:
- name: test connection
ping:
remote_user: wang
sudo: yes
#默认sudo为root
sudo_user:wang
#sudo为wang
7.3.3 tasks
play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task。task目的是使用指定的参数执行模块,而在模块参数中可以使用变量。
示例1:创建用户
yaml
---
- hosts: web
tasks:
- name: user
user: name=wyf uid=9999 system=yes createhome=no
示例2:删除用户
yaml
---
- hosts: web
tasks:
- name: user
user: name=wyf state=absent
示例3:安装httpd、关闭防火墙、开启httpd、创建网页页面
yaml
---
- hosts: web
remote_user: root
gather_facts: no
tasks:
- name: install httpd
yum: name=httpd state=latest
- name: firewalld
service: name=firewalld state=stopped enabled=no
- name: start httpd
service: name=httpd state=started enabled=yes
- name: index.html
copy: src=/data/index.html dest=/var/www/html/
js
[root@7-1 data]# echo "7-1 7-2 7-3"> index.html
*****通过ansible将7-1的页面,传给7-2和7-3*****
验证:
[root@7-1 data]# curl 192.168.125.120
7-1 7-2 7-3
[root@7-1 data]# curl 192.168.125.130
7-1 7-2 7-3
示例4:yum安装nginx
yaml
---
- hosts: web
tasks:
- name: install epel
yum: name=epel-release.noarch state=present
- name: install nginx
yum: name=nginx state=present
- name: stop httpd
service: name=httpd state=stopped
- name: start nginx
service: name=nginx state=started enabled=yes
- name: web page
copy: src=/data/index.html dest=/usr/share/nginx/html/
示例5:安装tree和telnet
yaml
---
- hosts: web
tasks:
- name: install
yum:
name:
- tree
- telnet //安装多个软件
state: present
7.3.4 tags 标签
tags 标签 可以只执行特定tags的 task,而不用执行整个.yaml文件。
yaml
---
- hosts: web
remote_user: root
gather_facts: no
tasks:
- name: install httpd
yum: name=httpd state=latest
- name: firewalld
service: name=firewalld state=stopped enabled=no
- name: start httpd
service: name=httpd state=started enabled=yes
- name: index.html
tags: html //打了tags标签,只会执行这三行
copy: src=/data/index.html dest=/var/www/html/
ansible-playbook -t html a.yaml //-t html 指定tags的名称。
小拓展:当执行多个tags时,中间用逗号隔开:
js
ansible-playbook -t tagsname1,tagsname2,tagsname3 tags.yaml
7.3.5 handlers notify
Handlers执行 notify监控 Handlers比 notify大一级
工作原理:先用notify去监控某项task,如果task发生了改变,那么才会执行Handlers
示例:
yaml
---
- hosts: web
tasks:
- name: install epel
yum: name=epel-release.noarch state=present
- name: install nginx
yum: name=nginx state=present
- name: stop httpd
service: name=httpd state=stopped
notify: //监控,这个执行发生变化了,才会执行handlers,如果不改变,就不会执行下面的handlers
- start nginx //与handlers对应的名称一致
handlers: //与tasks同级
- name: start nginx
service: name=nginx state=started enabled=yes
7.3.6 ignore_error 忽略错误
playbook中,如果一个task出错,默认将不会继续执行后续的其它task。但是有些命令的成功与失败,并不影响执行后面的命令,就利用 ignore errors: yes 忽路此 task的错误,继续向下执行playbook其它的task
8、变量
gather-facts
模块存放了关于变量的信息,所以要打开yes,不能用No。
变量的调用有多种方法,下面主要介绍其中5种:
- 使用setup模块中的变量
- 在playbook命令行中,定义变量
- 建立存放变量的var文件,定义变量
- 直接在yaml文件中 建立变量
- 调用独立的变量文件
8.1 使用setup模块中的变量
js
ansible web -m setup //可以web组所有的变量名称
ansible localhost -m setup -a "filter=ansible_memory_mb"
8.2 在playbook命令行中,定义变量
优先级最高。
js
{{ 变量名 }} //只支持数字、字母、下划线,且只能以字母开头
格式:
ansible-playbook -e abc=nginx(变量) a.yaml //-e指定变量
注意:特殊情况下,{{ 变量名 }}有可能会报错,需要加上双引号,即 "{{ 变量名 }}"
示例1:使用变量,安装vsftpd
yaml
vim a.yaml
---
- hosts: web
tasks:
- name: install vsftpd
yum: name={{ abc }} state=present
ansible-playbook -e abc=vsftpd a.yaml
8.3 建立存放变量的var文件,定义变量
yaml
`建立专门存放变量的文件,并定义变量:`
vim var
cxk1: tree
cxk2: vsftpd
`建立.yaml文件:`
vim a.yaml
---
- hosts: web
tasks:
- name: install "{{ cxk1 }}"
yum: name="{{ cxk1 }}" state=present
- name: install "{{ cxk2 }}"
yum: name="{{ cxk2 }}" state=present
ansible-playbook -e "@var" a.yaml //@var 就是调用var文件
8.4 直接在yaml文件中 建立变量⭐
使用vars 组件
yaml
vim w.yaml
---
- hosts: web
vars:
username: lisi
groupname: it
tasks:
- name: creat user
user: name={{ username }} createhome=no uid=666 group={{ groupname }}
- name: creat group
group: name={{ groupname }} state=present
ansible-playbook w.yaml
8.5 调用独立的变量文件
yaml
`独立的变量文件:`
vim x.yaml
wxy: mariadb-server
wjy: mariadb
vim j.yaml
---
- hosts: web
vars_files: //调用独立的变量文件
- x.yaml
tasks:
- name: install
yum: name={{ wxy }} state=present
- name: start service
service: name={{ wjy }} state=started enabled=yes
[root@7-1 data]# ansible-playbook j.yaml
9、template 模板技术
template 模板是一个文本文件,类似与copy模块。可以作为生成文件的模板,并且模板文件中还可嵌套 jinja2文件。
jinja2语言的特点:
- 灵活
- 可读性强
- 语法简洁清晰,不重复冗余
- 支持多种数据类型和操作。可以进行算数运算等
- 命名必须是以.j2结尾
js
目录结构:
[root@7-1 data]# tree
.
├── a.yaml
└── templates //先创建templates文件夹,与.yaml文件同级
└── a.j2 //在templates文件夹中,创建.j2文件
1 directory, 2 files
注意:
- templates与.yaml文件平级
- .j2文件创建在templates文件夹的下一级
示例:修改nginx配置文件中的cpu核数
yaml
`创建j2文件:`
vim a.j2
worker_processes {{ ansible_processor_vcpus+1 }};
`创建yaml文件:`
vim a.yaml
---
- hosts: web
tasks:
- name: config file
templates: src=a.j2 dest=/opt/nginx.conf //主节点的a.j2文件,对应在从节点中生效。
#copy: src=/data/index.html dest=/apps/nginx/html //类似于copy模块,可以做个对比。
ansible-playbook a.yaml
10、roles 角色
用于层次性、结构化地组织playbook剧本
运维复杂的场景:建议使用 roles,代码复用度高
默认roles存放的路径:/etc/ansible/roles
目录结构:
js
roles/ //一级目录
project1/ //二级目录,项目名称
tasks/ //其余都是三级目录
files/
vars/
templates/
handlers/
default/
meta/
project2/ //二级目录
tasks/
files/
vars/
templates/
handlers/
default/
meta/
roles 各目录作用:
-
roles:一级目录,总的文件夹,下面是各项目名称
-
project:项目名称,下一级根据不同的模块细分出子目录
- files:存放由copy或script模块等调用的文件
- templates:template模块查找所需要模板文件的目录
- tasks:定义task任务,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
- handlers:至少应该包含一个名为main.yml的文件;此目录下的其它的文件需要在此文件中通过include进行包含
- vars:定义变量,至少应该包含一个名为main.yml的文件;此目录下的其它的变量文件需要在此文件中通过include进行包含
- meta:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
- default:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低
-
创建roles的步骤:
- 创建roles的目录结构。
- 在以roles命名的目录下,分别创建以各角色名称命名的目录,如nginx、mysql等
- 在每个角色命名的目录中分别创建相关的目录和文件。比如tasks、files、handlers、templates和vars等目录。(用不到的目录可以创建为空目录,也可以不创建)
- 编写和准备role的功能文件
- 编写playbook文件调用需要的角色应用于指定的主机
示例:
yaml
[root@7-1 ~]# cd /etc/ansible/roles
[root@7-1 roles]# mkdir -pv /etc/ansible/roles/nginx/{tasks,templates,handlers,files}
mkdir: 已创建目录 "/etc/ansible/roles/nginx"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/tasks"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/templates"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/handlers"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/files"
[root@7-1 roles]# tree
.
└── nginx
├── files
├── handlers
├── tasks
└── templates
5 directories, 0 files
[root@7-1 roles]# cd nginx
[root@7-1 nginx]# vim tasks/main.yaml //必须先创建main.yaml,提前确定好需要用到的模块
- include: group.yaml
- include: user.yaml
- include: install.yaml
- include: config.yaml
- include: webpage.yaml
- include: service.yaml
[root@7-1 nginx]# vim tasks/group.yaml
- name: groups
group: name=nginx state=present
[root@7-1 nginx]# vim tasks/user.yaml
- name: user
user: name=nginx state=present
[root@7-1 nginx]# vim tasks/install.yaml
- name: install epel
yum: name=epel-release.noarch state=present
- name: install nginx
yum: name=nginx state=present
[root@7-1 nginx]# vim tasks/config.yaml
- name: web file
copy: src=/data/index.html dest=/usr/share/nginx/html/
[root@7-1 nginx]# vim tasks/service.yaml
- name: start nginx
service: name=nginx state=started
[root@7-1 nginx]# tree
.
├── files
├── handlers
├── tasks
│ ├── config.yaml
│ ├── group.yaml
│ ├── install.yaml
│ ├── main.yaml
│ ├── service.yaml
│ └── user.yaml
└── templates