概述

DeamonSet 可以理解为特殊的 ReplicaSet, 即确保每个节点只运行一个 pod 副本的 pod Set,DaemonSet 确保全部节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。即单实例,每个节点只跑一个pod。

应用场景

  • 在每个 Node上运行一个 GlusterFS 存储或者 Ceph 存储的 Daemon 进程
  • 在每个 Node 上运行一个日志采集程序,例如 Fluentd 或者 Logstach.
  • 在每个 Node 上运行一个性能监控程序,采集该 Node 的运行性能数据,例如 PrometheusNode Exporter, collectd, New Relic agent 或者 Ganglia gmond 等。

一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。DaemonSet 的 Pod 调度策略与 RC 类似,除了使用系统内置的算法在每台 Node 上进行调度,也可以在 Pod 的定义中使用 NodeSelector 或 NodeAffinity 来指定满足条件的 Node 范围进行调度

学习环境准备

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$dir=k8s-daemonset-create;mkdir $dir;cd $dir
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl config current-context
kubernetes-admin@kubernetes
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl  create ns liruilong-dameonset-create
namespace/liruilong-dameonset-create created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl config set-context $(kubectl config current-context) --namespace=liruilong-daemonset-create
Context "kubernetes-admin@kubernetes" modified.

kubeadm 中的 Deamonset

使用 kubeadm 安装的 k8s 环境中是使用的 DaemonSet,calico 是网路相关,所有节点都需要有 kube-proxy 是代理相关用于负载均衡等操作。

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-ReplicationController]
└─$kubectl  get ds -A
NAMESPACE     NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-system   calico-node   3         3         3       3            3           kubernetes.io/os=linux   4d23h
kube-system   kube-proxy    3         3         3       3            3           kubernetes.io/os=linux   4d23h
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-ReplicationController]
└─$

Demonset 的创建

DaemonSet 和 deployment 只有在 kind 的位置不同,可以拷贝 deployment 的模板进行修改

apiVersion: apps/v1
kind: DaemonSet
metadata:creationTimestamp: nulllabels:app: myds1name: myds1
spec:#replicas: 1selector:matchLabels:app: myds1#strategy: {}template:metadata:creationTimestamp: nulllabels:app: myds1spec:containers:- image: nginxname: nginxresources: {}
#status: {}
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl create deployment  myds1 --image=nginx --dry-run=client -o yaml > deamonset.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$vim deamonset.yaml

我们创建一个 Deamonset,当前只有 master 节点和一个 node 节点正常工作。因为 master 节点有污点,所以会发现这里只允许一个 deamonset。

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl apply -f deamonset.yaml
daemonset.apps/myds1 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl  get nodes
NAME                         STATUS     ROLES                  AGE     VERSION
vms81.liruilongs.github.io   Ready      control-plane,master   4d22h   v1.22.2
vms82.liruilongs.github.io   Ready      <none>                 4d22h   v1.22.2
vms83.liruilongs.github.io   NotReady   <none>                 4d22h   v1.22.2
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl  get pods
NAME          READY   STATUS    RESTARTS   AGE
myds1-fbmhp   1/1     Running   0          35s
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$

节点加入集群自动新增节点 pod

我们在启动一台机器,会发现,新加入的 vms83.liruilongs.github.io 节点自动运行一个 deamonset

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl get nodes
NAME                         STATUS   ROLES                  AGE     VERSION
vms81.liruilongs.github.io   Ready    control-plane,master   4d22h   v1.22.2
vms82.liruilongs.github.io   Ready    <none>                 4d22h   v1.22.2
vms83.liruilongs.github.io   Ready    <none>                 4d22h   v1.22.2
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
myds1-prldj   1/1     Running   0          6m13s
myds1-pvwm4   1/1     Running   0          10m

Deamonset 污点节点加入 pod

下面我们从新修改 deamonset 资源文件,容忍有污点的节点

apiVersion: apps/v1
kind: DaemonSet
metadata:creationTimestamp: nulllabels:app: myds1name: myds1
spec:#replicas: 1selector:matchLabels:app: myds1#strategy: {}template:metadata:creationTimestamp: nulllabels:app: myds1spec:terminationGracePeriodSeconds: 0tolerations:- operator: Existscontainers:- image: nginxname: nginxresources: {}
#status: {}
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl  apply  -f deamonsettaint.yaml
daemonset.apps/myds1 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl get pods
NAME          READY   STATUS              RESTARTS   AGE
myds1-8tsnz   0/1     ContainerCreating   0          3s
myds1-9l6d9   0/1     ContainerCreating   0          3s
myds1-wz44b   0/1     ContainerCreating   0          3s

