【云原生 | Kubernetes 实战】15、K8s 控制器 Daemonset 入门到企业实战应用

目录

一、DaemonSet 控制器:概念、原理解读

1.1  DaemonSet 概述

1.2  DaemonSet 工作原理:如何管理 Pod ?

1.3  Daemonset 典型的应用场景

1.4  DaemonSet 与 Deployment 的区别

二、DaemonSet 资源清单文件编写技巧 

三、DaemonSet 使用案例:部署日志收集组件 fluentd

四、Daemonset 管理 pod:滚动更新

4.1 查看 daemonset 的滚动更新策略:

4.2 创建带有 RollingUpdate 更新策略的 DaemonSet 


一、DaemonSet 控制器:概念、原理解读

1.1  DaemonSet 概述

        DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

1.2  DaemonSet 工作原理:如何管理 Pod ?

        daemonset 的控制器会监听 kuberntes 的 daemonset 对象、pod 对象、node 对象,这些被监听的对象之变动,就会触发 syncLoop 循环让 kubernetes 集群朝着 daemonset 对象描述的状态进行演进。

1.3  Daemonset 典型的应用场景

  • 在每个节点上运行集群守护进程,比如:glusterd 或 cep。
  • 在每个节点上运行日志收集守护进程,比如:flunentd 、 logstash、filebeat 等。
  • 在每个节点上运行监控守护进程,比如:Prometheus、 Node Exporter 、collectd 等。

        一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。 

1.4  DaemonSet 与 Deployment 的区别

  • Deployment 部署的副本 Pod 会分布在各个 Node 上,每个 Node 都可能运行好几个副本。
  • DaemonSet 的不同之处在于:每个 Node 上最多只能运行一个副本。

        DaemonSet 与 Deployment 非常类似, 它们都能创建 Pod,并且 Pod 中的进程都不希望被终止(例如,Web 服务器、存储服务器)。

        建议为无状态的服务使用 Deployment,比如前端服务。 对这些服务而言,对副本的数量进行扩缩容、平滑升级,比精确控制 Pod 运行在某个主机上要重要得多。 当需要 Pod 副本总是运行在全部或特定主机上,并且当该 DaemonSet 提供了节点级别的功能(允许其他 Pod 在该特定节点上正确运行)时, 应该使用 DaemonSet。

        例如,网络插件通常包含一个以 DaemonSet 运行的组件。 这个 DaemonSet 组件确保它所在的节点的集群网络正常工作。

DaemonSet 概念官方参考文档:DaemonSet | Kubernetes

二、DaemonSet 资源清单文件编写技巧 

# 查看定义 Daemonset 资源需要的字段有哪些
[root@k8s-master01 ~]# kubectl explain daemonset
KIND:     DaemonSet
VERSION:  apps/v1

DESCRIPTION:
     DaemonSet represents the configuration of a daemon set.

FIELDS:
   apiVersion	            # 当前资源使用的 api 版本,跟 VERSION:  apps/v1 保持
     

   kind	                    # 资源类型,跟 KIND:  DaemonSet 保持一致
     

   metadata	                # 元数据,定义 DaemonSet 名字的
     

   spec	                    # 定义容器的


   status	                # 状态信息,不能修改


# 查看 DaemonSet 的 spec 字段如何定义
[root@k8s-master01 ~]# kubectl explain daemonset.spec
KIND:     DaemonSet
VERSION:  apps/v1

RESOURCE: spec 

DESCRIPTION:
     The desired behavior of this daemon set. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

     DaemonSetSpec is the specification of a daemon set.

FIELDS:
   minReadySeconds	        # 当新的 pod 启动几秒种后,再 kill 掉旧的 pod
    

   revisionHistoryLimit	    # 历史版本
     The number of old history to retain to allow rollback. This is a pointer to
     distinguish between explicit zero and not specified. Defaults to 10.

   selector	 -required-      # 用于匹配 pod 的标签选择器  


   template	 -required-      # 定义 Pod 的模板,基于这个模板定义的所有 pod 是一样的 


   updateStrategy	         # daemonset 的升级策略


