目录
一、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 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
daemonset 的控制器会监听 kuberntes 的 daemonset 对象、pod 对象、node 对象,这些被监听的对象之变动,就会触发 syncLoop 循环让 kubernetes 集群朝着 daemonset 对象描述的状态进行演进。
一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。
DaemonSet 与 Deployment 非常类似, 它们都能创建 Pod,并且 Pod 中的进程都不希望被终止(例如,Web 服务器、存储服务器)。
建议为无状态的服务使用 Deployment,比如前端服务。 对这些服务而言,对副本的数量进行扩缩容、平滑升级,比精确控制 Pod 运行在某个主机上要重要得多。 当需要 Pod 副本总是运行在全部或特定主机上,并且当该 DaemonSet 提供了节点级别的功能(允许其他 Pod 在该特定节点上正确运行)时, 应该使用 DaemonSet。
例如,网络插件通常包含一个以 DaemonSet 运行的组件。 这个 DaemonSet 组件确保它所在的节点的集群网络正常工作。
DaemonSet 概念官方参考文档:DaemonSet | Kubernetes
# 查看定义 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.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
[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 运行于每个节点上。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 实现微服务配置管理