会发现每个节点都运行一个deamontset相关的pod

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl describe  nodes vms81.liruilongs.github.io | grep Taint
Taints:             node-role.kubernetes.io/master:NoSchedule
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl run pod1 --image=nginx --dry-run=server -o yaml | grep -A 6 terminationGracePeriodSecondsterminationGracePeriodSeconds: 30tolerations:- effect: NoExecutekey: node.kubernetes.io/not-readyoperator: ExiststolerationSeconds: 300- effect: NoExecute

当然,如果我们不想所以有污点的节点都运行 deamonset 相关 pod,那么我们可以使用另一种指定 kye 的方式

apiVersion: apps/v1
kind: DaemonSet
metadata:creationTimestamp: nulllabels:app: myds1name: myds1
spec:selector:matchLabels:app: myds1template:metadata:creationTimestamp: nulllabels:app: myds1spec:terminationGracePeriodSeconds: 0tolerations:- operator: Existskey: node-role.kubernetes.io/mastereffect: "NoSchedule"containers:- image: nginxname: nginxresources: {}

会发现 deamonset 可以运行在 master 和 node 节点

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl apply -f deamonsetaint.yaml
daemonset.apps/myds1 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-daemonset-create]
└─$kubectl get pods
NAME          READY   STATUS              RESTARTS   AGE
myds1-f7hbb   0/1     ContainerCreating   0          4s
myds1-hksp9   0/1     ContainerCreating   0          4s
myds1-nnmzp   0/1     ContainerCreating   0          4s

Daemon Pods 是如何被调度的

DaemonSet 确保所有符合条件的节点都运行该 Pod 的一个副本。 通常,运行 Pod 的节点由 Kubernetes 调度器选择。 不过,DaemonSet Pods 由 DaemonSet 控制器创建和调度。这就带来了以下问题:Pod 行为的不一致性,正常 Pod 在被创建后等待调度时处于 Pending 状态, DaemonSet Pods 创建后不会处于 Pending 状态下。Pod 抢占 由默认调度器处理。启用抢占后,DaemonSet 控制器将在不考虑 Pod 优先级和抢占 的情况下制定调度决策。这里的默认调度器即k8s中调度器。ScheduleDaemonSetPods 允许您使用默认调度器而不 DaemonSet 控制器来调度 DaemonSets, 方法是将 NodeAffinity 条件而不是 .spec.nodeName 条件添加到 DaemonSet Pods。 默认调度器接下来将 Pod 绑定到目标主机。如果 DaemonSet Pod 的节点亲和性配置已存在,则被替换 (原始的节点亲和性配置在选择目标主机之前被考虑)。 DaemonSet 控制器仅在创建或修改 DaemonSet Pod时执行这些操作, 并且不会更改 DaemonSet 的 spec.template。

nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchFields:- key: metadata.nameoperator: Invalues:- target-host-name

与 Daemon Pods 通信

DaemonSet 中的 Pod 进行通信的几种可能模式如下:

推送(Push):配置 DaemonSet 中的 Pod,将更新发送到另一个服务,例如统计数据库。 这些服务没有客户端。

NodeIP 和已知端口:DaemonSet 中的 Pod 可以使用 hostPort,从而可以通过节点 IP 访问到 Pod。客户端能通过某种方法获取节点 IP 列表,并且基于此也可以获取到相应的端口。

DNS:创建具有相同 Pod 选择算符的 无头服务, 通过使用 endpoints 资源或从 DNS 中检索到多个 A 记录来发现 DaemonSet。

Service:创建具有相同 Pod 选择算符的服务,并使用该服务随机访问到某个节点上的 守护进程(没有办法访问到特定节点)。

更新 DaemonSet

