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

如何让DaemonSet节点初始化Pod仅在每个节点运行一次?

解决Kubernetes DaemonSet初始化脚本重复执行的问题

问题背景

需要在每个Kubernetes节点上执行一次初始化脚本,当前使用DaemonSet部署的Pod执行完脚本后以exit code 0退出,导致DaemonSet反复重启Pod,脚本重复执行。尝试过添加preStop钩子为节点打k8s.amazee.io/node-configured标签,以及修改command追加标签操作,但均未生效。目标是确保每个节点仅执行一次初始化,阻止Pod重复重启。

失败原因分析

  1. preStop钩子未生效:当容器正常执行完脚本并exit 0时,Kubernetes的preStop钩子可能不会被触发——终止流程在容器主动退出后直接完成,钩子没有执行时机,导致节点未打上标签。
  2. command配置存在语法错误:之前修改的command中存在多余引号(/bin/sh")、错误的分号位置,导致kubectl标签命令未被正确执行,节点无法被标记为已配置,DaemonSet持续重启Pod。

正确解决方案

核心思路:在初始化脚本执行完成后,立即为节点打上标签,确保Pod退出前节点已被标记,DaemonSet后续不会在该节点重新调度Pod。

修正后的完整配置YAML如下:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: test-init-node-cr
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: test-init-node-sa
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: test-init-node-cr
subjects:
- kind: ServiceAccount
  name: test-init-node-sa
  namespace: default
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-init-node-sa
  namespace: default
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: test-init-node
  namespace: default
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: test-init-node
      app.kubernetes.io/component: configurator
  template:
    metadata:
      name: test-init-node
      labels:
        app.kubernetes.io/name: test-init-node
        app.kubernetes.io/component: configurator
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: k8s.amazee.io/node-configured
                operator: DoesNotExist
      hostPID: true
      hostNetwork: true
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
      serviceAccount: test-init-node-sa
      containers:
      - name: init
        env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        command: 
        - nsenter
        - --mount=/proc/1/ns/mnt
        - --
        - bash
        - -xc
        - |
          echo "starting the magic"
          # 执行初始化操作
          echo "*   hard  core    unlimited" >>  /etc/security/limits.d/game.conf 
          echo "*   soft  core    unlimited" >>  /etc/security/limits.d/game.conf 
          # 初始化完成后为节点打标签(--overwrite避免重复打标签报错)
          kubectl label node "$MY_NODE_NAME" k8s.amazee.io/node-configured=$(date +%s) --overwrite
        image: alpine/k8s:1.28.0
        resources:
          requests:
            cpu: 50m
            memory: 50M
        securityContext:
          runAsUser: 0
          privileged: true

关键修改点说明

  • 将标签操作整合到bash脚本的here-doc中,确保初始化脚本执行完成后才执行标签命令,保证节点在Pod退出前被标记。
  • 添加--overwrite参数,避免节点已有标签时命令报错,提升配置鲁棒性。
  • 修正了之前command配置中的语法错误,确保所有命令在同一个bash环境中执行。

验证方式

  1. 应用配置后,查看Pod状态:kubectl get pods -n default -l app.kubernetes.io/name=test-init-node
  2. 查看节点标签:kubectl get nodes --show-labels | grep k8s.amazee.io/node-configured
  3. 确认已完成初始化的节点上不会再重启新的Pod,且每个节点仅执行一次初始化脚本。

内容的提问来源于stack exchange,提问作者Y.H.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:44:52