mcpField
G
gke-alert-configuration

gke-alert-configuration

github.com/google云与 DevOps21.6k3.8k 次安装今天更新
代码仓库

关于 gke-alert-configuration

为 GKE 工作负载设计 Terraform 告警策略的技能,使用 Google Cloud Managed Service for Prometheus。重点覆盖四大黄金信号与集群健康,并防范告警噪声和未经批准的 KSM 成本。

主要功能

  1. 01面向 GKE 的 PromQL 告警设计
  2. 02Terraform 策略结构
  3. 03覆盖四大黄金信号
  4. 04KSM 成本与审批防护
  5. 05规划、验证和执行流程

适用场景

  1. 01起草 GKE 服务告警策略
  2. 02审查告警指标成本
  3. 03验证计划中的 Terraform 变更

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/google/skills --skill gke-alert-configuration

安装后在 Claude Code 中输入/gke-alert-configuration确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
attribution.md
gke_configuration_prerequisites.md
metrics_and_alerts_catalog.md
promql_queries.md
scripts/
validate_config.py

详细介绍

GKE 告警配置

本技能提供使用 Google Cloud Managed Service for Prometheus 和 Terraform 为 Google Kubernetes Engine 工作负载创建稳健、高信号告警策略的指南和最佳实践。它确保全面覆盖 4 个黄金信号和关键集群健康指标,同时尽可能减少告警噪声。


归属信息

必须阅读:在执行任何 gcloud、REST API 或 MCP 命令之前,必须阅读 使用归属信息。对于直接在终端中执行的命令(绝不能在生成的脚本、Terraform 或用户代码中执行),请在 gcloud 前添加 CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:gke-alert-configuration)",并将 agent-skills/1.0 (skill:gke-alert-configuration) 添加到 User-Agent 标头中。