# 查看 DaemonSet 的 spec.template 字段如何定义?
# 对于 template 而言,其内部定义的就是 pod,pod 模板是一个独立的对象
[root@k8s-master01 ~]# kubectl explain daemonset.spec.template
KIND:     DaemonSet
VERSION:  apps/v1

RESOURCE: template 

DESCRIPTION:
     An object that describes the pod that will be created. The DaemonSet will
     create exactly one copy of this pod on every node that matches the
     template's node selector (or on every node if no node selector is
     specified). More info:
     https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template

     PodTemplateSpec describes the data a pod should have when created from a
     template

FIELDS:
   metadata	


   spec	
······

三、DaemonSet 使用案例:部署日志收集组件 fluentd

下面的 daemonset.yaml 文件描述了一个运行 fluentd-elasticsearch Docker 镜像的 DaemonSet:

# 根据帮助命令编写 
[root@k8s-master01 ~]# kubectl explain ds
[root@k8s-master01 ~]# kubectl explain ds.metadata
[root@k8s-master01 ~]# kubectl explain ds.spec
[root@k8s-master01 ~]# kubectl explain ds.spec.template
[root@k8s-master01 ~]# kubectl explain ds.spec.template.metadata
[root@k8s-master01 ~]# kubectl explain ds.spec.template.spec
[root@k8s-master01 ~]# kubectl explain ds.spec.selector
[root@k8s-master01 ~]# kubectl explain ds.spec.selector.matchLabels
[root@k8s-master01 ~]# kubectl explain ds.spec.template.spec.containers
[root@k8s-master01 ~]# kubectl explain ds.spec.template.spec.containers.resources
[root@k8s-master01 ~]# kubectl explain ds.spec.template.spec.containers.resources.requests
[root@k8s-master01 ~]# kubectl explain ds.spec.template.spec.tolerations
[root@k8s-master01 ~]# kubectl explain ds.spec.template.spec.volumes

# 查看控制节点的污点
[root@k8s-master01 ~]# kubectl describe nodes k8s-master01 | grep Taints
Taints:             node-role.kubernetes.io/control-plane:NoSchedule

# 创建 DaemonSet
[root@k8s-master01 ~]# mkdir daemonset
[root@k8s-master01 ~]# cd daemonset/
[root@k8s-master01 daemonset]# vim daemonset.yaml
apiVersion: apps/v1                        # DaemonSet 使用的 api 版本
kind: DaemonSet                            # 资源类型
metadata:                            
  name: fluentd-elasticsearch              # 资源的名字  
  namespace: kube-system                   # 资源所在的名称空间 
  labels:
    k8s-app: fluentd-logging               # 资源具有的标签
spec:
  selector:                                # 标签选择器
    matchLabels:
      name: fluentd-elasticsearch          # 需与模板中的 pod 标签一致
  template:
    metadata:
      labels:                              # 基于这次模板定义的 pod 具有的标签
        name: fluentd-elasticsearch
    spec:
      tolerations:                         # 定义容忍度,根据实际情况填写。为了让 pod 在控制节点运行
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
      containers:                          # 定义容器
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        imagePullPolicy: IfNotPresent
        resources:                         # 资源配额
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:                      
        - name: varlog
          mountPath: /var/log              # 容器内的挂载目录
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers  # 容器内的挂载目录
          readOnly: true                   # 挂载目录是只读权限
      terminationGracePeriodSeconds: 30    # 优雅的关闭服务
      volumes:
      - name: varlog
        hostPath:
          path: /var/log                   # 基于本地目录创建一个卷
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers # 基于本地目录创建一个卷   

# 更新资源清单文件
[root@k8s-master01 daemonset]# kubectl apply -f daemonset.yaml 

# 查看 daemonset 是否创建成功
[root@k8s-master01 daemonset]# kubectl get ds -n kube-system -l k8s-app=fluentd-logging
NAME                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
fluentd-elasticsearch   3         3         3       3            3                     6m56s

# 查看 pod
[root@k8s-master01 daemonset]# kubectl get pods -n kube-system -o wide -l name=fluentd-elasticsearch
NAME                          READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
fluentd-elasticsearch-97td6   1/1     Running   0          2m13s   10.244.36.89     k8s-node1                 
fluentd-elasticsearch-nsw8s   1/1     Running   0          2m13s   10.244.32.132    k8s-master01              
fluentd-elasticsearch-trggq   1/1     Running   0          2m13s   10.244.169.185   k8s-node2                 

        通过上面可以看到在 k8s 的三个节点均创建了 fluentd 这个 pod,而且 pod 的名字是由 <控制器的名字-随机数> 组成的。

