一个Pod
运行集群存储的daemon
:例如每个节点上运行Clusterd、Ceph(分布式存储)等每个节点运行日志收集的daemon
:例如Fluentd、Logstash等每个节点运行监控的daemon
:例如Prometheus Node Exporter、Collectd、Datadog等每个节点运行的网络插件的dameon
:例如Flannel、Calico等
- 创建的Pod运行在K8S集群的每一个节点上
- 每个节点只会存在一个DaemonSet创建的Pod实例
- 如果有新节点
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了,除非是出于监控或者指标收集等原因。
---
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
spec唯一需要的字段是
spec.template
,除了必须字段外,在DaemonSet中的Pod模板必须指定合理的标签。并且还需要具有一个RestartPolicy(重启策略)
,默认策略是Always
注释:spec.template是一个Pod模板,与Pod具有相同的配置方式,但是她并没有
apiVersion
和kind
字段
Pod Selector代表的字段是
spec.selector
,与其他资源的spec.selector字段作用相同。spec.selector
表示一个对象,由如下两个字段组成:
matchLabels
:用于匹配符合条件的PodmatchExpressions
:允许构建更加复杂的Selector如果上面的两个字段同时指定是,结果表示的是
逻辑与(AND)
的关系注意:
spec.selector
必须与spec.template.metadata.labels
相匹配,如果没有指定,默认是等价的,如果这两个的配置不匹配,则会被API拒绝,也就会报错
[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
spec.template.spec.nodeSelector
字段,那么DaemonSet控制器将在与Node Selector(节点选择器)
匹配的节点上创建Pod,例如:只想部署Pod到磁盘为SSD的节点上
标签Label
,例如:containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector: #此字段同样适用于其他资源控制器
disktype: ssd
注意:这个标签名称、标签值都是自定义的
[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
[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>
[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会立即向新匹配的节点上添加Pod,同时也会删除不匹配节点上的Pod
在K8S1.6版本
之后,可以在DaemonSet上执行滚动更新,而之后的K8S也将支持节点的可控更新
DaemonSet有两种更新策略:
OnDelete
:使用此策略时,在更新DaemonSet之后,需要手动删除旧的DaemonSet创建的Pod,然后新的Pod才会被自动创建,与K8S1.6版本之前的方法类似RollingUpdate
:这是默认的更新策略,使用此策略时,在更新DaemonSet之后,旧的Pod将会被自动终止,并且以受控方式自动创建一个新的Pod,更新期间,最多只能有DaemonSet’的一个Pod运行在每个节点上,也就是说每个节点运行的Pod最多只能有一个
#查看.spec.updateStrategy.type 字段,可以看到是RollingUpdate更新策略
[root@master test]# kubectl get ds nginx -o yaml
。。。。。。
spec:
。。。。。。
updateStrategy:
rollingUpdate:
maxUnavailable: 1 #最大不可用pod数量
type: RollingUpdate #使用的更新策略
。。。。。。