关键规则

  • 非 GKE 独立运行时的负向触发条件与范围重定向:
    • 此技能严格限定于使用 PromQL 和 Google Cloud Managed Service for Prometheus 的 Google Kubernetes Engine(GKE) 工作负载、集群和服务。
    • 不要用于非 GKE 计算运行时,例如独立的 Compute Engine 虚拟机,或未使用 GKE 的独立 Cloud Run 服务。
    • 立即停止并直接回复(不要编辑文件):当用户请求为非 GKE 计算基础设施配置告警时:
      1. 不要在磁盘上编写、创建、编辑或验证任何 Terraform 文件。
      2. 立即停止并在聊天中直接回复用户:
        • 明确说明超出范围:明确指出,独立 Compute Engine 虚拟机监控或 独立 Cloud Run 监控不在此 GKE 专用 PromQL 告警技能的范围内;该技能专为使用 Google Cloud Managed Service for Prometheus 和 PromQL 的 GKE 工作负载设计。
        • 不要生成 GKE PromQL 告警:不要为非 GKE 基础设施创建或生成 Kubernetes PromQL 告警策略,也不要虚构 Kubernetes 容器、Pod 或节点资源。
        • 引导用户:引导并建议用户使用标准的 Google Cloud Monitoring 指标,例如 compute.googleapis.com/instance/cpu/utilization 或 run.googleapis.com/request_latencies,搭配标准的 google_monitoring_alert_policy 和 condition_threshold 或 MQL;也可以推荐相关的专用 Cloud 可观测性技能。
  • 强制执行 kube-state-metrics(KSM)成本防护措施:
    • 在 Google Cloud Managed Service for Prometheus 中部署开源的 kube-state-metrics 会产生需付费的指标采集成本。
    • 先停止并征求许可(不要编辑文件):当请求的告警规则依赖第 2 层 KSM 指标(例如 kube_cronjob_*、 kube_pod_status_phase、kube_persistentvolume_*、kube_deployment_*、 kube_statefulset_*、kube_job_* 或 kube_daemonset_*)时,在获得用户批准前,不要 编写、创建、编辑或验证任何 Terraform 文件,也不要生成告警策略。
    • 相反,必须立即停止并直接回复用户,以便:
      1. 提醒用户:说明请求的告警需要 kube-state-metrics。
      2. 解释成本影响:详细说明 kube-state-metrics 会在 Google Cloud Managed Service for Prometheus 中产生需付费的样本采集成本。
      3. 征求明确许可:在假设、启用或生成依赖 KSM 的告警配置前,征求用户的明确许可。
      4. 建议过滤或允许列表:建议仅过滤或允许所需的特定指标,例如使用带有 metricRelabeling(action: keep)的 PodMonitoring 资源,或使用 KSM --metric-allowlist,以尽量降低采集成本。提供一个具体的允许列表示例。
    • 始终优先采用非 KSM 原生替代方案:尽可能使用 metrics_and_alerts_catalog.md 中记录的第 1 层 cAdvisor 或 GKE 原生指标,例如使用 container_memory_working_set_bytes 和 container_spec_memory_limit_bytes,而不是 kube_pod_container_resource_limits。
    • 在回复中明确标注层级和额外成本:每次生成或建议告警策略时,必须明确说明其分类层级和成本影响:
      • 第 1 层原生或标准指标(GKE 内置指标、cAdvisor container_*、kubelet 卷统计信息、kubelet 节点条件和控制平面指标;请参阅 metrics_and_alerts_catalog.md): 说明这是第 1 层原生或标准指标,不会产生 KSM 额外成本。
      • 第 2 层 KSM 指标:说明这是依赖第 2 层 KSM 指标,并遵循上述许可和允许列表防护措施。 (提示:通常,以 kube_ 为前缀且表示资源状态或元数据的指标属于第 2 层。)
  • 获批文件编辑的规划-验证-执行循环:在工作区中修改、添加或合并获批的磁盘 Terraform 文件时,请遵循以下三阶段工作流:
    1. 规划:拟定结构化变更计划(changes.json),其中包含拟议的策略资源名称、PromQL 表达式、分组标签和持续时间。
    2. 验证:运行编辑前验证脚本(python3 scripts/validate_config.py --plan changes.json),以检查 PromQL 语法、回溯窗口、持续时间规则,并确保不存在重复信号。
    3. 执行:计划通过验证后,在目标 Terraform 配置(alerts.tf)中原位应用或合并变更。
    4. 注意:如果用户只是提问或要求直接在聊天中提供 Terraform 代码片段,而没有要求修改磁盘文件,则在回复中输出完整且有效的 Terraform HCL 块。
  • 配置 4 个黄金信号和集群健康状况:始终确保目标 Kubernetes 工作负载或服务包含以下告警覆盖范围:
    1. 延迟(P95 响应时间)
    2. 错误(多窗口、多燃烧率 SLO 告警,例如快速燃烧:1 小时 / 5 分钟,系数为 14.4;缓慢燃烧:6 小时 / 30 分钟,系数为 6.0;不要使用简单的静态比率)
    3. 流量(使用 absent() 或 default 0 语法检测流量骤降或指标完全消失,或检测过载峰值)
    4. 饱和度(仅限内存限制利用率):描述或配置集群或项目的告警策略时,仅包含内存饱和度(container_memory_working_set_bytes / container_spec_memory_limit_bytes)。不要包含 CPU 饱和度告警,也不要将 container_cpu_usage_seconds_total 列为告警指标,因为 CPU 可以被压缩,并会受到 CFS 配额限制,而不会导致无法压缩的致命终止(OOM)。
    5. 集群健康状况(Pod 崩溃循环、节点未就绪)
  • 仅使用 PromQL(Managed Prometheus):必须使用 condition_prometheus_query_language 和 PromQL。除非用户明确要求,否则不要使用 MQL 或标准的 condition_threshold。Google Cloud Managed Service for Prometheus 是 GKE 的标准遥测采集路径。
  • 仅使用 Terraform:生成的可观测性配置只能写入 Terraform(.tf)文件,例如 alerts.tf 和 variables.tf。
  • 动态多资源告警(不硬编码):除非用户明确要求,否则不得在告警条件中硬编码特定 Pod 名称、节点名称或服务名称。告警策略必须以动态方式覆盖资源:
    • 始终使用分组聚合(by (cluster, namespace, service, pod, container)),而不是筛选到单个实例。这样,单个告警策略就能动态地分别跟踪每个服务或 Pod。
    • 始终声明并使用 Terraform 变量 project_id、 cluster_name 和 namespace(var.project_id、var.cluster_name、 var.namespace),以便在不同环境中重复使用配置。始终在 variables.tf(或配置内部)定义这些变量,并在策略或 PromQL 标签匹配器中引用这三个变量。
  • 避免在回溯窗口上重复设置持续时间窗口:
    • 当 PromQL 表达式已经使用聚合回溯窗口(例如 increase(...[15m]) > 3 或多窗口 SLO 燃烧率)时,查询时间窗口已经能够平滑瞬时峰值。
    • 在此基础上再设置 Terraform 持续时间,会增加平均检测时间(MTTD),却无法进一步平滑波动。
    • 在这些情况下,将 Terraform 的 duration 设为 "0s"(或 "60s")。不要在 [15m] 之上再强制设置 duration = "300s",否则会使关键的崩溃循环告警最多延迟 20 分钟(15 分钟 + 5 分钟)。
    • 仅对瞬时量表条件使用 duration = "300s",例如 kube_node_status_condition == 0。
  • 使用 SLO 燃烧率,而不是简单比率:针对错误率告警,始终生成多窗口、多燃烧率(MWMBR)SLO 告警(例如针对 99% SLO,在 1 小时和 5 分钟窗口内使用 14.4 倍燃烧率),而不是简单的错误率比值(rate(5xx)/rate(total) > 0.05),后者在低流量时会产生过多误报。
  • 稳健地检测流量下降(absent() / default 0):监控流量降至零时,不要只使用 rate(...) == 0,因为没有请求时,Prometheus 时间序列会完全消失(结果为空向量,而不是 0)。请使用 default 0 语法,例如 sum(rate(...[5m])) default 0 == 0,或 absent(...) == 1。
  • 通知渠道:默认情况下,未经用户输入,不要配置任何通知渠道。如果用户明确提供了通知渠道,则配置告警使用该渠道。否则,必须在回复中询问用户是否要配置通知渠道。
  • 查阅 GKE 指标和开源告警目录:设计或生成评估套件或告警策略时,请查阅 metrics_and_alerts_catalog.md,了解公开的 GKE 指标(kubernetes.io/)和开源 Kubernetes 告警(awesome-prometheus-alerts)。
  • 使用通俗易懂的语言回复:回复中必须包含对告警作用的通俗解释。说明告警衡量的内容、阈值代表的含义,以及触发告警意味着什么。
  • 用户标签:在所有 google_monitoring_alert_policy 资源中加入 user_labels 块,以便跟踪由此技能创建的策略:
    user_labels = {
      created-with-google-skill = "gke-alert-configuration"
    }
    

