K8SDaemonSet
Posted 礁之
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K8SDaemonSet相关的知识,希望对你有一定的参考价值。
文章目录
一、DaemonSet概述
- DaemonSet即守护进程集,与守护进程类似。DaemonSet确保在符合匹配条件的节点上部署运行
一个Pod
- 当有新的节点加入时,也会为新节点添加Pod,同样当节点从集群移除时,运行的Pod也会被收回,而删除DaemonSet会删除DaemonSet创建的所有Pod
- 下面是使用DaemonSet的一些场景:
运行集群存储的daemon
:例如每个节点上运行Clusterd、Ceph(分布式存储)等每个节点运行日志收集的daemon
:例如Fluentd、Logstash等每个节点运行监控的daemon
:例如Prometheus Node Exporter、Collectd、Datadog等每个节点运行的网络插件的dameon
:例如Flannel、Calico等
- DaemonSet的主要特征:
- 创建的Pod运行在K8S集群的每一个节点上
- 每个节点只会存在一个DaemonSet创建的Pod实例
- 如果有新节点
- 在部署K8S时,其实已经创建了两个DaemonSet,分别是
flannel
和proxy
[root@master test]# kubectl get daemonsets.apps -A
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system kube-flannel-ds 2 2 2 2 2 <none> 11d
kube-system kube-proxy 2 2 2 2 2 kubernetes.io/os=linux 11d
- 注意
从1.6开始,DaemonSet控制器将不会再把Pod调度到主节点上。
这是因为主节点上有
node-role.kubernetes.io/master
及NoSchedule
污点,而Pod没有容忍该污点,所以不会调度到主节点上。官方已经不建议,那么如果没有必要就不要向主机调度Pod了,除非是出于监控或者指标收集等原因。
二、DaemonSet定义
- 创建一个DaemonSet的yaml大致如下,这是Prometheus部署时使用的node-exporter用于监控节点信息
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: kube-system
labels:
k8s-app: node-exporter
spec:
selector:
matchLabels:
k8s-app: node-exporter
template:
metadata:
labels:
k8s-app: node-exporter
spec:
containers:
- image: prom/node-exporter
name: node-exporter
ports:
- containerPort: 9100
protocol: TCP
name: http
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: node-exporter
name: node-exporter
namespace: kube-system
spec:
ports:
- name: http
port: 9100
nodePort: 31672
protocol: TCP
type: NodePort
selector:
k8s-app: node-exporter
- 其中必须字段:
和其他所有的K8S资源配置相同,必须字段有:
apiVersion
、kind
、metadata
、spec
- Pod模板:
spec唯一需要的字段是
spec.template
,除了必须字段外,在DaemonSet中的Pod模板必须指定合理的标签。并且还需要具有一个RestartPolicy(重启策略)
,默认策略是Always
注释:spec.template是一个Pod模板,与Pod具有相同的配置方式,但是她并没有
apiVersion
和kind
字段
- Pod Selector:
Pod Selector代表的字段是
spec.selector
,与其他资源的spec.selector字段作用相同。spec.selector
表示一个对象,由如下两个字段组成:
matchLabels
:用于匹配符合条件的PodmatchExpressions
:允许构建更加复杂的Selector如果上面的两个字段同时指定是,结果表示的是
逻辑与(AND)
的关系注意:
spec.selector
必须与spec.template.metadata.labels
相匹配,如果没有指定,默认是等价的,如果这两个的配置不匹配,则会被API拒绝,也就会报错
三、创建DaemonSet
- 下面创建一个nginx的DaemonSet
[root@master test]# cat nginx.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx
spec:
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.2
ports:
- containerPort: 80
name: nginx
dnsPolicy: ClusterFirst
restartPolicy: Always
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
——————————————————————————————————————————————————————————————————————————————
添加'容忍'即可使DaemonSet可以在主节点上创建Pod,字段是'spec.template.spec.tolerations'
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
——————————————————————————————————————————————————————————————————————————————
- 这里有一个字段
spec.template.spec.dnsPolicy
,这个字段可以指定DNS策略
无策略(None)
:清除Pod预设的DNS配置,当dnsPolicy
设置成这个值时,K8S不会为Pod预先加载任何逻辑用于判定得到的DNS配置默认预设(Default)
:设置为这个值时,Pod里面的DNS配置会继承宿主机上的配置,该Pod的DNS配置与宿主机的完全相同集群优先(ClusterFirst)
:与Default策略相反,设置为这个值时,会预先使用Kube-dns或者CoreDNS的信息当作预设参数写到创建Pod的DNS配置中ClusterFirstWithHostNet
:设置为这个值时,宿主机会与K8S共存,共同使用hostNetwork
与kube-dns
作为创建Pod的预设配置
- 创建
[root@master test]# kubectl apply -f nginx.yaml
daemonset.apps/nginx created
[root@master test]# kubectl get node #先看一下,这里有两个节点
NAME STATUS ROLES AGE VERSION
master Ready master 11d v1.18.0
node Ready <none> 11d v1.18.0
[root@master test]# kubectl get pods #因为添加了容忍,所以两个节点都创建pod了
NAME READY STATUS RESTARTS AGE
nginx-krr85 1/1 Running 0 3m19s
nginx-q7wz9 1/1 Running 0 3m19s
四、DaemonSet指定节点部署Pod
- 如果指定了
spec.template.spec.nodeSelector
字段,那么DaemonSet控制器将在与Node Selector(节点选择器)
匹配的节点上创建Pod,例如:
只想部署Pod到磁盘为SSD的节点上
- 如果想要指定节点部署Pod,我们需要提前给节点定义
标签Label
,例如:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector: #此字段同样适用于其他资源控制器
disktype: ssd
注意:这个标签名称、标签值都是自定义的
- 下面通过添加节点标签指定pod运行的节点
[root@master ~]# kubectl label node node ds=true #节点名称叫node
node/node labeled
[root@master ~]# kubectl get node --show-labels | grep ds=true #可以看到标签加了一个ds=true
node Ready <none> 13d v1.18.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ds=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=node,kubernetes.io/os=linux
- 下面修改yaml文件
[root@master test]# cat nginx.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx
spec:
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.2
ports:
- containerPort: 80
name: nginx
dnsPolicy: ClusterFirst
restartPolicy: Always
tolerations: #容忍不能去掉,不然master无法创建pod
- key: node-role.kubernetes.io/master
effect: NoSchedule
nodeSelector: #添加node的标签选择器
ds: "true" #与刚才添加的标签相同
- 重新生成
[root@master test]# kubectl apply -f nginx.yaml
daemonset.apps/nginx configured
[root@master test]# kubectl get pods -o wide #可以看到这次只有一个node节点的了了
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-mgmx8 1/1 Running 0 22s 10.244.1.63 node <none> <none>
- 给master也添加标签
[root@master test]# kubectl label node master ds=true
node/master labeled
[root@master test]# kubectl get pods -o wide #可以看到两个节点都创建了
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-5kl24 1/1 Running 0 47s 10.244.1.65 node <none> <none>
nginx-mwz4w 1/1 Running 0 3s 10.244.0.6 master <none> <none>
- 去除标签
[root@master test]# kubectl label node node ds- #去掉标签 ds- ,- 就是删除的意思
node/node labeled
[root@master test]# kubectl get pods -o wide #可以看到node节点的pod被删除了
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-mwz4w 1/1 Running 0 57s 10.244.0.6 master <none> <none>
五、DaemonSet更新策略
-
通过上面的添加、删除标签,我们可以知道,在修改节点标签后,DaemonSet会立即向新匹配的节点上添加Pod,同时也会删除不匹配节点上的Pod
-
在
K8S1.6版本
之后,可以在DaemonSet上执行滚动更新,而之后的K8S也将支持节点的可控更新 -
DaemonSet有两种更新策略:
OnDelete
:使用此策略时,在更新DaemonSet之后,需要手动删除旧的DaemonSet创建的Pod,然后新的Pod才会被自动创建,与K8S1.6版本之前的方法类似RollingUpdate
:这是默认的更新策略,使用此策略时,在更新DaemonSet之后,旧的Pod将会被自动终止,并且以受控方式自动创建一个新的Pod,更新期间,最多只能有DaemonSet’的一个Pod运行在每个节点上,也就是说每个节点运行的Pod最多只能有一个
- 查看已经创建的DaemonSet的更新方式:
#查看.spec.updateStrategy.type 字段,可以看到是RollingUpdate更新策略
[root@master test]# kubectl get ds nginx -o yaml
。。。。。。
spec:
。。。。。。
updateStrategy:
rollingUpdate:
maxUnavailable: 1 #最大不可用pod数量
type: RollingUpdate #使用的更新策略
。。。。。。
以上是关于K8SDaemonSet的主要内容,如果未能解决你的问题,请参考以下文章