自动化运维工具ansible
目录一:Ansible概述
- Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点, Pubbet和saltstack能实现的功能, Ansible基本上都可以实现。
- Ansible能批量配置、部署、管理上千台主机。比如以前需要切换到每个主机上执行的一或多个操作,使用Ansible只需在固定的一台Ansible控制节点上去完成所有主机的操作。
- Ansible是基于模块工作的,它只是提供了一种运行框架,它本身没有完成任务的能力,真正执行操作的是Ansible的模块,比如copy模块用于拷贝文件到远程主机上, service模块用于管理服务的启动、停止、重启等
- Ansible其中一个比较鲜明的特性是Agentless,即无Agent的存在,它就像普通命令一样,并非c/s软件,也只需在某个作为控制节点的主机上安装一次Ansible即可,通常它基于ssh连接来控制远程主机,远程主机上不需要安装Ansible或其它额外的服务
- 使用者在使用时,在服务器终端输入命令或者playbooks,会通过预定好的规则将playbook拆解为play,再组织成ansible可以识别的任务,调用模块和插件,根据主机清单通过SSH将临时文件发给远程的客户端执行并返回结果,执行结束后自动删除
- Ansible的另一个比较鲜明的特性是它的绝大多数模块都具备幂等性(idempotence)。所谓幂等性,指的是多次操作或多次执行对系统资源的影响是一致的。比如执行systemct1 stop xxx命令来停止服务,当发现要停止的目标服务已经处于停止状态它什么也不会做,所以多次停止的结果仍然是停止,不会改变结果,它是幂等的,而systemctl restart xxx是非幂等的。
- Ansible的很多模块在执行时都会先判断目标节点是否要执行任务,所以,可以放心大胆地让Ansible去执行任务,重复执行某个任务绝大多数时候不会产生任何副作用
- Ansible文档 — 国内最专业的Ansible中文官方学习手册
二: ansible 的环境安装部署
管理端: 192.168.23.103
被管理端: 192.168.23.104;192.168.23.105
2.1 管理端安装ansible
#安装epel源
[root@host103 ~]# yum -y install epel-release
#如果安装ansible时候显示没有镜像,可能是网速太慢。重新执行命令即可
[root@host103 ~]# yum -y install ansible
#查看ansible的版本
[root@host103 ansible]# ansible --version
ansible 2.9.25
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
2.2 ansible的目录结构
[root@host103 ~]# cd /etc/ansible/
[root@host103 ansible]# yum -y install tree
[root@host103 ansible]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg #ansible配置文件
├── hosts #ansible主机清单,用于存储需要管理的远程主机相关信息
└── roles #公共角色目录
1 directory, 2 files
2.3 配置主机清单
[root@host103 ~]# cd /etc/ansible/
[root@host103 ansible]# ls
ansible.cfg hosts roles
[root@host103 ansible]# vim hosts
#配置组名
[webservers]
#组里包含的被管理主机(可以是ip或则主机名,主机名需要修改/etc/hosts
192.168.23.104
[dbservers]
192.168.23.105
2.4 配置密钥对验证
#一路回车,使用免密登录
[root@host103 ansible]# ssh-keygen -t rsa
[root@host103 ansible]# ssh-copy-id 192.168.23.104
[root@host103 ansible]# ssh-copy-id 192.168.23.105
三 ansible的命令行模块
命令格式: ansible <组名> -m <模块> -a <参数列表>
ansible-doc -l #列出所有已安装的模块,按q退出
ansible-doc -s 模块 #列出指定的模块描述信息和操作动作
3.1 command 模块
在远程主机执行命令,不支持管道,重定向等shell特性
常用参数
chdir: 在远程主机上运行命令前提进入目录
-
creates: 判断指定文件是否存在,如果存在,不执行后面的操作
-
removes: 判断指定文件是否存在,如果存在,执行后面的操作
#-s 列出指定模块的描述信息和操作动作
[root@host103 ansible]# ansible-doc -s command
#指定ip 指定动作
[root@host103 ansible]# ansible 192.168.23.104 -m command -a 'date'
192.168.23.104 | CHANGED | rc=0 >>
2021年 10月 21日 星期四 11:29:35 CST
#指定组名执行动作(组内的主机都会执行)
[root@host103 ansible]# ansible webservers -m command -a 'date'
192.168.23.104 | CHANGED | rc=0 >>
2021年 10月 21日 星期四 11:29:55 CST
#all代表所有hosts里的主机
[root@host103 ansible]# ansible all -m command -a 'date'
192.168.23.104 | CHANGED | rc=0 >>
2021年 10月 21日 星期四 11:30:06 CST
192.168.23.105 | CHANGED | rc=0 >>
2021年 10月 21日 星期四 11:30:06 CST
#省略 -m 选项,则默认使用command模块
[root@host103 ansible]# ansible webservers -a 'date'
192.168.23.104 | CHANGED | rc=0 >>
2021年 10月 21日 星期四 11:30:17 CST
3.2 shell模块
在远程主机执行命令,相当于调用远程主机的shell进程,然后在该shell下打开一个子shell运行命令(支持管道符号等功能)
ansible-doc -s shell
[root@host103 ansible]# ansible dbservers -m shell -a 'echo 123456 | passwd --stdin test'
192.168.23.105 | CHANGED | rc=0 >>
更改用户 test 的密码 。
passwd:所有的身份验证令牌已经成功更新
[root@host103 ansible]# ansible dbservers -m shell -a 'ifconfig ens33| awk "NR==2 {print \$2}"'
192.168.23.105 | CHANGED | rc=0 >>
192.168.23.105
3.3 cron模块
在远程主机定义任务计划。其中有两种状态(state):present表示添加(可以省略),absent表示移除。
ansible-doc -s cron 按 q 退出
常用的参数:
- minute/hour/day/month/weekday:分/时/日/月/周
- job:任务计划要执行的命令
- name:任务计划的名称
#为webservers组里的主机创建计划任务test crontab.
[root@host103 ~]# ansible webservers -m cron -a 'minute="*/1" job="/bin/echo helloworld" name="test crontab"'
#查看webservers组里主机的计划任务
[root@host103 ~]# ansible webservers -a 'crontab -l'
#删除计划任务。假如该计划任务没有取名字,name=None即可。
[root@host103 ~]# ansible webservers -m cron -a 'name="test crontab" state=absent'
#再次查看计划任务
[root@host103 ~]# ansible webservers -a 'crontab -l'
3.4 user模块
用户管理的模块
ansible-doc -s user
常用的参数:
- name:用户名,必选参数
- state=present|absent:创建账号或者删除账号,present表示创建,absent表示删除
- system=yes|no:是否为系统账号
- uid:用户uid
- group:用户基本组
- shell:默认使用的shell
- move_home=yse|no:如果设置的家目录已经存在,是否将已经存在的家目录进行移动
- password:用户的密码,建议使用加密后的字符串
- comment:用户的注释信息
- remove=yes|no:当state=absent时,是否删除用户的家目录
#创建用户test01
[root@host103 ~]# ansible dbservers -m user -a 'name="test01"'
#查看
[root@host103 ~]# ansible dbservers -m command -a 'tail -1 /etc/passwd'
3.5 grouop 模块
用户组管理的模块
ansible-doc -s group
常用选项
- gid 设置组的GID号
- name 指定组的名称
- state 指定组的状态,默认为创建,设置值为absent为删除
- system 设置值为yes,表示创建为系统组
#创建组mysql,gid为3306
[root@host103 ~]# ansible dbservers -m group -a 'name=mysql gid=3306 system=yes'
[root@host103 ~]# ansible dbservers -a 'tail -1 /etc/group'
#创建用户test02,该用户组为mysql组
[root@host103 ~]# ansible dbservers -m user -a 'name=test02 uid=3306 system=yes group=mysql'
[root@host103 ~]# ansible dbservers -a 'tail -1 /etc/passwd'
[root@host103 ~]# ansible dbservers -a 'id test02'
#删除用户test02
[root@host103 ~]# ansible dbservers -m user -a 'name="test02" state=absent'
#删除组mysql
[root@host103 ~]# ansible dbservers -m group -a 'name=mysql state=absent'
3.6 copy模块
用于复制指定主机文件到远程主机的
ansible-doc -s copy
常用的参数:
- dest:指出复制文件的目标及位置,使用绝对路径,如果是源目录,指目标也要是目录,如果目标文件已经存在会覆盖原有的内容
- src:指出源文件的路径,可以使用相对路径或绝对路径,支持直接指定目录,如果源是目录则目标也要是目录
- mode:指出复制时,目标文件的权限
owner:指出复制时,目标文件的属主 - group:指出复制时,目标文件的属组
- content:指出复制到目标主机上的内容,不能与src一起使用
- mode目标文件或目录的权限,将提供给chmod
#将本地的/etc/fstab 文件复制到远程主机的/opt/fstab.bak,并设置属主为root,权限为640
[root@host103 ~]# ansible dbservers -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=root mode=640'
[root@host103 ~]# ansible dbservers -a 'ls -l /opt'
#将 'helloworld' 覆盖写入到远程主机的/opt/fstab.bak
[root@host103 ~]# ansible dbservers -m copy -a 'content="helloworld" dest=/opt/fstab.bak'
[root@host103 ~]# ansible dbservers -a 'cat /opt/fstab.bak'
3.7 file模块
设置文件属性
ansible-doc -s file
常用选项:
-
force
- 需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,
- 有两个选项:yes|no
-
group
- 定义文件/目录的属组。
- 后面可以加上mode:定义文件/目录的权限
-
owner
- 定义文件/目录的属主。
- 后面必须跟上path:定义文件/目录的路径
-
recurse
- 递归设置文件的属性,只对目录有效,
- 后面跟上src:被链接的源文件路径,只应用于state=link的情况
-
dest
- 被链接到的路径,只应用于state=link的情况
-
state 状态,有以下选项:
- directory:如果目录不存在,就创建目录
- file:即使文件不存在,也不会被创建
- link:创建软链接
- hard:创建硬链接
- touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
- absent:删除目录、文件或者取消链接文件
#创建mysql组和test01用户
[root@host103 ~]# ansible dbservers -m group -a 'name=mysql gid=3306 system=yes'
[root@host103 ~]# ansible dbservers -m user -a 'name=test01 uid=3306 system=yes group=mysql'
#修改文件的属主,属组,权限
[root@host103 ~]# ansible dbservers -m file -a 'owner=test01 group=mysql mode=644 path=/opt/fstab.bak'
#设置/opt/fstab.link 为 /opt/fstab.bak的软链接文件
[root@host103 ~]# ansible dbservers -m file -a 'path=/opt/fstab.link src=/opt/fstab.bak state=link'
#创建文件 /opt/abc.txt
[root@host103 ~]# ansible dbservers -m file -a "path=/opt/abc.txt state=touch"
#查看
[root@host103 ~]# ansible dbservers -a 'ls -l /opt/'
192.168.23.105 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 10月 21 15:27 abc.txt
-rw-r--r--. 1 test01 mysql 10 10月 21 14:55 fstab.bak
lrwxrwxrwx. 1 root root 14 10月 21 15:27 fstab.link -> /opt/fstab.bak
#删除文件/opt/abc.txtz
root@host103 ~]# ansible dbservers -m file -a "path=/opt/abc.txt state=absent"
[root@host103 ~]# ansible dbservers -a 'ls -l /opt/'
3.8 hostname和ping模块
hostname 模块用于管理远程主机上的主机名
ping 模块用于检测远程主机的连通性
[root@host103 ~]# ansible dbservers -m hostname -a 'name=test01'
[root@host103 ~]# ansible dbservers -a 'hostname'
[root@host103 ~]# ansible all -m ping
3.9 yum 模块
在远程主机上安装与卸载软件包
常用选项
- name 所安装的包的名称
- state present—>安装, latest—>安装最新的, absent—> 卸载软件。
- update_cache 强制更新yum的缓存
- conf_file 指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
- disable_pgp_check 是否禁止GPG checking,只用于presentor latest。
- disablerepo 临时禁止使用yum库。 只用于安装或更新时。
- enablerepo 临时使用的yum库。只用于安装或更新时
#yum安装httpd
[root@host103 ~]# ansible webservers -m yum -a 'name=httpd'
[root@host103 ~]# ansible webservers -a 'rpm -q httpd'
#yum 卸载httpd
[root@host103 ~]# ansible webservers -m yum -a 'name=httpd state=absent'
[root@host103 ~]# ansible webservers -a 'rpm -q httpd'
3.10 service/systemd模块
用于管理远程主机上的管理服务的运行状态
ansible-doc -s service
常用的参数:
- name:被管理的服务名称
- state=started|stopped|restarted:动作包含启动关闭或者重启
- enabled=yes|no:表示是否设置该服务开机自启(也可以使用 true| false)
- runlevel:如果设定了enabled开机自启去,则要定义在哪些运行目标下自启动
- arguments 命令行提供额外的参数
- sleep 在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
#先下载httpd
[root@host103 ~]# ansible webservers -m yum -a 'name=httpd'
[root@host103 ~]# ansible webservers -a 'systemctl status httpd'
#开启httpd服务,并设置为开机自启
[root@host103 ~]# ansible webservers -m service -a 'enabled=true name=httpd state=started'
[root@host103 ~]# ansible webservers -a 'systemctl status httpd'
#关闭httpd服务,并取消开机自启
[root@host103 ~]# ansible webservers -m systemd -a 'enabled=no name=httpd state=stopped'
[root@host103 ~]# ansible webservers -a 'systemctl status httpd'
3.11 script 模块
该模块用于将本机的脚本在被管理端的机器上运行
#先在管理主机上写个shell脚本
[root@host103 ~]# vim test.sh
#!/bin/bash
echo 'hello world' > /opt/script.txt
#指定脚本路径,使用script 模块在被管理的主机上批量执行脚本
[root@host103 ~]# ansible webservers -m script -a 'test.sh'
[root@host103 ~]# ansible webservers -a 'cat /opt/script.txt'
3.12setup 模块
facts 组件是用来收集被管理节点信息的,使用 setup 模块可以获取这些信息
facts就是变量,内建变量 。每个主机的各种信息,cpu颗数、内存大小等会存在facts中的某个变量中。
常用选项
- filter 只返回与这个shell样式(fnmatch)通配符匹配的事实。
#获取主机的facts信息
[root@host103 ~]# ansible webservers -m setup
#过滤,显示ip地址信息
[root@host103 ~]# ansible dbservers -m setup -a 'filter=*ipv4'
#过滤,显示内存信息
[root@host103 ~]# ansible dbservers -m setup -a 'filter=*mem*'
四 inventory 主机清单
inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。
4.1 使用列表的形式标识多个主机
#如果是名称类似的主机,可以使用列表的方式标识各个主机。
[root@host103 ~]# vim /etc/ansible/hosts
[webservers]
192.168.23.10:2222 #冒号后定义远程连接端口,默认是 ssh 的 22 端口
192.168.23.1[1:3] #表示 192.168.23.11 到192.168.23.13
[dbservers]
db-[a:f].example.org #支持匹配 a~f
4.2 inventory 中的变量
inventory 变量名 | 含义 |
---|---|
ansible_host | ansible连接节点时的IP地址 |
ansible_port | 连接对方的端口号,ssh连接时默认为22 |
ansible_user | 连接对方主机时使用的主机名。不指定时,将使用执行ansible或ansible-playbook命令的用户 |
ansible_password | 连接时的用户的ssh密码,仅在未使用密钥对验证的情况下有效 |
ansible_ssh_private_key_file | 指定密钥认证ssh连接时的私钥文件 |
ansible_ssh_common_args | 允许进行权限提升 |
ansible_become_method | 指定提升权限的方式,例如可使用sudo/su/runas等方式 |
ansible_become_user | 提升为哪个用户的权限,默认提升为root |
ansible_become_password | 提升为指定用户权限时的密码 |
4.2.1 主机变量
分配变量给主机很容易做到,这些变量定义后可在 playbooks 中使用
[root@host103 ~]# vim /etc/ansible/hosts
#在hosts文件里,设置ansible连接的端口,用户,密码
[testservers]
192.168.23.13 ansible_port=22 ansible_user=root ansible_password=abc123
#ansible链接成功
[root@host103 ~]# ansible testservers -a 'date'
192.168.23.13 | CHANGED | rc=0 >>
2021年 10月 21日 星期四 16:57:14 CST
注意,如果ansible使用密码连接远程主机,需要确保不是第一次ssh 远程主机,否则可能连接失败
4.2.2组变量
可以定义属于整个组的变量
[root@host103 ~]# vim /etc/ansible/hosts
[webservers:vars] #表示为 webservers 组内所有主机定义变量
ansible_user=root
ansible_password=abc1234
[all:vars] #表示为所有组内的所有主机定义变量
ansible_port=22
4.2.3 组嵌套
可以把一个组作为另一个组的子成员,以及分配变量给整个组使用.
这些变量可以给 /usr/bin/ansible-playbook 使用,但不能给 /usr/bin/ansible 使用:
[nginx]
192.168.23.103
192.168.23.104
192.168.23.105
[apache]
192.168.23.1[0:3]
[webs:children] #表示为 webs 主机组中包含了 nginx 组和 apache 组内的所有主机
nginx
apache