如果节点的标签被修改,DaemonSet 将立刻向新匹配上的节点添加 Pod, 同时删除不匹配的节点上的 Pod。你可以修改 DaemonSet 创建的 Pod。不过并非 Pod 的所有字段都可更新。 下次当某节点(即使具有相同的名称)被创建时,DaemonSet 控制器还会使用最初的模板。你可以修改 DaemonSet 创建的 Pod。不过并非 Pod 的所有字段都可更新。 下次当某节点(即使具有相同的名称)被创建时,DaemonSet 控制器还会使用最初的模板。您可以删除一个 DaemonSet。如果使用 kubectl 并指定 --cascade=orphan 选项, 则 Pod 将被保留在节点上。接下来如果创建使用相同选择算符的新 DaemonSet, 新的 DaemonSet 会收养已有的 Pod。 如果有 Pod 需要被替换,DaemonSet 会根据其 updateStrategy 来替换。

DaemonSet 的替代方案

init 脚本

直接在节点上启动守护进程(例如使用 init、upstartd 或 systemd)的做法当然是可行的。 不过,基于 DaemonSet 来运行这些进程有如下一些好处:

  • 像所运行的其他应用一样,DaemonSet 具备为守护进程提供监控和日志管理的能力。
  • 为守护进程和应用所使用的配置语言和工具(如 Pod 模板、kubectl)是相同的。
  • 在资源受限的容器中运行守护进程能够增加守护进程和应用容器的隔离性。 然而,这一点也可以通过在容器中运行守护进程但却不在 Pod 中运行之来实现。 例如,直接基于 Docker 启动。

裸 Pod

直接创建 Pod 并指定其运行在特定的节点上也是可以的。 然而,DaemonSet 能够替换由于任何原因(例如节点失败、例行节点维护、内核升级) 而被删除或终止的 Pod。 由于这个原因,你应该使用 DaemonSet 而不是单独创建 Pod。

静态 Pod

通过在一个指定的、受 kubelet 监视的目录下编写文件来创建 Pod 也是可行的。 这类 Pod 被称为静态 Pod。 不像 DaemonSet,静态 Pod 不受 kubectl 和其它 Kubernetes API 客户端管理。 静态 Pod 不依赖于 API 服务器,这使得它们在启动引导新集群的情况下非常有用。 此外,静态 Pod 在将来可能会被废弃。

Deployments

DaemonSet 与 Deployments 非常类似, 它们都能创建 Pod,并且 Pod 中的进程都不希望被终止(例如,Web 服务器、存储服务器)。建议为无状态的服务使用 Deployments,比如前端服务。 对这些服务而言,对副本的数量进行扩缩容、平滑升级,比精确控制 Pod 运行在某个主机上要重要得多。 当需要 Pod 副本总是运行在全部或特定主机上,并且当该 DaemonSet 提供了节点级别的功能(允许其他 Pod 在该特定节点上正确运行)时, 应该使用 DaemonSet。例如,网络插件通常包含一个以 DaemonSet 运行的组件。 这个 DaemonSet 组件确保它所在的节点的集群网络正常工作。

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-ReplicationController]
└─$kubectl  get ds -A
NAMESPACE     NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-system   calico-node   3         3         3       3            3           kubernetes.io/os=linux   4d23h
kube-system   kube-proxy    3         3         3       3            3           kubernetes.io/os=linux   4d23h
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-ReplicationController]
└─$

