在 Kubernetes 基础设施节点上隔离日志组件

本指南说明如何使用 label、taint 和 node selector,将日志相关的基础设施组件隔离到专用的 Kubernetes 基础设施节点上。

目标

  • 隔离资源:避免与业务工作负载发生资源争用。
  • 增强稳定性:减少驱逐和调度冲突。
  • 简化管理:使用一致的调度规则集中管理基础设施组件。

前提条件

  1. kubectl 已针对目标集群完成配置。
  2. 基础设施组件没有通过 local-PV nodeAffinity 绑定到节点,或者你已经考虑了这些节点(见下文)。
  3. 通过参考 集群节点规划 来规划基础设施节点。
INFO

在 Alauda OS 节点上,本地存储路径位于 /var/cpaas 下,例如 /var/cpaas/data/clickhouse/var/cpaas/data/elasticsearch。这些节点是不可变的,传统操作系统的 /cpaas 目录在这些节点上不可写。规划基础设施节点时,应确保 /var/cpaas 路径由可在节点重新预配后仍然保留的数据盘提供支持,并且这些节点上的 pv.spec.local.path 应引用 /var/cpaas 路径,而不是下文示例中显示的 /cpaas 路径。关于各插件字段,请参见 Installation

检查 Local PV 和 nodeAffinity

如果你的组件使用本地存储(例如 TopoLVM、local PV),请确认 PV 是否设置了 spec.nodeAffinity。如果设置了,则需要:

  1. pv.spec.nodeAffinity 中引用的所有节点都加入基础设施节点组,或者
  2. 使用不带 node affinity 的 storage class 重新部署组件(例如 Ceph/RBD)。

示例(Elasticsearch):

# 1) Get ES PVCs
kubectl get pvc -n cpaas-system | grep elastic

# 2) Inspect one PV
kubectl get pv elasticsearch-log-node-pv-192.168.135.243 -o yaml

如果 PV 显示:

spec:
  local:
    path: /cpaas/data/elasticsearch/data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - 192.168.135.243

则表示 Elasticsearch 数据固定在节点 192.168.135.243 上。请确保该节点属于基础设施节点组,或者迁移存储。

将 Kafka/ZooKeeper 节点加入基础设施节点

由于历史原因,请确保 Kafka 和 ZooKeeper 节点也被标记/taint 为 infra:

kubectl get nodes -l kafka=true
kubectl get nodes -l zk=true
# Add the listed nodes into infra nodes as above

将日志组件迁移到基础设施节点

ACP 日志组件默认容忍 infra taint。使用 nodeSelector 将工作负载固定到基础设施节点上。

Elasticsearch

# Data nodes
kubectl patch statefulset cpaas-elasticsearch -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

# Master nodes (if present)
kubectl patch statefulset cpaas-elasticsearch-master -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

# Verify
kubectl get pods -n cpaas-system -o wide | grep cpaas-elasticsearch

Kafka

kubectl patch statefulset cpaas-kafka -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

kubectl get pods -n cpaas-system -o wide | grep cpaas-kafka

ZooKeeper

kubectl patch statefulset cpaas-zookeeper -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

kubectl get pods -n cpaas-system -o wide | grep cpaas-zookeeper

ClickHouse

kubectl patch chi cpaas-clickhouse -n cpaas-system --type='json' -p='[
  {"op":"add","path":"/spec/templates/podTemplates/0/spec/nodeSelector/node-role.kubernetes.io~1infra","value":""},
  {"op":"add","path":"/spec/templates/podTemplates/1/spec/nodeSelector/node-role.kubernetes.io~1infra","value":""}
]'

kubectl get pods -n cpaas-system -o wide | grep clickhous

lanaya

kubectl patch deployment lanaya -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

kubectl get pods -n cpaas-system -o wide | grep lanaya

razor

# If deployed as Deployment (Elasticsearch backend)
kubectl patch deployment razor -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

# If deployed as StatefulSet (ClickHouse backend)
kubectl patch statefulset razor -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

kubectl get pods -n cpaas-system -o wide | grep razor

其他任何日志组件

# Deployment
kubectl patch deployment <deployment-name> -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

# StatefulSet
kubectl patch statefulset <statefulset-name> -n cpaas-system \
  --type='merge' \
  -p='{"spec":{"template":{"spec":{"nodeSelector":{"node-role.kubernetes.io/infra":""}}}}}'

kubectl get pods -n cpaas-system -o wide | grep <deployment-name>
kubectl get pods -n cpaas-system -o wide | grep <statefulset-name>

驱逐已经运行在基础设施节点上的非基础设施工作负载

如果某些非基础设施 Pod 仍在基础设施节点上运行,可通过更新这些工作负载(例如修改 annotation)触发重新调度,或者添加/调整 selector 以排除基础设施节点。

故障排查

常见问题与修复方法:

问题诊断方法解决方案
Pod 卡在 Pendingkubectl describe pod &lt;pod&gt; | grep Events添加 toleration 或调整 selector
taint/toleration 不匹配kubectl describe node &lt;node&gt; | grep Taints为工作负载添加匹配的 toleration
资源不足kubectl top nodes -l node-role.kubernetes.io/infra扩容基础设施节点或调整资源请求

错误示例:

Events:
  Warning  FailedScheduling  2m  default-scheduler  0/3 nodes are available:
  3 node(s) had untolerated taint {node-role.kubernetes.io/infra: true}

修复方法:为该工作负载添加匹配的 toleration。