DaemonSet简述
DaemonSet
对象确保所有(或部分)节点运行一个Pod的副本。随着节点被添加到集群中,Pods也被添加到集群中。当节点从集群中移除时,这些Pods将被垃圾收集。删除一个DaemonSet将清除它创建的Pods。
守护进程(daemon进程)是一种特殊的进程,它随着系统的启动而启动,随着系统的关闭而关闭。也有部分在特定情况下才启动,完成任务后自动结束进程
使用场景
DaemonSet这个机制听起来很简单,但对我们有很多帮助作用,各种和节点有关的插件,我们都可以使用Daemon对象来部署,例子:
- 各种网络插件,都必须运行在每一个节点,来保持各个节点上Pod的联通,比如:calico,flannel
- 各种存储插件,必须运行在每一个节点,挂载远程存储目录,操控容器Volume目录,比如:rook-ceph
- 各种监控和日志采集,典型的例子:node-exporter
还有一个稍微复杂的用法,为同一种守护进程部署多个
DaemonSet
;每个具有不同的标志, 但是对不同硬件可能有不同的内资源需求。
创建DaemonSet
1.编写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
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
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
- 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
这个DaemonSet管理的是镜像为fluentd的Pod,从yaml中可以看出DaemonSet和Deployment也是是分相似的,只是没有replicas,刚刚我们讲了DaemonSet会根据节点自动伸缩Pod。也使用selector选择管理携带 name:fluentd-elasticsearch 标签的Pod。
2.运行DaemonSet
[root@ycloud ~]# kubectl apply -f daemonset.yaml
daemonset.apps/fluentd-elasticsearch created
[root@ycloud ~]# kubectl get po -n kube-system -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fluentd-elasticsearch-6976r 1/1 Running 0 85s 192.168.234.207 10.0.0.1 <none> <none>
fluentd-elasticsearch-7hldk 1/1 Running 0 85s 192.168.245.147 10.0.0.2 <none> <none>
fluentd-elasticsearch-gpq4x 1/1 Running 0 85s 192.168.132.190 10.0.0.3 <none> <none>
在 DaemonSet 中的 Pod 模板必须具有一个值为 Always
的 RestartPolicy
。 当该值未指定时,默认是 Always
Fluentd是一个开源的通用日志采集和分发系统,可以从多个数据源采集日志,并将日志过滤和加工后分发到多种存储和处理系统。
Daemon Pod调度
之前的文章中详细讲了对Pod的调度,已经熟悉的同学,一定会想起用,
1.NodeSelector定向调度
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
disktype: ssd
2.通过亲和性匹配节点来创建Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
pod会被调度到携带 disktype: ssd
标签的Pod上
requiredDuringSchedulingIgnoredDuringExecution,硬请求,必须满足; preferredDuringSchdulingIgnoredDuringExecution, 软请求,不一定满足,优先调度到满足指定规则的node
如果根本就没有指定调度,则 DaemonSet Controller
将在所有节点上创建 Pod。
3.容忍和污点
DaemonSet 自动添加 tolerations,定义容忍的污点,在有此污点的节点上也可以调度。
apiVersion: v1
kind: Pod
metadata:
name: toleration
spec:
tolerations:
- key: node.kubernetes.io/unschedulable
operator: Exists
effect: NoSchedule
容忍携带 unschedulable 污点的Node。容忍是允许调度,如果节点上添加了污点,被调度对象没有进行"容忍",就不会被调度。
也可以这么认为,把
污点
当作一个label,携带对应的容忍
就会选择调度,这样应该好理解一点
滚动更新
我们来把这个 DaemonSet 的容器镜像版本到 v2.5.3
[root@ycloud ~]# kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fl
uentd_elasticsearch/fluentd:v2.5.3 -n kube-system --record daemonset.apps/fluentd-elasticsearch image updated
添加–record 参数,指令就会自动添加在 DaemonSet 的 rollout history 里面
也可查询历史操作记录
[root@ycloud ~]# kubectl rollout history ds/fluentd-elasticsearch -n kube-system
daemonset.apps/fluentd-elasticsearch
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.5.3 --namespace=kube-system --record=true
滚动更新和Deployment相似,可以了解这篇文章,不同点是,Deployment直接控制的ReplicaSet对象,DaemonSet对象之间控制的Pod对象
我们可以通过 controllerrevision ,查看是否更新,回滚时通过REVISION,回滚到旧版本
[root@ycloud ~]# kubectl get controllerrevision -n kube-system -l name=fluentd-elasticsearchNAME CONTROLLER REVISION AGE
fluentd-elasticsearch-84d7969c85 daemonset.apps/fluentd-elasticsearch 1 18m
fluentd-elasticsearch-86d54b564b daemonset.apps/fluentd-elasticsearch 2 10m
controllerrevision 专门用来记录 Controller 对象的版本
可以查看下controllervision 的描述信息
[root@ycloud ~]# kubectl describe controllerrevision fluentd-elasticsearch-86d54b564b -n kube-system
Name: fluentd-elasticsearch-86d54b564b
Namespace: kube-system
Labels: controller-revision-hash=86d54b564b
name=fluentd-elasticsearch
Annotations: deprecated.daemonset.template.generation: 2
kubernetes.io/change-cause:
kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.5.3 --namespace=kube-system --re...
API Version: apps/v1
Data:
Spec:
Template:
$patch: replace
Metadata:
Creation Timestamp: <nil>
Labels:
Name: fluentd-elasticsearch
Spec:
Containers:
Image: quay.io/fluentd_elasticsearch/fluentd:v2.5.3
Image Pull Policy: IfNotPresent
Name: fluentd-elasticsearch
Resources:
Limits:
Memory: 200Mi
Requests:
Cpu: 100m
Memory: 200Mi
Termination Message Path: /dev/termination-log
Termination Message Policy: File
Volume Mounts:
Mount Path: /var/log
Name: varlog
Mount Path: /var/lib/docker/containers
Name: varlibdockercontainers
Read Only: true
Dns Policy: ClusterFirst
Restart Policy: Always
Scheduler Name: default-scheduler
Security Context:
Termination Grace Period Seconds: 30
Tolerations:
Effect: NoSchedule
Key: node-role.kubernetes.io/master
Volumes:
Host Path:
Path: /var/log
Type:
Name: varlog
Host Path:
Path: /var/lib/docker/containers
Type:
Name: varlibdockercontainers
Kind: ControllerRevision
Metadata:
Creation Timestamp: 2022-10-03T14:11:16Z
Managed Fields:
API Version: apps/v1
Fields Type: FieldsV1
fieldsV1:
f:data:
f:metadata:
f:annotations:
.:
f:deprecated.daemonset.template.generation:
f:kubectl.kubernetes.io/last-applied-configuration:
f:kubernetes.io/change-cause:
f:labels:
.:
f:controller-revision-hash:
f:name:
f:ownerReferences:
.:
k:{"uid":"a6ae6104-d0ee-4dc2-bf72-650016927fd5"}:
f:revision:
Manager: kube-controller-manager
Operation: Update
Time: 2022-10-03T14:11:16Z
Owner References:
API Version: apps/v1
Block Owner Deletion: true
Controller: true
Kind: DaemonSet
Name: fluentd-elasticsearch
UID: a6ae6104-d0ee-4dc2-bf72-650016927fd5
Resource Version: 36359613
UID: 4a56423a-ddbe-49ca-82e3-14ce24d2e194
Revision: 2
Events: <none>
可以看到,ControllerRevision其实就是
DaemonSet 控制器
每个版本创建的
接下来进行回滚动作
[root@ycloud ~]# kubectl rollout undo daemonset fluentd-elasticsearch --to-revision=1 -n kube-system
daemonset.apps/fluentd-elasticsearch rolled back
[root@ycloud ~]# kubectl get ds -n kube-system -oyaml|grep image
- image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
imagePullPolicy: IfNotPresent
可以看到镜像已经从v2.5.3替换到2.5.2,回滚成功。
结论
我们了解了,DeamonSet对象会确保每个节点都运行一个Pod,如果我们对 node 打上”污点“,DaemonSet会自动添加tolerations,确保该节点可以运行该Pod。这才是DaemonSet对象的精髓所在。