一文搞懂什么是 DaemonSets

DeamonSets类似于Replica Sets,因为它们可以帮助我们部署多个pod实例,但是它在Kubernetes集群的每个节点上只运行一个pod副本。

DaemonSets确保所有(或部分)节点运行Pod的副本。随着节点被添加到集群中,pod也被添加到集群中,当节点从集群中移除时,这些pod将会被删除。

DaemonSets的使用场景

下面是一些典型的daemonset用例:

  • 当我们希望在集群中的每个节点上部署监控代理,以便更好地监视集群时。然后,当集群中发生了变化,我们不必担心在这些节点上添加或删除监视代理,因为守护进程将为我们处理这些更改。如Prometheus Node export, Datadog agent等。
  • 在集群中的每个节点上运行的日志收集器。例如logstash, fluentd。
  • 在集群中的每个节点上运行的集群存储守护进程。例如glusterd - ceph。
  • 对于网络解决方案,例如Weavenet需要在集群中的每个节点上运行一个Weavenet代理。
  • kube-proxy是DaemonSets的另一个很好的用例。原因是集群中的每个节点都需要kube-proxy来运行IP Tables,这样每个节点都可以访问这个pod,而不管它运行在哪个节点上。因此,当我们将kube-proxy设置为守护进程,并且稍后将另一个节点添加到集群中时,kube-proxy将自动在该节点上生成。

在一个简单的情况下,可以为每种不同类型的守护进程使用一个Daemonset(覆盖所有节点)。我们也可以为单一类型的守护进程配置多个daemonset,使用不同的标志、内存、CPU等。

Kube-dns的职责是使用其名称发现服务IP,并且只需Kube-dns的一个副本就足以将服务名称解析为其IP。因此,我们将kube-dns作为一个部署,因为我们不需要在每个节点上都部署kube-dns。

如何调度DaemonSets

守护进程控制器管理像部署、复制集和状态集这样的pod。

创建一个DaemonSet

一文搞懂什么是 DaemonSets_第1张图片

在本例中,我们将在集群的每个节点上部署prometheus节点导出代理pod。

下面是一个DaemonSet manifest文件的示例:

root@kube-master:~/DaemonSet# cat daemonset_demo.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-demo-prometheus
spec:
  selector:
    matchLabels:
      tier: monitoring
      name: prometheus-exporter  # Label selector that determines which Pods belong to the DaemonSet
  template:
    metadata:
      labels:
        tier: monitoring # Pod template's label selector
        name: prometheus-exporter # Pod template's label selector
    spec:
      containers:
      - name: prometheus
        image: prom/node-exporter
        ports:
        - containerPort: 80

关于daemonset_demo.yml的说明

  • 创建一个名为DaemonSet -demo-prometheus的守护进程,由metadata: name字段表示。
  • 守护进程的Pod被标记为prometheus-expoter,并被标记为monitoring
  • Pod的容器提取最新的节点导出器映像。容器映像由container Registry托管。

使用kubectl命令创建DaemonSet

root@kube-master:~/DaemonSet# kubectl apply -f daemonset_demo.yml --record
daemonset.apps/daemonset-demo-prometheus created

--record 表示将跟踪通过每次编辑所做的更改

验证创建的DaemonSet

root@kube-master:~/DaemonSet# kubectl get daemonsets daemonset-demo-prometheus -o wide
NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE     CONTAINERS   IMAGES               SELECTOR
daemonset-demo-prometheus   3         3         3       3            3                     2m13s   prometheus   prom/node-exporter   name=prometheus-exporter,tier=monitoring

获取更多有关DaemonSet的详细信息:

root@kube-master:~/DaemonSet# kubectl describe daemonsets daemonset-demo-prometheus
Name:           daemonset-demo-prometheus
Selector:       name=prometheus-exporter,tier=monitoring
Node-Selector:  
Labels:         
Annotations:    deprecated.daemonset.template.generation: 1
                kubernetes.io/change-cause: kubectl apply --filename=daemonset_demo.yml --record=true
Desired Number of Nodes Scheduled: 3
Current Number of Nodes Scheduled: 3
Number of Nodes Scheduled with Up-to-date Pods: 3
Number of Nodes Scheduled with Available Pods: 3
Number of Nodes Misscheduled: 0
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  name=prometheus-exporter
           tier=monitoring
  Containers:
   prometheus:
    Image:        prom/node-exporter
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  
    Mounts:       
  Volumes:        
