一、认识DaemonSet控制器
DaemonSet是Pod控制器的又一种实现,用于在集群中的全部节点上同时运行一份指定的Pod资源副本,后续加入集群的工作节点也会自动创建一个相关的Pod对象,当从集群移除节点时,此类Pod对象也将被自动回收而无需重建。管理员也可以使用节点选择器及节点标签指定仅在部分具有特定特征的节点上运行指定的Pod对象。
DaemonSet控制器是一种特殊的控制器,它有特定的应用场景,通常运行那些执行系统级操作任务的应用,其应用场景具体如下:
1)运行集群存储的守护进程,如在各个节点上运行glusterd或ceph
2)在各个节点上运行日志收集守护进程,如fluentd和logstash
3)在各个节点上运行监控系统的代理守护进程,如Prometheus Node Exporter、Collectd、Datadog agent等
二、DaemonSet控制器实验
1)编写DaemonSet控制器的yaml文件
]# cat daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
labels:
app: filebeat
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
labels:
app: filebeat
spec:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.5-alpine
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: ["/bin/sh","-c"," echo hello filebeat > /tmp/filebeat.txt"]
env:
- name: LOG_LEVEL
value: info
- name: REDIS_HOST
value: node1:6379
]# kubectl apply -f daemonset.yaml
daemonset.apps/filebeat-ds created
2)查看Pod信息
]# kubectl get pods -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
filebeat-ds-9htfd 1/1 Running 0 86s 10.244.1.48 node1 <none> <none> app=filebeat,controller-revision-hash=6d454c8f79,pod-template-generation=1
filebeat-ds-jtt7z 1/1 Running 0 86s 10.244.0.18 master <none> <none> app=filebeat,controller-revision-hash=6d454c8f79,pod-template-generation=1
filebeat-ds-vnnz8 1/1 Running 0 86s 10.244.2.17 node2 <none> <none> app=filebeat,controller-revision-hash=6d454c8f79,pod-template-generation=1
可以看到集群中每一个上都运行了一个DaemonSet控制器的Pod副本
3)进入Pod内部查看
]# kubectl exec filebeat-ds-9htfd -it -- /bin/sh
/ # cat /tmp/filebeat.txt
hello filebeat
/ # printenv | grep -Ei "log_level|redis_host"
LOG_LEVEL=info
REDIS_HOST=node1:6379
/ # exit
设定的环境变量信息的确存在
4)查看DaemonSet控制器的详细信息
]# kubectl get ds -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
filebeat-ds 3 3 3 3 3 <none> 8m10s filebeat ikubernetes/filebeat:5.6.5-alpine app=filebeat
]# kubectl describe ds filebeat-ds
Name: filebeat-ds
Selector: app=filebeat
Node-Selector: <none>
Labels: app=filebeat
Annotations: deprecated.daemonset.template.generation: 1
Desired Number of Nodes Scheduled: 3
Current Number of Nodes Scheduled: 3
Number of Nodes Scheduled with Up-to-date Pods: 3
Number of Nodes Scheduled with Available Pods: 3
Number of Nodes Misscheduled: 0
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=filebeat
Containers:
filebeat:
Image: ikubernetes/filebeat:5.6.5-alpine
Port: <none>
Host Port: <none>
Environment:
LOG_LEVEL: info
REDIS_HOST: node1:6379
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 8m24s daemonset-controller Created pod: filebeat-ds-9htfd
Normal SuccessfulCreate 8m24s daemonset-controller Created pod: filebeat-ds-vnnz8
Normal SuccessfulCreate 8m24s daemonset-controller Created pod: filebeat-ds-jtt7z
集群状态描述:
DESIRED:需要的Pod个数
CURRENT:当前已存在的Pod个数
READY:就绪的Pod个数
UP-TO-DATE:最新创建的Pod个数
AVAILABLE:可用的Pod个数
NODE SELECTOR:节点选择标签
从上面的信息可以看到,Node-Selector字段的值为空,它表示需要运行于集群中的每个节点之上。而当前集群的节点数量为3,因此,其期望的Pod副本数(Desired Number of Nodes Scheduled)为3,而当前也已经成功的创建了3个相关的Pod对象。
三、更新DaemonSet对象
DaemonSet自Kubernetes 1.6版本起也开始支持更新机制,相关的配置定义在spec.update-Strategy嵌套字段中。目前,它支持RollingUpdate(滚动更新)和OnDelete(删除时更新)两种更新策略,滚动更新为默认的更新策略,工作逻辑类似于Deployment控制器,不过,仅支持使用macUnavailabe属性定义最大不可用的Pod资源副本数(默认值为1),而删除时更新的方式则是在删除相应的节点的Pod资源后重建并更新为新版本。
]# kubectl set image ds filebeat-ds filebeat=ikubernetes/filebeat:5.6.6-alpine
daemonset.apps/filebeat-ds image updated
]# kubectl get ds -o wide -w
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
filebeat-ds 3 3 3 3 3 <none> 22m filebeat ikubernetes/filebeat:5.6.5-alpine app=filebeat
filebeat-ds 3 3 3 3 3 <none> 22m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 3 0 3 <none> 22m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 2 0 2 <none> 22m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 2 1 2 <none> 22m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 3 1 3 <none> 22m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 2 1 2 <none> 23m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 2 2 2 <none> 23m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 3 2 3 <none> 23m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 2 2 2 <none> 23m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 2 3 2 <none> 23m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
filebeat-ds 3 3 3 3 3 <none> 23m filebeat ikubernetes/filebeat:5.6.6-alpine app=filebeat
]# kubectl get pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
filebeat-ds-9htfd 1/1 Running 0 22m 10.244.1.48 node1 <none> <none>
filebeat-ds-jtt7z 1/1 Running 0 22m 10.244.0.18 master <none> <none>
filebeat-ds-vnnz8 1/1 Running 0 22m 10.244.2.17 node2 <none> <none>
filebeat-ds-jtt7z 1/1 Terminating 0 22m 10.244.0.18 master <none> <none>
filebeat-ds-jtt7z 0/1 Terminating 0 22m 10.244.0.18 master <none> <none>
filebeat-ds-jtt7z 0/1 Terminating 0 22m 10.244.0.18 master <none> <none>
filebeat-ds-jtt7z 0/1 Terminating 0 22m 10.244.0.18 master <none> <none>
filebeat-ds-pchxh 0/1 Pending 0 0s <none> <none> <none> <none>
filebeat-ds-pchxh 0/1 Pending 0 0s <none> master <none> <none>
filebeat-ds-pchxh 0/1 ContainerCreating 0 0s <none> master <none> <none>
filebeat-ds-pchxh 1/1 Running 0 20s 10.244.0.19 master <none> <none>
filebeat-ds-9htfd 1/1 Terminating 0 22m 10.244.1.48 node1 <none> <none>
filebeat-ds-9htfd 0/1 Terminating 0 23m <none> node1 <none> <none>
filebeat-ds-9htfd 0/1 Terminating 0 23m <none> node1 <none> <none>
filebeat-ds-9htfd 0/1 Terminating 0 23m <none> node1 <none> <none>
filebeat-ds-bhxl5 0/1 Pending 0 0s <none> <none> <none> <none>
filebeat-ds-bhxl5 0/1 Pending 0 0s <none> node1 <none> <none>
filebeat-ds-bhxl5 0/1 ContainerCreating 0 0s <none> node1 <none> <none>
filebeat-ds-bhxl5 1/1 Running 0 19s 10.244.1.49 node1 <none> <none>
filebeat-ds-vnnz8 1/1 Terminating 0 23m 10.244.2.17 node2 <none> <none>
filebeat-ds-vnnz8 0/1 Terminating 0 23m 10.244.2.17 node2 <none> <none>
filebeat-ds-vnnz8 0/1 Terminating 0 23m 10.244.2.17 node2 <none> <none>
filebeat-ds-vnnz8 0/1 Terminating 0 23m 10.244.2.17 node2 <none> <none>
filebeat-ds-h2krd 0/1 Pending 0 0s <none> <none> <none> <none>
filebeat-ds-h2krd 0/1 Pending 0 0s <none> node2 <none> <none>
filebeat-ds-h2krd 0/1 ContainerCreating 0 0s <none> node2 <none> <none>
filebeat-ds-h2krd 1/1 Running 0 19s 10.244.2.18 node2 <none> <none>
]# kubectl describe ds filebeat-ds
Name: filebeat-ds
Selector: app=filebeat
Node-Selector: <none>
Labels: app=filebeat
Annotations: deprecated.daemonset.template.generation: 2
Desired Number of Nodes Scheduled: 3
Current Number of Nodes Scheduled: 3
Number of Nodes Scheduled with Up-to-date Pods: 3
Number of Nodes Scheduled with Available Pods: 3
Number of Nodes Misscheduled: 0
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=filebeat
Containers:
filebeat:
Image: ikubernetes/filebeat:5.6.6-alpine
Port: <none>
Host Port: <none>
Environment:
LOG_LEVEL: info
REDIS_HOST: node1:6379
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 25m daemonset-controller Created pod: filebeat-ds-9htfd
Normal SuccessfulCreate 25m daemonset-controller Created pod: filebeat-ds-vnnz8
Normal SuccessfulCreate 25m daemonset-controller Created pod: filebeat-ds-jtt7z
Normal SuccessfulDelete 3m7s daemonset-controller Deleted pod: filebeat-ds-jtt7z
Normal SuccessfulCreate 2m59s daemonset-controller Created pod: filebeat-ds-pchxh
Normal SuccessfulDelete 2m39s daemonset-controller Deleted pod: filebeat-ds-9htfd
Normal SuccessfulCreate 2m37s daemonset-controller Created pod: filebeat-ds-bhxl5
Normal SuccessfulDelete 2m18s daemonset-controller Deleted pod: filebeat-ds-vnnz8
Normal SuccessfulCreate 2m16s daemonset-controller Created pod: filebeat-ds-h2krd
从上面的命令结果中可以看出,默认的滚动更新策略是删除一个工作节点上的Pod资源,待其新版本Pod资源重建完成后再开始操作另一个工作节点上的Pod资源。DaemonSet控制器的滚动更新机制也可以借助于minReadySeconds字段控制滚动节奏,必要时可以执行暂停和继续操作,因此它也能够设计为金丝雀发布机制。另外,故障得更新操作也可以进行回滚,包括回滚至revision历史记录中的任何一个指定版本。