深入浅出 Elastic 工作流(Workflows):核心架构与十一大顶级字段详解

在现代 IT 运维与安全运营中,自动化和编排能力已经成为团队提升效率、缩短响应时间(MTTR)的关键。作为 Elastic 生态中强大的自动化工具,Elastic 工作流(Workflows) 能够帮助团队无缝编排安全响应、可观测性诊断以及日常的数据管理流程。

要编写一个高效、健壮的 Elastic 工作流,首先必须理解其底层的 YAML 定义结构。本文将带你深度剖析 Elastic 工作流的"解剖图",详细拆解其 11 个顶级字段,并解析工作流的完整执行生命周期。


1. Elastic 工作流的 "骨架":YAML 完整结构

一个标准的 Elastic 工作流定义由 11 个顶级字段构成,其中大部分是可选的。在深入细节之前,我们先通过一个模拟 "SLO 违约响应(SLO Breach Response)"的 YAML 完整示例来建立直观认知:

堆栈版本 9.5+ / Serverless 推荐结构(输入参数嵌套在触发器内)

yaml 复制代码
`

1.  name: slo-breach-response
2.  description: 调查并缓解 SLO 违约。
3.  enabled: true
4.  tags:
5.    - observability
6.    - slo

8.  version: "1"

10.  triggers:
11.    - type: manual
12.      inputs:
13.        - name: service_name
14.          type: string
15.          required: true

17.  consts:
18.    severity_threshold: 70

20.  outputs:
21.    - name: result
22.      type: string

24.  settings:
25.    timeout: "5m"
26.    concurrency:
27.      strategy: drop

29.  steps:
30.    - name: investigate
31.      type: elasticsearch.esql.query
32.      with:
33.        query: "..."

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

💡 版本差异提示 :在 Elastic Stack 9.4 及更早版本中,inputs(运行时输入参数)位于 YAML 的最顶层(与 namesteps 同级)。自 9.5+ 版本及 Serverless 环境 起,新创建的工作流推荐将 inputs 定义在具体的 manual 触发器内部,以便更紧密地绑定触发场景。不过,旧版的顶级 inputs 结构依然保持向下兼容。


2. 核心字段逐一拆解:11 大顶级字段

Elastic 工作流的每个字段都承载着特定的功能。以下是它们的详细参考和设计最佳实践:

name(字符串 | 必填)------ 工作流的唯一身份标识

name 是工作流的编程标识符,会显示在 Kibana UI 中,并在 API 调用中作为标识。

  • 最佳命名实践 :推荐使用 <领域>--<动词>-<名词> 的命名规范。例如:
    • security--triage-malware-alert(安全领域-分流恶意软件告警)
    • observability--respond-to-slo-breach(可观测性-响应 SLO 违约)
    • platform--rotate-service-account-keys(平台维护-轮换服务账号密钥)
  • 注意:工作流名称在同一个 Kibana 空间(Space)内必须是唯一的。

description(字符串 | 可选)------ 简短的副标题

用于在工作流列表中展示的简短说明。

  • 设计建议 :尽量控制在一句话内,说明工作流做什么(业务价值),而不是 "如何做"(技术实现)。
  • 示例description: 调查并缓解生产服务中的 SLO 违约。

enabled(布尔值 | 可选)------ 工作流的 "紧急安全开关"

控制工作流是否处于激活状态,默认为 true

  • 妙用场景 :当你想暂停一个工作流又不想将其彻底删除时,可以将其设为 false。此时,定时触发器会停止触发,关联了告警的工作流将停止响应,手动运行则会返回明确的"工作流已禁用"错误。
  • 提示 :在实验或重构工作流时,禁用比删除更安全,因为这不会破坏任何引用该工作流的告警规则。

tags(字符串数组 | 可选)------ 过滤与组织标签

用于在工作流列表中进行分类过滤的免费文本标签。

  • 常用模式
    • 按产品领域:securityobservabilitysearch
    • 按环境 criticality:proddemo
    • 按受众/角色:soconcall

version(字符串 | 可选)------ 架构版本

声明工作流定义所遵循的 Schema 版本,默认值为 "1"

  • ⚠️ 踩坑点警告 :它的值必须是带双引号的字符串 "1" ,而不能是未加引号的数字 1。未加引号的 1 会被解析为数值类型,从而导致 Schema 验证失败。

triggers(触发器数组 | 必填)------ 何时运行

定义启动工作流的一个或多个触发源。你可以在一个工作流中定义多个触发器。

  • 示例:支持手动触发和每小时定时触发共存:

    markdown 复制代码
    `
    
    1.  triggers:
    2.    - type: manual
    3.    - type: scheduled
    4.      with:
    5.        every: "1h"
    
    `AI写代码

inputs(对象或输入参数数组 | 可选)------ 运行时参数

工作流在调用时期望接收的输入。用户在 Kibana 的"运行"弹窗中输入的数据,或 API 调用者在请求体中提供的值,都属于 inputs

  • 引用方式 :在工作流内部,使用双大括号的 Liquid 模板语法进行引用,例如:{{ inputs.service_name }}
  • 参数支持类型string(字符串)、number(数字)、boolean(布尔值)、choice(下拉选择,需配合 options 数组使用)和 array(数组)。
  • 高级技巧default(默认值)不仅可以接受字面量,还可以接受 Liquid 表达式(例如自动生成当前时间戳:default: "{{ 'now' | date: '%Y-%m-%dT%H:%M:%SZ' }}")。注意:在 Elastic Stack 9.3-9.4 版本中,默认值仅支持字面量解析。

consts(对象 | 可选)------ 命名常量

用于定义那些在工作流中会被多次引用的固定值。

  • 示例

    yaml 复制代码
    `
    
    1.  consts:
    2.    watch_index: "security.watch.findings"
    3.    threshold: 0.85
    
    `AI写代码
  • 注意 :常量在工作流加载时只被评估一次。它们无法 访问 inputsstepsevent。如果你需要动态变量,请使用 data.set 步骤。

outputs(对象或输出参数数组 | 可选)------ 声明输出结构

描述工作流结束时产生的数据结构。

  • 关键作用 :在 工作流嵌套/组合(Workflow Composition) 场景中,父工作流调用此工作流作为子工作流时,父工作流必须知道子工作流的输出结构。

  • 示例

    markdown 复制代码
    `
    
    1.  outputs:
    2.    - name: verdict
    3.      type: string
    4.    - name: severity
    5.      type: number
    
    `AI写代码

settings(对象 | 可选)------ 全局运行行为

这是一组控制工作流范围行为的 "杂货袋",支持配置超时时间、时区、并发控制、全局错误处理等。

  • 示例(限制最大运行时间、并发排队策略以及失败重试):

    yaml 复制代码
    `
    
    1.  settings:
    2.    timeout: "10m"
    3.    timezone: "America/Los_Angeles"
    4.    concurrency:
    5.      key: "{{ event.alerts[0].host.name }}"
    6.      strategy: drop
    7.      max: 1
    8.    on-failure:
    9.      retry:
    10.        max-attempts: 2
    11.        delay: "10s"
    
    `AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

steps(步骤数组 | 必填)------ 工作流的主体结构

工作流具体执行的有序步骤列表。每个步骤都包含唯一的 name(在当前工作流中唯一)、步骤类型 type 以及类型特有的 with 参数块。

  • 示例:先从 Elasticsearch 查询,然后用 AI 进行总结:

    markdown 复制代码
    `
    
    1.  steps:
    2.    - name: fetch
    3.      type: elasticsearch.search
    4.      with:
    5.        index: logs-*
    6.        size: 100
    7.    - name: summarize
    8.      type: ai.summarize
    9.      connector-id: my-openai
    10.      with:
    11.        input: "{{ steps.fetch.output.hits.hits | map: '_source.message' | join: '\\n' }}"
    
    `AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

3. 工作流执行生命周期与状态机

当工作流通过手动、定时或事件触发运行后,Elastic 引擎会管理其生命周期,在 Kibana 界面或 API 响应中,你会看到它流转于以下状态:

状态名称 (State) 状态含义 (Meaning)
queued 处于并发限制队列中,等待空闲槽位(与 pending 不同)。
pending 已调度并正在等待正式启动。
running 至少有一个步骤正在执行中。
waiting 工作流在 wait 步骤上暂停,等待计时器到期。
waiting_for_input 工作流在 waitForInput 步骤上暂停,等待外部输入。
waiting_for_child 工作流在等待通过嵌套执行的子工作流完成。
completed 🏁 终结状态。工作流全部步骤成功执行完毕。
failed 🏁 终结状态 。某一步骤失败且全局 on-failure 策略未能挽回。
cancelled 🏁 终结状态。运行被操作员手动取消,或由于并发策略而被终止。
timed_out 🏁 终结状态 。执行时间超过了 settings.timeout 的限制。
skipped 🏁 终结状态 。运行被丢弃。例如,由于并发 drop 策略,或队列积压超过限制。

4. 实战演示:一个完整且可运行的简单工作流示例

为了帮助你更直观地理解工作流的运转,我们来看一个完整、简单且可直接运行的实际示例

该工作流的场景是:"当指定微服务出现 Error 级别日志时,自动检索该日志并通过 AI 总结其报错原因,最后发送 Slack 通知。" 1

完整工作流 YAML 定义

yaml 复制代码
``

1.  name: observability--alert-and-summarize-errors
2.  description: 检索指定服务的错误日志并使用 AI 进行根因总结和 Slack 告警。
3.  enabled: true
4.  tags:
5.    - observability
6.    - alert
7.    - ai

9.  version: "1"

11.  # 1. 触发器与运行时输入
12.  triggers:
13.    - type: manual
14.      inputs:
15.        - name: service_name
16.          type: string
17.          required: true
18.          default: "order-service"  # 默认查询订单服务

20.  # 2. 内部重用常量
21.  consts:
22.    log_index: "logs-*"
23.    slack_channel: "#ops-alerts"

25.  # 3. 声明输出结果,便于在组合工作流中被父流程调用
26.  outputs:
27.    - name: summary_result
28.      type: string

30.  # 4. 全局行为配置
31.  settings:
32.    timeout: "3m"  # 3分钟超时
33.    on-failure:
34.      retry:
35.        max-attempts: 2
36.        delay: "5s"

38.  # 5. 执行步骤主体(有序串行)
39.  steps:
40.    # 步骤一:在 Elasticsearch 中检索近期的 Error 日志 [1]
41.    - name: fetch_error_logs
42.      type: elasticsearch.search
43.      with:
44.        index: "{{ consts.log_index }}"
45.        query:
46.          bool:
47.            must:
48.              - match:
49.                  service.name: "{{ inputs.service_name }}"
50.              - match:
51.                  log.level: "error"
52.        size: 5

54.    # 步骤二:调用 AI 总结步骤一获取到的错误日志内容 [1]
55.    - name: summarize_errors
56.      type: ai.summarize
57.      connector-id: my-openai-connector # 指向你在 Kibana 中配置好的 OpenAI 连接器 ID
58.      with:
59.        # 通过 Liquid 模板动态提取步骤一(fetch_error_logs)中命中数据的 _source.message,并用换行符拼接 [1]
60.        input: "{{ steps.fetch_error_logs.output.hits.hits | map: '_source.message' | join: '\\n' }}"

62.    # 步骤三:将 AI 总结结果发送至 Slack 运维频道 [1]
63.    - name: post_to_slack
64.      type: slack.postMessage
65.      with:
66.        channel: "{{ consts.slack_channel }}"
67.        text: |
68.          🚨 **【服务异常告警】** 🚨
69.          服务名称:`{{ inputs.service_name }}`

71.          **AI 异常诊断总结:**
72.          {{ steps.summarize_errors.output }}

74.    # 步骤四:设置最终输出,结束工作流 [1]
75.    - name: return_output
76.      type: data.set  # 使用 data.set 来设置局部变量或最终输出
77.      with:
78.        summary_result: "{{ steps.summarize_errors.output }}"

``AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)收起代码块![](https://csdnimg.cn/release/blogv2/dist/pc/img/arrowup-line-top-White.png)

💡 该工作流是如何运行的?

根据我们在第三部分介绍的生命周期,该工作流的执行过程如下 1

  1. 触发 (Triggers & Inputs) : 你在 Kibana 界面中手动点击 "Run" 运行此工作流,或通过 Kibana 告警规则触发 1。由于设置了输入参数,你可以输入目标服务名称(例如 payment-service)。如果未提供,系统将自动使用默认值 order-service 1
  2. 状态流转至 running (Running)
    • 步骤一 (fetch_error_logs) 启动 1。它利用常量 consts.log_index (logs-*),在 Elasticsearch 中检索 payment-service 且日志级别为 error 的最新 5 条数据 1
    • 步骤二 (summarize_errors) 启动 1。它读取步骤一的输出结果(steps.fetch_error_logs.output),利用 Liquid 的 map 过滤器将多条日志的 message 字段串联起来,作为 Prompt 发送给你配置的 OpenAI Connector,让 AI 总结出报错的底层原因 1
    • 步骤三 (post_to_slack) 启动 1。它读取步骤二 AI 生成的文本,将其排版格式化,然后通过 Slack 渠道发送至运维频道 #ops-alerts 1
    • 步骤四 (return_output) 启动 1。将 AI 的总结结果绑定至输出,以便其他父流程使用 1
  3. 完成并进入 completed 终结状态 : 工作流顺利执行完毕,Kibana 执行历史中状态变为绿色 1。如果在执行过程中因为网络抖动导致 AI 或 Slack 调用失败,由于我们在 settings 中配置了 on-failure,引擎会自动延迟 5 秒并最多重试 2 次,从而极大减少了偶发性失败 1

5. 总结与开发建议

理解了 Elastic 工作流的解剖结构,你在构建自动化流程时就能更加得心应手。在编写自己的工作流时,不妨牢记以下几条"黄金准则":

  1. 优先做好命名规范 :遵循 <domain>--<verb>-<noun>,这能让你的工作流列表井井有条。
  2. 谨慎对待版本号 :记住 version: "1" 的双引号不能省。
  3. 充分利用 constssettings :把硬编码的阈值提取到常量中,并为生产工作流设置合理的超时(timeout)与重试(retry),能极大地增强自动化流程的稳健性。
相关推荐
Elasticsearch4 小时前
在 Elasticsearch 中构建上下文:AI Indices 如何使用更少的 tokens 为更智能的 agent 提供支持
elasticsearch
淮北4948 小时前
ubuntu22 默认输入法调整频率
运维·服务器·git·ubuntu·elasticsearch
Elasticsearch1 天前
Elasticsearch:使用 AI Agent 来创建 workflows
elasticsearch
gll7731 天前
RAG 检索层实战:Redis 缓存 + ES 混合检索 + BGE-Rerank 重排全链路落地与踩坑
elasticsearch
Elasticsearch1 天前
ES 存日志很贵?我用 ES 9.5 把日志从 4.5G 压到 412M 压缩比11.2倍,日志硬扫每秒128万行!
elasticsearch
Elasticsearch1 天前
Elasticsearch 作为统一平台:引入第二套数据系统究竟要付出什么代价
elasticsearch
Elastic 中国社区官方博客1 天前
Elasticsearch:列式索引模式 - Columnar index mode
大数据·数据库·elasticsearch·搜索引擎·全文检索
Elasticsearch1 天前
Elasticsearch 的批量查询阶段如何在大规模场景下提升搜索性能
elasticsearch
Ramboooooooo1 天前
SkyWalking-10.4.0 Docker + Nacos + Elasticsearch 生产级部署手册
elasticsearch·docker·skywalking