自动化部署工具【Ansible】之入门详解~

1、ansible 功能和特性

  1. 模块化:调用特定的模块完成特定任务,支持自定义模块,可使用任何编程语言写模块(账号,软件等)。ansible 模块非常多,大约3000多个,但常用也就二三十个左右。
  2. Paramiko(python对ssh的实现),PyYAML,Jinja2(模板语言)三个关键模块
  3. 基于Python语言实现,软件是用python开发的。
  4. 部署简单,基于python和SSH(默认已安装),agentless 无需客户端、无需代理不依赖PKI(无需ssl)
  5. 安全,基于OpenSSH
  6. 幂等性:一个任务执行1遍和执行n遍效果一样。不因重复执行带来意外情况。注意:此特性非绝对
  7. 支持playbook编排任务,YAML格式,编排任务,支持丰富的数据结构 剧本演员要按照 系统按照你规定的方式去执行命令
  8. 较强大的多层解决方案 role

2、 ansible 组成

  1. INVENTORY 主机清单:Ansible需要管理的主机的清单,要把IP地址 填写到 /etc/anaible/hosts文件中。
  2. MODULES 功能模块:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义。
  3. PLUGINS 补充功能:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
  4. 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免密登录,那么如何设置免密登录呢?

  1. 关闭验证信息:
js 复制代码
 `方法一:`
 vim /etc/ssh/ssh_config
 35 StrictHostKeyChecking no    //第35行,删除注释;并将ask改为no
 ​
 `方法二:`
 vim /etc/ansible/ansible.cfg 
 71 host_key_checking = False
 //开启71行的ansible的不验证即可,去掉注释

谁主动,谁是客户端。

  1. 免密登录:(临时性)
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键和空格混用。

三种常见的数据格式:

  1. XML:Extensible Markup Language,可扩展标记语言,可用于数据交换和配置,不适合两台主机之间传递信息。tomcat
  2. JSON:JavaScript Object Notation, JavaScript 对象表记法,主要用来数据交换或配置,不支持注释
  3. 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种:

  1. 使用setup模块中的变量
  2. 在playbook命令行中,定义变量
  3. 建立存放变量的var文件,定义变量
  4. 直接在yaml文件中 建立变量
  5. 调用独立的变量文件

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的步骤:

  1. 创建roles的目录结构。
  2. 在以roles命名的目录下,分别创建以各角色名称命名的目录,如nginx、mysql等
  3. 在每个角色命名的目录中分别创建相关的目录和文件。比如tasks、files、handlers、templates和vars等目录。(用不到的目录可以创建为空目录,也可以不创建)
  4. 编写和准备role的功能文件
  5. 编写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
相关推荐
flysnow0101 小时前
Linux CMakeLists编写之可执行程序
linux·cmake
码农郁郁久居人下1 小时前
Linux:文件系统与日志分析
linux·运维·服务器
你疯了抱抱我2 小时前
【CentOS7.6】yum 报错:Could not retrieve mirrorlist http://mirrorlist.centos.org
linux·centos·yum
-无-为-3 小时前
科普文:Linux服务器性能调优概叙
linux·运维·服务器
梅孔立4 小时前
linux 默认 python 2.7 版本没有pip安装教程
linux·python·pip
你可以自己看4 小时前
深入解析Linux的使用(上)
linux·运维·服务器
峰上踏雪4 小时前
\r:回车符 与 \n:换行符
linux·运维·c++
程序边界4 小时前
云数据中心运维新纪元:让Linux服务器如虎添翼
linux·运维·服务器
笨笨小乌龟114 小时前
Linux Shell 脚本入门教程:开启你的自动化之旅
linux·物联网·自动化
Spcarrydoinb5 小时前
嵌入式学习——硬件(Linux内核驱动编程LED、蜂鸣器、按键)——day59
linux·驱动开发·学习