自动化部署工具【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
相关推荐
Charary34 分钟前
字符设备驱动开发与杂项开发
linux·驱动开发
孤寂大仙v1 小时前
【Linux笔记】理解文件系统(上)
linux·运维·笔记
钢板兽2 小时前
Java后端高频面经——JVM、Linux、Git、Docker
java·linux·jvm·git·后端·docker·面试
byxdaz2 小时前
NVIDIA显卡驱动、CUDA、cuDNN 和 TensorRT 版本匹配指南
linux·人工智能·深度学习
pyliumy2 小时前
在基于Arm架构的华为鲲鹏服务器上,针对openEuler 20.03 LTS操作系统, 安装Ansible 和MySQL
服务器·架构·ansible
大白的编程日记.3 小时前
【Linux学习笔记】Linux基本指令分析和权限的概念
linux·笔记·学习
努力学习的小廉3 小时前
深入了解Linux —— 调试程序
linux·运维·服务器
努力学习的小廉3 小时前
深入了解Linux —— git三板斧
linux·运维·git
只做开心事4 小时前
Linux网络之数据链路层协议
linux·服务器·网络
钡铼技术物联网关4 小时前
ARM嵌入式低功耗高安全:工业瘦客户机的智慧城市解决方案
linux·安全·智慧城市