超级节点上支持运行 DaemonSet

最近更新时间:2025-07-01 14:42:22

我的收藏

功能概述

由于超级节点没有实节点概念,因此在普通节点上运行的资源对象 DaemonSet 无法按照预期的方式运行,DaemonSet 所支持的某些系统层面的应用能力,如日志收集、资源监控等服务均无法在超级节点上统一支持。业内常规的解决方案为通过 sidecar 注入的方式实现 DaemonSet 相关的能力,但这带来了跟常规节点不一致的使用体验,且在功能上也是有损的,例如 sidecar 的更新将影响业务 Pod 的生命周期等,基于此,腾讯云全新推出了 DaemonSet Pod 注入方案用于在超级节点上运行 DaemonSet。作为业内唯一的在 Nodeless 架构中支持了 DaemonSet Pod 的运行,该方案拥有如下优势:
全兼容:完全兼容原生 DaemonSet Pod 的使用方式。
零侵入:DaemonSet Pod 与业务 Pod 拥有独立的生命周期,DaemonSet 的任何变更不会影响业务 Pod。
可观测:控制台支持对 DaemonSet Pod 的监控,支持查询 DaemonSet Pod 日志、事件等。

使用场景

TKE 托管集群:在 TKE 托管集群中,如果您添加了超级节点,且超级节点上运行的 Pod 期望支持与普通节点一致的 DaemonSet 能力。
TKE Serverless 集群:在 TKE Serverless 集群中,若期望运行 DaemonSet 资源。
IDC 集群:在 IDC 集群中,如果您添加了超级节点,且超级节点上运行的 Pod 期望支持与 IDC 节点一致的 DaemonSet 能力。

前置准备

检查控制面 master 组件是否已升级到如下指定版本或更高版本:
Kubernetes 版本
控制面 master 组件版本要求
超级节点组件版本要求
v1.32
v1.32.0-tke.1 或更高版本
v2.16.10或更高版本
v1.30
v1.30.0-tke.1 或更高版本
v2.16.10或更高版本
v1.28
v1.28.3-tke.1或更高版本
v2.16.10或更高版本
v1.26
v1.26.1-tke.1 或更高版本
v2.16.10或更高版本
v1.24
v1.24.4-tke.4 或更高版本
v2.16.10或更高版本
v1.22
v1.22.5-tke.8 或更高版本
v2.16.10或更高版本
v1.20
v1.20.6-tke.30 或更高版本
v2.16.10或更高版本
v1.18
v1.18.4-tke.34 或更高版本
v2.16.10或更高版本
v1.16
v1.16.3-tke.33 或更高版本
v2.16.10或更高版本
检查超级节点的版本是否已升级到 v2.11.20 或以上。


使用方法

1. 创建 DaemonSet 并标记需要运行在超级节点的 DaemonSet


在 TKE 标准集群中,通过以下步骤配置即可在超级节点上运行 DaemonSet 负载,并且不会影响普通节点和原生节点上的 DaemonSet 负载正常运行。
如下面文件所示,标记将要注入的 DaemonSet 为:eks.tke.cloud.tencent.com/ds-injection: "true"。对于按量计费超级节点,由于默认打了污点(key=eks.tke.cloud.tencent.com/eklet,effect=NoSchedule),因此需要容忍污点,才能支持将 DaemonSet Pod 创建上去。
注意:
调度时,DaemonSet 中定义的 resources 不会有效,并且也不会产生额外计费。
spec:
template:
metadata:
annotations:
eks.tke.cloud.tencent.com/ds-injection: "true"
spec:
tolerations:
- key: eks.tke.cloud.tencent.com/eklet
operator: Exists
effect: NoSchedule
通过以上步骤,如果集群内存在超级节点,则可以通过运行 kubectl get ds 命令查看新的副本扩出情况,集群内有多少个超级节点则会展示多少个副本,如下图所示:


2. 启动 DaemonSet Pod

完成 DaemonSet 在超级节点的运行声明后,意味着当前超级节点上的 Pod 均会自动注入一个 DaemonSet Pod,后续启动的业务 Pod 也会被自动注入(kube-system 命名空间下的 Pod 除外),Pod 状态为 Injection 状态。

被注入的 Pod 本身的 YAML 配置不会发生任何变化,但 Container Status 里会新增注入的 DaemonSet Pod 容器的状态,以便更方便地观察 DaemonSet Pod 的状态,如下图所示:

DaemonSet Pod 容器的事件,例如拉镜像、启动、异常退出等信息,都会上报到被注入的 Pod 上:


3. 登录节点

在节点列表中找到一个普通节点,在右侧操作中,选择更多 > 登录,即可进入终端进行下一步操作。


4. 登录 DaemonSet Pod

在普通节点终端中使用 kubectl exec 命令可以正常登录原本 Pod 的容器。若要登录 DaemonSet Pod 的容器,则需要将 exec 指向被注入的 Pod,然后通过 -c 参数,指定要登录的 DaemonSet Pod 容器。命令如下:
kubectl exec -it <pod-name> -c <daemonset-container-name> -- /bin/bash
示例如下:

注意:
如果 DaemonSet Pod 的容器名称与原本 Pod 的容器名称相同,exec 命令会优先指向原本 Pod,此时无法登录 DaemonSet Pod 的容器。但是,DaemonSet Pod 的容器依旧在正常运行,为了 DaemonSet Pod 的容器可观测,建议将 DaemonSet Pod 的容器名称与 Pod 名称区分开。

5. 查看 DaemonSet Pod 日志

与使用 kubectl exec 命令类似,您可以使用 kubectl logs命令结合 -c 参数来查看 DaemonSet Pod 容器的日志。命令如下:
kubectl logs <pod-name> -c <daemonset-container-name>
示例如下:

请注意,由于 kubectl 1.18及以上版本的客户端,会在发起 logs 请求之前校验 Pod Spec 是否包含指定容器。如果不存在指定容器,则直接返回如下错误:
container xxx is not valid for pod xxx
出现此类情况时,您可以将 kubectl 版本切换到1.16版本,或者使用我们后续提供的发行版。以下是 kubectl 1.16 版本的下载链接:
curl -LO "https://dl.k8s.io/release/v1.16.0/bin/linux/amd64/kubectl"

6. 滚动更新

集群维度

在 TKE 标准集群维度,超级节点支持了 Kubernetes 原生能力一致的滚动更新能力,可以通过 updateStrategy 来设置 DaemonSet 的滚动更新规则。
spec:
updateStrategy:
rollingUpdate:
maxUnavailable: 1 # 更新期间不可用 Pod 的最大数量,默认为1
在 DaemonSet 配置发生更新后,超级节点会与普通节点或原生节点一样按照滚动更新策略进行更新。
修改 DaemonSet 配置后,通过 kubectl get ds 查看滚动更新状态。
kubectl get ds

新建 DaemonSet 时,状态过程转移如下:

更新 DaemonSet 时,状态转移过程如下:

当发布更新出现问题时,会停止滚动:


节点维度

在超级节点维度,某超级节点进入更新状态后,当且仅当该超级节点上的业务 Pod 都完成了 DaemonSet 的注入容器更新时,该超级节点所对应的虚拟DaemonSet 状态才为 Ready,至此该节点的更新完成。
通过注解eks.tke.cloud.tencent.com/ds-inject-rate即可控制在超级节点内部的注入容器更新下发速率。
eks.tke.cloud.tencent.com/ds-inject-rate: "50%"
通过kubectl get po xxx -o yaml查看正在更新的超级节点所对应的更新状态信息聚合。


暂停发布:
spec:
updateStrategy:
rollingUpdate:
maxUnavailable: 0 # 将更新期间不可用副本的最大数量设置为0即可暂停发布
发布回滚:
kubectl rollout history daemonset <ds_name>

kubectl rollout history daemonset <ds_name>


7. 注入规则

注入方式

首先找到需要编辑的 DaemonSet 工作负载。

在 DaemonSet 的工作负载上点击编辑 Annotation 可以进行对应注解的编辑。

也可以点击编辑 YAML 进行修改。


示例

若超级节点上声明启用了 DaemonSet Pod,则除 kube-system 命名空间下的 Pod 外,该超级节点上的其他 Pod,均会被注入 DaemonSet Pod。若您有特殊 Pod 不希望被注入 DaemonSet Pod,可以配置如下 annotation:
eks.tke.cloud.tencent.com/ds-injection: "false"
如果您希望整个命名空间下的所有 Pod 都不被注入 DaemonSet Pod,可以在命名空间上配置如下 annotation:
eks.tke.cloud.tencent.com/ds-injection: "false"
如果您希望 kube-system 命名空间下的 Pod 被注入 DaemonSet Pod,则需要在创建这些 Pod 时显式声明如下 annotation:
eks.tke.cloud.tencent.com/ds-injection: "true"
如果您希望按 Label 过滤需要注入的 DaemonSet,可以在 DaemonSet 上配合使用如下 annotation:
当与 pod 的某个 Label 匹配时注入:
eks.tke.cloud.tencent.com/ds-inject-by-label: "k1:v1,k2:v2"
当与 pod 的某个 Label 匹配时不注入:
eks.tke.cloud.tencent.com/ds-evict-by-label: "k1:v1,k2:v2"
注意:
当两个 annotation 同时存在时,ds-evict-by-label 的优先级更高。

8. 特殊能力

调整 DaemonSet Pod 的启动顺序

如果注入的 DaemonSet Pod 需要先于业务 Pod 启动,可以给业务 Pod 配上如下 annotation ,让业务 Pod 晚于 DaemonSet Pod 启动:
eks.tke.cloud.tencent.com/start-after-ds: "true"

开放端口

注入的 DaemonSet Pod 若需要对外暴露端口,则需额外通过 annotation 声明,声明方式如下:
eks.tke.cloud.tencent.com/metrics-port: "9100,8080,3000-5000"
默认只暴露9100端口,用来提供监控数据 metrics,您可以在9100之后添加其他端口,支持范围 range 写法,多个端口之间用逗号分隔,最多支持 4 个逗号。请注意,可以变更9100端口,但不要删除,第一个端口默认用于提供监控数据 metrics。
从容器外访问 DaemonSet Pod 的端口时,访问的 IP 为业务 Pod 的 IP,端口为 DaemonSet Pod 的端口:
curl "http://<pod-ip>:<ds-port>/"

业务 Pod 与本地 DaemonSet Pod 通信

如果业务 Pod 需要主动访问注入的 DaemonSet Pod,则需要获取到注入的 DaemonSet Pod 使用的虚拟 IP。通过添加如下 annotation,业务 Pod 可以通过 env from hostIP,获取到 DaemonSet Pod 所使用的虚拟 IP:
eks.tke.cloud.tencent.com/env-host-ip: "true"
容器里使用类似 env from hostIP:
env:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP

DaemonSet Pod 访问 kubelet 的 10250 端口

如果 DaemonSet Pod 要通过 kubelet 的接口获取本地 pod 的列表,可以给业务 pod 配上如下 annotation:
eks.tke.cloud.tencent.com/read-only-port: "10250"
此时 DaemonSet Pod 就可以通过 127.0.0.1:10250 访问到 pod 列表。