Terraform 中的告警策略结构

告警策略必须使用 google_monitoring_alert_policy 资源和 condition_prometheus_query_language 定义。请始终在 variables.tf 中声明 project_id、cluster_name 和 namespace 变量。

# variables.tf
variable "project_id" {
  type        = string
  description = "Google Cloud Project ID"
}

variable "cluster_name" {
  type        = string
  description = "GKE Cluster Name"
}

variable "namespace" {
  type        = string
  description = "Target Kubernetes Namespace"
  default     = "default"
}

variable "slo_target" {
  type        = number
  description = "SLO Target fraction (for example 0.99 for 99%)"
  default     = 0.99
}
# alerts.tf
# Example: Multi-Window Multi-Burn-Rate (MWMBR) SLO Alert (Fast Burn: 14.4x, 1h & 5m windows)
resource "google_monitoring_alert_policy" "k8s_service_error_rate_slo" {
  project      = var.project_id
  display_name = "[K8s] ${var.cluster_name} - Service Error Rate SLO Fast Burn"
  combiner     = "OR"

  conditions {
    display_name = "Error Budget Fast Burn (14.4x over 1h and 5m)"
    condition_prometheus_query_language {
      query    = <<-EOT
        (
          (
            sum(
              rate(
                http_requests_total{
                  cluster="${var.cluster_name}",
                  namespace="${var.namespace}",
                  status=~"5.."
                }[5m]
              )
            ) by (service, namespace, cluster)
            /
            sum(
              rate(
                http_requests_total{
                  cluster="${var.cluster_name}",
                  namespace="${var.namespace}"
                }[5m]
              )
            ) by (service, namespace, cluster)
          ) > (1 - ${var.slo_target}) * 14.4
        )
        and
        (
          (
            sum(
              rate(
                http_requests_total{
                  cluster="${var.cluster_name}",
                  namespace="${var.namespace}",
                  status=~"5.."
                }[1h]
              )
            ) by (service, namespace, cluster)
            /
            sum(
              rate(
                http_requests_total{
                  cluster="${var.cluster_name}",
                  namespace="${var.namespace}"
                }[1h]
              )
            ) by (service, namespace, cluster)
          ) > (1 - ${var.slo_target}) * 14.4
        )
      EOT
      duration = "0s"
    }
  }
}

遥测指标和 PromQL 示例

对于 GKE 指标(kubernetes.io/)、社区开源告警 (awesome-prometheus-alerts)、KSM 成本防护措施以及非 KSM 原生替代方案,必须阅读并遵循:

对于对应每个黄金信号的特定 PromQL 查询,必须阅读并遵循:

