一:ansible基础知识
1.1 ansible的定义与工作原理简述
ansible是一个自动化运维工具,用于执行自动化任务,包括像配置管理,应用部署,任务执行等等,本质上来说也是基础设施及代码工具,通过可读性较强的代码声明基础设施的期望状态,再通过附带的ansible模块去执行。
什么是基础设施?
基础设施及代码”里的**“基础设施”,专指支撑应用运行的所有底层环境和依赖**,而不限于传统意义上的机房、机柜、网线。它通常被拆成三层:
计算资源
物理机、虚拟机(KVM/VMware/Hyper-V)、容器运行时(Docker/containerd)、Kubernetes Node、Lambda/Function 等可运行代码的实体。网络与连通性
VPC、子网、路由表、安全组、负载均衡(ELB/SLB/NGINX Ingress)、VPN、DNS、CDN、Service Mesh 等让流量能正确且安全地进出的组件。存储与数据
块存储(EBS、云盘)、对象存储(S3、OSS)、文件存储(EFS、NAS)、数据库(RDS、Aurora、MongoDB)、缓存(Redis、Memcached)、备份与快照。
一句话:
“基础设施”= 让应用能跑起来、能被访问、能把数据存下来的所有“云+底层资源”;把这一切用代码(Terraform、Ansible、Pulumi、K8s YAML、Helm Chart)声明出来,就成了 IaC 中的“基础设施”。
工作原理是什么?
加载配置
读取ansible.cfg
、环境变量、命令行参数,决定 SSH/WinRM 选项、并发数(forks)、回调插件等。生成库存(Inventory)
把静态 INI、动态脚本(AWS、VMware、OpenStack、K8s CRD 等)或 Tower 数据库里的主机信息解析成内存对象,附带变量(host_vars、group_vars)。建立连接
控制节点按ansible_connection
字段决定用 SSH、local、docker、kubectl、winrm 等协议并发地与目标机握手;这一步只建一次连接,后续指令复用同一通道。任务编排与模块传输
• 对每条 Play/Role,先按策略插件(linear、free、debug)切分批次。
• 把要执行的模块(Python 文件或二进制)+ 参数打包成 ZIP,通过 SCP/SFTP 推到远端临时目录(~/.ansible/tmp/...
)。
• 远端用指定的解释器(/usr/bin/python3
、/usr/bin/pwsh
等)一次性执行该模块,返回 JSON 结果。
• 如果是幂等模块,会先收集当前状态做差异比较(例如yum list installed nginx
),再决定是否改动。结果收集与回调
控制节点把每台主机的 JSON 回包解析成统一结构(changed、ok、failed、skipped),通过回调插件输出到终端、日志、Slack、Prometheus 或 Tower 数据库,并根据any_errors_fatal
或max_fail_percentage
决定是否中止整个 Playbook。
ansible的优势是什么?
核心能力拆解
声明式编排
Playbook 只描述“要变成什么样”,而不是“怎么变”。例如“确保 nginx 已安装并运行”,Ansible 会自己判断是否需要安装、启动或重启。幂等执行
同一 Playbook 反复运行,结果不变。第 1 次会改动系统,第 N 次直接返回 OK,天然适合 CI/CD 与回滚。无 agent 架构
控制节点通过 SSH(Linux/Unix)或 WinRM(Windows)连接,目标机无需预装客户端,降低入侵面和维护成本。模块化插件体系
6000+ 个模块(command、yum、template、kubernetes、vmware…)+ 回调插件、动态库存、过滤器,几乎覆盖所有基础设施和应用场景。可版本化、可审计
Playbook/Role 是纯文本,天然进 Git;执行日志可 JSON 化输出,方便审计与合规。跨平台:可以操控linux,windows,unix,网络设备等等。
什么是幂等执行,如何实现的?
幂等执行(idempotency)指:
无论操作执行 1 次还是 N 次,系统的最终状态都保持一致,且不会产生额外副作用。
举例:
第 1 次执行“确保 nginx 已安装并启动” → 系统安装了 nginx 并启动。
第 2 次执行同样指令 → 检测到 nginx 已安装且进程已运行,直接返回 OK,不再重复安装或重启。
Ansible 实现幂等的核心机制
声明式模块
每个模块内部先“查现状”,再“算差异”,最后“只做必要改动”。yum:
模块 → 先rpm -q nginx
;若已安装则直接返回ok
。service:
模块 → 先systemctl is-active nginx
;若已是active
,则跳过启动。copy:
模块 → 先比较 checksum;文件一致则跳过传输。
facts 缓存
运行setup
模块把系统信息(包列表、服务状态、文件属性等)缓存到ansible_facts
,后续任务可直接引用,避免重复查询。check mode / diff mode
ansible-playbook -C
:模拟运行,只返回“哪些任务会改变”,不真正执行。ansible-playbook -D
:在终端显示文件 diff,提前确认变更。
条件判断与 register
通过register
保存任务结果,再用when
或changed_when/failed_when
控制后续逻辑,避免重复操作。幂等性开关
个别模块提供显式参数:command:
/shell:
默认非幂等,但可配creates
/removes
文件标记。uri:
模块可用status_code
判断接口是否已创建资源。
一句话总结:
Ansible 的幂等性不是靠用户写“if not exist then …”,而是每个模块内部自带“查-比-改”三步逻辑,从而保证多次执行结果一致。
1.2 ansible的分类
ansible是属于redhat公司的核心产品,分为红帽企业版和社区版,两者差别就是在于模块数量和功能完整度,社区版的软件包是ansible-core只包含了运行ansible的必需几个组件和内建模块通过pip下载,而企业版通过rpm包下载,不仅包含了ansible-core,还包含了最新的组件ansible-navigator可以代替过去多个ansible命令,用于开发和测试ansible的playbook。
过去常用的ansible命令有哪些?
运行 playbook
ansible-playbook查看 playbook 中某个关键词用法
ansible-doc 关键词查看主机清单
ansible-inventory --list查看配置
ansible-config dump
现在的ansible-navigator怎么全部代替他们?
老命令 | ansible-navigator 等价用法 |
---|---|
ansible-playbook site.yml | ansible-navigator run site.yml |
ansible-doc 关键字 | ansible-navigator doc 关键字 |
ansible-inventory --list | ansible-navigator inventory --list |
ansible-config dump | ansible-navigator config dump |
ansible-core软件包和ansible-navigator软件包运行环境有什么这区别?
一句话区分
• ansible-core:直接在你本地 Python 环境里跑 ansible-playbook
。
• ansible-navigator:把 ansible-core 装进一个容器镜像里跑,你用 navigator 命令只是去启动那个容器。
所以:
– 安装 ansible-core 要先配 Python、pip 依赖;
– 安装 ansible-navigator 只要装好 podman/docker,它自动拉镜像,里面已经打包好 ansible-core 和所有常用集合,版本隔离、依赖不污染宿主机。
为什么ansible一定需要一个运行环境?
Ansible 控制节点必须有一个“运行环境”,是因为 它才是真正干活的程序,而不是一个单纯的“遥控器”。
简单一句话:
控制节点需要 Python + Ansible 代码 + 模块库,用来 把 YAML 翻译成远程机器上可执行的命令,并收集结果。
具体作用拆开说:
解释 Playbook
YAML 里的任务、变量、模板全由控制节点的 Python 进程解析成内部数据结构。加载并执行模块
每个任务对应一个.py
模块,控制节点先把模块代码通过 SSH/WinRM 复制到目标机,再远程执行;模块返回 JSON 结果,控制节点再解析。变量与事实处理
控制节点运行setup
收集 facts,再把 host_vars、group_vars、Jinja2 模板在本地渲染好,再下发。并发与结果聚合
forks、策略插件、回调插件都在控制节点里跑,负责并发调度、输出格式化、失败重试等。依赖管理
模块、集合、Jinja2 过滤器、额外 Python 库(如 boto3、kubernetes)都装在控制节点;目标机不需要这些依赖。
因此,控制节点必须有一个 包含 Python 解释器 + ansible-core + 相关依赖 的运行环境;没有它,YAML 只是纯文本,无法变成可执行指令。
二:实施ansible的playbook
前提条件
实施playbook前需要集齐主机清单和ansible的配置。
2.1 主机清单
主机清单是用来管控ansible实施主机对象的文件,分为静态主机清单文本文件和通过外部程序提供信息动态生成主机信息的动态主机清单。(以静态主机清单为例)。
格式如下:由主机ip或域名与主机组构成。
直接列主机
192.168.1.10
web01.example.com
2分组 + 主机 + 变量
[web]
web01 ansible_host=192.168.1.10 ansible_user=deploy
web02 ansible_host=192.168.1.11[db]
db01 ansible_host=192.168.2.5
db02 ansible_host=192.168.2.6 ansible_port=2222[web:vars] # 全组共用变量
http_port=80
直接写在主机后面
web01 ansible_host=192.168.1.10 ansible_user=deploy
2写在组名 :vars
段里(组内共用)
[web:vars]
http_port=80
3写在
all:vars
段里(全体共用)
[all:vars]
ansible_ssh_private_key_file=~/.ssh/id_rsa
保存后 Ansible 会自动读取这些变量,优先级:主机变量 > 组变量 > all 变量。
3嵌套/继承组
[prod:children]
web
db
存在默认的两个主机组
all:全体主机
ungrouped:没有被列进主机组的主机
另外在主机清单里还可以通过[start:end]格式来简化主机格式例如:
inventory查找的默认顺序如下:(ansible执行的时候工作路径是当前执行的工作路径)
Ansible 查找主机清单的默认顺序(从先到后):
命令行
-i
指定的文件或脚本。ANSIBLE_INVENTORY
环境变量指定的路径。当前目录下的
ansible.cfg
里inventory = ...
指定的路径。用户主目录
~/.ansible.cfg
里inventory = ...
指定的路径。系统级
/etc/ansible/ansible.cfg
里inventory = ...
指定的路径。若以上都没有,则回退到 /etc/ansible/hosts。
2.2 ansible的配置文件
ansible的配置文件一般基础配置文件命名为ansible.cfg,管理ansible-navigator的配置文件命名为ansible-navigato.yml.
ansible.cfg包含两个部分[defaults]和[privilege_escalation].
defaults 段
[defaults]
• inventory = ./hosts # 指定清单文件
• remote_user = deploy # 默认 SSH 用户
• forks = 20 # 并发数
• host_key_checking = False # 首次连接免确认privilege_escalation 段
[privilege_escalation]
• become = True # 默认启用提权
• become_method = sudo # 用 sudo
• become_user = root # 提权到 root
可以通过ansible-navigator config去查看ansible.cfg所有配置。
ansible-navigator.yml文件主要包含以下部分:
playbook-artifact 就是 把一次 playbook 运行的完整结果(每个 play、每个任务的状态、stdout、返回值等)自动写成一个 JSON 快照文件,作用:
事后回放:
用ansible-navigator replay xxx.json
随时在终端里“重看”这次运行,不用原 playbook 和清单。共享/审计:
JSON 单文件即可发给同事或归档,满足合规和变更追踪需求。离线排查:
失败现场被完整保留,方便脱离原始环境做调试。
一句话:playbook-artifact 是把运行结果“录像”成 JSON,随时回放、共享、审计。
ansible两个配置文件的执行查找顺序是什么?
先找 ansible.cfg → 再找 ansible-navigator.yml。
ansible-navigator 启动时,先用 Ansible 自己的查找顺序(当前目录 → ~/.ansible.cfg → /etc/ansible/ansible.cfg)确定 ansible.cfg。
然后读取同一目录下的 ansible-navigator.yml(或
~/.ansible-navigator.yml
)。
后者仅对 navigator 生效,不会覆盖 ansible.cfg 中已设置的参数,只是补充或改用容器执行环境。
2.2 ansible playbook的语法规则
一个完整的ansible playbook的示例如下:
---
- name: Ensure nginx is installed and runninghosts: webbecome: yesvars:http_port: 80tasks:- name: Install nginxyum:name: nginxstate: presentwhen: ansible_facts['os_family'] == 'RedHat'- name: Deploy index.htmltemplate:src: templates/index.html.j2dest: /usr/share/nginx/html/index.html- name: Ensure nginx is started and enabledservice:name: nginxstate: startedenabled: yes- name: Verify port is listeningwait_for:port: "{{ http_port }}"host: "{{ ansible_default_ipv4.address }}"
开头为:---
注释用#
在 Playbook 中,只有当 YAML 需要「列表项」时才必须写 -
(破折号+空格)。
出现位置只有两处:
顶层:每个 play 是列表成
--- - name: play1 # ← 这里hosts: web - name: play2 # ← 再一个 play
任务/角色/变量等列表:tasks、roles、pre_tasks、post_tasks、vars、loop、block、handlers
tasks:- name: task1 # ← 任务列表- name: task2
其余场景(字典 key、模块参数、变量赋值)绝不要 -
,直接键值对即可。
常用执行的参数如下:
类别 | 参数 | 作用说明 |
---|---|---|
清单/范围 | -i <文件> | 指定主机清单 |
-l <模式> | 只跑匹配的主机或组 | |
语法检查 | --syntax-check | 仅检查 playbook 语法 |
空运行 | --check 或 -C | 干跑,不真正改变系统 |
--diff | 空跑时显示文件差异 | |
输出详细程度 | -v | 详细输出 |
-vv / -vvv | 更详细 / 最详细 | |
并发 | -f N | 并发进程数(默认 5) |
提权 | --become | 自动使用 sudo/ become |
标签 | -t <标签> | 仅执行带指定 tag 的任务 |