Ansible 是一个开源的基于 OpenSSH 的自动化配置管理工具,它能够实现 IT 流程的自动化,包括置备、配置管理、应用部署和编排等任务。Ansible 通过软件工程的方法重新定义和描述 IT 应用基础设施,用自动化技术替代重复和手动操作,可提高工作效率并降低人工干预的风险。通过运用 Ansible 自动化工具,IT 团队可以在整个企业范围内更高效地安装软件、管理基础设施、管理配置、修补系统并共享自动化等。
配置管理
部署发布
命令行批量执行
多层次任务编排
使用 Ansible 无须在被管理的客户端上安装代理。它通过标准 SSH 进行通信,以便从远程客户端检索信息、执行命令和复制文件。这是 Ansible 简化客户端管理的一种方式。任何 Ansible 可达的 SSH 端口的客户端都可以进行配置和管理。
Ansible 采用模块化的设计,所以非常容易扩展到各种特定的使用场景。模块可以用任何语言编写,并使用标准 JSON 进行通信。除了通过命令行工具(Ad-Hoc), Ansible 还可以通过配置剧本(Playbooks)与客户端进行交互。


Ansible:Ansible 核心程序。
Inventory:清单文件**,**记录由 Ansible 管理的主机信息,包括 IP、端口、密码、变量等。
Ad-Hoc:使用单个模块的临时命令,支持批量主机执行单条命令。
Playbooks:YAML 格式文件,将多个任务定义在剧本中,由 Ansible 执行。
CoreModules:核心模块,主要操作是通过调用核心模块来完成管理任务。
CustomModules:自定义模块,完成核心模块无法完成的功能,支持多种语言。
Plugins:支持使用插件的方式对 Ansible 本身的功能进行扩展,模块是用来实现任务的,增强 Ansible 自己的功能就需要使用插件(如:logging 插件记录日志,email 插件发送邮件)
ConnectionPlugins:Ansible 基于连接插件连接到各个主机上,虽然默认情况下 Ansible 使用 SSH 连接到各个主机上,但它还支持其它的连接方法。