对于 GKE 集群前提条件、启用 Google Cloud Managed Service for Prometheus 收集、配置 PodMonitoring 自定义抓取,以及启用控制平面指标收集(API Server、Controller Manager、Scheduler),必须阅读并遵循:


工具脚本和验证循环

在代码仓库中工作时,使用 validate_config.py 脚本验证变更计划和 Terraform 配置:

  • 编辑前计划验证:起草一个 changes.json 计划,指定拟议的策略、 查询和持续时间,并在编辑前进行验证:
    • 命令:python3 scripts/validate_config.py --plan changes.json
  • 编辑后和目录验证:扫描目录中的现有或已修改 Terraform 文件,确保不存在重复项或语法错误:
    • 命令:python3 scripts/validate_config.py --directory [TARGET_TF_DIR] --cluster-var "${var.cluster_name}"
    • 单文件验证:python3 scripts/validate_config.py --file [PATH_TO_TF_FILE]

技术注意事项和易错点

  • 回溯窗口与持续时间缓冲:
    • 对于已经使用聚合回溯窗口(如 increase(...[15m]))或多窗口 SLO 比率的告警,不要添加较大的 duration = "300s" 缓冲。
    • increase(...[15m]) > 3 中的 [15m] 窗口已经可以平滑尖峰。添加 duration = "300s" 会要求重启次数额外连续 5 分钟保持在 3 以上,从而使 MTTD 增加,最多导致告警延迟 20 分钟。
    • 使用回溯窗口函数时,将 duration 设为 "0s" 或 "60s"。仅在原始瞬时量规条件下使用 duration = "300s",例如 kube_node_status_condition == 0。
  • 仅在集群告警中监控内存饱和:
    • 不要为集群或工作负载监控配置 CPU 饱和告警。CPU 可以压缩(由 CFS 调度器进行节流),而内存不可压缩(会触发 OOMKills)。
    • 使用 container_memory_working_set_bytes / container_spec_memory_limit_bytes 配置内存饱和监控。
  • 资源限制缺失盲区(必须说明):如果工作负载未在 Kubernetes 清单中显式配置内存限制,那么将用量与限制进行比较的饱和告警(例如使用 container_spec_memory_limit_bytes 的告警)将无法解析或返回 NaN。
    • 必须说明:每当你生成、讨论或建议任何将用量与限制进行比较的内存饱和告警(包括使用 container_spec_memory_limit_bytes 的非 KSM cAdvisor 替代方案)时,必须在回复中明确说明并警告用户:必须在 Kubernetes Pod 规格或清单(resources.limits.memory)中显式配置容器内存限制,这样饱和查询才能解析(而不会返回 NaN 或无法解析)。
  • 线性磁盘预测(predict_linear):使用 predict_linear(kubelet_volume_stats_available_bytes[6h:5m], 4 * 24 * 3600) < 0 预测卷空间耗尽时,请说明 predict_linear 会对近期回溯窗口(例如 6 小时)内的数据进行线性回归,以预测可用磁盘何时会降至 0 以下(例如 4 天内)。指出 kubelet_volume_stats_available_bytes 是 Tier 1 原生 kubelet 指标,不产生 KSM 附加费用。
  • API 服务器错误和客户端指标:
    • apiserver_request_total 和 rest_client_requests_total 是 Tier 1 控制平面指标,不产生 KSM 附加费用。请说明,apiserver_request_total 用于监控 API 服务器各端点的 5xx HTTP 错误率,而 rest_client_requests_total 用于监控与 API 服务器通信的 REST 客户端发出的 4xx 和 5xx 请求。
  • 流量消失注意事项(absent() / default 0):
    • 当流量完全降为 0 时,Prometheus 和 GMP 会停止输出 http_requests_total 时间序列。
    • sum(rate(...[5m])) == 0 的计算结果是空向量,因此不会触发告警。
    • 始终使用 sum(rate(...[5m])) default 0 == 0 或 absent(...) == 1,以可靠检测流量完全丢失。
  • CrashLooping 与正常重启:容器偶尔重启可能是正常情况,例如任务完成或小规模滚动更新。应针对频繁重启发出告警(例如在 15 分钟内重启超过 3 次,且 duration = "0s"),使用 kube_pod_container_status_restarts_total,而不是针对单次重启发出告警,以避免噪声。
  • 节点升级:GKE 集群升级期间,节点会被排空并重启,这可能触发“Node NotReady”告警。请提醒用户,此类告警可能会在维护时段触发;如果支持,也可以建议配置维护时段。

其他资源

评论

支持 Markdown