k8s–基础–19–DaemonSet
1、介绍
- 是个控制器
- 能够确保k8s的所有节点都运行一个相同的pod副本,假设这个pod名称为pa
- 当增加node节点时,这个节点会自动创建一个pa副本
- 当删除node节点时,pa副本会自动删除
- 删除daemonset会删除它们创建的pod
1.1、使用场景
- 需要在每一个node节点运行一个存储服务,例如gluster,ceph
- 需要在每一个node节点运行一个日志收集服务,例如fluentd,logstash
- 需要在每一个node节点运行一个监控服务,例如Prometheus Node Exporter,zabbix agent等
1.2、用法
1.2.1、简单用法
在所有的节点上都启动一个 DaemonSet
1.2.2、复杂用法
单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志,并且对不同硬件类型具有不同的内存、CPU要求。
2、创建DaemonSet
2.1、创建脚本
vi /root/test2/daemonset-nginx.yaml
内容
apiVersion: apps/v1
kind: DaemonSet
metadata:
# DaemonSet的名称
name: daemonset-nginx
# 命名空间
namespace: kube-system
labels:
# DaemonSet 标签
la-nginx: daemonset-nginx
spec:
# 标签选择器
selector:
matchLabels:
# 使用 k2-nginx: daemonset-nginx2 标签的template
k2-nginx: daemonset-nginx2
# 定义模板
template:
metadata:
labels:
# 定义标签
k2-nginx: daemonset-nginx2
spec:
# 定义容忍度,容忍哪些污点
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
# 定义容器
containers:
- name: c-nginx
image: nginx
# 定义资源
resources:
# 最大CPU和内存
limits:
cpu: 200m
memory: 200Mi
# 最小CPU和内存
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
# 引入名称为nginx-volume1的存储定义
- name: nginx-volume1
# 容器存储卷目录
mountPath: /usr/share/nginx/html
- name: nginx-volume2
mountPath: /usr/share/nginx/conf
readOnly: true
# pod中断所需的时间
terminationGracePeriodSeconds: 30
volumes:
# 存储卷名称
- name: nginx-volume1
# 存储卷类型
hostPath:
# 节点的目录
path: /data/nginx-volume1
- name: nginx-volume2
hostPath:
path: /data/nginx-volume2
2.2、执行
kubectl apply -f /root/test2/daemonset-nginx.yaml
# 查看
kubectl -n kube-system get pods -o wide
3、DaemonSet运行在哪个节点上
- 有指定节点,那就在指定节点创建pod
- 未指定节点,将在所有节点上创建Pod
3.1、daemonset.spec.template.spec.nodeName
DaemonSet只在某个节点上创建Pod
apiVersion: apps/v1
kind: DaemonSet
metadata:
# DaemonSet的名称
name: daemonset-nginx
# 命名空间
namespace: kube-system
labels:
# DaemonSet 标签
la-nginx: daemonset-nginx
spec:
# 标签选择器
selector:
# 匹配拥有哪些标签的pod
matchLabels:
# 使用 k2-nginx: daemonset-nginx2 标签的template
k2-nginx: daemonset-nginx2
# 定义模板
template:
metadata:
labels:
# 定义标签
k2-nginx: daemonset-nginx2
spec:
# DaemonSet将在node1节点上创建Pod
nodeName: node1
# 定义容忍度,容忍哪些污点
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
# 定义容器
containers:
- name: c-nginx
image: nginx
3.2、daemonset.spec.template.spec.affinity
DaemonSet控制器将在与该节点关联相匹配的节点上创建Pod。
kubectl explain daemonset.spec.template.spec.affinity
4、怎么调度daemonset pod
- 通过默认scheduler调度,DaemonSet确保所有符合条件的节点都运行相同的Pod副本
- 运行Pod的节点由Kubernetes调度器选择。
4.1、DaemonSet pods 由 DaemonSet 创建和调度。这将引入以下问题:
- Pod 行为的不一致性:
- 等待调度的正常Pod已被创建并处于Pending 状态,但DaemonSet pods未在Pending状态下创建。
- Pod preemption由默认scheduler处理。启用抢占后,DaemonSet控制器将在不考虑pod优先级和抢占的情况下制定调度决策。
4.2、ScheduleDaemonSetPods允许使用默认调度器而不是DaemonSet来调度
DaemonSets方法是将NodeAffinity添加到DaemonSet pods,而不是.spec.nodeName。 然后使用默认调度器将pod绑定到目标主机。 如果DaemonSet pod的亲和节点已存在,则替换它。
4.3、DaemonSet 控制器仅在创建或修改 DaemonSet pods时执行这些操作,并且不对 DaemonSet的spec.template进行任何更改。
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchFields:
- key: metadata.name
operator: In
values:
- target-host-name
- 系统会自动添加 node.kubernetes.io/unschedulable:NoSchedule 容忍度到 DaemonSet Pods。
- 在调度DaemonSet Pod时,默认调度器会忽略unschedulable节点。
5、污点和容忍度
尽管Daemon Pods遵循污点和容忍度规则,根据相关特性,会自动将以下容忍度添加到 DaemonSet Pods 中。
6、与DaemonSet中的Pod进行通信
与DaemonSet中的Pod进行通信的几种可能模式如下
- Push
- NodeIP和已知端口
- DNS
- Service
6.1、Push
将DaemonSet中的Pod配置为将更新发送到其他服务,例如统计数据库。
6.2、NodeIP和已知端口
- DaemonSet 中的Pod可以使用hostPort,从而可以通过 节点IP 访问到 Pod。
- 客户端能通过某种方法获取 节点IP 列表,并且基于此也可以获取到相应的端口。
6.3、DNS
创建具有相同PodSelector的 Headless Service,然后通过使用 endpoints 资源或从 DNS 中检索到多个 A 记录来发现 DaemonSet。
6.4、Service
创建具有相同PodSelector 的 Service,并使用该 Service 随机访问到某个节点上的DaemonSet pod(没有办法访问到特定节点)。
7、更新 DaemonSet
- 如果修改了节点标签,DaemonSet将立刻向新匹配上的节点添加Pod,同时删除不能够匹配的节点上的Pod。
- 可以修改DaemonSet创建的Pod。然而,不允许对Pod的所有字段进行更新。
- 当下次节点(即使具有相同的名称)被创建时,DaemonSet Controller 还会使用最初的模板。
- 可以删除一个DaemonSet。
- 如果使用kubectl并指定 --cascade=false,则Pod将被保留在节点上。
- 可以创建具有不同模板的新DaemonSet。
- 具有不同模板的新DaemonSet将能够通过标签匹配并识别所有已经存在的Pod。
- 如果有任何Pod需要替换,则DaemonSet根据它的 updateStrategy来替换
8、DaemonSet 的可替代选择
8.1、init 脚本
我们很可能希望直接在一个节点上启动daemon(守护)进程(例如,使用 init、upstartd、systemd)。这非常好,但基于DaemonSet来运行这些进程有如下一些好处
- 像对待应用程序一样,具备为daemon提供监控和管理日志的能力。
- 为daemon和应用程序使用相同的配置语言和工具(如Pod模板、kubectl)。
- 在资源受限的容器中运行daemon,能够增加daemon和应用容器的隔离性。然而,这也实现了在容器中运行daemon,但却不能在Pod中运行, 例如:直接基于Docker启动
9、Deployments和Daemonset区别联系
9.1、相似性
- 都能创建Pod
- 创建的Pod对应的进程都不希望被终止掉,举例如下
- Web 服务器
- 存储服务器
9.2、使用Deployments的场景
无状态的Sevice使用Deployments,需要实现对副本的数量进行扩缩容、平滑升级,就用Deployments文章来源:https://www.toymoban.com/news/detail-445534.html
9.3、使用Daemonset的场景
需要Pod副本总是运行在全部或特定主机上,并需要先于其他Pod启动,就用daemonset。文章来源地址https://www.toymoban.com/news/detail-445534.html
到了这里,关于k8s--基础--19--DaemonSet的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!