K8SDaemonSet

Posted 礁之

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K8SDaemonSet相关的知识,希望对你有一定的参考价值。

文章目录

一、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.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
  • 其中必须字段:

和其他所有的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
——————————————————————————————————————————————————————————————————————————————  
  • 这里有一个字段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

四、DaemonSet指定节点部署Pod

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

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

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

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

  • 下面通过添加节点标签指定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
  • 下面修改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"    #与刚才添加的标签相同
  • 重新生成
[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>
  • 给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>
  • 去除标签
[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>

五、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   #使用的更新策略
。。。。。。

以上是关于K8SDaemonSet的主要内容,如果未能解决你的问题,请参考以下文章

K8SDaemonSet

pod 调度详解:亲和污点和容忍

pod 调度详解:亲和污点和容忍

校招污点公司名单

校招污点公司名单

再战 k8s(11):污点容忍,亲和性