哪些动作属于控制节点
有些动作本质上不属于任何被管主机:调用云平台或负载均衡接口、生成并保管构件、汇总各主机返回的信息、操作只有控制节点能访问的凭据。把这些动作跑在被管主机上是常见错误——本机路径不存在、接口不可达、或者同一动作重复执行几十次。正确做法是把它们显式标记为在控制节点执行。
基本信息
| 整段本机执行 | 把剧本的目标写成本机并声明本地连接,或直接以本机为目标运行 |
|---|---|
| 单任务本机执行 | 给任务加委派到本机,只把该任务放到控制节点 |
| 本机目标来源 | 隐式的本机目标无需在清单中定义,也可以用清单中的本机条目替换它 |
| 变量差异 | 隐式本机目标没有清单变量,其解释器与路径行为随版本变化,以官方文档为准 |
| 实现形式 | 也可以把控制节点动作写成独立剧本,在需要时显式调用 |
| 权限 | 本机动作按控制节点上的执行用户运行,不涉及远程提权 |
典型使用场景
- 接口交互:向负载均衡、注册中心、云平台发起一次调用
- 构件与凭据:在控制节点生成配置、签发请求、保管私钥
- 信息汇总:收集各主机的返回值并汇总成报告或上报监控
- 编排与编排后处理:执行的编排动作本身而非主机上的配置
- 访问受限资源:只有控制节点或跳板机可达的外部系统
- 触发调度:调用外部流水线或作业平台继续后续流程
三种标记方式
三种标记方式
# 方式一:整个剧本以本机为目标,声明本地连接
- hosts: localhost
connection: local
gather_facts: false
tasks:
- name: 汇总各主机信息并上报
ansible.builtin.uri:
url: http://cmdb.internal/api/sync
method: POST
body_format: json
body:
hosts: "{{ groups['web'] }}"
# 方式二:只有某个任务在控制节点执行(其余仍在被管主机)
- hosts: web
tasks:
- name: 配置主机
ansible.builtin.template:
src: app.conf.j2
dest: /etc/app/app.conf
- name: 在控制节点生成并校验证书请求
ansible.builtin.command: /usr/local/bin/gen-csr.sh {{ inventory_hostname }}
delegate_to: localhost
run_once: false # 每台主机各生成一份,因此不单次执行
changed_when: false
# 方式三:把控制节点动作写成独立剧本,需要时显式调用
# ansible-playbook -i inventory control-plane.yml执行位置对照
| 做法 | 执行位置 | 适用 |
|---|---|---|
| 默认(不声明) | 当前被管主机 | 主机上的配置与命令 |
| 整剧本本机目标 | 控制节点 | 汇总、编排、接口交互类任务 |
| 单任务委派到本机 | 控制节点 | 混在远程任务里的个别本机动作 |
| 委派到清单内某主机 | 指定主机 | 跳板机或特定主机上的动作 |
| 独立剧本 | 按目标声明决定 | 控制面动作较多时的清晰划分 |
本机目标上的路径都是控制节点的路径:模板源、本地收集目录、私钥位置都按控制节点解释。混在远程任务里做本机动作时,这条差异是排错的第一方向。
遗漏标记会把仅限控制节点的动作推到每台被管主机上:轻则接口被调用几十次、产生重复数据,重则把凭据分发到不该存在的主机上。涉及凭据的任务应确认执行位置并设置日志抑制。
怎么划分
用一句话判断:这个动作修改的是主机自己的状态,还是共享资源与全局状态?前者留在主机侧,后者放到控制节点侧。控制节点动作变多时,把它们收拢到独立剧本,比散落在各处加委派更容易阅读与复用。