目录
一、概述
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
DaemonSet 的重要作用,是在 Kubernetes 集群里,运行一个 Daemon Pod。 DaemonSet 只管理 Pod 对象,然后通过 nodeAffinity 和 Toleration 这两个调度器参数的功能,包管了每个节点上有且只有一个 Pod
二、适用场景
DaemonSet适用于每个node节点均必要部署一个保卫进程的场景
- 日志采集agent,如fluentd或logstash
- 监控采集agent,如Prometheus Node Exporter,Sysdig Agent,Ganglia gmond
- 分布式集群组件,如Ceph MON,Ceph OSD,glusterd,Hadoop Yarn NodeManager等
- k8s须要运行组件,如网络flannel,weave,calico,kube-proxy等
三、基本操纵
1、官网的DaemonSet资源清单
- apiVersion: apps/v1
- kind: DaemonSet
- metadata:
- name: fluentd-elasticsearch
- namespace: kube-system
- labels:
- k8s-app: fluentd-logging
- spec:
- selector:
- matchLabels:
- name: fluentd-elasticsearch
- template:
- metadata:
- labels:
- name: fluentd-elasticsearch
- spec:
- tolerations:
- # 这些容忍度设置是为了让该守护进程集在控制平面节点上运行
- # 如果你不希望自己的控制平面节点运行 Pod,可以删除它们
- - key: node-role.kubernetes.io/control-plane
- operator: Exists
- effect: NoSchedule
- - key: node-role.kubernetes.io/master
- operator: Exists
- effect: NoSchedule
- containers:
- - name: fluentd-elasticsearch
- image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
- resources:
- limits:
- memory: 200Mi
- requests:
- cpu: 100m
- memory: 200Mi
- volumeMounts:
- - name: varlog
- mountPath: /var/log
- # 可能需要设置较高的优先级类以确保 DaemonSet Pod 可以抢占正在运行的 Pod
- # priorityClassName: important
- terminationGracePeriodSeconds: 30
- volumes:
- - name: varlog
- hostPath:
- path: /var/log
复制代码 2、字段解释
- apiVersion: apps/v1 #指定YAML文件的API版本,这里是apps/v1
- kind: DaemonSet #定义资源类型,这里是DaemonSet
- metadata: #包含DaemonSet的元数据
- name: fluentd-elasticsearch #此DaemonSet的名称
- namespace: kube-system #定义DaemonSet所属的命名空间
- labels: #定义标签
- k8s-app: fluentd-logging #此标签表示该DaemonSet与日志处理有关
- spec: #DaemonSet的规约,包含了DaemonSet的规格和行为的详细配置
- selector: #定义了DaemonSet所管理的Pods的标签选择器,即哪些Pods应该被这个DaemonSet管理。这里matchLabels必须与template.metadata.labels相匹配。
- matchLabels:
- name: fluentd-elasticsearch
- template: #Pod的模板,用于创建和管理DaemonSet下的Pods
- metadata: #Pod的元数据,这里包含了与spec.selector.matchLabels相匹配的标签。
- labels:
- name: fluentd-elasticsearch
- spec: #Pod的规约
- tolerations: #定义了Pod可以容忍的节点污点,允许Pod在带有特定污点的节点上运行。这里配置了两个容忍度,分别针对控制平面节点和标记为master的节点,确保日志采集容器可以在这些特殊节点上运行。
- # 这些容忍度设置是为了让该守护进程集在控制平面节点上运行
- # 如果你不希望自己的控制平面节点运行 Pod,可以删除它们
- - key: node-role.kubernetes.io/control-plane #污点的键,通常表示控制平面节点的标签。
- operator: Exists #Exists,表示只要节点上有与key匹配的污点,无论其值是什么,都将被视为匹配
- effect: NoSchedule #NoSchedule,表示如果节点上存在与key匹配的污点,则默认情况下不允许Pod被调度到该节点。但是,由于这个Pod声明了对该污点的容忍度,所以Pod可以被调度到带有node-role.kubernetes.io/control-plane污点的节点上。
- - key: node-role.kubernetes.io/master #指向标记为master的节点的污点键。
- operator: Exists #只要节点上有与key匹配的污点,无论其值是什么,都将被视为匹配。
- effect: NoSchedule #表明默认情况下,没有相应容忍度的Pod将不能被调度到带有node-role.kubernetes.io/master污点的节点上。但是,由于这个Pod声明了对该污点的容忍度,所以Pod可以被调度到带有node-role.kubernetes.io/master污点的节点上。
- containers: #Pod的容器配置
- - name: fluentd-elasticsearch #容器的名称
- image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2 #指定容器的镜像来源
- resources: #定义了容器的资源限制和请求
- limits: #容器的最大资源限制
- memory: 200Mi
- requests: #容器启动时请求的最小资源量
- cpu: 100m
- memory: 200Mi
- volumeMounts: #容器如何挂载卷
- - name: varlog #指定了要挂载的卷的名称
- mountPath: /var/log #定义了容器内部挂载卷的路径
- # 可能需要设置较高的优先级类以确保 DaemonSet Pod 可以抢占正在运行的 Pod
- # priorityClassName: important
- terminationGracePeriodSeconds: 30 #定义了当Pod被删除时,Kubernetes等待的秒数,以允许容器优雅地关闭。
- volumes: #定义Pod可以使用的卷
- - name: varlog #定义了一个卷的名称
- hostPath: #指定了这个卷的主机路径
- path: /var/log
复制代码 3、编写DaemonSet资源清单
daemonset.yaml
- apiVersion: apps/v1
- kind: DaemonSet
- metadata:
- name: simple-daemonset
- namespace: default
- spec:
- selector:
- matchLabels:
- app: simple-daemonset-app
- template:
- metadata:
- labels:
- app: simple-daemonset-app
- spec:
- containers:
- - name: nginx-container
- image: nginx:latest
- ports:
- - containerPort: 80
复制代码 4、基于yaml创建DaemonSet
- kubectl apply -f daemonset.yaml
复制代码
5、注意点
5.1、必须字段
DaemonSet必要apiVersion、kind 、metadata 和spec字段
以下是DaemonSetYAML定义中最基本的必需字段:
- apiVersion: apps/v1
- kind: DaemonSet
- metadata:
- name: <daemonset-name>
- namespace: <namespace>
- spec:
- selector:
- matchLabels:
- <label-key>: <label-value>
- template:
- metadata:
- labels:
- <label-key>: <label-value>
- spec:
- containers:
- - name: <container-name>
- image: <image-name>
复制代码
- apiVersion:指定YAML文件利用的Kubernetes API版本。对于DaemonSet,通常利用apps/v1。
- kind:指定资源类型,这里应为DaemonSet。
- metadata:
- name:DaemonSet的名称,必须是唯一的。
- namespace:DaemonSet所在的命名空间,默以为default,但猛烈建议明白指定。
- spec:DaemonSet的规格,定义了它的行为和管理的Pod的模板。
- selector:选择器,用于标识DaemonSet管理的Pods。
- matchLabels:一个键值对的映射,用于匹配DaemonSet管理的Pods的标签。这是必须的,用于确保DaemonSet管理的Pods与之关联。
- template:Pod的模板,定义了DaemonSet创建的Pods的结构。
- metadata:Pod的元数据,此中必须包罗与spec.selector.matchLabels相匹配的labels字段。
- spec:Pod的规格,定义了容器、卷、网络设置等。
- containers:一个或多个容器的列表,每个容器都必要定义name和image。
5.2、DaemonSet 对象的名称
DaemonSet 对象的名称必须是一个正当的 DNS 子域名。
- 不能凌驾 253 个字符
- 只能包罗小写字母、数字,以及 '-' 和 '.'
- 必须以字母数字开头
- 必须以字母数字结尾
5.3、.spec.selector 与 .spec.template.metadata.labels之间的关系
.spec.selector 必须与 .spec.template.metadata.labels 匹配。这意味着 matchLabels 中定义的每个键值对都必须存在于 .spec.template.metadata.labels 中,以确保DaemonSet能够正确地选择它所创建的Pods。如果 .spec.selector 中的标签是 .spec.template.metadata.labels 的子集,则这种匹配是有效的。但如果 .spec.template.metadata.labels 中缺少 .spec.selector 中的任何一个标签,或者标签值不同,那么设置将被视为无效,Kubernetes API将拒绝这个设置。
6、查看DaemonSet
6.1、查看DaemonSet列表
- kubectl get ds -n default -o wide
复制代码
NAME:DaemonSet的名称。在这个例子中,DaemonSet的名称是simple-daemonset。
DESIRED:这是DaemonSet期望在集群中运行的Pod数量。对于DaemonSet而言,这通常是集群中节点的数量,因为DaemonSet的目标是在每个节点上运行至少一个Pod的实例。在这个例子中,DESIRED的值是2,是因为集群有两个节点。
CURRENT:这是DaemonSet当前管理的Pod数量。理想环境下,CURRENT的值应该等于DESIRED的值,这意味着DaemonSet已经达到了其目标状态。在这个例子中,CURRENT的值也是2,与DESIRED相匹配。
READY:这是DaemonSet管理的Pod中处于就绪状态的数量。就绪状态(Ready)意味着Pod中的所有容器都已经启动而且健康检查(如果有的话)已通过。在这个例子中,READY的值是2,表明Pod已经准备好并正在运行。
UP-TO-DATE:这是当前正在运行的Pod中与DaemonSet最新模板匹配的数量。当DaemonSet更新其Pod模板时,这个数字可以帮助你跟踪更新进度。在这个例子中,UP-TO-DATE的值是2,意味着所有运行的Pod都利用了最新的模板。
AVAILABLE:这是DaemonSet管理的Pod中可以服务流量的数量。这个数字通常与READY相同,除非某些Pod由于某种缘故起因被标志为不可用。在这个例子中,AVAILABLE的值是2,与READY一致。
NODE SELECTOR:这是DaemonSet利用的节点选择器,它定义了哪些节点可以运行DaemonSet的Pod。表现DaemonSet没有利用节点选择器,它的Pod可以在任何节点上运行。如果NODE SELECTOR包罗特定的键值对,那么DaemonSet的Pod将仅在具有相应标签的节点上运行。
AGE:这是DaemonSet的创建时间,以连续时间的形式给出。在这个例子中,DaemonSet的AGE是65s,意味着它在65秒前创建。
6.2、查看 DaemonSet 控制器所创建的 Pod 副本信息
- kubectl get pods -n default -o wide
复制代码
7、滚动更新
7.1、查看DaemonSet详情
- kubectl get ds -n default
-
- kubectl get daemonset simple-daemonset -n default -o json | jq '.spec.updateStrategy'
复制代码
可以看到DaemonSet支持RollingUpdate滚动更新策略
- RollingUpdate:这是默认的更新策略。利用 RollingUpdate 更新策略时,在更新 DaemonSet 模板后, 老的 DaemonSet Pod 将被终止,而且将以受控方式自动创建新的 DaemonSet Pod。 更新期间,最多只能有 DaemonSet 的一个 Pod 运行于每个节点上。
- maxSurge:定义了在更新过程中可以超出desiredNumberScheduled(期望的Pod数量)的额外Pod数量。在这个例子中,maxSurge设置为0,意味着在更新过程中不会创建凌驾当前期望数量的额外Pod。换句话说,DaemonSet在终止一个旧的Pod之前不会创建一个新的Pod。
- maxUnavailable:定义了在更新过程中可以有多少Pod不可用。maxUnavailable设置为1,意味着在更新过程中,可以有最多1个Pod不可用。这通常发生在旧的Pod被终止,而新的Pod尚未完全启动并变得可用时。
- type :为 RollingUpdate 是要启用 DaemonSet 的滚动更新功能必须设置的
7.2、更新nginx镜像版本
- kubectl set image daemonsets simple-daemonset nginx-container=nginx:1.14.0 -n default
复制代码
7.3、查看滚动更新状态
- kubectl rollout status ds simple-daemonset -n default
复制代码
7.4、查看DS滚动更新过程
- kubectl describe ds simple-daemonset -n default
复制代码
7.5、查看DS滚动更新版本
- kubectl rollout history ds simple-daemonset -n default
复制代码
REVERSION1就是初始版本
8、版本回退
8.1、回滚
- kubectl rollout undo daemonset -n default simple-daemonset --to-revision=1
复制代码
8.2、查看版本回退环境
- kubectl describe ds simple-daemonset -n default
复制代码
9、删除DaemonSet
9.1、直接删除DS
- kubectl delete ds simple-daemonset -n default
复制代码
9.2、基于创建的资源清单删除DS
- kubectl delete -f daemonset.yaml
复制代码
四、DaemonSet调度
1、调度方式
DaemonSet通过kubernetes默认的调度器scheduler会在所有的node节点上运行一个Pod副本,可以通过如下三种方式将Pod运行在部分节点上
- 指定 nodeName 节点运行
- 通过标签运行 nodeSelector
- 通过亲和力调度 node Affinity 和 node Anti-affinity
- 污点与容忍度(Tolerations 和 Taints)
- Priority 和 Preemption (优先级和抢占)
2、指定nodeName节点运行
这种方式通常不用于 DaemonSet,因为 DaemonSet 的目标是在尽大概多的节点上运行 Pod 副本。但是可以通过 .spec.nodeName 来指定特定节点运行 Pod。
2.1、原理机制
- 当为 Pod 指定了具体的 nodeName 后,Kubernetes 调度器将跳过调度过程,直接将 Pod 分配给指定的节点。
- 这种方式通常用于测试目的或者在特殊场景下利用,例如当您必要确保某个 Pod 在特定节点上运行时。
2.2、示例
2.2.1、创建一个DaemonSet资源清单,指定nodeName
[code]cat |