本文最后更新于:2023年12月5日 晚上
ansible 介绍和架构
ansible 特性
- 基于 python 实现
- 模块化:支持自定义模块,可以使用任何语言编写模块
- 安全:基于 OpenSSH
- 部署简单:被控端不需要配置环境
- 幂等性:一个任何执行一遍和执行 n 遍效果一样,不因重复执行带来意外情况,此特性非绝对
- 支持 playbook 编排任务,YAML 格式,编排任务,支持丰富的数据结构
- 较强大的多层解决方案 role
ansible 架构
- INVENTORY:Ansible 管理主机的清单/etc/anaible/hosts
- MODULES:Ansible 执行命令的功能模块,多数为内置核心模块,也可自定义
- PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
- API:供第三方程序调用的应用程序编程接口
ansible 命令执行来源
- USER:普通用户,即 SYSTEM ADMINISTRATOR
- PLAYBOOKS:任务剧本(任务集),编排定义 Ansible 任务集的配置文件,由 Ansible 顺序依次执行,通常是 JSON 格式的 YML 文件
- CMDB(配置管理数据库) API 调用
- PUBLIC/PRIVATE CLOUD API 调用
- USER-> Ansible Playbook -> Ansibile
注意事项
- 执行 ansible 的主机一般称为管理端, 主控端,中控,master 或堡垒机
- 主控端 Python 版本需要 2.6 或以上
- 如果被控端 Python 版本小于 2.4,则需要安装 python-simplejson
- 被控端如开启 SELinux 需要安装 libselinux-python
- windows 不能做为主控端
ansible 安装和入门
pip安装
pip 安装后没有配置文件,需要手动创建,有以下四种方式:
- ANSIBLE_CONFIG (environment variable if set)
- ansible.cfg (in the current directory)
- ~/.ansible.cfg (in the home directory)
- /etc/ansible/ansible.cfg
ansible 相关文件
ansible 主配置文件
默认为:/etc/ansible/ansible.cfg
参考文档:
https://github.com/ansible/ansible/blob/stable-2.9/examples/ansible.cfg
http://www.ansible.com.cn/docs/intro_configuration.html
inventory 主机清单
ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名。
默认:/etc/ansible/hosts
参考文档:
https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html
http://www.ansible.com.cn/docs/intro_inventory.html?highlight=hosts
格式
支持两种格式:ini
和 yaml
ini
示例:
对应的yaml
格式:
默认组
即使inventory文件中没有定义任何组,ansible也会创建两个默认组:all
和ungrouped
。all
包含每个主机,ungrouped
组包含除所有主机外没有其他组的all
主机。每个主机都至少属于两个组(all
和ungrouped
或者 all
和其他一些组)。例如,在上面的示例中,主机mail.example.com
属于all
和ungrouped
组;主机two.example.com
属于all
和dbservers
组。尽管all
和ungrouped
组始终存在,但他们是隐式的,不会出现在group_names
等组列表中。
简写
如果您有很多具有类似模式的主机,您可以将它们添加为一个范围,而不是单独列出每个主机名:
您可以在定义主机的数字范围时指定步幅(序列号之间的增量):
选择连接类型和连接用户名
主机变量
inventory中定义的变量, 在playbooks中使用。
分配变量给主机很容易做到:
组的变量
也可以定义属于整个组的变量:
或者:
父/子组
您可以在组之间创建父/子关系。父组也称为嵌套组。例如,如果您的所有生产主机已经在atlanta_prod
和denver_prod
等组中,您可以创建一个包含这些较小组的production
组。
在INI格式中,使用 :children
后缀;在YAML格式中,使用 children:
条目:
inventory 参数说明
ansible.builtin.ssh connection – connect via SSH client binary — Ansible Documentation
ansible 相关工具
- ansible:主程序,临时命令执行工具
- ansible-doc:查看配置文档,模块功能查看工具,相当于 man
- ansible-playbook:定制自动化任务,剧本
- ansible-pull:远程执行命令的工具
- ansible-vault:文件加密工具
- ansible-console:基于 Console 界面与用户交互的执行工具
- ansible-galaxy:下载/上传优秀代码或 Roles 模块的官网平台
ansible
通过 ssh 协议,实现对远程主机的配置管理、应用部署、任务执行等功能
注意:使用 ansible 之前,需要配置各个被控端基于 key 的密钥认证
host-pattern:匹配被控主机
- all:inventory 中的所有主机
- 支持通配符
- 支持正则表达式:需要以 ‘~’ 开头
- 使用:表示或关系
- 使用:&表示与关系
- 使用:!表示非关系
示例:
常用 option
- –version:显示版本等信息
- -m module:指定模块,默认为 command
- -a | –args MODULE_ARGS:指定模块的参数
- –list-hosts:显示主机列表,可简写 –lists
- -C | –check:检查,并不执行
- -T | –timeout=TIMEOUT:执行命令的超时时间,默认 10s
- -k | –ask-pass:提示输入 ssh 连接密码,默认 Key 验证
- -u | –user REMOTE_USER:指定远程执行的用户
- -b | –become:代替旧版的 sudo 切换
- –become-user=USERNAME:指定 sudo 的 runas 用户,默认为 root
- -K | –ask-become-pass:提示输入 sudo 时的口令
ansible 命令执行顺序
- 加载配置文件,默认/etc/ansible/ansible.cfg
- 加载对应的模块文件,如:command
- 将模块或命令生成临时 py 文件,并将该文件传输至远程服务器远程服务器:$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY
- 给文件+x 权限
- 执行并返回结果
- 删除临时 py 文件,退出
ansible 执行状态
在 ansible.cfg 的[colors]配置项中设置:
- 绿色:执行成功且没有对目标主机做更改
- 黄色:执行成功且对目标主机做了更改
- 红色:执行失败
ansible 使用示例
ansible-doc
显示模块帮助,相当于 man
options:
- -l|–list:列出可用模块
- -s|–snippet:显示指定模块的 playbook 片段
示例:
ansible-playbook
执行编写好的 playbook 任务
- –syntax-check:语法检查
- -C|–check:只检测可能会发生的改变,但不真正执行操作
- –list-hosts:列出运行任务的主机
- –list-tags:列出 tag
- –list-tasks:列出 task
- –limit 主机列表:只针对主机列表中的特定主机执行
- -v -vv -vvv:显示过程
ansible-vault
加密解密 yml 文件
- encrypt:加密
- decrypt:解密
- view:查看
- edit:编辑加密文件
- rekey:修改口令
- create:创建新文件
ansible-console
交互执行命令,支持 tab,ansible 2.0+新增
常用子命令:
- 设置并发数: forks n 例如:
forks 10
- 切换组: cd 主机组 例如:
cd web
- 列出当前组主机列表:
list
- 列出所有的内置命令:
?
或help
示例:
ansible-galaxy
连接 https://galaxy.ansible.com 下载相应的 roles
示例:
ansible 常用 模块(module)和插件(plugin)
模块和插件的区别:
modules
是ansible的核心内容,它使playbook变得更加简单明了,一个task就是完成某一项功能。ansible模块是被传送到远程主机上运行的。所以它们可以用远程主机可以执行的任何语言编写modules。
plugins
是在 ansible控制节点 上执行的,用来辅助modules做一些操作。比如连接远程主机,拷贝文件到远程主机之类的。
- 执行的位置:
- 模块:文件被传送到 远端主机 并执行
- 插件:在 ansible控制节点 上执行
- 执行顺序:插件 先于 模块
本文以 ansible 2.10.5 为准
虽然模块众多,但最常用的模块也就 2,30 个而已,针对特定业务只用 10 几个模块
常用模块帮助文档参考:
使用 ansible-doc 可以查看每个模块的具体用法:
command
ansible.builtin.command module – Execute commands on targets — Ansible Documentation
默认模块,可忽略 -m 选项
注意:此命令不支持 $VARNAME < > | ; &
等,可以用 shell 模块实现
shell
和 command 相似,但是功能更丰富,支持各种符号,比如 *、$、>
注意:类似 cat /tmp/test.md | awk -F'|' '{print $1,$2}' &> /tmp/example.txt
这
些复杂命令,即使使用 shell 也可能会失败,解决办法:写到脚本时,copy 到远程,执行,再把需要的
结果拉回执行命令的机器
建议将 shell 模块替换 command,设为默认模块
script
在远程主机上运行 ansible 服务器上的脚本(无需执行权限)
copy
从 ansible 服务器主控端复制文件到远程主机
示例:
fetch
从远程主机提取文件至 ansible 的主控端,和 copy 相反,目前不支持目录
file
file 模块可以帮助我们完成一些对文件的基本操作,比如,创建文件或目录、删除文件或目录、修改文件权限等
示例:
unarchive
解包解压缩
示例:
archive
打包压缩保存在被管理节点
示例:
hostname
管理主机名
示例:
cron
计划任务,支持时间:minute,hour,day,month,weekday
示例:
yum、apt
yum:管理软件包,只支持 RHEL,CentOS,fedora
apt:模块管理 Debian 相关版本的软件包
yum
示例:
apt
示例:
serivce
管理服务
示例:
user
管理用户
group
管理组
示例:
lineinfile
参考:http://www.zsythink.net/archives/2542
我们可以借助 lineinfile 模块,确保”某一行文本”存在于指定的文件中,或者确保从文件中删除指定的”文本”(即确保指定的文本不存在于文件中),还可以根据正则表达式,替换”某一行文本”
ansible 在使用 sed 进行替换时,经常会遇到需要转义的问题,而且 ansible 在遇到特殊符号进行替换时,存在问题,无法正常进行替换 。所以 ansible 提供了两个模块:lineinfile 模块和 replace 模块,可以方便的进行替换
一般在 ansible 当中去修改某个文件的单行进行替换的时候需要使用 lineinfile 模块
示例:
replace
lineinfile 模块的主要功能是操作 in file 的 line,只能替换单行文本,多行匹配进行替换需要使用 replace 模块
该模块有点类似于 sed 命令,主要也是基于正则进行匹配和替换,建议使用
示例:
setup
setup 模块来收集主机的系统信息,这些 facts 信息可以直接以变量的形式使用,但是如果主机较多,会影响执行速度,可以使用 gather_facts: no 来禁止 ansible 收集 facts 信息
playbook
- playbook 是由一个或多个”play”组成的列表
- play 的主要功能在于将预定义的一组主机,装扮成事先通过 ansible 中的 task 定义好的角色。Task 实际是调用 ansible 的一个 module,将多个 play 组织在一个 playbook 中,即可以让它们联合起来,按事先编排的机制执行预定义的动作
- playbook 文件是采用 YAML 语言编写的
- hosts:执行的远程主机列表
- tasks:任务集
- variables:内置变量或自定义变量在 playbook 中调用
- templates:模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- handlers 和 notify:两者结合使用,特定条件出发操作
- tags:标签,指定某条任务执行,用于选择运行 playbook 中的部分代码。ansible 具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常长。此时,如果确信其没有变化,就可以通过 tags 跳过此些代码片断
hosts 组件
playbook 中的每一个 play 的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts 用于指定要执行指定任务的主机,须事先定义在 inventory 主机清单中
示例:
remote_user、sudo、sudo_user 组件
- remote_usr:指定远程主机执行任务的用户
- sudo:支持使用 sudo,默认切换到 root
- sudo_user:指定使用 sudo 时切换的用户
tasks 和 action
tasks 是 task 列表,task是字典类型。
play 的主体部分是 tasks,所有 task依次在所有远程主机上执行,可以是同步也可以是异步;
task 的目的是使用指定的参数执行模块,
未完待续…
handlers 和 notify
Playbook 中使用变量
两类变量:
ansible 内置变量 和 自定义变量,这些变量不仅可以在 playbook 中使用,在 ansible 中任何地方都可以使用
facts 信息,来自 setup 模块收集(允许自定义),可以禁止收集,这些变量只能在 playbook 中使用
内置变量 hostvars
在 playbook 中,自己主机的变量,无论是 ansible 内置、自定义还是 facts,都可以直接调用,其他主机的变量,可以通过 hostvars 间接调用,例如:
常用变量
- groups:来自 ansible 内置,主机列表
- group_names:来自 ansible 内置,当前主机在主机列表中的所属组
playbook 中使用 when
playbook 使用迭代 with_items(loop)
当有需要重复性执行的任务时,可以使用迭代机制
对迭代项的引用,固定内置变量名为”item”
要在 task 中使用 with_items 给定要迭代的元素列表
注意: ansible2.5 版本后,可以用 loop 代替 with_items
示例:
迭代嵌套子变量:在迭代中,还可以嵌套子变量,关联多个变量在一起使用
示例:
管理节点过多导致的超时问题解决方法
roles
roles 目录结构如下所示: