Skip to content

DaemonSet

概述

DaemonSet是Kubernetes中用于在每个节点上运行一个Pod副本的控制器。它确保集群中的每个节点(或符合条件的节点)都运行指定的Pod,适合部署节点级别的守护进程。

DaemonSet核心特性

1. 节点覆盖

  • 在每个符合条件的节点上运行Pod
  • 新节点加入时自动创建Pod
  • 节点移除时自动删除Pod

2. 自动管理

  • 自动调度到新节点
  • 自动清理Pod
  • 支持节点选择器

3. 更新策略

  • 滚动更新
  • OnDelete更新
  • 支持回滚

4. 资源保证

  • 使用DaemonSet专用调度器
  • 不受资源限制影响
  • 优先级保证

DaemonSet配置详解

基本DaemonSet配置

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-ds
  namespace: kube-system
  labels:
    k8s-app: fluentd
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluentd:v1.14
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

完整DaemonSet配置

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
  labels:
    app: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  revisionHistoryLimit: 10
  template:
    metadata:
      labels:
        app: node-exporter
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9100"
    spec:
      serviceAccountName: node-exporter
      hostNetwork: true
      hostPID: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.3.0
        args:
        - --path.procfs=/host/proc
        - --path.sysfs=/host/sys
        - --path.rootfs=/host/root
        - --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
        ports:
        - name: metrics
          containerPort: 9100
          hostPort: 9100
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 200m
            memory: 200Mi
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
        - name: root
          mountPath: /host/root
          mountPropagation: HostToContainer
          readOnly: true
      tolerations:
      - operator: Exists
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      - name: root
        hostPath:
          path: /

节点选择

1. nodeSelector

yaml
spec:
  template:
    spec:
      nodeSelector:
        disktype: ssd
        zone: east

2. 节点亲和性

yaml
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 50
            preference:
              matchExpressions:
              - key: zone
                operator: In
                values:
                - east

3. 污点和容忍

yaml
spec:
  template:
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
      - key: dedicated
        operator: Equal
        value: monitoring
        effect: NoSchedule

更新策略

1. RollingUpdate(默认)

yaml
updateStrategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 1  # 最大不可用Pod数量

2. OnDelete

yaml
updateStrategy:
  type: OnDelete  # 手动删除Pod时才更新

操作命令

创建DaemonSet

bash
# 从YAML文件创建
kubectl apply -f daemonset.yaml

# 查看DaemonSet
kubectl get daemonsets
kubectl get ds

# 查看详细信息
kubectl describe daemonset <daemonset-name>

查看DaemonSet

bash
# 查看所有DaemonSet
kubectl get ds --all-namespaces

# 查看DaemonSet详情
kubectl describe ds <daemonset-name> -n <namespace>

# 查看Pod分布
kubectl get pods -o wide -l app=<app-name>

更新DaemonSet

bash
# 更新镜像
kubectl set image daemonset/<daemonset-name> <container-name>=<new-image>

# 查看更新状态
kubectl rollout status daemonset/<daemonset-name>

# 查看更新历史
kubectl rollout history daemonset/<daemonset-name>

回滚操作

bash
# 回滚到上一个版本
kubectl rollout undo daemonset/<daemonset-name>

# 回滚到指定版本
kubectl rollout undo daemonset/<daemonset-name> --to-revision=2

删除DaemonSet

bash
# 删除DaemonSet
kubectl delete daemonset <daemonset-name>

# 删除所有DaemonSet
kubectl delete daemonsets --all

实践示例

示例1:日志收集器Fluentd

yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fluentd
rules:
- apiGroups: [""]
  resources: ["pods", "namespaces"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: fluentd
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: fluentd
subjects:
- kind: ServiceAccount
  name: fluentd
  namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: kube-system
  labels:
    k8s-app: fluentd
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      serviceAccountName: fluentd
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch
        env:
        - name: FLUENT_ELASTICSEARCH_HOST
          value: "elasticsearch.logging"
        - name: FLUENT_ELASTICSEARCH_PORT
          value: "9200"
        - name: FLUENT_ELASTICSEARCH_SCHEME
          value: "http"
        resources:
          limits:
            memory: 500Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: etcfluentd-main
          mountPath: /fluentd/etc
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: etcfluentd-main
        configMap:
          name: fluentd-config
          defaultMode: 0644

示例2:监控代理Node Exporter

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
  labels:
    app: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      hostNetwork: true
      hostPID: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:latest
        args:
        - --path.procfs=/host/proc
        - --path.sysfs=/host/sys
        - --collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)
        ports:
        - name: metrics
          containerPort: 9100
          hostPort: 9100
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 200m
            memory: 200Mi
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
        - name: root
          mountPath: /host/root
          mountPropagation: HostToContainer
          readOnly: true
      tolerations:
      - effect: NoSchedule
        operator: Exists
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      - name: root
        hostPath:
          path: /

