• K8S(4)DaemonSet


    一、DaemonSet概述

    • DaemonSet即守护进程集,与守护进程类似。DaemonSet确保在符合匹配条件的节点上部署运行一个Pod
    • 当有新的节点加入时,也会为新节点添加Pod,同样当节点从集群移除时,运行的Pod也会被收回,而删除DaemonSet会删除DaemonSet创建的所有Pod
    • 下面是使用DaemonSet的一些场景:
    1. 运行集群存储的daemon:例如每个节点上运行Clusterd、Ceph(分布式存储)等
    2. 每个节点运行日志收集的daemon:例如Fluentd、Logstash等
    3. 每个节点运行监控的daemon:例如Prometheus Node Exporter、Collectd、Datadog等
    4. 每个节点运行的网络插件的dameon:例如Flannel、Calico等
    • DaemonSet的主要特征:
    1. 创建的Pod运行在K8S集群的每一个节点上
    2. 每个节点只会存在一个DaemonSet创建的Pod实例
    3. 如果有新节点
    • 在部署K8S时,其实已经创建了两个DaemonSet,分别是flannelproxy
    [root@master test]# kubectl get daemonsets.apps -A
    NAMESPACE     NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
    kube-system   kube-flannel-ds   2         2         2       2            2           <none>                   11d
    kube-system   kube-proxy        2         2         2       2            2           kubernetes.io/os=linux   11d
    
    • 1
    • 2
    • 3
    • 4
    • 注意

    从1.6开始,DaemonSet控制器将不会再把Pod调度到主节点上。

    这是因为主节点上有node-role.kubernetes.io/masterNoSchedule污点,而Pod没有容忍该污点,所以不会调度到主节点上。

    官方已经不建议,那么如果没有必要就不要向主机调度Pod了,除非是出于监控或者指标收集等原因。

    二、DaemonSet定义

    • 创建一个DaemonSet的yaml大致如下,这是Prometheus部署时使用的node-exporter用于监控节点信息
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: node-exporter
      namespace: kube-system
      labels:
        k8s-app: node-exporter
    spec:
      selector:
        matchLabels:
          k8s-app: node-exporter
      template:
        metadata:
          labels:
            k8s-app: node-exporter
        spec:
          containers:
          - image: prom/node-exporter
            name: node-exporter
            ports:
            - containerPort: 9100
              protocol: TCP
              name: http
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        k8s-app: node-exporter
      name: node-exporter
      namespace: kube-system
    spec:
      ports:
      - name: http
        port: 9100
        nodePort: 31672
        protocol: TCP
      type: NodePort
      selector:
        k8s-app: node-exporter
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 其中必须字段:

    和其他所有的K8S资源配置相同,必须字段有:apiVersionkindmetadataspec

    • Pod模板:

    spec唯一需要的字段是spec.template,除了必须字段外,在DaemonSet中的Pod模板必须指定合理的标签。并且还需要具有一个RestartPolicy(重启策略),默认策略是Always

    注释:spec.template是一个Pod模板,与Pod具有相同的配置方式,但是她并没有apiVersionkind字段

    • Pod Selector:

    Pod Selector代表的字段是spec.selector与其他资源的spec.selector字段作用相同spec.selector表示一个对象,由如下两个字段组成:

    1. matchLabels:用于匹配符合条件的Pod
    2. matchExpressions:允许构建更加复杂的Selector

    如果上面的两个字段同时指定是,结果表示的是逻辑与(AND)的关系

    注意:spec.selector必须与spec.template.metadata.labels相匹配,如果没有指定,默认是等价的,如果这两个的配置不匹配,则会被API拒绝,也就会报错

    在这里插入图片描述

    三、创建DaemonSet

    • 下面创建一个nginx的DaemonSet
    [root@master test]# cat nginx.yaml
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nginx
    spec:
      selector:
        matchLabels:
          run: nginx
      template:
        metadata:
          labels:
            run: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.15.2
            ports:
            - containerPort: 80
              name: nginx
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          tolerations:    
          - key: node-role.kubernetes.io/master
            effect: NoSchedule
            
    ——————————————————————————————————————————————————————————————————————————————
    添加'容忍'即可使DaemonSet可以在主节点上创建Pod,字段是'spec.template.spec.tolerations'
    tolerations:    
    - key: node-role.kubernetes.io/master
      effect: NoSchedule
    ——————————————————————————————————————————————————————————————————————————————  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 这里有一个字段spec.template.spec.dnsPolicy,这个字段可以指定DNS策略
    1. 无策略(None):清除Pod预设的DNS配置,当dnsPolicy设置成这个值时,K8S不会为Pod预先加载任何逻辑用于判定得到的DNS配置
    2. 默认预设(Default):设置为这个值时,Pod里面的DNS配置会继承宿主机上的配置,该Pod的DNS配置与宿主机的完全相同
    3. 集群优先(ClusterFirst):与Default策略相反,设置为这个值时,会预先使用Kube-dns或者CoreDNS的信息当作预设参数写到创建Pod的DNS配置中
    4. ClusterFirstWithHostNet:设置为这个值时,宿主机会与K8S共存,共同使用hostNetworkkube-dns作为创建Pod的预设配置
    • 创建
    [root@master test]# kubectl apply -f nginx.yaml
    daemonset.apps/nginx created
    [root@master test]# kubectl get node  #先看一下,这里有两个节点
    NAME     STATUS   ROLES    AGE   VERSION
    master   Ready    master   11d   v1.18.0
    node     Ready    <none>   11d   v1.18.0
    
    [root@master test]# kubectl get pods  #因为添加了容忍,所以两个节点都创建pod了
    NAME          READY   STATUS    RESTARTS   AGE
    nginx-krr85   1/1     Running   0          3m19s
    nginx-q7wz9   1/1     Running   0          3m19s
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    四、DaemonSet指定节点部署Pod

    • 如果指定了spec.template.spec.nodeSelector字段,那么DaemonSet控制器将在与Node Selector(节点选择器)匹配的节点上创建Pod,例如:

    只想部署Pod到磁盘为SSD的节点上

    • 如果想要指定节点部署Pod,我们需要提前给节点定义标签Label,例如:
    containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
      nodeSelector:  #此字段同样适用于其他资源控制器
        disktype: ssd
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意:这个标签名称、标签值都是自定义的

    • 下面通过添加节点标签指定pod运行的节点
    [root@master ~]# kubectl label node node ds=true  #节点名称叫node
    node/node labeled
    [root@master ~]# kubectl get node --show-labels | grep ds=true  #可以看到标签加了一个ds=true
    node     Ready    <none>   13d   v1.18.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ds=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=node,kubernetes.io/os=linux
    
    • 1
    • 2
    • 3
    • 4
    • 下面修改yaml文件
    [root@master test]# cat nginx.yaml
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nginx
    spec:
      selector:
        matchLabels:
          run: nginx
      template:
        metadata:
          labels:
            run: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.15.2
            ports:
            - containerPort: 80
              name: nginx
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          tolerations:          #容忍不能去掉,不然master无法创建pod
          - key: node-role.kubernetes.io/master
            effect: NoSchedule
          nodeSelector:   #添加node的标签选择器
            ds: "true"    #与刚才添加的标签相同
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 重新生成
    [root@master test]# kubectl apply -f nginx.yaml
    daemonset.apps/nginx configured
    [root@master test]# kubectl get pods -o wide  #可以看到这次只有一个node节点的了了
    NAME          READY   STATUS    RESTARTS   AGE   IP            NODE   NOMINATED NODE   READINESS GATES
    nginx-mgmx8   1/1     Running   0          22s   10.244.1.63   node   <none>           <none>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 给master也添加标签
    [root@master test]# kubectl label node master ds=true
    node/master labeled
    [root@master test]# kubectl get pods  -o wide  #可以看到两个节点都创建了
    NAME          READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
    nginx-5kl24   1/1     Running   0          47s   10.244.1.65   node     <none>           <none>
    nginx-mwz4w   1/1     Running   0          3s    10.244.0.6    master   <none>           <none>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 去除标签
    [root@master test]# kubectl label node node ds-  #去掉标签 ds- ,- 就是删除的意思
    node/node labeled
    [root@master test]# kubectl get pods  -o wide  #可以看到node节点的pod被删除了
    NAME          READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
    nginx-mwz4w   1/1     Running   0          57s   10.244.0.6   master   <none>           <none>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    五、DaemonSet更新策略

    • 通过上面的添加、删除标签,我们可以知道,在修改节点标签后,DaemonSet会立即向新匹配的节点上添加Pod,同时也会删除不匹配节点上的Pod

    • K8S1.6版本之后,可以在DaemonSet上执行滚动更新,而之后的K8S也将支持节点的可控更新

    • DaemonSet有两种更新策略:

    1. OnDelete:使用此策略时,在更新DaemonSet之后,需要手动删除旧的DaemonSet创建的Pod,然后新的Pod才会被自动创建,与K8S1.6版本之前的方法类似
    2. RollingUpdate:这是默认的更新策略,使用此策略时,在更新DaemonSet之后,旧的Pod将会被自动终止,并且以受控方式自动创建一个新的Pod,更新期间,最多只能有DaemonSet’的一个Pod运行在每个节点上,也就是说每个节点运行的Pod最多只能有一个
    • 查看已经创建的DaemonSet的更新方式:
    #查看.spec.updateStrategy.type 字段,可以看到是RollingUpdate更新策略
    [root@master test]# kubectl get ds nginx -o yaml
    。。。。。。
    spec:
    。。。。。。
      updateStrategy:
        rollingUpdate:
          maxUnavailable: 1   #最大不可用pod数量
        type: RollingUpdate   #使用的更新策略
    。。。。。。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    作业-11.8
    Web前后端漏洞分析与防御
    旅游推荐系统
    Struts.xml 配置文件说明
    leetcode刷题日记:100.Same Tree(相同的树)和101.Symmetric Tree(对称二叉树)
    【Vue入门】MVVM数据双向绑定与Vue的生命周期
    【教学类-19-03】20221127《ABBABB式-规律排序-A4竖版2份》(中班)
    柱状图 kate
    C 语言 math.h 库介绍
    Oracle/PLSQL: NULLIF Function
  • 原文地址:https://blog.csdn.net/rzy1248873545/article/details/125971180