基本概述
什么是Ansible?
Ansible是一个自动化统一配置管理工具,自动化主要体现在Ansible集成了丰富模块以及功能组件,可以通过一个命令完成一系列的操作,进而能减少重复性的工作和维护成本,可以提高工作效率。
ansible同款软件
Ansible 支持语言:Python2 基于SSH协议
Saltstack 支持语言:Python2 和 Python3 可以基于SSH协议也可以基于客户端TCP协议
Puppet Ruby
Ansible的优点:
远程执行
批量执行远程命令,可以对多台主机进行远程操作
统一配置管理
批量配置软件服务,可以进行自动化方式配置,服务的统一配置管理,和启停
事件驱动
通过Ansible的模块,对服务进行不同的事件驱动
比如:
1)修改配置后重启
2)只修改配置文件,不重启
3)修改配置文件后,重新加载
4)远程启停服务管理
管理公有云
通过API接口的方式管理公有云,不过这方面做的不如saltstack.saltstack本身可以通过saltcloud管理各大云厂商
的云平台。
二次开发
因为语法是Python,所以便于运维进行二次开发。
任务编排
可以通过playbook的方式来统一管理服务,并且可以使用一条命令,实现一套架构的部署
跨平台、跨系统
几乎不受到平台和系统的限制,比如安装apache和启动服务
在Ubuntu上安装apache服务名字叫apache2
在CentOS上安装apache服务名字叫httpd
在CentOS6上启动服务器使用命令:/etc/init.d/nginx
start
在CentOS7上启动服务器使用命令:systemctl start nginx
ansible的架构
1、连接插件connection plugins用于连接主机 用来连接被管理端
2、核心模块core modules连接主机实现操作, 它依赖于具体的模块来做具体的事情
3、自定义模块custom modules根据自己的需求编写具体的模块
4、插件plugins完成模块功能的补充
5、剧本playbookansible的配置文件,将多个任务定义在剧本中,由ansible自动执行
6、主机清单inventor定义ansible需要操作主机的范围最重要的一点是 ansible是模块化的 它所有的操作都依赖于模块
ansible执行流程
1.Ansible读取playbook剧本,剧本中会记录对哪些主机执行哪些任务。
2.首先Ansible通过主机清单找到要执行的主机,然后调用具体的模块。
3.其次Ansible会通过连接插件连接对应的主机并推送对应的任务列表。
4.最后被管理的主机会将Ansible发送过来的任务解析为本地Shell命令执行
Ansible实践部署
环境准备:
主机名 | 外网IP | 内网IP | 角色 | 环境 |
---|---|---|---|---|
m01 | 10.0.0.61 | 172.16.1.61 | ansible控制端 | ansible |
web01 | 10.0.0.7 | 172.16.1.7 | ansible被控制端 | 无 |
web02 | 10.0.0.8 | 172.16.1.8 | ansible被控制端 | 无 |
ansible服务端部署:
#1.安装epel源
[root@m01 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
#2.安装Ansible
[root@m01 ~]# yum install -y ansible
# ansible 命令选项
--version #ansible版本信息
-i #主机清单文件路径,默认是在/etc/ansible/hosts
-m #使用的模块名称,默认使用command模块
-a #使用的模块参数,模块的具体动作
-k #提示输入ssh密码,而不使用基于ssh的密钥认证
-C #模拟执行测试,但不会真的执行
-T #执行命令的超时
#3.查看Ansible版本及模块路径
[root@m01 ~]# ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg #//配置文件路径
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] #//ansible模块路径
ansible python module location = /usr/lib/python2.7/site-packages/ansible #//python模块位置路径
executable location = /usr/bin/ansible #//ansible命令存放路径
python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
# 3.修改配置文件
[root@m01 ~]# vim /etc/ansible/ansible.cfg
#此部分为ansible主要修改内容,
#inventory = /etc/ansible/hosts
#library = /usr/share/my_modules/
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp
#local_tmp = ~/.ansible/tmp
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#forks = 5
#poll_interval = 15
#sudo_user = root
#ask_sudo_pass = True
#ask_pass = True
#transport = smart
#remote_port = 22
#module_lang = C
#module_set_locale = False
----------------------------------------------------------------------------------------------------
#配置文件解释:
- inventory: 主机清单文件的位置,默认为/etc/ansible/hosts
- library: 模块库文件的位置,默认为/usr/share/my_modules/
- module_utils: 模块工具文件的位置,默认为/usr/share/my_module_utils/
- remote_tmp: 远程主机上的临时目录位置,默认为~/.ansible/tmp
- local_tmp: 本地主机上的临时目录位置,默认为~/.ansible/tmp
- plugin_filters_cfg: 插件过滤器配置文件的位置,默认为/etc/ansible/plugin_filters.yml
- forks: 允许同时在多少台主机上运行Ansible命令,默认为5
- poll_interval: 每次线程轮询主机之间的间隔时间,默认为15秒
- sudo_user: 运行命令时使用的sudo用户,默认为root
- ask_sudo_pass: 是否在运行命令时询问sudo用户的密码,默认为True
- ask_pass: 是否在运行命令时询问远程主机用户的密码,默认为True
- transport: 连接方式,根据主机数量动态选择,可以是ssh或paramiko,默认为smart
- remote_port: 远程主机的SSH端口号,默认为22
- module_lang: 使用的模块语言,默认为C
- module_set_locale: 是否设置语言环境变量来执行命令,默认为False
-----------------------------------------------------------------------------------------------------
#上诉部分,一般默认不修改,看具体情况,我们主要修改的是文档71行的内容
67 # additional paths to search for roles in, colon separated
68 #roles_path = /etc/ansible/roles
69
70 # uncomment this to disable SSH key host checking
71 host_key_checking = False #//指纹检测
#把host_key_checking = False注释打开,切记,打开后语句要对齐,否则在测试时会报错
#编写主机清单(inventory)
[root@m01 ~]# vim /etc/ansible/hosts //进入文件后可以把原注释掉的内容全部删除。编写格式如下
[web_group]
web01 ansible_ssh_host=10.0.0.7 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='1'
web02 ansible_ssh_host=10.0.0.8 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='1'
#测验
[root@m01 ~]# ansible web -m ping //检测ansible主机是否通。返回绿色文档表示成功
web01 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
web02 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
#我们发现上诉主机名单编写格式不仅繁琐,而且还暴露了用户名和密码,有一定的风险程度
#那么,我们可以使用密钥链接来编写主机名单
-----------------------------------------------------------------------------------------------------
#使用密钥链接,首先生成密钥
[root@m01 ~]# ssh-keygen
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:IA/pglkP0FhCBC9898WhEdD6jKxilIo9xOeG99pyzKE root@m01
The key's randomart image is:
+---[RSA 2048]----+
|B*. .oo.. |
|o+. . .+ . |
|..+.+.o. o |
| =.+.=... |
|o.o + =.S |
| oo..o.o |
|+o +.+ . |
|oo+.E.+ |
|. .+.=o |
+----[SHA256]-----+ //重复回车即可
#创建成功后在root下生成一个.ssh的隐藏文件
[root@m01 ~]# ll .ssh/
total 8
-rw------- 1 root root 1675 May 18 15:23 id_rsa
-rw-r--r-- 1 root root 390 May 18 15:23 id_rsa.pub
#下载免密发送
[root@m01 ~]# yum install -y sshpass
ssh -o StrictHostKeyChecking=no 10.0.0.7 #//此命令是表示跳过指纹检测而直接输入密码登录至web01
#编写发送密钥脚本 //用于生产实践中有多台web服务器时
[root@m01 ~]# vim ssh.sh
#!/bin/bash
. /etc/init.d/functions
for num in 5 6 7 8 9 31 41 51;do
ping -W1 -c1 10.0.0.$num &>/dev/null
if [ $? -eq 0 ];then
sshpass -p '1' ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa.pub root@10.0.0.$num &>/dev/null
action "主机:10.0.0.$num" /bin/true
else
action "主机:10.0.0.$num" /bin/false
fi
done
----------------------------------------------------------------------------------------------------
#执行脚本
[root@wm01 ~]# sh ssh.sh
主机:10.0.0.5 [FAILED]
主机:10.0.0.6 [FAILED]
主机:10.0.0.7 [ OK ]
主机:10.0.0.8 [ OK ]
主机:10.0.0.9 [FAILED]
主机:10.0.0.31 [FAILED]
主机:10.0.0.41 [FAILED]
主机:10.0.0.51 [FAILED]
----------------------------------------------------------------------------------------------------
#因为我们只使用了web01和web02两台虚拟机,所以上诉脚本执行成功的只有两台
#现在所有需要被控制的机器上都有了ansible所在的m01机器的密钥,那么我们就可以究极优化编写主机名单了
[root@m01 ~]# vim /etc/ansible/hosts
[web_group]
web01 ansible_ssh_host=10.0.0.7
web02 ansible_ssh_host=10.0.0.8
----------------------------------------------------------------------------------------------------
#测试是否推送成功
[root@m01 ~]# ansible web -m ping
web02 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
web01 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
----------------------------------------------------------------------------------------------------
#主机名单在有多个模块时,如果想要全部打开测试,可以使用默认模块名all来测试,表示所有模块