环境准备
默认所有虚拟机已关闭防火墙、关闭SELINUX、时间同步
虚拟机三台:
主机版本 | 主/被 | 主机IP | 主机名 |
---|---|---|---|
CentOS 7 | 主控端 | 192.168.124.5 | C7 |
CentOS 7 | 被控端 | 192.168.124.13 | C7-3 |
CentOS 7 | 被控端 | 192.168.124.14 | C7-4 |
实验准备
#在主控端 主机C7上操作:
#安装ansible
[root@C7 ~]# yum install ansible
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: mirrors.neusoft.edu.cn
* extras: mirrors.aliyun.com
* updates: mirrors.neusoft.edu.cn
No package ansible available.
Error: Nothing to do
#很显然,我们的光盘仓库中缺失ansible相关依赖包
#搜索一下epel并添加epel源
[root@C7 ~]# yum list | grep epel-release
epel-release.noarch 7-11 extras
[root@C7 ~]# yum install epel-release -y
#这次安装成功
[root@C7 ~]# yum install ansible
……………
Total download size: 20 M
Installed size: 114 M
Is this ok [y/d/N]: y
…………
Installed:
ansible.noarch 0:2.9.9-1.el7
Dependency Installed:
python-babel.noarch 0:0.9.6-8.el7 python-httplib2.noarch 0:0.9.2-1.el7 python-jinja2.noarch 0:2.7.2-4.el7
python-markupsafe.x86_64 0:0.11-10.el7 python-paramiko.noarch 0:2.1.1-9.el7 python2-jmespath.noarch 0:0.9.4-2.el7
sshpass.x86_64 0:1.06-2.el7
Complete!
#在继续实验之前我们需要提前配置好远程被控主机的免密钥登录
#全部直接回车直到结束
[root@C7-3 ~]# ssh-keygen -t rsa -C "ansible@linux"
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
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:KLIoqlICPAnj9JYIHr5opUN8gH4gnziRF56LlxFyweQ ansible@linux
The key's randomart image is:
+---[RSA 2048]----+
|o+*o |
|OXoo |
|%*E.. |
|+&o@ . |
|=.& . . S |
|oB.o . |
|+oo |
|+ |
|= |
+----[SHA256]-----+
#这里的 id_rsa 为私钥文件,id_rsa.pub 为公钥文件
#特别注意:.ssh目录的权限需是700
[root@C7-3 ~]# ll /root/.ssh/
total 8
-rw------- 1 root root 1675 Jun 2 17:21 id_rsa
-rw-r--r-- 1 root root 395 Jun 2 17:21 id_rsa.pub
[root@C7 ~]# cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
[root@C7 ~]# ll /root/.ssh/
total 16
-rw-r--r-- 1 root root 395 Jun 3 08:39 authorized_keys
-rw------- 1 root root 1675 Jun 2 17:15 id_rsa
-rw-r--r-- 1 root root 395 Jun 3 08:39 id_rsa.pub
#当前登录远程被控主机提示需要输入密码
[root@C7 ~]# ssh 192.168.124.13
root@192.168.124.13's password:
#将authorized_keys 文件发送到另外两台被控主机
#中间输入yes;密码输入被控主机的root密钥
[root@C7 ~]# scp /root/.ssh/authorized_keys 192.168.124.13:/root/.ssh/
The authenticity of host '192.168.124.13 (192.168.124.13)' can't be established.
ECDSA key fingerprint is SHA256:Qqm+M0hyyYv59HC4ibs/tKiKpM4TIO7HqrZmDJoGWrs.
ECDSA key fingerprint is MD5:66:0c:de:ae:d5:6a:99:77:2f:f3:f0:20:a7:73:30:1a.
Are you sure you want to continue connecting (yes/no)? yes #输入yes
Warning: Permanently added '192.168.124.13' (ECDSA) to the list of known hosts.
root@192.168.124.13's password: #输入被控主机的root密钥
authorized_keys 100% 395 121.4KB/s 00:00
[root@C7 ~]# scp /root/.ssh/authorized_keys 192.168.124.14:/root/.ssh/
The authenticity of host '192.168.124.14 (192.168.124.14)' can't be established.
ECDSA key fingerprint is SHA256:Qqm+M0hyyYv59HC4ibs/tKiKpM4TIO7HqrZmDJoGWrs.
ECDSA key fingerprint is MD5:66:0c:de:ae:d5:6a:99:77:2f:f3:f0:20:a7:73:30:1a.
Are you sure you want to continue connecting (yes/no)? yes #输入yes
Warning: Permanently added '192.168.124.14' (ECDSA) to the list of known hosts.
root@192.168.124.14's password: #输入被控主机的root密钥
authorized_keys 100% 395 212.5KB/s 00:00
#现在我们来尝试以下是否可以在主控端远程免密钥登录两台被控主机
[root@C7 ~]# ssh 192.168.124.13
Last login: Tue Jun 2 17:19:57 2020 from 192.168.124.5
[root@C7-3 ~]# exit
logout
Connection to 192.168.124.13 closed.
[root@C7 ~]# ssh 192.168.124.14
Last login: Tue Jun 2 16:14:35 2020 from 192.168.124.1
[root@C7-4 ~]# exit
logout
Connection to 192.168.124.14 closed.
#如果你觉得输入主机IP 进行远程连接过于麻烦,你可以在主控端的 /etc/hosts 文件中配置IP解析
[root@C7 ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
#追加以下两行就行了
192.168.124.13 C7-3
192.168.124.14 C7-4
[root@C7 ~]# ssh C7-3
The authenticity of host 'c7-3 (192.168.124.13)' can't be established.
ECDSA key fingerprint is SHA256:Qqm+M0hyyYv59HC4ibs/tKiKpM4TIO7HqrZmDJoGWrs.
ECDSA key fingerprint is MD5:66:0c:de:ae:d5:6a:99:77:2f:f3:f0:20:a7:73:30:1a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'c7-3' (ECDSA) to the list of known hosts.
Last login: Tue Jun 2 17:32:53 2020 from 192.168.124.5
[root@C7-3 ~]# exit
logout
Connection to c7-3 closed.
[root@C7 ~]# ssh C7-4
The authenticity of host 'c7-4 (192.168.124.14)' can't be established.
ECDSA key fingerprint is SHA256:Qqm+M0hyyYv59HC4ibs/tKiKpM4TIO7HqrZmDJoGWrs.
ECDSA key fingerprint is MD5:66:0c:de:ae:d5:6a:99:77:2f:f3:f0:20:a7:73:30:1a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'c7-4' (ECDSA) to the list of known hosts.
Last login: Tue Jun 2 17:33:05 2020 from 192.168.124.5
[root@C7-4 ~]# exit
logout
Connection to c7-4 closed.
#觉得手动操作有些不够逼格呢?这里提供参考脚本
#利用 sshpass 批量实现基于 key 验证
#!/bin/bash
ssh-keygen -f /root/.ssh/id_rsa -P ''
NET=192.168.124
export SSHPASS=linux
for IP in {
10..20}; do
sshpass -e ssh-copy-id ${NET}.${IP}
done
建议从此刻状态对所有主机创建虚拟机快照
实验开始
#终于可以配置ansible了,前期工作基本就是这些
#ansible有三个重要的文件,在yum安装下文件默认在:/etc/ansible/ 下
[root@C7 ~]# ls /etc/ansible/
ansible.cfg hosts roles
#ansible.cfg 毫无疑问这是ansible的主配置文件
#hosts 远程控制主机清单
#roles 存放角色的目录
#配置hosts文件
[root@C7 ~]# vim /etc/ansible/hosts
#随便找个位置写即可
[srvs] # []中的英文尽量写的好记一点,因为后面的终端中要输入
192.168.124.13 #被控主机IP
192.168.124.14 #被控主机IP
#查看被ansible管理的所有主机列表
[root@C7 ~]# ansible srvs --list
hosts (2):
192.168.124.13
192.168.124.14
#测试一下被管理的主机能否ping通
[root@C7 ~]# ansible all -m ping
192.168.124.14 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.124.13 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
#你是否想过:倘若这里管理的主机多达100台,是否我就必须写100行主机IP呢?
#当然不必如此,对于被管理主机非常多的情况下,我们有另一种写法
[root@C7 ~]# vim /etc/ansible/hosts
#将前面两台主机IP注释掉,添加新行
[srvs]
#192.168.124.13 #被控主机IP
#192.168.124.14 #被控主机IP
192.168.124.[10:20] #表示10到20的主机IP
#重新查看被ansible管理的所有主机列表
[root@C7 ~]# ansible srvs --list
hosts (11):
192.168.124.10
192.168.124.11
…………..#省略不写
192.168.124.19
192.168.124.20
#当然,我这里仅部署了两台被控主机,若此时测试所有主机能否ping通,其余18台主机是不通的
#不仅这些主机ping不通,其ping的过程也并不是按照主机IP顺序进行的
[root@C7 ~]# ansible all -m ping
192.168.124.10 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 192.168.124.10 port 22: Connection refused",
"unreachable": true
}
192.168.124.14 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.124.13 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.124.11 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 192.168.124.11 port 22: No route to host",
"unreachable": true
}
#为了试验正常进行,还是把hosts主机清单改回来吧
#ansible中拥有非常多的模块,通过这些模块能够帮助我们完成及减少工作当中一些繁琐重复的内容
#例举ansible常用模块:篇幅有限这里仅做例举而不进行详细说明
#若你对此很感兴趣的话,这里提供详细博客链接:点击跳转
Command 模块;Shell 模块;Script 模块;Copy 模块;Fetch 模块;File 模;
unarchive 模块;Archive 模块;Hostname 模块;Cron 模块;Yum 模块;
Service 模块;User 模块;Group 模块;Setup 模块;
#倘若你对这些如此多的模块感到非常迷茫,那么使用ansible-doc是个办法
#其作用是ansible-doc +指定模块 查看该模块的帮助信息
#例如yum模块
[root@C7 ~]# ansible-doc yum
> YUM (/usr/lib/python2.7/site-packages/ansible/modules/packaging/os/yum.py)
Installs, upgrade, downgrades, removes, and lists packages and groups with the `yum‘ package
manager. This module only works on Python 2. If you require Python 3 support see the [dnf]
module.
* This module is maintained by The Ansible Core Team
* note: This module has a corresponding action plugin.
………
#若后面跟 --list 或 -l 则可以查看所有支持的ansible模块
[root@C7 ~]# ansible-doc --list
fortios_router_community_list Configure community lists in Fortinet's FortiOS and FortiGate
azure_rm_devtestlab_info Get Azure DevTest Lab facts
……….
剧本
#ansible中有一个非常重要的组成部分,那就是Playbook(剧本)
#通过剧本我们可以实现一次同时部署多台主机
#playbook由YAML语法构成,文件首行固定为 ---,且对缩进有严格要求,敏感大小写
#一个完整的代码块最少包括name和task,且一个name只能包含一个task
#YAML文件扩展名通常为yml或yaml
#尝试编写一个简单的剧本
[root@C7 ~]# mkdir /etc/ansible/roles/playbook
[root@C7 ~]# vim !$/hi.yml
---
- hosts: srvs
tasks:
- name: test
shell: /bin/echo "Hi,I'm `who am i`" > /data/hi.txt
#编辑结束应进行运行测试,是否有语法错误
#俗称干跑,而不进行实际操作
[root@C7 ~]# ansible-playbook --check -C /etc/ansible/roles/playbook/hi.yml
PLAY [srvs] *************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [192.168.124.13]
ok: [192.168.124.14]
TASK [test] ************************************************************************************************************************
skipping: [192.168.124.13]
skipping: [192.168.124.14]
PLAY RECAP *************************************************************************************************************************
192.168.124.13 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
192.168.124.14 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
#现在进行真正执行操作
[root@C7 ~]# ansible-playbook /etc/ansible/roles/playbook/hi.yml
PLAY [srvs] *************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [192.168.124.13]
ok: [192.168.124.14]
TASK [test] ************************************************************************************************************************
changed: [192.168.124.13]
changed: [192.168.124.14]
PLAY RECAP *************************************************************************************************************************
192.168.124.13 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.124.14 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#执行完,我们是否可以在本机查看远程被控主机的文件内容呢?
[root@C7 ~]# ansible all -a "cat /data/hi.txt"
192.168.124.14 | CHANGED | rc=0 >>
Hi,I'm root pts/3 2020-06-03 09:23 (192.168.124.5)
192.168.124.13 | CHANGED | rc=0 >>
Hi,I'm root pts/3 2020-06-03 09:23 (192.168.124.5)
#很明显可以直接看到内容,那么如果我只想在某一台主机上执行刚才的yml文件呢?
#略微修改一下之前的yml文件内容以作区分
[root@C7 ~]# vim /etc/ansible/roles/playbook/hi.yml
---
- hosts: srvs
tasks:
- name: test
shell: /bin/echo "You can see !" > /data/see.txt
#这次我就不干跑测试了,直接运行
#这次我们只对C7-3主机执行操作
[root@C7 ~]# ansible-playbook --limit 192.168.124.13 /etc/ansible/roles/playbook/hi.yml
PLAY [srvs] *************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [192.168.124.13]
TASK [test] ************************************************************************************************************************
changed: [192.168.124.13]
PLAY RECAP *************************************************************************************************************************
192.168.124.13 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#查看执行后,远程主机C7-3上的文件内容
#注意,命令参数有顺序要求
[root@C7 ~]# ansible -a 192.168.124.13 "cat /data/see.txt"
[WARNING]: Could not match supplied host pattern, ignoring: cat
[WARNING]: Could not match supplied host pattern, ignoring: /data/see.txt
[WARNING]: No hosts matched, nothing to do
[root@C7 ~]# ansible 192.168.124.13 -a "cat /data/see.txt"
192.168.124.13 | CHANGED | rc=0 >>
You can see !
#很显然我只是把 -a参数写在了前面,但这样会导致命令执行失败
部署httpd
#让我们更近一步,尝试使用ansible-playbook 来完成远程主机的httpd服务的部署
#在部署远程主机httpd服务之前,首先我们要在主控端安装httpd
[root@C7 ~]# yum -y install httpd
[root@C7 ~]# cp /etc/httpd/conf/httpd.conf /etc/ansible/roles/playbook/
[root@C7 ~]# vim /etc/ansible/roles/playbook/index.html
If you can see,that‘s good!
#编写httpd_install.yml playbook脚本
[root@C7 ~]# vim /etc/ansible/roles/playbook/httpd_install.yml
---
- hosts: srvs
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: config httpd service
copy: src=/etc/ansible/roles/playbook/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: copy default index.html
copy: src=/etc/ansible/roles/playbook/index.html dest=/usr/share/httpd/noindex/index.html
- name: manage httpd service
service: name=httpd state=started enabled=yes
#在C7-3主机上进行干跑测试
[root@C7 ~]# ansible-playbook --check --limit 192.168.124.13 -C /etc/ansible/roles/playbook/httpd_install.yml
PLAY [srvs] *************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [192.168.124.13]
TASK [install httpd