![[IMG-01 - Ansible 概述、
加载 Ansible Config,读取配置。
读取 Anisble Inventory,找到需要执行任务的主机或组。
加载任务需要的模块,如 command、file、copy 等。
通过 Ansible 将模块或命令生成对应的临时 python 文件。将该文件传输至远程服务器,文件存放于对应执行用户的 ~/.ansible/tmp/xxx/xxx.py。
授予 python 文件执行权限。
执行并返回结果。
删除临时 python 文件,退出。
安装 Ansible 社区版本有两种可选的方式
通过 Linux Package 管理工具安装
通过 Python pip package 管理工具安装
# yum install -y epel-release
# yum install -y ansible
# rpm -qa | grep ansible
ansible-2.9.27-1.el7.noarch
Ansible 安装后的主要文件
/etc/ansible # Ansible 主目录
/etc/ansible/ansible.cfg # Ansible 主配置文件
/etc/ansible/hosts # Ansible 主机清单
/etc/ansible/roles # Ansible 角色目录
/usr/bin/ansible # Ansible 主程序目录
/usr/bin/ansible-connection # Ansible 连接工具
/usr/bin/ansible-console # Ansible 控制台
/usr/bin/ansible-doc # Ansible 文档工具
/usr/bin/ansible-galaxy # Ansible Galaxy
/usr/bin/ansible-inventory # Ansible 资产工具
/usr/bin/ansible-playbook # Ansible Playbook剧本工具
/usr/bin/ansible-pull # Ansible Pull是指在客户端组件基于Ansible Pull的方式从服务器上拉取文件
~/.ansible/plugins/modules:/usr/share/ansible/plugins # 默认模块路径
python3 -m pip install --user ansible
安装 Ansible 做两个配置, 一个是 Ansible Config(ansible.cfg) ,另一个就是 Ansible Inventory(hosts)。Ansible Config 是 Ansible 的核心配置文件,一般情况下大部分配置不需要更改。
[defaults]
inventory=/etc/ansible/hosts # 被控端主机清单文件
library=/usr/share/my_modules/ # 指定 Ansible 搜索模块位置,如果需要自定义 Ansible 模块,需要放到 library 所指定的目录下
remote_tmp=~/.ansible/tmp # 远程主机临时文件存放目录
local_tmp=~/.ansible/tmp # 本地主机临时文件存放目录
forks=5 # Ansible在执行工作时进程数量
poll_interval=15 # 默认轮询间隔时间,单位:秒
sudo_user=root # 客户端默认执行 sudo 命令所切换的用户
ask_sudo_pass=True # 每次执行 sudo 命令时是否询问 sudo 到目标用户的密码
ask_pass=True # 每次执行 Ansible 命令是否询问 SSH 密码
transport=smart # 通信机制
remote_port=22 # 连接远程客户端 SSH 端口的默认端口号
module_lang=C # 模块和系统之间通信的语言,默认为C语言
gathering=implicit # 控制默认 facts 收集,远程系统变量
roles_path=/etc/ansible/roles # 角色存储路径
host_key_checking=False # 是否检查远程主机密钥
sudo_exe=sudo # sudo 远程执行命令
sudo_flags=-H -S -n # 传递 sudo 之外的参数
timeout=10 # SSH 超时时间
remote_user=root # 指定默认的远程连接用户
log_path=/var/log/ansible.log # Ansible 日志文件,执行 Ansible 的用户需要对日志文件具有写入权限
module_name=command # Ansible 默认执行的模块
executable=/bin/sh # 执行的 Shell 环境,用户 Shell 模块
hash_behaviour=replace # 如果变量重叠,优先级更高的一个是替换优先级低得还是合并在一起,默认为替换
private_role_vars=yes # 默认情况下,角色中的变量将在全局变量范围中可见。 为了防止这种情况,可以启用以下选项,只有 tasks 的任务和 handlers 得任务可以看到角色变量
private_key_file=/path/to/file # 私钥文件存储位置
command_warnings=False # command 模块 Ansible 默认发出警告
nocolor=1 # Ansible 输出不带上颜色区别,0表示开启,1表示关闭
pipelining=False # 开启 pipe ssh 通道优化
[inventory]
[privilege_escalation]
# 出于安全角度考虑,部分公司不希望直接以root的高级管理员权限直接部署应用,往往会开放普通用户权限并给予sudo的权限,该部分配置主要针对sudo用户提权的配置
become=True # 是否 sudo
become_method=sudo # sudo 方式
become_user=root # sudo 后的用户
become_ask_pass=False # sudo 时是否需要验证密码
[paramiko_connection]
pty=False # 是否禁用 sudo 功能
[ssh_connection]
# Ansible默认使用SSH协议连接对端主机,该部署是主要是SSH连接的一些配置,但配置项较少,多数默认即可
ssh_args=-C -o ControlMaster=auto -o ControlPersist=60s # SSH 连接时的参数
pipelining=False # SSH pipelining 是一个加速 Ansible 执行速度的简单方法。ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选项。如果不使用 sudo,建议开启。打开此选项可以减少 Ansible 执行没有传输时 ssh 在客户端上执行任务的连接数。不过,如果使用 sudo,必须关闭 requiretty 选项
scp_if_ssh=smart # 该项为 True 时,如果连接类型是 SSH,使 Ansible 使用 scp,为 False,Ansible 使用 sftp 。默认为 smart ,smart 为先尝试 sftp,然后尝试 scp
[persistent_connection] # 保持连接
connect_timeout=30 # Ansible 如果在30秒内没有收到请求,则关闭连接,默认为30秒
command_timeout=30 # Ansible 执行命令如果在30秒内没有收到回应则认为命令超时
[accelerate] # 缓存加速
accelerate_port=5099 # 加速连接 509 端口
accelerate_timeout = 30 # 命令执行超时时间
ccelerate_connect_timeout = 5.0 # 连接超时时间,单位为秒
accelerate_daemon_timeout = 30 # 上一个活动连接的时间,单位为分钟
accelerate_multi_key = yes # 允许多个私钥被加载到 daemon
[selinux]
special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p # 文件系统在处理安全上下文时需要特殊处理,定义复制现有上下文的文件系统
libvirt_lxc_noseclabel = yes # 将此设置为 yes,以允许libvirt_lxc连接在没有SELinux的情况下工作
[colors]
# Ansible对于输出结果的颜色也进行了详尽的定义且可配置,该选项对日常功能应用影响不大,几乎不用修改,保持默认即可。
highlight = white
verbose = blue
warn = bright purple
error = red
debug = dark gray
deprecate = purple
skip = cyan
unreachable = red
ok = green
changed = yellow
diff_add = green
diff_remove = red
diff_lines = cyan
[diff]
always = no
context = 3
Ansible Inventory 是一个由主机(IP/域名)或一组主机(多台主机组成的组)组成的主机清单。Ansible Inventory 不仅仅是一个主机清单,还可以通过对特定主机或特定的组赋值变量,供后续 Ansible 操作时使用。你可以在同一时间使用多个 Ansible Inventory,在命令行中使用 -i 参数可以指定特定的 Inventory 文件 。
Ansible Inventory 里面分为 Static Inventory (静态,读取文件获取清单) 和 Dynamic Inventory (动态,调用 API 获取清单)。
这是一个默认的 Ansible Inventory 文件,默认存放在 /etc/ansible/hosts。
‘#’ 为注释符号
空白行会被忽略
组由 ‘[Group Name]’ 分隔
可以使用域名或 IP 定义主机
一个 IP 或域名可以同时属于多个组
# 例子 1: 不分组的主机,需要在所有的[Group Name]前指定
## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10
# 例子 2: 一个属于 webservers 组的主机集合
## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110
# 如果你有多个主机遵循一种规范,则可以这样指定
## www[001:006].example.com
# 例子 3: 一个属于 dbservers 组的主机集合
## [dbservers]
##
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57
# 例子 4:一个属于 nginx 组的主机集合,使用别名并指定用户和密码登陆
[nginx]
nginx_node1 ansible_ssh_host=172.26.3.57 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456
nginx_node2 ansible_ssh_host=172.26.3.58 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456
# 例子 5:一个属于 redis 组的主机集合,使用组变量指定用户和密码登陆
[redis]
172.26.3.84
172.26.3.85
[redis:vars]
ansible_ssh_port=22
ansible_ssh_user=root
ansible_ssh_pass=123456
使用 ansible 命令测试 主机清单 中的主机是否可以正常连接


Ansible 底层使用 SSH 协议连接被管理的主机,因此在使用 ansible 命令之前需要先配置免密登录 或是 在主机清单中标明用户名和密码。
配置免密登录后再访问, 看到如下输出说明被控端可以正常连接。

如果 Ansible Inventory 是会随着时间推移而更改,跟着业务需求而改变的。(如弹性伸缩、新增或移除大量主机等)那么 Static Inventory 就没办法满足我们的需求。Dynameic Inventory 支持从云提供程序、LDAP、Cobbler 和企业级 CMDB 系统获取 Inventory。实现的方式有两种,一种是 Ansible 插件,另一种是通过脚本实现。一般情况下推荐使用 Ansible 插件作 Dynameic Inventory 的获取方式,脚本作为确保向后兼容。
Ansible 管理端下发公钥
sshpass -p 'password' ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.11.10
如果控制端和被控制端第一次通讯,需要确认指纹信息,如果机器特别多,只要将 Ansible 配置文件中的 host_key_checking = False 参数注释打开即可。