自动化运维工具——ansible
- ansible 简介
- 什么是ansible?
- ansible 特点
- ansible 架构图
- 项目
ansible 简介
什么是ansible?
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
ansible是基于 paramiko 开发的,并且基于模块化工作,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远
程主机通讯的。ansible目前已经已经被红帽官方收购,是自动化运维工具中大家认可度最高的,并且上手容易,学习简单。是每位运维工程师必须掌握的技能之一。
ansible 特点
1、部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
2、默认使用SSH协议对设备进行管理;
3、有大量常规运维操作模块,可实现日常绝大部分操作;
4、配置简单、功能强大、扩展性强;
5、支持API及自定义模块,可通过Python轻松扩展;
6、通过Playbooks来定制强大的配置、状态管理;
7、轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
8、提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台。
ansible 架构图
项目
环境:
管理端 192.168.188.10 master
被管理端 192.168.188.20 node1
被管理端 192.168.188.30 node2
1、关闭防火墙
[root@server1 ~]# systemctl stop firewalld
[root@server1 ~]# setenforce 0
[root@server1 ~]# iptables -F
2、设置服务器名称
[root@server1 ~]# hostnamectl set-hostname master
[root@server1 ~]# su
[root@master ~]# hostnamectl set-hostname node1
[root@master ~]# su
[root@master ~]# hostnamectl set-hostname node2
[root@master ~]# su
3、安装epel源
把CentOS7-Base-163.repo epel.repo放入/etc/yum.repos.d/里
[root@master ~]# cd /etc/yum.repos.d/
[root@master yum.repos.d]# ls
backup CentOS7-Base-163.repo epel.repo local.repo
[root@master yum.repos.d]# vim ep
[root@master yum.repos.d]# vi epel.repo
[root@master yum.repos.d]# cd
[root@master ~]# yum makecache //建立yum仓库
[root@master ~]# yum -y install epel-release //安装epel源
4、安装ansible软件
[root@master ~]# yum -y install ansible
[root@master ~]# ansible --version //查看ansible版本
ansible 2.9.16
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)]
[root@master ~]# yum -y install tree
[root@master ~]# tree /etc/ansible/ //树结构展示文件
/etc/ansible/
├── ansible.cfg //ansible配置文件
├── hosts //ansible主仓库
└── roles //角色
5、配置主机清单
[root@master ~]# vim /etc/ansible/hosts
[webservers]
192.168.188.20
[mysql]
192.168.188.30
6、设置密钥对
[root@master ~]# 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): //密钥对 不是rot登陆密码
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:DNnJRp3eR50K0UFST0ZiL5pmEtJHXh6LQ4vyLkSbkuk root@master
The key's randomart image is:
+---[RSA 2048]----+
| .. *=Oo=.|
| =..B.B.X..|
| o+== B.=.o |
| ++* + =.o |
| + +So = . |
| . o . + |
| E . . |
| . |
| |
[root@master ~]# ssh-copy-id root@192.168.188.20
[root@master ~]# ssh-copy-id root@192.168.188.30
7、ansible语法
ansible 主机标识/ip -m 模块 -a ‘参数’
[root@master ~]# ansible mysql -m command -a 'date'
Enter passphrase for key '/root/.ssh/id_rsa': //密钥对
192.168.188.30 | CHANGED | rc=0 >>
2021年 01月 12日 星期二 09:09:53 CST
[root@master ~]# ansible mysql -a 'date' // 不加指定模块 默认是command
Enter passphrase for key '/root/.ssh/id_rsa':
192.168.188.30 | CHANGED | rc=0 >>
2021年 01月 12日 星期二 09:16:43 CST
8、免交互代理
[root@master ~]# ssh-agent bash
[root@master ~]# ssh-add
Enter passphrase for /root/.ssh/id_rsa:
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
[root@master ~]# ansible mysql -a 'date' //指定主机名只执行date
192.168.188.30 | CHANGED | rc=0 >>
2021年 01月 12日 星期二 09:19:35 CST
[root@master ~]# ansible 192.168.188.20 -a 'date' //指定ip执行date
192.168.188.20 | CHANGED | rc=0 >>
2021年 01月 12日 星期二 09:29:57 CST
[root@master ~]# ansible all -a 'date' //所有hosts主机执行date
192.168.188.30 | CHANGED | rc=0 >>
2021年 01月 12日 星期二 09:27:25 CST
192.168.188.20 | CHANGED | rc=0 >>
2021年 01月 12日 星期二 09:27:25 CST
9、cron模块
两种状态(state):present表示添加(可以省略)、absent表示移除
[root@master ~]# ansible-doc -s cron //查看cron模块信息
[root@master ~]# ansible mysql -m cron -a 'minute="*/1" job="/usr/bin/echo song >> /opt/song.txt" name="cron_song"' //每一分钟执行一次
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"cron_song"
]
}
在mysql被控制端查看
[root@server3 ~]# cat /opt/song.txt
song
song
song
移除计划
[root@master .ssh]# ansible mysql -m cron -a 'name="cron_song" state=absent'
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
[root@master .ssh]# ansible mysql -a 'crontab -l'
192.168.188.30 | CHANGED | rc=0 >>
10、user模块
user模块请求的是useradd、userdel、usermod三个指令
ansible-doc -s user //查看user模块
[root@master .ssh]# ansible all -m user -a 'name=shufeng' //hosts里面的所有服务器都创建shufeng用户
[root@node1 ~]# id shufeng
uid=1001(shufeng) gid=1001(shufeng) 组=1001(shufeng)
[root@node2 ~]# id shufeng
uid=1001(shufeng) gid=1001(shufeng) 组=1001(shufeng)
[root@master .ssh]# ansible webserver -m user -a 'name=shufeng state=absent' //给webserver删除用户
[root@node1 ~]# id shufeng
id: shufeng: no such user
[root@node2 ~]# id shufeng
uid=1001(shufeng) gid=1001(shufeng) 组=1001(shufeng)
11、group模块
group模块请求的是groupadd、groupdel、groupmod命令
ansible-doc -s group //查看group模块
[root@master .ssh]# ansible mysql -m group -a 'name=song gid=11011 system=yes //创建gid11011 song组
'
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 11011,
"name": "song",
"state": "present",
"system": true
}
[root@master .ssh]# ansible mysql -m user -a 'name=shufeng uid=11011 system=yes group=song' //给shufeng用户添加到song的组里 gid11011
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"append": false,
"changed": true,
"comment": "",
"group": 11011,
"home": "/home/shufeng",
"move_home": false,
"name": "shufeng",
"shell": "/bin/bash",
"state": "present",
"uid": 11011
}
[root@node2 ~]# id shufeng
uid=11011(shufeng) gid=11011(song) 组=11011(song)
[root@node2 ~]# getent group //查看组
song:x:11011:
[root@node2 ~]# getent networks //查看网段
default 0.0.0.0
loopback 127.0.0.0
link-local 169.254.0.0
[root@node2 ~]# getent protocols //查看协议
[root@node2 ~]# getent group | grep song
song:x:11011:
12、copy模块
ansible-doc -s copy //查看copy模块信息
[root@master .ssh]# ansible mysql -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=shufeng mode=600'
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "7b4db04fe505ad40ab97509144f9d1278b7ec265",
"dest": "/opt/fstab.bak",
"gid": 0,
"group": "root",
"md5sum": "631e929e8ccddec454cc4b6eaaba62e1",
"mode": "0600",
"owner": "shufeng",
"secontext": "system_u:object_r:usr_t:s0",
"size": 595,
"src": "/root/.ansible/tmp/ansible-tmp-1610420182.19-58400-69732785430898/source",
"state": "file",
"uid": 11011
}
[root@node2 opt]# ll
总用量 8
-rw-------. 1 shufeng root 595 1月 12 10:56 fstab.bak
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
-rw-r--r--. 1 root root 65 1月 12 10:02 song.txt
[root@master .ssh]# ansible mysql -m copy -a 'content="this is hehe" dest=/opt/hehe.txt' //把this is heh 写入 opt下面的hehe.txt里
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "6c8ae57dedb78254dedb0c269e7be2a3e23147bc",
"dest": "/opt/hehe.txt",
"gid": 0,
"group": "root",
"md5sum": "74decded7e8300a962239189f4992608",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:usr_t:s0",
"size": 12,
"src": "/root/.ansible/tmp/ansible-tmp-1610420500.01-58492-166741034891744/source",
"state": "file",
"uid": 0
}
[root@node2 opt]# cat /opt/hehe.txt
this is hehe
13、file模块(对文件进行管理)
ansible-doc -s file //查看file模块信息
[root@master .ssh]# ansible mysql -m file -a 'owner=root group=song mode=777 path=/opt/fstab.bak' //修改数组 修改权限
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 11011,
"group": "song",
"mode": "0777",
"owner": "root",
"path": "/opt/fstab.bak",
"secontext": "system_u:object_r:usr_t:s0",
"size": 595,
"state": "file",
"uid": 0
}
[root@node2 opt]# ll
总用量 12
-rwxrwxrwx. 1 root song 595 1月 12 10:56 fstab.bak
-rw-r--r--. 1 root root 12 1月 12 11:01 hehe.txt
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
-rw-r--r--. 1 root root 65 1月 12 10:02 song.txt
[root@master .ssh]# ansible mysql -m file -a 'path=/fstab.link src=/opt/fstab.bak state=link' //创建软链接
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/fstab.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:root_t:s0",
"size": 14,
"src": "/opt/fstab.bak",
"state": "link",
"uid": 0
}
[root@node2 opt]# ll /
总用量 30
lrwxrwxrwx. 1 root root 7 1月 11 09:35 bin -> usr/bin
dr-xr-xr-x. 5 root root 4096 1月 11 09:44 boot
drwxr-xr-x. 19 root root 3300 1月 11 09:48 dev
drwxr-xr-x. 142 root root 8192 1月 12 10:49 etc
lrwxrwxrwx. 1 root root 14 1月 12 11:11 fstab.link -> /opt/fstab.bak
drwxr-xr-x. 4 root root 31 1月 12 10:09 home
lrwxrwxrwx. 1 root root 7 1月 11 09:35 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 1月 11 09:35 lib64 -> usr/lib64
drwxr-xr-x. 2 root root 6 11月 5 2016 media
drwxr-xr-x. 8 root root 2048 9月 5 2017 mnt
drwxr-xr-x. 3 root root 65 1月 12 11:01 opt
dr-xr-xr-x. 213 root root 0 1月 11 09:47 proc
dr-xr-x---. 17 root root 4096 1月 12 09:53 root
drwxr-xr-x. 43 root root 1240 1月 12 09:47 run
lrwxrwxrwx. 1 root root 8 1月 11 09:35 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 11月 5 2016 srv
dr-xr-xr-x. 13 root root 0 1月 11 09:48 sys
drwxrwxrwt. 17 root root 4096 1月 12 11:11 tmp
drwxr-xr-x. 13 root root 155 1月 11 09:35 usr
drwxr-xr-x. 21 root root 4096 1月 11 09:44 var
[root@master .ssh]# ansible mysql -m file -a 'path=/opt/fstab.bak state=absent' //删除fstab。bak文件
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/opt/fstab.bak",
"state": "absent"
}
[root@node2 opt]# ll
总用量 8
-rw-r--r--. 1 root root 12 1月 12 11:01 hehe.txt
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
-rw-r--r--. 1 root root 65 1月 12 10:02 song.txt
[root@master .ssh]# ansible mysql -m file -a 'path=/opt/test state=touch' //在opt下面创建test文件
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/opt/test",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
[root@node2 opt]# ll
总用量 8
-rw-r--r--. 1 root root 12 1月 12 11:01 hehe.txt
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
-rw-r--r--. 1 root root 65 1月 12 10:02 song.txt
-rw-r--r--. 1 root root 0 1月 12 11:17 test
[root@master .ssh]# ansible mysql -m file -a 'path=/opt/song state=directory mode=755' //创建song目录 权限755
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/opt/song",
"secontext": "unconfined_u:object_r:usr_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
[root@node2 opt]# ll
总用量 8
-rw-r--r--. 1 root root 12 1月 12 11:01 hehe.txt
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
drwxr-xr-x. 2 root root 6 1月 12 11:20 song
-rw-r--r--. 1 root root 65 1月 12 10:02 song.txt
-rw-r--r--. 1 root root 0 1月 12 11:17 test
14、yum模块
ansible-doc -s yum //查看yum模块的信息
[root@master ~]# ansible all -m yum -a 'name=httpd' //所有安装yum安装
[root@node1 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64
[root@node2 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64
[root@master ~]# ansible mysql -m yum -a 'name=httpd state=absent' //mysql卸载httpd软件
[root@node1 ~]# rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64
[root@node2 ~]# rpm -q httpd
未安装软件包 httpd
15、service模块
ansible-doc -s service
[root@master ~]# ansible mysql -m yum -a 'name=httpd' //给mysql安装httpd
192.168.188.30 | CHANGED => {
[root@master ~]# ansible mysql -a 'systemctl status httpd' //查询httpd是否启动
192.168.188.30 | FAILED | rc=3 >> //非零值 代表没有启动
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:httpd(8)
man:apachectl(8)non-zero return code
[root@master ~]# ansible mysql -m service -a 'name=httpd state=started enabled=true' //给mysql启动httpd服务
[root@master ~]# ansible mysql -m command -a 'systemctl status httpd' //查询httpd是否开启
192.168.188.30 | CHANGED | rc=0 >> //返回零值 代表开启
[root@master ~]# ansible mysql -m service -a 'name=firewalld state=stopped enabled=true' //给mysql关闭防火墙
[root@master ~]# ansible mysql -m command -a 'systemctl status firewalld' //查询防火墙是否关闭
192.168.188.30 | FAILED | rc=3 >> //返回非零值 代表关闭
[root@master ~]# ansible mysql -m copy -a 'content="this is Apcha" dest=/var/www/html/index.html ' //给Apcha页面写入this is Apcha
192.168.188.30 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "3564b1efea961e5f8e29e342ba7fb6438f798f24",
"dest": "/var/www/html/index.html",
"gid": 0,
"group": "root",
"md5sum": "ab168add191f89bfb84b9d3e6278a83b",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:httpd_sys_content_t:s0",
"size": 13,
"src": "/root/.ansible/tmp/ansible-tmp-1610498880.81-58409-145715107618586/source",
"state": "file",
"uid": 0
}
16、shell模块
chdir:指定工作目录 ,在执行对应的命令之前,会先进入到chdir参数指定的目录中
creates;指定一个文件,到指定的文件存在时,就不执行对应的文件。
removes:使用此参数指定哟个文件,当指定的文件不存在时,就不执行对应的命令
ansible-doc -s shell
默认的command模块不识别重定向符号/追加符号
[root@master ~]# ansible mysql -m command -a 'echo this is dog > /opt/dog.txt' //用command 模块 写把this is dog 写入opt下面的dog.txt
192.168.188.30 | CHANGED | rc=0 >>
[root@node2 opt]# ls //
rh
[root@master ~]# ansible mysql -m shell -a 'echo this is dog > /opt/dog.txt' //用shell模块 使用重定向
192.168.188.30 | CHANGED | rc=0 >>
[root@node2 opt]# ls
dog.txt rh
[root@master ~]# ansible mysql -m shell -a 'chdir=/usr/local echo this is dog > dog.txt' //cd到/usr/local目录下 写this is dog 到dog.txt
192.168.188.30 | CHANGED | rc=0 >>
[root@node2 ~]# cat /usr/local/dog.txt
this is dog
17、script模块
ansible-doc -s script
[root@master ~]# vim test.sh //在ansible 管理端创建脚本
#!/bin/bash
echo "hello word" > /opt/script.txt
[root@master ~]# chmod +x test.sh //给权限
[root@master ~]# ansible mysql -m script -a 'test.sh' //给mysql 执行脚本
192.168.188.30 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.188.30 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.188.30 closed."
],
"stdout": "",
"stdout_lines": []
}
[root@node2 ~]# cat /opt/script.txt
hello word
18、setup模块
ansible-doc -s setup
[root@master ~]# ansible mysql -m setup //获取mysql组主机的facts信息
19、ping模块
[root@master ~]# ansible all -m ping //查看所有组的主句是否ping通
192.168.188.30 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.188.20 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}