Kubernetes 学习总结(21)—— 深入理解 Kubernetes 中的 DeamonSet相关推荐

  1. Kubernetes学习总结(16)—— Kubernetes 实战之部署 Redis 集群

    一.问题分析 本质上来说在 k8s 上部署一个 redis 集群和部署一个普通应用没有什么太大的区别,但需要注意下面几个问题: Redis 是一个有状态应用:这是部署 redis 集群时我们最需要注意 ...

  2. Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere

    前言 Kubernetes(K8s)集群管理平台都是基于 Kubernetes 提供功能,可以说他们是在 K8s 的基础上封装了一层更为友好的操作方式.他们都是为了降低 k8s 集群运维复杂度,降低运 ...

  3. Kubernetes学习总结(8)—— Kubernetes Pod 资源管理 和 Pod 服务质量

    一.Pod 资源管理 1.1.resource 的定义 容器运行过程中需要分配所需的资源,如何与 cggroup 联动配合呢?答案是通过定义resource来实现资源的分配,资源的分配单位主要是 cp ...

  4. Kubernetes学习总结(6)——Kubernetes 7周年:它为什么如此受欢迎?

    今年 6 月 7 日,Kubernetes 迎来 7 周年.七年前,当谷歌宣布 Kubernetes 项目时,谁也不曾想到它会取得如此大的成功.作为后起之秀,Kubernetes 打败了 Docker ...

  5. Kubernetes学习总结(5)——Kubernetes 常见面试题汇总

    简述etcd及其特点 etcd是CoreOS团队发起的开源项目,是一个管理配置信息和服务发现(service discovery)的项目,它的目标是构建一个高可用的分布式键值(key-value)数据 ...

  6. Kubernetes 学习总结(35)—— Kubernetes 1.25 正式发布,多方面重大突破

    前言 美国时间 2022 年 8 月 23 日,Kubernetes 1.25 正式发布.此版本更新距离上版本发布时隔 4 个月,是 2022 年的第二个版本.受新冠疫情和国际形势变化影响以及发布团队 ...

  7. Kubernetes学习总结(2)——Kubernetes设计架构

    Kubernetes集群包含有节点代理kubelet和Master组件(APIs, scheduler, etc),一切都基于分布式的存储系统.下面这张图是Kubernetes的架构图. Kubern ...

  8. Kubernetes学习总结(1)——Kubernetes入门简介

    1.前言 Together we will ensure that Kubernetes is a strong and open container management framework for ...

  9. Kubernetes学习(1)-----搭建kubernetes环境

    1. 搭建kubernetes环境 1.1 环境准备 1.1.1 基本配置 为了避免和Docker的iptables产生冲突,需要关闭Node节点上的防火墙 systemctl stop firewa ...

  10. Kubernetes 学习总结(25)—— Kubernetes 中的 pod 与容器的区别和联系

    前言 容器本可以成为轻量级虚拟机的替代品.但是由于 Docker/OCI 的标准化,最广泛使用的容器形式是每个容器只有一个进程服务.这种方法有很多优点--增加隔离性.简化水平扩展.更高的可重用性等.但 ...

最新文章

  1. (六)java多线程之ReadWriteLock
  2. php使用file,PHP中is_file()函数使用指南
  3. 使用python实现简单的爬虫
  4. Mysql 数据库学习笔记03 存储过程
  5. SpringMVC 另一种基于xml的处理器、适配器(了解)
  6. markdown生成html不出效果,mdeditor: 简单markdown编辑器,同步预览html效果。不依赖任何插件,使用简单,原创,造轮子中。。。更新中。。。...
  7. java实现浏览器_利用Java实现网页浏览器
  8. Redis配置和持久性
  9. soft215@163.com,销售工程造价,建筑,工控,模拟分析,财务等商业版软件︻◣
  10. java从0单排之java就业培训教程复习与面试题回顾——02
  11. 【CAD arx二次开发】CAD2020 通过Wizard向导新建arx项目
  12. LED电子时钟,时间显示屏,网络子母钟系统方案(京准电子)
  13. selectpicker.js的属性和方法
  14. svd在matlab中的使用,matlab - 使用SVD在MATLAB中压缩图像 - 堆栈内存溢出
  15. alios下载_AliOS Studio开源工具|AliOS Cloud App集成开发环境(AliOS Studio)下载 v1.2.1 官方Windows版 - 比克尔下载...
  16. 清晰易懂的“K个一组翻转链表”解法
  17. 信息及信息技术概述(一)
  18. PDF.js特殊字体、水印加载不出来问题解决
  19. html中repeat的作用,background-repeat属性怎么用
  20. java函数式接口意义与场景

热门文章

  1. python- FTP 实现上传文件到服务器
  2. 考研数二第三讲 极限存在准则和两个重要极限和极限运算准则
  3. H3C IRF2典型应用
  4. 【Electron-vue】创建桌面应用(12)- 修改electron窗口图标和桌面图标
  5. Roblox入场教育游戏,是换道拥抱元宇宙还是新瓶装旧酒?
  6. jedis是什么?jedis概念
  7. 华为服务器web界面配置文件,如何查看服务器web配置文件
  8. 三段式抽屉BottomSheetBehavior嵌套RecyclerView滑动冲突问题
  9. 产品经理必读:这样设计NPS提问,回收率提高30%!
  10. 网狐棋牌服务器IP地址配置方法