技术博客

Ansible 2026 实战:ansible-core 2.20 新特性与 Event-Driven Ansible 落地指南

ansible-core 2.20 于 2025 年 11 月发布,支持周期延续至 2027 年中。2026 年最值得关注的不是 core 的小改动,而是 Event-Driven Ansible(EDA)的成熟落地——它让 Ansible 从"手动触发的批处理工具"变成了"能主动响应事件的自动化平台"。本文讲解 ansible-core 2.20 的关键改动、EDA 的核心架构与 Rulebook 配置、自动化告警响应实战(Prometheus AlertManager → EDA → Ansible Playbook),以及与 AWX/AAP 的集成方式。

Ansible自动化运维EDAEvent-DrivenPlaybookAWX运维自动化YAML

Ansible 已经是运维自动化的事实标准,但长期以来它有一个明显的局限:只能被动执行——等人手动跑 Playbook,或者靠 Cron 定期触发,没有能力主动感知环境变化。

Event-Driven Ansible(EDA) 解决了这个问题。它在 2024 年随 AAP 2.4 进入生产阶段,2025-2026 年已经在大量企业落地。今天来讲清楚 EDA 怎么用,以及 ansible-core 2.20 有哪些值得关注的改动。


ansible-core 2.20 关键变化

发布时间:2025 年 11 月 3 日
支持周期:至 2027 年 5 月 31 日
对应社区包:Ansible 13.x(含 2000+ 个 Collection)

主要变化:

1. Inventory 插件改进
   - 动态 Inventory 缓存机制优化(减少 API 调用次数)
   - 支持在 Inventory 文件中引用环境变量({{ lookup('env', 'DB_HOST') }})

2. 任务执行改进
   - loop + until 组合的重试逻辑修复(此前某些场景下会忽略 until 条件)
   - register 变量在 delegate_to 场景下的作用域问题修复

3. 密码管理
   - ansible-vault encrypt_string 支持从 stdin 读取内容(适合 CI/CD 流水线)
   - Vault ID 支持多级继承

4. 性能
   - 大型 Playbook(1000+ 个 task)的解析速度提升约 15%
   - fact 缓存(fact_caching=jsonfile)的写入性能改进

版本规划:
  ansible-core 2.19:维护至 2026 年 11 月
  ansible-core 2.20:维护至 2027 年 5 月(当前推荐版本)
  ansible-core 2.21:2026 年 5 月发布(beta 进行中)

安装和升级

# 安装最新稳定版(ansible-core 2.20)
pip install ansible-core==2.20.5

# 安装社区包(含所有 Collection)
pip install ansible==13.6.0

# 检查版本
ansible --version
# ansible [core 2.20.5]
# python version = 3.11.x

# 升级(保留已安装的 Collection)
pip install --upgrade ansible-core
ansible-galaxy collection list    # 查看现有 Collection
ansible-galaxy collection upgrade  # 升级所有 Collection

Event-Driven Ansible(EDA)核心概念

EDA 让 Ansible 能够监听外部事件,并根据预定义规则自动触发 Playbook。

EDA 的三层架构:

Event Source(事件来源)
  │ 实时监听外部系统的事件
  │ 支持:Prometheus AlertManager、Kafka、Webhook、AWS CloudTrail、
  │       Dynatrace、PagerDuty、GitLab CI、Kubernetes Events 等

Rulebook(规则书)
  │ 定义:当收到什么事件 → 执行什么动作
  │ 语法:YAML 格式,类似 Ansible Playbook

Action(动作)
  执行 Playbook、发送通知、设置变量、打印日志等

核心组件:
  ansible-rulebook:EDA 命令行工具(开源)
  EDA Controller:Web UI 管理界面(AAP 企业版包含)
  Decision Environment:预打包的容器镜像(含 ansible-rulebook + 依赖)

安装 ansible-rulebook

# 安装依赖(需要 Java 17+)
# macOS
brew install openjdk@17
export JAVA_HOME=$(brew --prefix openjdk@17)

# Ubuntu
apt-get install openjdk-17-jdk

# 安装 ansible-rulebook
pip install ansible-rulebook

# 安装 EDA 事件源 Collection
ansible-galaxy collection install ansible.eda

# 验证安装
ansible-rulebook --version

Rulebook 示例:自动响应 Prometheus 告警

这是 EDA 最典型的落地场景:Prometheus 触发告警 → EDA 自动执行修复 Playbook。

