一、 Ansible简介
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。Ansible架构相对比较简单,仅需通过SSH连接客户机执行任务即可
官方文档:docs.ansible.com/
1. Ansible 功能
- 批量执行远程命令,可以对远程的多台主机同时进行命令的执行
- 批量安装和配置软件服务,可以对远程的多台主机进行自动化的方式配置和管理各种服务
- 编排高级的企业级复杂的IT架构任务, Ansible的Playbook和role可以轻松实现大型的IT复杂架构
- 提供自动化运维工具的开发API, 有很多运维工具,如jumpserver(堡垒机)就是基于 ansible 实现自动化管理功能
2. Ansible 特性
- 模块化:调用特定的模块完成特定任务,支持自定义模块,可使用任何编程语言写模块(账号,软件等)
- Paramiko(python对ssh的实现),PyYAML,Jinja2(模板语言)三个关键模块
- 基于Python语言实现
- 部署简单,基于python和SSH(默认已安装),agentless,无需代理不依赖PKI(无需ssl)
- 安全,基于OpenSSH
- 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况,此特性非绝对
- 支持playbook编排任务,YAML格式,编排任务,支持丰富的数据结构 剧本演员要按照 系统按照你规定的方式去执行命令
- 较强大的多层解决方案 role
3. Ansible 组成
- INVENTORY:Ansible管理主机的清单 /etc/anaible/hosts 需要管理的服务清单
- MODULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
- PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
- API:供第三方程序调用的应用程序编程接口
二、 Ansible安装和入门
1. 安装Ansible
- 管理端安装ansible;被管理端无需安装
[root@node1 ~]# yum install epel-release.noarch -y //安装epel源
[root@node1 ~]# yum install ansible -y //安装ansible
- 配置主机清单,修改/etc/ansible/hosts文件
[root@node1 ~]# vim /etc/ansible/hosts //配置主机清单
[lkk] //组名
192.168.204.20 //组里包含被管理的主机IP
192.168.204.30
- ansible默认使用ssh连接,所以管理前要设置免密登录
[root@node1 ~]# vim /etc/ssh/ssh_config //开启免交互
35 StrictHostKeyChecking no
[root@node1 ~]# ssh-keygen //生成密钥
[root@node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa 192.168.204.20
[root@node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa 192.168.204.30
2. 查看基本信息
输入命令ansible --version可查看基本信息
3. 相关文件
- /etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性,也可以在项目的目录中创建此文件,当前目录下如果也有ansible.cfg,则此文件优先生效,建议每个项目目录下,创建独有的ansible.cfg文件
- /etc/ansible/hosts 主机清单
- /etc/ansible/roles/ 存放角色的目录
3.1 主配置文件
Ansible 的默认配置文件是 /etc/ansible/ansible.cfg ,其中大部分的配置内容无需进行修改。
bash
[defaults]
#inventory = /etc/ansible/hosts //主机列表配置文件
#library = /usr/share/my_modules/ //库文件存放目录
#remote_tmp = $HOME/.ansible/tmp //临时py命令文件存放在远程主机目录
#local_tmp = $HOME/.ansible/tmp //本机的临时命令执行目录
#forks = 5 //默认并发数
#sudo_user = root //默认sudo 用户
#ask_sudo_pass = True //每次执行ansible命令是否询问ssh密码
#ask_pass = True
#remote_port = 22
#host_key_checking = False //检查对应服务器的host_key,建议取消此行注释,实现第一次连接自动信任目标主机
#log_path=/var/log/ansible.log //日志文件,建议启用
#module_name = command //默认模块,可以修改为shell模块
[privilege_escalation] //普通用户提权配置
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
3.2 主机清单文件
ansible的主要功能用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory 主机清单文件中将其分组组织。
官方文档:docs.ansible.com/ansible/lat...
默认的 inventory file 位置在:/etc/ansible/hosts
示例:
bash
[web]
192.168.91.101:666
//可以指定ssh端口非默认的端口
192.168.91.102
[server]
192.168.91.[100:105]
//指定连续的主机
[ky15]
node[1:5]
//指定连续的主机
[server:ky15]
server
ky15
//可以嵌套组
[local]
192.168.91.100 ansible_connection=local
//指定本地连接,无需ssh配置
4. Ansible相关工具
- /usr/bin/ansible :主程序,临时命令执行工具
- /usr/bin/ansible-doc:查看配置文档,模块功能查看工具,相当于man ansible-doc -l |grep 关键字
- /usr/bin/ansible-playbook :定制自动化任务,编排剧本工具,相当于脚本
- /usr/bin/ansible-pull :远程执行命令的工具
- /usr/bin/ansible-vault :文件加密工具
- /usr/bin/ansible-console :基于Console界面与用户交互的执行工具
- /usr/bin/ansible-galaxy :下载/上传优秀代码或Roles模块的官网平台
4.1 ansible
执行临时任务一次性任务
用法:
ansible <host-pattern> [-m module_name] [-a args]
命令 主机或者清单中的组 -m 指定模块 -a 执行的任务
选项:
bash
--version //显示版本
--list-hosts //显示主机列表,可简写 --list
-m module //指定模块,默认为command
-v //详细过程 -vv -vvv更详细
-C, --check //检查,并不执行
-T, --timeout=TIMEOUT //执行命令的超时时间,默认10s
-k, --ask-pass //提示输入ssh连接密码,默认Key验证
-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任务的主机数
执行返回结果:
- 绿色\color{green}{绿色}绿色:执行成功并且不需要做改变的操作
- 黄色\color{orange}{黄色}黄色:执行成功并且对目标主机做变更
- 红色\color{red}{红色}红色:执行失败
4.2 ansible-doc
ansible-doc -l
//查看所有支持的模块
ansible-doc 模块名
//查看该模块的详细信息
4.3 playbook
此工具用于执行编写好的 playbook 任务
三、 模块
ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。
官方帮助文档:docs.ansible.com/ansible/2.9...
1. Command 模块
功能:在远程主机执行命令,此为默认模块,可忽略 -m 选项
注意:此模块不具有幂等性;此命令不支持 $VARNAME < > | ; & 等,可以用shell模块实现(shell模块是加强版的命令模块)
示例:
bash
[root@node1 ~]# ansible lkk -a 'hostname'
192.168.204.20 | CHANGED | rc=0 >>
node2
192.168.204.30 | CHANGED | rc=0 >>
node3
[root@node1 ~]# ansible lkk -a 'touch /opt/ky36'
[WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient you can
add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
//此处的警告是让你用 file 模块 专业的模块
192.168.204.30 | CHANGED | rc=0 >>
192.168.204.20 | CHANGED | rc=0 >>
//不支持重定向
[root@node1 ~]# ansible lkk -a 'echo 123 > /opt/123'
192.168.204.20 | CHANGED | rc=0 >>
123 > /opt/123
192.168.204.30 | CHANGED | rc=0 >>
123 > /opt/123
2. Shell 模块
功能:和command相似,用shell执行命令,支持各种符号,比如:*,$, >
注意:此模块不具有幂等性
示例:
bash
//在主配置文件中,修改默认模块为shell
[root@node1 ~]# vim /etc/ansible/ansible.cfg
114 #module_name = command
115 module_name = shell
//支持重定向
[root@node1 ~]# ansible lkk -a "echo $PATH"
192.168.204.30 | CHANGED | rc=0 >>
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
192.168.204.20 | CHANGED | rc=0 >>
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
3. Script 模块
功能:在远程主机上运行ansible服务器上的脚本(无需执行权限)
注意:此模块不具有幂等性
示例:
[root@node1 ~]# vim test.sh
#!/bin/bash
hostname
[root@node1 ~]# ansible lkk -m script -a '/root/test.sh'
4. Copy 模块
功能:从ansible服务器主控端复制文件到远程主机
注意:src=file 如果是没指明路径,则为当前目录或当前目录下的files目录下的file文件。有幂等性
|---------|--------------------------|
| 关键字 | 含义 |
| src | 代表源文件路径 |
| dest | 代表文件落地路径 |
| owner | 属主 |
| group | 属组 |
| mode | 代表权限 |
| backup | 如果复制时有同名文件会先备份再复制 |
| content | 指定复制到目标主机上的内容,不能与src一起使用 |
示例:
bash
[root@node1 ~]# ansible lkk -m copy -a "src=/etc/passwd dest=/opt/lkk"
//把本地文件/etc/passwd 复制到web组里主机的 /opt文件夹下,并改名为lkk
[root@node1 ~]# ansible lkk -m copy -a "src=/etc/fstab dest=/opt/xwx owner=lisi group=lisi mode=644"
//指定属主、属组、权限;注意服务端中要有对应的用户
[root@node1 ~]# ansible lkk -m copy -a "src=/etc/fstab dest=/opt/xwx owner=lisi group=lisi mode=644 backup=yes"
//backup=yes 先备份再复制;如目标存在,默认覆盖
不加/ (/etc):复制加改名
加/ (/etc/):连/etc一起复制
5. Fetch 模块
功能:从远程主机提取文件至ansible的主控端,copy相反,目前不支持目录(可以通过压缩实现)。常用于拷贝日志
示例:
[root@node1 ~]# ansible lkk -m fetch -a "src=/data/fx dest=/opt"
//将远程主机的/data/fx文件拷贝到本地/opt下
6. Get_url 模块
功能: 用于将文件从http、https或ftp下载到被管理机节点上
示例:
[root@node1 ~]# ansible lkk -m get_url -a "url=https://nginx.org/download/nginx-1.18.0.tar.gz dest=/opt"
url 指明下载路径
dest 指明下载文件的存放目录
7. File 模块
功能:设置文件属性,创建软链接等
|---------|--------------------------------------------------------|
| 参数 | 含义 |
| path | 指定文件路径 |
| state | 文件状态 有:新建(touch) 删除(absent) 文件夹(directory) 连接文件(link)等 |
| src | 源文件 (建立链接文件时可使用) |
| mode | 权限 |
| owner | 属主 |
| group | 属组 |
| recurse | 递归修改 |
示例:
bash
[root@node1 ~]# ansible lkk -m file -a 'path=/opt/wj state=touch owner=lisi group=lisi mode=644'
//创建空文件,路径为/opt/wj,属主属组为lisi,权限为644
[root@node1 ~]# ansible lkk -m file -a 'path=/opt/wj state=absent'
//删除文件
[root@node1 ~]# ansible lkk -m file -a 'path=/opt/wjj state=directory'
//创建文件夹
[root@node1 ~]# ansible lkk -m file -a 'src=/etc/passwd path=/opt/soft state=link'
//创建软链接
[root@node1 ~]# ansible all -m file -a "path=/data/mysql state=directory owner=mysql group=mysql recurse=yes"
//递归修改目录及子目录的属性
8. Stat 模块
功能:检查文件或文件系统的状态
注意:对于Windows目标,请改用win_stat模块
示例:
ansible web -m stat -a 'path=/mnt/test.txt'
//查看是否存在
9. Unarchive 模块
功能:解包解压缩
实现有两种用法:
- 将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes,此为默认值,可省略
- 将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
|------------|-------------------------------------------------------------------------|
| 参数 | 含义 |
| copy | 默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上;如果设置为copy=no,会在远程主机上寻找src源文件 |
| remote_src | 和copy功能一样且互斥,yes表示在远程主机,不在ansible主机;no表示文件在ansible主机上 |
| src | 源路径,可以是ansible主机上的路径,也可以是远程主机(被管理端或者第三方主机)上的路径,如果是远程主机上的路径,则需要设置copy=no |
| dest | 远程主机上的目标路径 |
| mode | 设置解压缩后的文件权限 |
示例:
[root@node1 data]# ansible lkk -m unarchive -a "src=/data/nginx-1.22.0.tar.gz dest=/data"
//把本地/data下的nginx压缩包解压到远程主机的/data下
[root@node1 data]# ansible lkk -m unarchive -a "src=/opt/openssl-1.1.1k.tar.gz dest=/opt copy=no"
//将远程主机/opt下的压缩包解压到远程主机的/opt下;copy=no 代表压缩文件不是去本机上查找
10. Archive 模块
功能:打包压缩保存在被管理节点
示例:
[root@node1 data]# ansible lkk -m archive -a "path=/var/log dest=/data/alllog.gz"
//将本地/var/log 压缩保存到远程主机/data/alllog.gz
format压缩格式:bz2、gz、tar、xz、zip (默认gz)
11. Hostname 模块
功能:管理主机名
示例:
ansible 192.168.204.20 -m hostname -a 'name=node2'
//一般不使用此模块,主机名会一致
12. Cron 模块
功能:计划任务
支持时间:minute,hour,day,month,weekday
|--------|------------|
| 参数 | 含义 |
| name | 标题,会生成一行注释 |
| job | 执行的命令 |
示例:
[root@node1 data]# ansible lkk -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh'
//创建任务
[root@node1 data]# ansible lkk -m cron -a "name='backup mysql' state=absent"
//删除任务
13. Yum 和 Apt 模块
功能:yum 管理软件包,只支持RHEL,CentOS,fedora,不支持Ubuntu其它版本apt 模块管理 Debian 相关版本的软件包
|-------------------|----------------------------------------------------|
| 参数 | 含义 |
| name | 所安装的包的名称 |
| state | present--->安装, latest--->安装最新的, absent---> 卸载软件 |
| update_cache | 强制更新yum的缓存 |
| conf_file | 指定远程yum安装时所依赖的配置文件(安装本地已有的包) |
| disable_pgp_check | 是否禁止GPG checking,只用于present 或 latest |
| disablerepo | 临时禁止使用yum库。 只用于安装或更新时 |
| enablerepo | 临时使用的yum库。只用于安装或更新时 |
示例:
[root@node1 ~]# ansible lkk -m yum -a 'name=httpd state=present'
//远程主机安装httpd
[root@node1 ~]# ansible lkk -m yum -a 'name=httpd state=absent'
//远程主机卸载httpd;但是ansent卸载不掉依赖包
[root@node1 ~]# ansible lkk -m yum -a 'name=httpd state=present enablerepo=epel'
//启用epel源进行安装
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 源 |
示例:
ansible lkk -m yum_repository -a 'name=cxk description=cxk baseurl=file:///mnt gpgcheck=no file=cxk'
15. Service 模块
功能:管理服务
|---------|-----------------------------------------------------------------------------------|
| 参数 | 含义 |
| name | 此参数用于指定需要操作的服务名称,比如 nginx |
| state | 此参数用于指定服务的状态,比如:启动 started;停止 stopped。此参数的可用值有 started、stopped、restarted、reloaded |
| enabled | 此参数用于指定是否将服务设置为开机 启动项,设置为 yes 表示将对应服务设置为开机启动,设置为 no 表示不会开机启动 |
示例:
[root@node1 ~]# ansible lkk -m service -a 'name=nginx state=started'
//开启远程主机nginx服务
[root@node1 ~]# ansible lkk -m service -a 'name=nginx state=stopped'
//关闭远程主机nginx服务
16. Mount 模块
功能:挂载和卸载文件系统
示例:
bash
//临时挂载
mount web -m mount -a 'src="UUID=b3e48f45-f933-4c8e-a700-22a159ec9077" path=/home fstype=xfs opts=noatime state=present'
//临时取消挂载
mount web -m mount -a 'path=/home fstype=xfs opts=noatime state=unmounted'
//永久挂载
ansible web -m mount -a 'src=10.0.0.8:/data/wordpress path=/var/www/html/wp-content/uploads opts="_netdev" state=mounted'
//永久卸载
ansible web -m mount -a 'src=10.0.0.8:/data/wordpress path=/var/www/html/wp-content/uploads state=absent'
//永久挂载光盘
ansible web -m mount -a 'src=/dev/sr0 path=/mnt state=mounted fstype=iso9660'
//永久卸载
ansible web -m mount -a 'src=/dev/sr0 path=/mnt state=absent'
17. User 模块
功能:管理用户
|------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| 参数 | 含义 |
| comment | 用户的描述信息 |
| createhome | 是否创建家目录 yes 或no |
| force | 在使用state=absent时, 行为与userdel --force一致 |
| group | 指定基本组 |
| groups | 指定附加组,如果指定为(groups=)表示删除所有组 |
| home | 指定用户家目录 |
| move_home | 如果设置为home=时, 试图将用户主目录移动到指定的目录 |
| name | 指定用户名 |
| non_unique | 该选项允许改变非唯一的用户ID值 |
| password | 指定用户密码,使用 SHA512 hash |
| remove | 在使用state=absent时, 行为是与userdel --remove一致 |
| shell | 指定默认shell |
| state | 设置帐号状态,不指定为创建,指定值为absent表示删除 |
| system | 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户 |
| uid | 指定用户的uid |
| update_ password | ①always 如果password参数设置的值与用户当前的加密过的密码字符串不一致,则直接更新用户的密码,默认值即为always ②on_create 如果password参数设置的值与用户当前的加密过的密码字符串不一致,则不会更新用户的密码字符串,保持之前的密码设定 |
[root@node1 ~]# ansible lkk -m user -a "name=user1 createhome=no uid=10000 group=root"
//创建用户,名为user1,不创建家目录,指定uid为10000,指定组为root
[root@node1 ~]# ansible lkk -m user -a "name=user1 state=absent"
//删除用户
18. Group 模块
功能:管理组 (不常用)
示例:
//创建组
ansible web -m group -a 'name=nginx gid=88 system=yes'
//删除组
ansible web -m group -a 'name=nginx state=absent'
19. Reboot 模块
功能:重启
示例:
ansible web -m reboot
20. Lineinfile 模块
功能:相当于sed,可以修改文件内容(单行)
ansible在使用sed进行替换时,经常会遇到需要转义的问题,而且ansible在遇到特殊符号进行替换时,存在问题,无法正常进行替换 。其实在ansible自身提供了两个模块:lineinfile模块和replace模块,可以方便的进行替换一般在ansible当中去修改某个文件的单行 进行替换的时候需要使用lineinfile模块 ,如果想进行多行 匹配进行替换需要使用replace模块。
|--------------|-----------------------------------------------------------------------------------------------|
| 参数 | 含义 |
| path | 指定要操作的文件 |
| regexp | 使用正则表达式匹配对应的行 (当替换 文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换;当删除文本时,如果有多行文本都能被匹配,那么这些行都会被删除。) |
| line | 修改为新的内容 |
| insertafter | 将文本插入到"指定的行"之后 |
| insertbefore | 将文本插入到"指定的行"之前 |
| state | 删除对应的文本时,需要state=absent |
| backrefs | ①支持后向引用 ②当未匹配到内容则不操作文件 |
| backup | 是否在修改文件之前对文件进行备份 |
| create | 当要操作的文件并不存在时,是否创建对应的文件 |
示例:
[root@node1 ~]# ansible lkk -m lineinfile -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen.*' line='Listen 8080'"
//把以Listen开头的行 替换为Listen8080
21. Replace 模块
功能:类似于sed命令,主要也是基于正则进行匹配和替换(可以处理多行,推荐使用)
示例:
[root@node1 ~]# ansible lkk -m replace -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen.*' replace='Listen 80'"
22. Setup 模块
功能: 用来收集主机的系统信息,这些 facts 信息可以直接以变量的形式使用,但是如果主机较多,会影响执行速度
可以使用 gather_facts: no 来禁止 Ansible 收集 facts 信息
示例:
ansible all -m setup -a "filter=ansible_hostname"
ansible all -m setup -a "filter=ansible_all_ipv4_addresses"