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 两种方式,默认是滚动更新。

相关推荐
李彦亮老师(本人)12 小时前
【Linux系统】Rocky Linux 9.7操作系统简介
linux·运维·服务器·docker·kubernetes
DynamicsAgg13 小时前
企业数字化底座-k8s企业实践系列第二篇pod创建调度
java·容器·kubernetes
T1an-113 小时前
Docker + K8s:现代开发的“标配”
docker·容器·kubernetes
yzx99101316 小时前
实时数据流处理实战:从滑动窗口算法到Docker部署
算法·docker·容器
Sarapines Programmer18 小时前
【Docker】Windows 安装 Docker 简明指南
运维·docker·容器
万象.21 小时前
docker镜像操作实操
运维·docker·容器
F1FJJ21 小时前
VS Code 里管理 PostgreSQL,有哪些选择?主流扩展横向对比
网络·数据库·postgresql·容器
mit6.8241 天前
llm-ready|docker|三文件规划
人工智能·容器
国医中兴1 天前
分布式存储的缓存优化:从理论到实践
微服务·云原生·容器·kubernetes·k8s
Kapibalapikapi1 天前
Web笔记 | docker常用指令 --搭建测试靶场
web安全·docker·容器