3. 节点拓扑标签:node-topology.kubernetes.io/zone 等内置标签,自定义故障域标签设计

在 Kubernetes 集群中,节点拓扑标签(Node Topology Labels)是连接物理基础设施与调度、监控、告警系统的核心元数据。SRE 团队通过标签将节点归属到特定的故障域(Failure Domain),从而在指标采集时携带位置上下文,在告警分层时实现按域收敛。本章深入解析内置拓扑标签体系,并给出生产环境自定义故障域标签的设计原则与最佳实践。

3.1 内置拓扑标签体系

Kubernetes 社区定义了标准拓扑标签,用于描述节点所在的区域(Region)、可用区(Zone)以及主机(Host)层级。这些标签由云厂商的节点控制器(Node Controller)或集群管理员自动注入。

标签键(Label Key) 语义层级 示例值 说明
topology.kubernetes.io/region 区域 cn-north-1 地理区域,通常对应云厂商的大区
topology.kubernetes.io/zone 可用区 cn-north-1a 同一区域内的独立故障域,电力/网络隔离
node-topology.kubernetes.io/zone 节点级可用区 az-1 节点级别的可用区标识,与 Pod 调度亲和性相关
kubernetes.io/hostname 主机 ip-10-0-1-23.ec2.internal 节点主机名,唯一标识一台物理/虚拟主机
生产建议:在自建机房或混合云场景下,topology.kubernetes.io/zone 和 node-topology.kubernetes.io/zone 可能不存在。SRE 团队应主动通过 kubectl label node 命令或节点初始化脚本注入这些标签,确保监控系统能够识别故障域边界。

3.2 自定义故障域标签设计原则

当内置标签无法满足多级故障域(如:机房 → 机架 → 电源域 → 网络交换机域)时,需要设计自定义标签。以下为生产环境验证过的设计原则:

  • 层级明确:使用前缀区分层级,例如 failure-domain.kubernetes.io/rack、failure-domain.kubernetes.io/pdu。
  • 值标准化:采用统一命名规范,如 rack-01、pdu-a,避免大小写混用。
  • 可枚举:每个标签的值集合应有限且可枚举,便于告警规则按域聚合。
  • 与监控标签对齐:自定义标签的键值应同步到 Prometheus 的 node_meta 指标或 OpenTelemetry 的 Resource 属性中。
设计示例:某金融企业定义三级故障域标签:
failure-domain.kubernetes.io/datacenter → dc-shanghai
failure-domain.kubernetes.io/rack → rack-12
failure-domain.kubernetes.io/power-domain → pdu-3

3.3 标签注入与验证流程

为确保标签在集群生命周期内一致,推荐使用声明式标签管理,而非手动操作。以下为推荐流程:

  1. 定义标签模板:在 GitOps 仓库中维护 node-labels.yaml,按节点 IP 或主机名映射标签。
  2. 自动化注入:使用 DaemonSet 或节点初始化脚本(如 cloud-init)在节点加入集群时自动打标。
  3. 定期校验:通过 Prometheus 的 kube_node_labels 指标或 kubectl get nodes --show-labels 巡检标签完整性。
  4. 告警缺失:设置 Prometheus 告警规则,当节点缺少关键故障域标签时触发告警。
# 示例:使用 kubectl 为节点注入自定义故障域标签
kubectl label node node-01 \
  failure-domain.kubernetes.io/datacenter=dc-shanghai \
  failure-domain.kubernetes.io/rack=rack-12 \
  failure-domain.kubernetes.io/power-domain=pdu-3 \
  --overwrite

3.4 拓扑标签在指标采集与告警分层中的作用

拓扑标签是连接基础设施拓扑与可观测性数据的桥梁。在指标采集阶段,Prometheus 通过 relabel_configs 将节点标签复制到时间序列中;在告警分层阶段,Alertmanager 根据标签中的故障域信息实现告警分组与抑制。

拓扑标签在指标采集与告警分层中的流转 节点 Node-01 标签: zone=az-1, rack=12 节点 Node-02 标签: zone=az-1, rack=12 节点 Node-03 标签: zone=az-2, rack=15 Prometheus 指标采集 relabel_configs 将节点标签复制到时间序列 告警规则按故障域分组 group_by: [zone, rack] → 同一故障域告警合并 Alertmanager 抑制与路由

3.5 自定义标签与监控系统的集成

在 Prometheus 中,通过 relabel_configs 将节点标签映射为指标标签。以下为典型配置:

# prometheus.yml 中的 relabel 配置示例
scrape_configs:
  - job_name: 'kubernetes-nodes'
    kubernetes_sd_configs:
      - role: node
    relabel_configs:
      - source_labels: [__meta_kubernetes_node_label_topology_kubernetes_io_zone]
        target_label: zone
      - source_labels: [__meta_kubernetes_node_label_failure_domain_kubernetes_io_rack]
        target_label: rack
      - source_labels: [__meta_kubernetes_node_label_failure_domain_kubernetes_io_power_domain]
        target_label: power_domain
注意:自定义标签的键名在 Prometheus 中会转换为下划线格式(如 failure-domain.kubernetes.io/rack 变为 __meta_kubernetes_node_label_failure_domain_kubernetes_io_rack)。务必在 relabel 配置中正确引用转换后的名称。

3.6 故障域标签设计检查清单

检查项 标准 验证方法
标签键命名 使用 failure-domain.kubernetes.io/ 前缀 kubectl get nodes -o json | jq '.items[].metadata.labels'
标签值枚举 每个标签值不超过 20 个唯一值 PromQL: count by (rack) (kube_node_labels)
标签覆盖率 100% 节点拥有所有必需标签 PromQL: count(kube_node_labels{label_rack!=""}) / count(kube_node_labels)
监控同步 标签已出现在 Prometheus 指标中 up{rack="rack-12"} 返回结果

3.7 多级故障域拓扑示例

以下 SVG 展示了一个包含数据中心、机架、电源域三级故障域的节点拓扑结构,以及对应的标签设计:

多级故障域拓扑与标签映射 数据中心 dc-shanghai 机架 rack-12 机架 rack-13 机架 rack-14 电源域 pdu-a 电源域 pdu-b 电源域 pdu-c node-01 node-02 node-03 node-04 node-05 node-06 标签映射:node-01 → failure-domain.kubernetes.io/datacenter=dc-shanghai, failure-domain.kubernetes.io/rack=rack-12, failure-domain.kubernetes.io/power-domain=pdu-a

3.8 常见问题与避坑指南

  • 标签值变更导致历史数据断裂:避免在运行中修改节点标签值,否则 Prometheus 时间序列会分裂。如需变更,应先在监控系统中处理历史数据。
  • 标签键冲突:自定义标签不要与内置标签(如 topology.kubernetes.io/zone)同名,否则可能导致调度器行为异常。
  • 标签数量过多:每个节点标签数量建议控制在 10 个以内,过多标签会增加 Prometheus 存储开销和查询延迟。
  • 忽略标签缺失告警:务必为关键故障域标签设置缺失告警,否则在故障发生时,告警分层可能失效。