You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

容器级亲和性实现:DaemonSet中部分容器按需部署至指定节点

可行实现方案

核心思路是让DaemonSet把Pod部署到所有节点,同时通过容器启动逻辑控制:容器a正常启动运行,容器b仅在满足标签/条件的节点上启动业务,不满足条件时进入休眠(避免容器退出导致Pod反复重启)。

方案1:容器启动时直接判断节点标签

不需要额外的init容器,直接在容器b的启动命令里检查当前节点是否有目标标签,符合条件就跑业务,不符合就休眠。

示例DaemonSet配置片段:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: mixed-daemonset
spec:
  selector:
    matchLabels:
      app: mixed-app
  template:
    metadata:
      labels:
        app: mixed-app
    spec:
      containers:
      - name: a
        image: your-a-image:latest
        # 这里写容器a的正常配置,比如端口、资源限制等
      - name: b
        image: your-b-image:latest
        # 用shell脚本判断节点标签,比如检查节点是否有"special-node=true"标签
        command: ["/bin/sh", "-c"]
        args:
        - |
          # 通过环境变量获取当前节点名称
          NODE_NAME=$(echo $NODE_NAME)
          # 调用K8s API查询节点标签,需要镜像里有curl和jq
          LABEL_VALUE=$(curl -sS --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
            -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
            https://kubernetes.default.svc/api/v1/nodes/$NODE_NAME | jq -r '.metadata.labels."special-node"')
          
          if [ "$LABEL_VALUE" = "true" ]; then
            # 符合条件,启动容器b的业务命令
            /usr/local/bin/start-b-service
          else
            # 不符合条件,无限休眠,不占用核心资源
            sleep infinity
          fi
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        # 给休眠的容器b设置最小资源限制,避免浪费
        resources:
          requests:
            cpu: "10m"
            memory: "10Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"

如果你的容器镜像里没有curl和jq,可以换用带kubectl的镜像(比如bitnami/kubectl:latest),把判断逻辑改成:

if kubectl get node $NODE_NAME --no-headers -o custom-columns=:.metadata.labels.special-node | grep -q "true"; then
  /usr/local/bin/start-b-service
else
  sleep infinity
fi

方案2:用Init容器提前做节点检查

先通过一个Init容器判断节点是否符合条件,在共享空目录里创建标记文件,容器b启动时读取这个标记,决定是否跑业务。这种方式把判断逻辑和业务容器解耦,更清晰。

示例配置片段:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: mixed-daemonset
spec:
  selector:
    matchLabels:
      app: mixed-app
  template:
    metadata:
      labels:
        app: mixed-app
    spec:
      # 定义共享卷,用来传递标记文件
      volumes:
      - name: node-check
        emptyDir: {}
      # Init容器:检查节点标签,生成标记文件
      initContainers:
      - name: check-node
        image: busybox:latest
        command: ["/bin/sh", "-c"]
        args:
        - |
          NODE_NAME=$(cat /etc/hostname)
          # 用wget调用K8s API,busybox自带wget
          wget --ca-certificate=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
            --header="Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
            -O - https://kubernetes.default.svc/api/v1/nodes/$NODE_NAME | grep -q '"special-node": "true"' \
            && touch /check/run-b || touch /check/skip-b
        volumeMounts:
        - name: node-check
          mountPath: /check
      containers:
      - name: a
        image: your-a-image:latest
        # 容器a的正常配置
      - name: b
        image: your-b-image:latest
        command: ["/bin/sh", "-c"]
        args:
        - |
          if [ -f /check/run-b ]; then
            /usr/local/bin/start-b-service
          else
            sleep infinity
          fi
        volumeMounts:
        - name: node-check
          mountPath: /check
        resources:
          requests:
            cpu: "10m"
            memory: "10Mi"
          limits:
            cpu: "100m"
            memory: "100Mi"

关键注意点

  • 容器b不要直接退出,否则Pod会因为容器异常终止而重启,造成资源浪费。用sleep infinity让它保持运行但不干活是最优选择。
  • 要确保容器镜像里包含所需的工具(curl、jq、kubectl等),或者选择自带这些工具的基础镜像(比如alpine、bitnami的镜像)。

内容的提问来源于stack exchange,提问作者Fermat's Little Student

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:45:33