Kubernetes-DaemonSet控制器

通过该控制器的名称我们可以看出它的用法:Daemon ,就是用来部署守护进程的, DaemonSet用于在每个 Kubernetes 节点中将守护进程的副本作为后台进程运行,说白了就是在每个节点部署一个 Pod 副本,当节点加入到 Kubernetes 集 群中,Pod 会被调度到该节点上运行,当节点从集群只能够被移除后,该节点上的这个 Pod 也会被移除,当然,如果我们 删除 DaemonSet,所有和这个对象相关的 Pods 都会被删除。那么在哪种情况下我们会需要用到这种业务场景呢?其实这 种场景还是比较普通的,比如:

  • 集群存储守护程序,如 glusterd、ceph 要部署在每个节点上以提供持久性存储;
  • 节点监控守护进程,如 Prometheus 监控集群,可以在每个节点上运行一个 node-exporter 进程来收集监控节点的信息;
  • 日志收集守护程序,如 fluentd 或 logstash,在每个节点上运行以收集容器的日志;
  • 节点网络插件,比如 flannel、calico,在每个节点上运行为 Pod 提供网络服务。

这里需要特别说明的一个就是关于 DaemonSet 运行的 Pod 的调度问题,正常情况下,Pod 运行在哪个节点上是由 Kubernetes 的调度器策略来决定的,然而,由 DaemonSet 控制器创建的 Pod 实际上提前已经确定了在哪个节点上了 (Pod 创建时指定了.spec.nodeName ),所以:

  • DaemonSet 并不关心一个节点的 unshedulable 字段,这个我们会在后面的调度章节和大家讲解的。
  • DaemonSet 可以创建 Pod,即使调度器还没有启动。

下面我们直接使用一个示例来演示下,在每个节点上部署一个 Nginx Pod:

复制代码
# nginx-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ds
  namespace: default
  labels:
    app: nginx-ds
    version: v1
spec:
  selector:
    matchLabels:
      app: nginx-ds
  template:
    metadata:
      labels:
        app: nginx-ds
        version: v1
    spec:
      tolerations:                    # 容忍度,允许在特定节点上运行
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      containers:
        - name: nginx
          image: nginx:1.27.0
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          resources:
            requests:
              memory: "64Mi"
              cpu: "250m"
            limits:
              memory: "128Mi"
              cpu: "500m"
          livenessProbe:               # 存活探针
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:              # 就绪探针
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 5
      terminationGracePeriodSeconds: 30

创建完成后,我们查看 Pod 的状态:

复制代码
root@master01:~/kubernetes# kubectl get nodes
NAME       STATUS   ROLES           AGE     VERSION
master01   Ready    control-plane   7d22h   v1.32.12
node01     Ready    <none>          7d22h   v1.32.12
node02     Ready    <none>          7d22h   v1.32.12
root@master01:~/kubernetes# kubectl apply -f nginx-ds.yaml 
daemonset.apps/nginx-ds created
root@master01:~/kubernetes# kubectl get pod -l app=nginx-ds -o wide
NAME             READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
nginx-ds-9z8pl   1/1     Running   0          2m50s   172.16.241.74    master01   <none>           <none>
nginx-ds-c9kdz   1/1     Running   0          86s     172.16.196.155   node01     <none>           <none>
nginx-ds-mbxjx   1/1     Running   0          79s     172.16.140.83    node02     <none>           <none>

在给主节点添加了污点容忍后,可以看到所有节点都调度了一个nginx的pod。

基本上我们可以用下图来描述 DaemonSet 的拓扑图:

集群中的 Pod 和 Node 是一一对应的,而 DaemonSet 会管理全部机器上的 Pod 副本,负责对它们进行更新和删除。 那么,DaemonSet 控制器是如何保证每个 Node 上有且只有一个被管理的 Pod 呢?

首先控制器从 Etcd 获取到所有的 Node 列表,然后遍历所有的 Node。

根据资源对象定义是否有调度相关的配置,然后分别检查 Node 是否符合要求。

在可运行 Pod 的节点上检查是否已有对应的 Pod,如果没有,则在这个 Node 上创建该 Pod;如果有,并且数量大 于 1,那就把多余的 Pod 从这个节点上删除;如果有且只有一个 Pod,那就说明是正常情况。

实际上当我们学习了资源调度后,我们也可以自己用 Deployment 来实现 DaemonSet 的效果,这里我们明白 DaemonSet 如何使用的即可,当然该资源对象也有对应的更新策略,有 OnDelete 和 RollingUpdate 两种方式,默认是滚动更新。

相关推荐
什么都干的派森6 小时前
Qdrant生产环境部署方法(Docker)
运维·docker·容器·qdrant
叱咤少帅(少帅)6 小时前
docker 镜像加速地址
运维·docker·容器
阿寻寻7 小时前
【云原生技术】探针**就是:Kubelet(K8s 节点上的组件)会**进入容器里执行一条命令**,根据命令的退出码判断健康
云原生·kubernetes·kubelet
迎仔8 小时前
11-裸金属算力中心:K8s的实际价值与“管一切“的体现
云原生·容器·kubernetes
岁岁种桃花儿8 小时前
kubeadm构建单master多Node的k8s集群。
云原生·容器·kubernetes
礼拜天没时间.9 小时前
Docker Compose 实战:从单容器命令到多服务编排
运维·网络·docker·云原生·容器·centos
only_Klein9 小时前
kubernetes-Service
云原生·容器·kubernetes
迎仔10 小时前
10-算力中心运维三剑客:Ansible + Jenkins + K8s 高效实战
运维·kubernetes·ansible·jenkins
礼拜天没时间.19 小时前
Docker自动化构建实战:从手工到多阶段构建的完美进化
运维·docker·容器·centos·自动化·sre