目录结构

eda-playbooks/
├── rulebooks/
│   └── prometheus-alerts.yml     # Rulebook
├── playbooks/
│   ├── restart-pod.yml           # 重启 Pod
│   ├── scale-deployment.yml      # 扩容 Deployment
│   └── disk-cleanup.yml          # 清理磁盘
└── inventory/
    └── k8s-nodes.yml

Rulebook 配置

# rulebooks/prometheus-alerts.yml
---
- name: 响应 Prometheus 告警
  hosts: all
  sources:
  # 监听 AlertManager Webhook(EDA 作为 AlertManager 的 Receiver)
  - ansible.eda.alertmanager:
      host: 0.0.0.0
      port: 5000
      data_alerts_path: alerts    # AlertManager Webhook 中的 alerts 字段路径

  rules:
  # 规则1:Pod CrashLoop → 自动重启
  - name: Pod CrashLooping 自动重启
    condition: event.alert.labels.alertname == "PodCrashLooping"
    action:
      run_playbook:
        name: playbooks/restart-pod.yml
        extra_vars:
          pod_name: "{{ event.alert.labels.pod }}"
          namespace: "{{ event.alert.labels.namespace }}"

  # 规则2:内存不足 → 自动扩容
  - name: 内存使用率过高自动扩容
    condition: |
      event.alert.labels.alertname == "HighMemoryUsage" and
      event.alert.status == "firing"
    action:
      run_playbook:
        name: playbooks/scale-deployment.yml
        extra_vars:
          deployment: "{{ event.alert.labels.deployment }}"
          namespace: "{{ event.alert.labels.namespace }}"
          replicas: 3    # 扩容到 3 副本

  # 规则3:磁盘告警 → 清理 + 通知
  - name: 节点磁盘压力告警
    condition: event.alert.labels.alertname == "NodeDiskPressure"
    actions:
    - run_playbook:
        name: playbooks/disk-cleanup.yml
        extra_vars:
          node: "{{ event.alert.labels.instance }}"
    - print_event:
        pretty: true

  # 规则4:告警恢复 → 记录日志(resolved 状态)
  - name: 告警恢复记录
    condition: event.alert.status == "resolved"
    action:
      print_event:
        pretty: true

Playbook 示例(重启 Pod)

# playbooks/restart-pod.yml
---
- name: 重启 CrashLoop Pod
  hosts: localhost
  connection: local
  gather_facts: false
  vars:
    pod_name: "{{ pod_name }}"
    namespace: "{{ namespace }}"

  tasks:
  - name: 获取 Pod 所属 Deployment
    kubernetes.core.k8s_info:
      api_version: v1
      kind: Pod
      name: "{{ pod_name }}"
      namespace: "{{ namespace }}"
    register: pod_info

  - name: 删除 CrashLoop Pod(让 Deployment 重新创建)
    kubernetes.core.k8s:
      state: absent
      api_version: v1
      kind: Pod
      name: "{{ pod_name }}"
      namespace: "{{ namespace }}"
    when: pod_info.resources | length > 0

  - name: 等待新 Pod 就绪
    kubernetes.core.k8s_info:
      api_version: v1
      kind: Pod
      namespace: "{{ namespace }}"
      label_selectors:
      - "app={{ pod_info.resources[0].metadata.labels.app }}"
    register: new_pods
    until: >
      new_pods.resources | selectattr('status.phase', 'eq', 'Running') | list | length > 0
    retries: 10
    delay: 15

  - name: 发送钉钉通知
    uri:
      url: "{{ lookup('env', 'DINGTALK_WEBHOOK') }}"
      method: POST
      body_format: json
      body:
        msgtype: text
        text:
          content: "✅ 已自动重启 Pod {{ namespace }}/{{ pod_name }},当前状态恢复正常"

启动 EDA

# 启动 Rulebook(监听 5000 端口,等待告警)
ansible-rulebook \
  --rulebook rulebooks/prometheus-alerts.yml \
  --inventory inventory/k8s-nodes.yml \
  --verbose

# 配合 AlertManager,在 alertmanager.yml 中添加 EDA 为 Receiver
# receivers:
# - name: eda-receiver
#   webhook_configs:
#   - url: 'http://eda-server:5000/endpoint'

