基本概述

什么是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是模块化的 它所有的操作都依赖于模块

image-20230518144621355

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来测试,表示所有模块