目录DaemonSet简介DaemonSet使用场景DaemonSet创建查看DaemonSet更新DaemonSet删除DaemonSet其它使用场景容忍性Toleration使用节...
目录
DaemonSet 简介DaemonSet 使用场景
DaemonSet 创建
查看 DaemonSet
更新 DaemonSet
删除 DaemonSet
其它使用场景
容忍性 Toleration 使用
节点亲和性 nodeAffinity 使用
总结
DaemonSet 简介
DaemonSet 的主要作用,是在 Kubernetes 集群里,运行一个 Daemon Pod。 DaemonSet 只管理 Pod 对象,然后通过 nodeAffinity 和 Toleration 这两个调度器参数的功能,保证了每个节点上有且只有一个 Pod。
DaemonSet 是一种面向特定应用场景的 Pod 控制器,尽管它也可以管理 Pod 的多个副本,但它主要用于保证一个 Node 上只运行一个 Pod 的场景:
DaemonSet 使用场景
每个节点上只有一个这样的 Daemon Pod 实例,然后当有新的节点加入 Kubernetes 集群后,该 Pod 会自动地在新节点上被创建出来。当旧节点被删除后,它上面的 Pod 也会相应地被回收掉。
Daemon Pod 的意义确实是非常重要的。比如的作用:
网络插件的 Agent 组件,都必须运行在每一个节点上,用来处理这个节点上的容器网络。存储插件的 Agent 组件,也必须运行在每一个节点上,用来在这个节点上挂载远程存储目录,操作容器的 Volume 目录,比如:glusterd、ceph。
监控组件和日志组件,也必须运行在每一个节点上,负责这个节点上的监控信息和日志搜集,比如:fluentd、logstash、Prometheus 等。
DaemonSet 创建
k8s 环境搭建参考网上教程,这里就不再赘述了。
先来个简单的例子快速体验 DaemonSet 控制器是如何应用的。
一个简单的 DaemonSet 配置如下:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemonset
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.17.0
初步看,这份配置跟 Deployment 基本类似,唯一一个显著的差异是 DaemonSet 不需要指定副本数,因为它的副本数取决于工作节点数。
DaemonSet 配置中 spec.selector 和 spec.template 作用我们已在介绍 Deployment 时介绍过,在此不再赘述。
该份配置将创建一个 DaemonSet 对象,然后 DaemonSet 控制器会根据该对象信息分别在每个节点上创建一个 Pod 副本。
接下来使用kubectl create命令将该配置提次给 kube-apiserver,如下所示:
[root@k8s-master]# kubectl create -f daemonset.yaml daemonset.apps/nginx-daemonset created
查看 DaemonSet
首先查看刚刚创建的 DaemonSet 对象:
[root@k8s-master]# kubectl get daemonset NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE nginx-daemonset 3 3 3 3 3 <none> 1m3s
命令行输出中各字段含义如下:
NAME: DaemonSet 对象名称,同配置中的 metadata.name;DESIRED:需求副本个数,由于没有刻意筛选节点,所以副本个数等同于节点个数(默认);
CURRENT:当前已创建的副本个数;
READY:处于 Rehttp://www.cppcns.comady 状态的副本个数;
UP-TO-DATE:已按最新 Pod 模版创建的 Pod 个数;
AVAILABLE:可用的副本个数;
NODE SELECTOR:节点选择器,本例中我们没有选择,值为空;
AGE:创建至今经历的时间。
上面的字段中,除了 NODE SELECTOR 以外,我们已在前面的章节中介绍过。其实 Node Selector 并不是 DaemonSet 对象特有的配置android,它是 Pod 模版中用于为 Pod 匹配节点的配置,DaemonSet 控制器使用该 Node Selector 来筛选需要创建副本的节点,如果没有指定,则默认选择全部节点。
接着,查看 DaemonSet 控制器所创建的 Pod 副本信息:
[root@k8s-master]# kubectl get pods -o wide NAME android READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-daemonset-66dbc 1/1 Running 0 5m13s 10.135.3.2 k8s-master <none> <none> nginx-daemonset-akpdg 1/1 Running 0 5m13s 10.135.1.2 k8s-node1 <none> <none> nginx-daemonset-l3wnd 1/1 Running 0 5m13s 10.135.2.2 k8s-node2 <none> <none>
可以看到,在每个节点上均创建了一个副本,是符合预期的。
更新 DaemonSet
下面我们适当的调整下 Pod 部署策略,只希望 Pod 运行在名为 k8s-node 的节点上,这样我们只需要配置 DaemonSet 对象的 spec.template.spec.nodeSelector 来选择节点即可。
在 k8s-node 的节点中存在一个标识节点的 label:
kubernetes.io/hostname: k8s-node1
使用 kubectl edit 命令修改配置的 spec.template.spec.nodeSelector 参数如下:
apiVersion: apps/v1
kind: DaemonSet
metadata:
...
spec:
...
template:
...
spec:
...
nodeSelector:
kubernetes.io/hostname: k8s-node1
然后再次观察 DaemonSet 对象和 Pod 副本:
[root@k8s-master]# kubectl get daemonsets NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR 编程 AGE nginx-daemonset 1 1 1 1 1 kubernetes.io/hostname=k8s-node1 37m [root@k8s-master]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-daemonset-66gk2 1/1 Running 0 10s 10.135.2.3 k8s-node1 <none> <none>
可以发现 DaemonSet 状态中,NODE SELECTOR 正确地展示了上面的修改,而且需求的 Pod 副本数也变成了 1 个,符合预期。
原来运行的 3 个 Pod 副本减少到 1 个,而且只在我们配置选定的节点(k8s-node1)上运行。
删除 DaemonSet
像其他 Pod 控制器一样,当删除 DaemonSet 对象时,其所管理的 Pod 默认也会被删除,操作如下所示:
[root@k8s-master ~]# kubectl delete daemonsets nginx-daemonset daemonset.apps "nginx-daemonset" deleted [root@k8s-master ~]# kubectl get pods No resources found in default namespace.
其它使用场景
容忍性 Toleration 使用
DaemonSet 还会给这个 Pod 自动加上另外一个与调度相关的字段,叫作 tolerations。这个字段意味着这个 Pod,会“容忍”(Toleration)某些 Node 的“污点”(Taint)。
Toleration 使用 yaml 配置如下:
apiVersion: v1
kind: Pod
metadata:
name: with-toleration
spec:
tolerations:
- key: node.kubernetes.io/unschedulable
operator: Exists
effect: NoSchedule
在正常情况下,被标记了 unschedulable“污点”的 Node,是不会有任何 Pod 被调度上去的(effect: NoSchedule)。
可是,DaemonSet 自动地给被管理的 Pod 加上了这个特殊的 Toleration,就使得这些 Pod 可以忽略这个限制,继而保证每个节点上都会被调度一个 Pod。
当然,如果这个节点有故障的话,这个 Pod 可能会启动失败,而 DaemonSet 则会始终尝试下去,直到 Pod 启动成功。
主要作用:
通过这样一个 Toleration,调度器在调度这个 Pod 的时候,就会忽略当前节点上的“污点”,从而成功地将一些组件调度到这台机器上启动起来。
这种机制,正是我们在部署 Kubernetes 集群的时候,能够先部署 Kubernetes 本身、再部署网络插件的根本原因:因为当时我们所创建的 Weave 的 YAML,实际上就是一个 DaemonSet。
节点亲和性 nodeAffinity 使用
正常情况下 DaemonSet Controller 会在创建 Pod 的时候,自动在这个 Pod 的 API 对象里,加上这样一个 nodeAffinity 定义。
在这个 Pod 里,声明了一个 spec.affinity 字段,然后定义了一个 nodeAffinity。其中,spec.affinity 字段,是 Pod 里跟调度相关的一个字段。
nodeAffinity 使用 yaml 配置如下:
apiVersion: v1
kind: Pod
metadata:
name: demo-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: metadata.name
operator: In
values:
- demo-node
以上关键参数含义:
requiredDuringSchedulingIgnoredDuringExecution 这个代表 nodeAffinity 必须在每次调度的时候予以考虑,同时,这也意味着可以设置在某些情况下不考虑这个 nodeAffinity;这个 Pod,将来只允许运行在“metadata.name”是“demo-node”的节点上。
总结
DaemonSet 其实就是依靠 nodeAffinity 和 Toleration 实现的。这是一种不需要增加设计结构,而直接使用标签等方式完成的 Daemon 进程。这样的结构非常符合 Kubernetes 的控制器模式,正所谓一切皆对象。
以上就是k8s控制器DaemonSet理解的详细内容,更多关于k8s控制器DaemonSet的资料请关注我们其它相关文章!