Events:
  Type    Reason            Age    From                  Message
  ----    ------            ----   ----                  -------
  Normal  SuccessfulCreate  2m52s  daemonset-controller  Created pod: daemonset-demo-prometheus-2l57n
  Normal  SuccessfulCreate  2m52s  daemonset-controller  Created pod: daemonset-demo-prometheus-8sgfk
  Normal  SuccessfulCreate  2m52s  daemonset-controller  Created pod: daemonset-demo-prometheus-ffbp6

在Pod中获取更多DaemonSet的信息

root@kube-master:~/DaemonSet# kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE    IP                NODE           NOMINATED NODE   READINESS GATES
daemonset-demo-prometheus-2l57n   1/1     Running   0          5m1s   192.168.221.241   kube-master               
daemonset-demo-prometheus-8sgfk   1/1     Running   0          5m1s   192.168.194.4     kube-worker1              
daemonset-demo-prometheus-ffbp6   1/1     Running   0          5m1s   192.168.161.240   kube-worker2              

从上面的输出可以看到,部署了3个pod。主节点和工作节点各一个。在这里,守护进程确保每个节点有一个pod,而不使用任何关联规则。

删除一个DaemonSet

像所有其他Kubernetes对象一样,DaemonSet也可以通过使用创建它的相同的manifest file或使用kubectl命令来删除。

root@kube-master:~/DaemonSet# kubectl delete -f daemonset_demo.yml
daemonset.apps "daemonset-demo-prometheus" deleted
root@kube-master:~/DaemonSet# kubectl delete daemonsets daemonset-demo-prometheus
daemonset.apps "daemonset-demo-prometheus" deleted

更新一个DaemonSet

可以通过更改以下规格来更新DaemonSet:

  • Pod specification
  • resource requests
  • limits
  • labels
  • Annotations

我们可以使用以下两种更新策略来更新守护进程:

rolllingupdate —这是默认策略,将在配置更改时应用。它会自动删除并重新创建DaemonSet pod。

OnDelete -当使用此策略时,Kubernetes不会自动删除DaemonSet pods,并在配置更改时重新创建它们。我们必须手动删除pod,然后控制器将创建一个带有新更改的新pod。

Daemon Pod 是如何调度的?

DaemonSet确保所有符合条件的节点都运行Pod的副本。通常,Kubernetes调度器决定Pod运行的节点。但是,DaemonSet pod是由DaemonSet控制器创建和调度的。

但这会导致以下问题:

  • Pod行为不一致:创建等待调度的普通Pod并保持Pending状态,但DaemonSet Pod没有创建Pending状态。这会让用户感到困惑。
  • Pod抢占由默认调度器处理。当启用抢占时,守护进程控制器将在不考虑pod优先级和抢占的情况下做出调度决策。

那么如何解决这种问题?

ScheduleDaemonSetPods允许我们使用默认调度器而不是DaemonSet控制器来调度DaemonSet,通过将NodeAffinity 添加到DaemonSet pods中,而不是.spec.nodename。然后使用默认调度器将pod绑定到目标主机。

下面的清单文件使用节点关联规则创建一个pod。

apiVersion: v1
kind: Pod
metadata:
  name: web-servers
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: workload
            operator: In
            values:
            - staging
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent

如果你观察上面的main file,我们有一个使用requiredduringscheduleingignoredduringexecution类型节点亲和力和表达式key-value作为workload: staging调度的Pod。这意味着pod将只被安排在具有workload=staging标签的节点上。

污点和容忍度

Daemon Pods 允许污点和容忍度。node.kubernetes.io/ unscheable:将NoSchedule容忍自动添加到DaemonSet Pods中。默认调度程序在调度DaemonSet pod时忽略不可调度的节点。

与Daemon pod通信

我们可以通过不同的方式与DaemonSets创建的pod进行通信。

  • Push:使用这种方式,可以配置pods来发送诸如统计、数据库或监控服务之类的信息给其他服务。他们没有客户。
  • NodeIP & Known Port : pod可以使用hostPort通过它们各自的节点ip到达。用户可以使用已知的端口和节点IP与pod通信。
  • DNS:我们可以使用相同的pod选择器创建无头服务,然后使用端点资源发现daemonset或从DNS检索多个a记录。
  • Service:我们可以使用相同的Pod选择器创建服务,并使用该服务访问随机节点上的守护进程。(无法到达特定节点。)

总结

当我们想要部署需要在所有或某些节点上运行的应用程序时,daemonset非常有用。此类任务的示例包括日志收集守护进程(如logstash)、存储守护进程(如ceph)和节点监控守护进程(如prometheus node-export)等。

你可能感兴趣的:(Kubernetes,kubernetes)