# 测试:手动发送模拟告警
curl -X POST http://localhost:5000/endpoint \
  -H "Content-Type: application/json" \
  -d '{
    "alerts": [{
      "status": "firing",
      "labels": {
        "alertname": "PodCrashLooping",
        "pod": "myapp-xxx-yyy",
        "namespace": "production"
      }
    }]
  }'

Webhook 事件源:通用事件接入

# 使用 Webhook 事件源接收任意 HTTP 请求
- name: 通用 Webhook 自动化
  hosts: all
  sources:
  - ansible.eda.webhook:
      host: 0.0.0.0
      port: 5001

  rules:
  # 接收 GitHub Push 事件,自动部署
  - name: GitHub Push 自动部署
    condition: >
      event.payload.ref == "refs/heads/main" and
      event.payload.repository.name == "my-app"
    action:
      run_playbook:
        name: playbooks/deploy-app.yml
        extra_vars:
          commit_sha: "{{ event.payload.head_commit.id }}"
          repo: "{{ event.payload.repository.clone_url }}"

Kafka 事件源:高吞吐场景

# 监听 Kafka Topic,响应业务事件
- name: 业务事件驱动自动化
  hosts: all
  sources:
  - ansible.eda.kafka:
      host: kafka.internal.company.com
      port: 9092
      topic: infra-events
      group_id: eda-consumer

  rules:
  - name: 数据库连接数告警
    condition: >
      event.payload.type == "db_alert" and
      event.payload.metric == "connection_count" and
      event.payload.value > 1000
    action:
      run_playbook:
        name: playbooks/optimize-db-connections.yml

Kubernetes Events 源:监听集群内部事件

# 直接监听 K8s Events
- name: Kubernetes 集群事件响应
  hosts: localhost
  sources:
  - ansible.eda.k8s:
      api_version: v1
      kind: Event
      namespace: production

  rules:
  - name: ImagePullBackOff 自动处理
    condition: >
      event.resource.reason == "Failed" and
      "ImagePullBackOff" in event.resource.message
    action:
      run_playbook:
        name: playbooks/fix-image-pull.yml
        extra_vars:
          pod: "{{ event.resource.involvedObject.name }}"
          namespace: "{{ event.resource.involvedObject.namespace }}"
          image: "{{ event.resource.message }}"

与 AWX / Ansible Automation Platform 集成

如果团队使用 AWX(开源)或 AAP(企业版),EDA 可以通过 Job Template 触发已定义的 Playbook。

# 使用 controller(AWX/AAP)动作代替直接执行 Playbook
rules:
- name: 触发 AWX Job Template
  condition: event.alert.labels.alertname == "NodeDown"
  action:
    run_job_template:
      name: "Node Recovery Playbook"     # AWX 中 Job Template 的名称
      organization: "IT Ops"
      extra_vars:
        target_node: "{{ event.alert.labels.instance }}"
# 连接 AWX Controller
export CONTROLLER_URL=https://awx.internal.company.com
export CONTROLLER_TOKEN=<your-api-token>

ansible-rulebook \
  --rulebook rulebooks/prometheus-alerts.yml \
  --inventory inventory/ \
  --controller-url $CONTROLLER_URL \
  --controller-token $CONTROLLER_TOKEN

常用命令速查

# 列出可用的 EDA 事件源插件
ansible-doc -t eda_event_source ansible.eda.webhook
ansible-doc -t eda_event_source ansible.eda.alertmanager
ansible-doc -t eda_event_source ansible.eda.kafka

# 验证 Rulebook 语法(不实际执行)
ansible-rulebook \
  --rulebook rulebooks/prometheus-alerts.yml \
  --check

# 查看 EDA Collection 版本
ansible-galaxy collection list | grep eda

# 升级 EDA Collection
ansible-galaxy collection install ansible.eda --upgrade

# 调试模式运行(输出详细日志)
ansible-rulebook \
  --rulebook rulebooks/test.yml \
  --inventory inventory/ \
  --verbose \
  --debug

小结

EDA 让 Ansible 从定时批处理工具升级为真正的响应式自动化平台。它最大的价值在于减少告警→响应之间的人工等待时间:一个 Pod CrashLoop 告警,传统流程需要运维人员看到→登录→执行,可能需要几分钟到几十分钟;EDA 可以在秒级内触发 Playbook 完成自动修复。

ansible-core 2.20 作为当前稳定版本,适合作为新环境的默认选择,支持到 2027 年中,搭配 EDA,能覆盖大多数企业运维自动化需求。