编写 DaemonSet Spec 官方参考文档:DaemonSet | Kubernetes 

四、Daemonset 管理 pod:滚动更新

4.1 查看 daemonset 的滚动更新策略:

[root@k8s-master01 ~]# kubectl explain ds.spec.updateStrategy
KIND:     DaemonSet
VERSION:  apps/v1

RESOURCE: updateStrategy 

DESCRIPTION:
     An update strategy to replace existing DaemonSet pods with new pods.

     DaemonSetUpdateStrategy is a struct used to control the update strategy for
     a DaemonSet.

FIELDS:
   rollingUpdate	
     Rolling update config params. Present only if type = "RollingUpdate".

   type	
     Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is
     RollingUpdate.

     Possible enum values:
     - `"OnDelete"` Replace the old daemons only when it's killed
     - `"RollingUpdate"` Replace the old daemons by new ones using rolling
     update i.e replace them on each node one after the other.

[root@k8s-master01 ~]# kubectl explain ds.spec.updateStrategy.rollingUpdate

DaemonSet 有两种更新策略:

  • OnDelete: 使用 OnDelete 更新策略时,在更新 DaemonSet 模板后,只有当你手动删除老的 DaemonSet pods 之后,新的 DaemonSet Pod 才会被自动创建。跟 Kubernetes 1.6 以前的版本类似。
  • RollingUpdate: 这是默认的更新策略。使用 RollingUpdate 更新策略时,在更新 DaemonSet 模板后, 老的 DaemonSet Pod 将被终止,并且将以受控方式自动创建新的 DaemonSet Pod。 更新期间,最多只能有 DaemonSet 的一个 Pod 运行于每个节点上。

4.2 创建带有 RollingUpdate 更新策略的 DaemonSet 

要启用 DaemonSet 的滚动更新功能,必须设置 .spec.updateStrategy.type 为 RollingUpdate

你可能想设置 .spec.updateStrategy.rollingUpdate.maxUnavailable (默认为 1), .spec.minReadySeconds (默认为 0) 和 .spec.updateStrategy.rollingUpdate.maxSurge (默认为 0)。

下面的 YAML 包含一个 DaemonSet,其更新策略为 'RollingUpdate':

# 将原来的 yaml 简单修改下
[root@k8s-master01 daemonset]# vim daemonset.yaml 
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  updateStrategy:                        # 增加滚动更新内容
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
······
      containers:
      - name: fluentd-elasticsearch
        image: billygoo/tomcat8-jdk8     # 修改镜像
        imagePullPolicy: IfNotPresent
······

[root@k8s-master01 daemonset]# kubectl apply -f daemonset.yaml 
daemonset.apps/fluentd-elasticsearch configured

[root@k8s-master01 daemonset]# kubectl get pods -n kube-system -o wide -l name=fluentd-elasticsearch
NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
fluentd-elasticsearch-g8p97   1/1     Running   0          34s   10.244.32.133    k8s-master01              
fluentd-elasticsearch-jm4qq   1/1     Running   0          33s   10.244.36.92     k8s-node1                 
fluentd-elasticsearch-k6psp   1/1     Running   0          31s   10.244.169.187   k8s-node2                 

# 最后,观察 DaemonSet 最新滚动更新的进度
[root@k8s-master01 ~]# kubectl rollout status daemonset fluentd-elasticsearch -n kube-system 

 当滚动更新完成时,输出结果如下:

DaemonSet 执行滚动更新官方参考文档:对 DaemonSet 执行滚动更新 | Kubernetes 

上一篇文章:【云原生 | Kubernetes 实战】14、K8s 控制器 Statefulset 入门到企业实战应用_Stars.Sky的博客-CSDN博客

下一篇文章:【云原生 | Kubernetes 实战】16、K8s 配置管理中心 ConfigMap 实现微服务配置管理

你可能感兴趣的:(从零开始学,K8s,kubernetes,云原生,docker)