自动化运维工具ansible的安装管理以及模块介绍
目录
一、ansible概述
1、几种常用运维工具比较
Puppet
—基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱
SaltStack
—基于 Python 开发,采用 C/S 架构,相对 puppet 更轻量级,配置语法使用 YAML,使得配置脚本更简单
Ansible
—基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用YAML 及 Jinja2模板语言,更强的远程命令执行操作
2、Ansible简介
Ansible 基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。
connection plugins:连接插件,负责和被监控端实现通信,有SSH,ZEROMQ等,默认使用SSH连接
host inventory:主机清单,是一个配置文件里面定义监控的主机
modules : 模块,核心模块、command模块、自定义模块等
plugins : modules功能的补充,包括连接插件,邮件插件等
playbook:编排,定义 Ansible 多任务配置文件,非必需
3、Ansible特性
1)、no agents:不需要在被管控主机上安装任何客户端,更新时,只需在操作机上进行一次更新即可
2)、no server:无服务器端,使用时直接运行命令即可
3)、modules in any languages:基于模块工作,可使用任意语言开发模块
4)、yaml,not code:使用yaml语言定制剧本playbook
5)、ssh by default:基于SSH工作
6)、strong multi-tier solution:可实现多级指挥
二、ansible 安装
----关闭防火墙及安全机制----
[root@ansible ~]# systemctl stop firewalld && systemctl disable firewalld
[root@ansible ~]# setenforce 0 && sed -i "s/SELINUX=*/SELINUX=disabled/g" /etc/selinux/config
----配置在线YUM源----
[root@ansible ~]# mkdir -p /etc/yum.repos.d
[root@ansible ~]# mv -f /etc/yum.repos.d/* /etc/yum.repos.d/repos-0.bak
[root@ansible ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
[root@ansible ~]# yum clean all && yum makecache fast
----安装epel源及ansible----
[root@ansible ~]# yum install -y epel-release
'//epel:能为linux提供高质量软件包,相当于一个第三方源'
[root@ansible ~]# yum install -y ansible
'//建议下两遍,避免遗漏'
----查看ansible版本及结构----
[root@ansible ~]# ansible --version
ansible 2.9.18
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)]
三、ansible 配置主机清单及密钥对验证
[root@ansible ~]# yum install -y tree
'//安装树形查看工具'
[root@ansible ~]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg '//配置文件'
├── hosts '//主机清单(管理)'
└── roles
1 directory, 2 files
----配置主机清单----
[root@ansible ~]# vim /etc/ansible/hosts
25 [webserver] '//插入,上面有模板,指向另外两台主机'
26 192.168.126.20
27 [mysql]
28 192.168.126.40
----配置密钥对验证----
[root@ansible ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): '//输入要保存密钥的文件,这里直接选择默认回车'
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): '//输入密码'
Enter same passphrase again: '//再次确认密码'
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:3g4zXJ+pp+DH460lQ0qiPPPXAb5GLxgAwxuC3WdNaeM root@localhost.localdomain
The key's randomart image is:
+---[RSA 2048]----+
|.o . o.. |
|o * . o = |
| . = o o . |
| . . E |
| ...S.o |
| . ..=o=.. o |
| = +O=+.= |
| +..=***. |
| .o.+*=. |
+----[SHA256]-----+
[root@ansible ~]# ls -a '//查看隐藏文件'
. .bash_profile .esd_auth .tcshrc 图片
.. .bashrc .ICEauthority .viminfo 文档
anaconda-ks.cfg .cache initial-setup-ks.cfg .Xauthority 下载
.ansible .config .local 公共 音乐
.bash_history .cshrc .pki 模板 桌面
.bash_logout .dbus .ssh 视频
[root@ansible ~]# cd .ssh/
[root@ansible .ssh]# ls
id_rsa id_rsa.pub '//生成的公钥和私钥文件'
[root@ansible .ssh]# ssh-copy-id root@192.168.126.12
'//将公钥推给被管理端'
[root@ansible .ssh]# ssh-copy-id root@192.168.126.13
'//切换至webserver端(192.168.126.12)'
[root@webserver ~]# cd .ssh/
[root@webserver .ssh]# ls
authorized_keys
四、ansible 命令格式及基本用法
----命令格式----
ansible [主机] [-m 模块] [-a args]
ansible-doc -l '//列出所有已安装的模块(按q退出)'
ansible-doc -s yum '//-s列出yum模块描述信息和操作动作'
----基本用法----
[root@ansible .ssh]# ansible webserver -m command -a 'date' '//指定主机执行date命令'
Enter passphrase for key '/root/.ssh/id_rsa': '//输入密钥密码,之前设为123123'
192.168.126.12 | CHANGED | rc=0 >>
2021年 04月 02日 星期五 10:25:01 CST
[root@ansible .ssh]# ansible mysql -m command -a 'date'
Enter passphrase for key '/root/.ssh/id_rsa':
192.168.126.13 | CHANGED | rc=0 >>
2021年 04月 02日 星期五 10:25:33 CST
'//每次执行该命令都要输入密钥密码,比较麻烦,我们可以通过免交互代理来避免'
[root@ansible .ssh]# ssh-agent bash
[root@ansible .ssh]# ssh-add
Enter passphrase for /root/.ssh/id_rsa: '//输入密码'
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
'//再次尝试执行命令试试'
[root@ansible .ssh]# ansible 192.168.126.20-m command -a 'date'
192.168.126.20 | CHANGED | rc=0 >>
2021年 04月 02日 星期五 10:28:34 CST
'//这里除了别名也可以填IP地址,现在可以免交互执行命令了'
[root@ansible .ssh]#ansible 192.168.126.40 -m command -a 'ls /opt'
192.168.126.40 | CHANGED | rc=0 >>
rh
五、ansible 常用模块管理
环境:
主机名 | IP地址 | 软件服务 | 操作系统 |
---|---|---|---|
ansible | 192.168.126.10 | ansible | CentOS7 |
node1 | 192.168.126.20 | / | CentOS7 |
node2 | 192.168.126.40 | / | CentOS7 |
1、command - 默认模块
命令格式:
ansible [主机] [-m 模块] [-a args]
例:
ansible-doc -l '//列出所有已安装的模块(按q退出)'
ansible-doc -s yum '//-s列出yum模块描述信息和操作动作(按q退出)'
[root@ansible ~]# ansible 192.168.126.20 -m command -a 'date' '//指定ip执行date命令,这里上文已做过免交互'
192.168.126.20 | CHANGED | rc=0 >>
2021年 04月 06日 星期二 17:17:36 CST
[root@ansible ~]# ansible webserver -m command -a 'date' '//主机名与ip地址同理'
192.168.126.20 | CHANGED | rc=0 >>
2021年 04月 06日 星期二 17:17:36 CST
[root@ansible ~]# ansible mysql -m command -a 'date'
192.168.126.40 | CHANGED | rc=0 >>
2021年 04月 06日 星期二 17:18:24 CST
[root@ansible ~]# ansible all -m command -a 'date' '//所有hosts主机执行date命令'
192.168.126.40 | CHANGED | rc=0 >>
2021年 04月 06日 星期二 17:18:43 CST
192.168.126.20 | CHANGED | rc=0 >>
2021年 04月 06日 星期二 17:18:43 CST
[root@ansible ~]# ansible all -a 'ls /opt' '//若不加-m模块,则默认运行command模块'192.168.126.40 | CHANGED | rc=0 >>
rh
192.168.126.20 | CHANGED | rc=0 >>
rh
2、cron - 定时任务模块
有两种状态(state):present表示添加,absent表示移除
例:
ansible-doc -s cron '//-s查看cron模块信息'
[root@mysqlr .ssh]# which echo '//在PATH变量指定的路径中搜索echo命令的位置'
/usr/bin/echo
[root@ansible ~]# ansible mysql -m cron -a 'minute="*/1" job="/usr/bin/echo hello" name="cw cron job"'
'//指定webserver主机,-m不可省略,否则默认执行command模块'
'//-a指定参数,每分钟执行(间隔频率);执行操作;指定计划性任务名称'
'//这里注意格式,单引号与双引号的使用'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"cw cron job"
]
}
[root@ansible ~]# ansible mysql -a 'crontab -l' '//执行命令查看以下有无该计划性任务'
192.168.126.40 | CHANGED | rc=0 >>
#Ansible: cw cron job
*/1 * * * * /usr/bin/echo hello
[root@mysql .ssh]# crontab -l '//切换至mysql查看以下'
#Ansible: cw cron job
*/1 * * * * /usr/bin/echo hello
[root@ansible ~]# ansible mysql -m cron -a 'name="cw cron job" state=absent'
'//移除计划性任务'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
'//再切换至mysql查看,原先的计划性任务没了'
[root@mysql .ssh]# crontab -l
3、user - 用户模块
'该模块请求的是useradd,userdel,usermod三个指令'
'即创建/删除用户,设定用户所属组'
例:
ansible-doc -s user '//-s查看user模块信息'
[root@ansible ~]# ansible mysql -m user -a 'name="zhangsan"' '//在mysql主机中创建用户zhangsan'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1002,
"home": "/home/zhangsan",
"name": "zhangsan",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
[root@node2 ~]# id zhangsan
uid=1001(zhangsan) gid=1002(zhangsan) 组=1002(zhangsan)
#去到node2节点,可以看到zhangsan用户已经创好存在了
[root@ansible ~]# ansible mysql -m user -a 'name="zhangsan" state=absent'
'//删除该用户;absent使用频率较高'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"force": false,
"name": "zhangsan",
"remove": false,
"state": "absent"
}
[root@node2 ~]# id zhangsan
id: zhangsan: no such user
#切换到node2节点,可以看到zhangsan用户不存在了
4、group - 用户(组)模块
'该模块请求的是groupadd,groupdel,groupmod这三个指令(组)'
例:
ansible-doc -s group
[root@ansible ~]# ansible mysql -m group -a 'name=mysql gid=306 system=yes'
'//在mysql主机上创建组,组名为mysql;gid号为306(不指定也行,会自动生成);指定system'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 306,
"name": "mysql",
"state": "present",
"system": true
}
[root@node2 ~]# id mysql
uid=990(mysql) gid=306(mysql) 组=306(mysql)
[root@ansible ~]# ansible mysql -m user -a 'name=test02 uid=306 system=yes group=mysql'
'//创建用户,添加至mysql组,指定系统用户'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 306,
"home": "/home/cw",
"name": "cw",
"shell": "/bin/bash",
"state": "present",
"system": true,
"uid": 308
}
[root@ansible .ssh]#ansible mysql -a 'id cw'
192.168.126.40 | CHANGED | rc=0 >>
uid=308(cw) gid=306(mysql) 组=306(mysql)
'//注意一点,检查基本都是用-a,即command命令来检查的'
5、copy - 模块
例:
ansible-doc -s copy
[root@ansible ~]# ansible mysql -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=root mode=644'
'//src表示原文件; dest表示目标;即从哪复制到哪'
'//owner表示属主(所有者),mode表示权限'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "c2c0064d6bf5b2406fb8f0b0e1375c64dfb31bf9",
"dest": "/opt/fstab.bak",
"gid": 0,
"group": "root",
"md5sum": "ff5317baec6e65db01351886774c36a6",
"mode": "0644",
"owner": "root",
"size": 595,
"src": "/root/.ansible/tmp/ansible-tmp-1617704881.31-40190-62239597790259/source",
"state": "file",
"uid": 0
}
[root@ansible ~]# ansible mysql -a 'ls -l /opt'
192.168.126.13 | CHANGED | rc=0 >>
总用量 4
-rw-r--r-- 1 root root 683 4月 2 12:08 fstab.bak
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
[root@ansible ~]# ansible mysql -a 'cat /opt/fstab.bak'
'//查看复制文件的内容'
[root@ansible ~]# ansible mysql -m copy -a 'content="hello world" dest=/opt/fstab.bak2'
'//指定内容为hello world,重定向至该目录下(生成一个全新的文件)'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
"dest": "/opt/fstab.bak2",
"gid": 0,
"group": "root",
"md5sum": "5eb63bbbe01eeed093cb22bb8f5acdc3",
"mode": "0644",
"owner": "root",
"size": 11,
"src": "/root/.ansible/tmp/ansible-tmp-1617705515.51-40339-204544609892125/source",
"state": "file",
"uid": 0
}
[root@ansible ~]# ansible mysql -a 'cat /opt/fstab.bak2'
'//再次查看'
192.168.126.40| CHANGED | rc=0 >>
hello world~
'//以上用法能够使用copy指定内容生成一个新文件'
6、file - 模块
实现创建/删除文件信息 对数据权限进行修改
例:
ansible-doc -s file
[root@ansible ~]# ansible mysql -m file -a 'path=/opt/fstab.bak owner=test02 group=mysql mode=666'
'//path指定路径;指定属主test02(需已存在);group指定mysql组;权限修改为666'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 306,
"group": "mysql",
"mode": "0700",
"owner": "zhangsan",
"path": "/opt/fstab.bak",
"size": 595,
"state": "file",
"uid": 1001
}
'//可切至mysql主机查看下'
[root@mysql opt]# ls -l '//这是执行file模块之前的参数'
[root@node2 opt]# ls -l
总用量 8
-rwx------ 1 zhangsan mysql 595 4月 6 18:28 fstab.bak
-rw-r--r-- 1 root root 11 4月 6 18:38 fstab.bak2
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
'//前后对比'
[root@mysql opt]# ls -l '//执行file模块成功,提权,且修改了属组为zhangsan'
[root@ansible ~]# ansible mysql -m file -a 'src=/opt/fstab.bak path=/opt/fstab.bak.link state=link'
'//创建软链接'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/opt/fstab.bak.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 14,
"src": "/opt/fstab.bak",
"state": "link",
"uid": 0
}
[root@ansible ~]# ansible mysql -a 'ls -l /opt'
192.168.126.13 | CHANGED | rc=0 >>
192.168.126.40 | CHANGED | rc=0 >>
总用量 8
-rwx------ 1 zhangsan mysql 595 4月 6 18:28 fstab.bak
-rw-r--r-- 1 root root 11 4月 6 18:38 fstab.bak2
lrwxrwxrwx 1 root root 14 4月 6 18:55 fstab.bak.link -> /opt/fstab.bak
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
[root@ansible ~]# ansible mysql -m file -a "path=/opt/fstab.bak.link state=absent"
'//删除'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/opt/fstab.bak.link",
"state": "absent"
}
[root@ansible ~]# ansible mysql -a 'ls -l /opt'
192.168.126.40 | CHANGED | rc=0 >>
总用量 8
-rwx------ 1 zhangsan mysql 595 4月 6 18:28 fstab.bak
-rw-r--r-- 1 root root 11 4月 6 18:38 fstab.bak2
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
[root@ansible ~]# ansible mysql -m file -a "path=/opt/test state=touch"
'//建立空文件'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/opt/cw",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
[root@ansible ~]# ansible mysql -a 'ls -l /opt'
192.168.126.40 | CHANGED | rc=0 >>
总用量 8
-rw-r--r-- 1 root root 0 4月 6 18:59 cw
-rwx------ 1 zhangsan mysql 595 4月 6 18:28 fstab.bak
-rw-r--r-- 1 root root 11 4月 6 18:38 fstab.bak2
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
[root@ansible ~]# ansible mysql -a 'cat /opt/cw'
192.168.126.40 | CHANGED | rc=0 >>
'//确认为空文件'
7、ping - 模块
[root@ansible ~]# ansible all -m ping
'//测试被管理主机是否在线'
192.168.126.40 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.126.20 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
8、yum/service - 模块
service:用于管理服务运行状态
yum:使用yum软件包管理器安装,升级,降级,删除和列出软件包和组
ansible-doc -s service
ansible-doc -s yum
例:
[root@ansible ~]# ansible mysql -m yum -a 'name=httpd'
'//yum下载httpd服务;也可以使用all,让所有主机一起运行'
192.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"installed": [
"httpd"
]
},
"msg": "",
[root@node2 opt]# rpm -q httpd
httpd-2.4.6-97.el7.centos.x86_64
[root@node2 opt]# '//有了'
[root@ansible ~]# ansible mysql -m yum -a 'name=httpd state=absent'
'//卸载该软件包'
192\.168.126.40 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"removed": [
"httpd"
]
},
[root@node2 opt]# rpm -q httpd
未安装软件包 httpd
'//卸载成功'
'//再次执行命令安装服务,之后使用service模块启动该服务'
[root@ansible ~]# ansible mysql -m yum -a 'name=httpd'
[root@ansible ~]# ansible mysql -m service -a 'name=httpd enabled=true state=started'
'//启动该服务并设置开机自启(生成内容较多)'
[root@ansible ~]# ansible mysql -a 'systemctl status httpd'
'//检查该服务是否正常开启'
9、shell/script - 模块
ansible-doc -s shell
ansible-doc -s script
例:
[root@ansible ~]# ansible webserver -m user -a 'name=sicong'
'//在webserver端建立一个用户,以作后续测试'
192.168.126.20 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1001,
"home": "/home/mm",
"name": "mm",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
[root@ansible ~]# ansible webserver -m shell -a 'echo 123123|passwd --stdin sicong'
192.168.126.20 | CHANGED | rc=0 >>
更改用户 mm 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@ansible ~]# vim /opt/test.sh
#!/bin/bash
'//这是一个测试脚本,生成一个测试文件到对方指定目录中去'
echo "echo "my name is cw" > /opt/script.txt
chmod 666 /opt/script.txt '//赋权'
[root@ansible ~]# ansible all -m script -a '/opt/test.sh'
'//使用script执行该脚本'
192.168.126.40 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.126.40 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.126.40 closed."
],
"stdout": "",
"stdout_lines": []
}
192.168.126.20 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.126.20 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.126.20 closed."
],
"stdout": "",
"stdout_lines": []
}
[root@ansible .ssh]#ansible all -a 'cat /opt/script.txt'
'//查看是否生成新文件,该测试脚本书否成功,这种方法可用于大批量创建用户等循环重复场景'
192.168.126.40 | CHANGED | rc=0 >>
my name is cw
192.168.126.20 | CHANGED | rc=0 >>
my name is cw
10、setup - 模块
ansible-doc -s setup
例:
[root@ansible ~]# ansible mysql -m setup
'//查看该主机详细信息,信息量巨大,建议配合grep使用'