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

基于Helm的DaemonSet目录管理咨询:存活策略与目录删除

使用Helm+DaemonSet管理节点目录的问题解答

场景与现有配置

需求:通过DaemonSet管理节点/var/log/at下的目录集合,支持创建、删除或存在不操作,目录列表从Helm的values.yaml动态读取。

现有DaemonSet定义

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: create-directory
spec:
  selector:
    matchLabels:
      app: create-directory
  template:
    metadata:
      labels:
        app: create-directory
    spec:
      # use default service-account with scc role-binding
      serviceAccountName: default
      containers:
      - name: create-directory
        image: "{{ .Values.container.image }}"
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh", "-c"]
        args:
          - |
            {{- range .Values.directories }}

            dir_path="/var/log/at/{{ . }}"
            echo $dir_path

            # Check if the directory exists
            if [ -d "$dir_path" ]; then
              echo "Directory $dir_path already exists."
            else
              # Create the directory
              mkdir -p "$dir_path" && echo "Directory $dir_path created."
            fi

            {{- end }}
            
            while true; do
              sleep 100000;
            done
        # run the container as root
        securityContext:
          runAsUser: 0
        volumeMounts:
          - name: at-volume
            mountPath: /var/log/at
      volumes:
        - name: at-volume
          hostPath:
            path: /var/log/at

对应values.yaml

container:
  image: registry.access.redhat.com/ubi8/toolbox:8.5
directories:
  - directory1
  - directory2

问题解答

1. 用sleep保持Pod存活是否合理?社区有哪些推荐方案?

用sleep维持Pod存活的方式并不合理:

  • 不必要的资源占用:即使sleep消耗极低,Pod仍会持续占用节点的Pod配额、网络命名空间等资源;
  • 无意义的存活状态:脚本执行完成后,Pod的存活状态对目录管理没有任何价值,反而会让人误以为Pod在持续提供服务。

社区主流推荐方案:

  • Run-once DaemonSet:
    给Pod配置restartPolicy: OnFailure或Never,脚本执行完成后Pod进入Completed状态,DaemonSet不会重启它。为了在values.yaml更新时触发Pod重建执行新脚本,需给Pod模板添加校验和注解,确保配置变化时滚动更新:
    template:
      metadata:
        labels:
          app: create-directory
        annotations:
          checksum/values: {{ include (print $.Template.BasePath "/values.yaml") . | sha256sum }}
    
  • Init Container 配合业务Pod:如果目录是为其他业务Pod准备的,可以将目录创建逻辑放到业务Pod的Init Container中,业务Pod启动前完成目录初始化,无需单独的DaemonSet;
  • Job + 节点亲和性:若仅需在每个节点执行一次目录管理任务,可使用Job结合nodeAffinity或nodeSelector遍历所有节点,但DaemonSet更能保证每个节点必有一个实例执行任务。

2. 移除values.yaml中的目录时,如何自动删除对应目录?

需要修改脚本逻辑,增加清理非目标目录的步骤,具体实现如下:

修改后的容器命令脚本

{{- /* 先把values中的目录转换成绝对路径列表 */ -}}
{{- $targetDirs := list }}
{{- range .Values.directories }}
{{- $targetDirs = append $targetDirs (printf "/var/log/at/%s" .) }}
{{- end }}
TARGET_DIRS="{{ join " " $targetDirs }}"

# 1. 创建需要保留的目录
for dir in $TARGET_DIRS; do
  if [ -d "$dir" ]; then
    echo "Directory $dir already exists."
  else
    mkdir -p "$dir" && echo "Directory $dir created."
  fi
done

# 2. 删除不在目标列表中的目录
for dir in /var/log/at/*; do
  # 仅处理目录,跳过文件
  if [ -d "$dir" ]; then
    # 检查当前目录是否在目标列表中
    if ! echo "$TARGET_DIRS" | grep -q "^$dir$"; then
      echo "Removing unused directory: $dir"
      # 可选:若要保留非空目录,替换为 rmdir "$dir" 2>/dev/null || echo "Directory $dir is not empty, skip removal"
      rm -rf "$dir"
    fi
  fi
done

配套调整

  • 移除原脚本末尾的sleep循环;
  • 在Pod模板中设置restartPolicy: OnFailure;
  • 添加前面提到的checksum/values注解,确保values更新时触发Pod重建执行清理逻辑。

注意:使用rm -rf删除目录时需谨慎,若目录中存在业务写入的日志或数据,会导致数据丢失。建议优先使用rmdir仅删除空目录,或在脚本中增加额外校验逻辑。


内容的提问来源于stack exchange,提问作者Somnath Pathak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:15:10