示例3:网络插件Calico

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: calico-node
  namespace: kube-system
  labels:
    k8s-app: calico-node
spec:
  selector:
    matchLabels:
      k8s-app: calico-node
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        k8s-app: calico-node
    spec:
      nodeSelector:
        kubernetes.io/os: linux
      hostNetwork: true
      tolerations:
      - key: CriticalAddonsOnly
        operator: Exists
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
      serviceAccountName: calico-node
      priorityClassName: system-node-critical
      containers:
      - name: calico-node
        image: calico/node:v3.22.0
        env:
        - name: DATASTORE_TYPE
          value: "kubernetes"
        - name: FELIX_LOGSEVERITYSCREEN
          value: "info"
        - name: CLUSTER_TYPE
          value: "k8s,bgp"
        - name: IP
          value: "autodetect"
        - name: CALICO_IPV4POOL_IPIP
          value: "Always"
        - name: FELIX_IPINIPMTU
          value: "1440"
        - name: CALICO_NETWORKING_BACKEND
          value: "bird"
        - name: NODENAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: FELIX_HEALTHENABLED
          value: "true"
        securityContext:
          privileged: true
        resources:
          requests:
            cpu: 250m
        livenessProbe:
          exec:
            command:
            - /bin/calico-node
            - -felix-live
          periodSeconds: 10
          initialDelaySeconds: 10
          failureThreshold: 6
        readinessProbe:
          exec:
            command:
            - /bin/calico-node
            - -felix-ready
          periodSeconds: 10
        volumeMounts:
        - mountPath: /lib/modules
          name: lib-modules
          readOnly: true
        - mountPath: /run/xtables.lock
          name: xtables-lock
        - mountPath: /var/run/calico
          name: var-run-calico
        - mountPath: /var/lib/calico
          name: var-lib-calico
      volumes:
      - name: lib-modules
        hostPath:
          path: /lib/modules
      - name: var-run-calico
        hostPath:
          path: /var/run/calico
      - name: var-lib-calico
        hostPath:
          path: /var/lib/calico
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock
          type: FileOrCreate

示例4:存储插件Ceph RBD

yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ceph-rbd
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: ceph-rbd
  template:
    metadata:
      labels:
        app: ceph-rbd
    spec:
      hostNetwork: true
      containers:
      - name: ceph-rbd
        image: ceph/ceph:v15
        command:
        - /bin/bash
        - -c
        - |
          modprobe rbd
          while true; do sleep 3600; done
        securityContext:
          privileged: true
        volumeMounts:
        - name: modules
          mountPath: /lib/modules
          readOnly: true
      volumes:
      - name: modules
        hostPath:
          path: /lib/modules

故障排查

常见问题

1. Pod无法调度

bash
# 查看DaemonSet状态
kubectl describe daemonset <daemonset-name>

# 查看节点状态
kubectl get nodes

# 检查节点污点
kubectl describe node <node-name> | grep Taints

2. Pod启动失败

bash
# 查看Pod状态
kubectl get pods -l app=<app-name> -o wide

# 查看Pod事件
kubectl describe pod <pod-name>

# 查看容器日志
kubectl logs <pod-name>

3. 权限问题

bash
# 检查ServiceAccount
kubectl get serviceaccount <serviceaccount-name>

# 检查RBAC权限
kubectl get clusterrolebinding | grep <serviceaccount-name>

# 查看Pod权限
kubectl auth can-i --list --as=system:serviceaccount:<namespace>:<serviceaccount-name>

4. 资源不足

bash
# 查看节点资源
kubectl describe node <node-name>

# 查看资源配额
kubectl get resourcequotas

# 检查资源限制
kubectl describe daemonset <daemonset-name> | grep -A 5 Resources

最佳实践

1. 资源管理

  • 设置合理的资源请求和限制
  • 使用PriorityClass保证调度
  • 监控资源使用情况
  • 避免资源竞争

2. 更新策略

  • 生产环境使用RollingUpdate
  • 设置合理的maxUnavailable
  • 测试环境使用OnDelete
  • 制定回滚方案

3. 节点选择

  • 使用节点选择器精确控制
  • 配置污点和容忍
  • 实现节点分组部署
  • 避免单点故障

4. 安全配置

  • 使用最小权限原则
  • 配置安全上下文
  • 限制特权容器
  • 启用审计日志

5. 监控告警

  • 监控DaemonSet状态
  • 监控Pod运行状态
  • 设置资源告警
  • 实现自动恢复

总结

DaemonSet是Kubernetes中部署节点级守护进程的核心控制器,确保每个节点运行指定的Pod。掌握DaemonSet的使用对于部署日志收集、监控代理、网络插件等系统组件至关重要。

下一步学习