【探索 Kubernetes|作业管理篇 系列 15】DaemonSet 的”过人之处“

news2024/11/19 17:38:19

前言

大家好,我是秋意零。

在上一篇中,我们讲解了 StatefulSet 的存储状态;我们发现,它的存储状态,就是利用了 PV 与 PVC 的设计。StatefulSet 自动为我们创建 PVC 并且以 <pvc-name>-<pod-name>-<编号>命名,从而始终与 Pod 编号名一致的绑定。

需要注意的是:StatefulSet 的“滚动更新”是从最后一个 Pod 开始的,为了不破坏拓扑状态。如:主从数据库,主的 Pod 编号是 0,后面是从,如果先更新主数据库 0 编号,那么后面的从数据库就会出现问题。

StatefulSet 的“滚动更新”还允许我们进行更精细的控制,比如:金丝雀发布(Canary Deploy)或者灰度发布,这意味着应用的多个实例中被指定的一部分不会被更新到最新的版本。

StatefulSet 的 partition 字段设置为 2,那么编号小于 2 的 Pod 是不会进行镜像更新的

$ kubectl patch statefulset mysql -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":2}}}}'
statefulset.apps/mysql patched

今天的内容是 DaemonSet 控制器。

👿 简介

  • 🏠 个人主页: 秋意零
  • 🧑 个人介绍:在校期间参与众多云计算相关比赛,如:🌟 “省赛”、“国赛”,并斩获多项奖项荣誉证书
  • 🎉 目前状况:24 届毕业生,拿到一家私有云(IAAS)公司 offer,暑假开始实习
  • 🔥 账号:各个平台, 秋意零 账号创作者、 云社区 创建者
  • 💕欢迎大家:欢迎大家一起学习云计算,走向年薪 30 万

系列文章目录


【云原生|探索 Kubernetes-1】容器的本质是进程
【云原生|探索 Kubernetes-2】容器 Linux Cgroups 限制
【云原生|探索 Kubernetes 系列 3】深入理解容器进程的文件系统
【云原生|探索 Kubernetes 系列 4】现代云原生时代的引擎
【云原生|探索 Kubernetes 系列 5】简化 Kubernetes 的部署,深入解析其工作流程


更多点击专栏查看:深入探索 Kubernetes

正文开始

  • 快速上船,马上开始掌舵了(Kubernetes),距离开船还有 3s,2s,1s...

目录

前言

系列文章目录

一、DaemonSet 介绍

Daemon Pod 的意义

二、DaemonSet 的“过人之处”

三、DaemonSet 的镜像版本如何维护

一切皆对象

总结


一、DaemonSet 介绍

DaemonSet 的主要作用,是在集群中运行一个类似守护进程的 Pod 服务(Daemon Pod)。

DaemonSet 管理 Pod 的三个特性:

  • 这个 Pod 运行在 Kubernetes 集群中,每一个节点(Node)上
  • DaemonSet 只会在每个节点创建一个 Pod(Daemon Pod);
  • 集群中有新节点加入时,DaemonSet 也会马上为这个新节点创建一个 Pod;当然当节点从集群中移除时,这个 Pod 也会回收。

实际上就是为每个节点只创建一个 Pod,就是像所谓的守护程序。

Daemon Pod 的意义

DaemonSet 机制听起来很简单,但是 Daemon Pod 的意义确实是非常重要的。如下:

  • 1.各种网络插件的 Agent 组件,用来处理这个节点上容器网络,必须运行在每一个节点上;
  • 2.各种存储插件的 Agent 组件,用来在这个节点上挂载远程存储目录,操作容器的 Volume 目录,也必须运行在每一个节点上;
  • 3.各种监控组件和日志组件,负责这个节点上的监控信息和日志搜集,也必须运行在每一个节点上。

需要注意的是,DaemonSet 运行的时机,很多时候比整个 Kubernetes 集群出现的时机都要早。

这个乍一听起来可能有点儿奇怪。但其实你来想一下:如果这个 DaemonSet 正是一个网络插件的 Agent 组件呢?

  • 首先要知道,在部署 Kubernetes 集群时,没有网络插件,节点的状态就会是 NotReady 状态(NetworkReady=false)。
  • 这个情况下,普通 Pod 是不能运行在集群中的。而为了让集群能正常运行 Pod 那么就需要使用 DaemonSet。

这里或许还有一个疑问,就是普通 Pod 在这种 NotReady 情况下不能运行,那 DaemonSet 就能运行吗?

二、DaemonSet 的“过人之处”

要理解 DaemonSet 的“过人之处”。首先,要了解 DaemonSet 的工作过程。

来看一个 DaemonSet 的 YAML 文件:

  • 可以看到,DaemonSet 的 YAML 与 Deployment 的 YAML 文件可以说是几乎一模一样只不过是没有 replicas 字段因为 DaemonSet 每个节点只需要一个副本,replicas 字段就没有必要存在了。
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: example-daemonset
  labels:
    app: example
spec:
  selector:
    matchLabels:
      app: example
  template:
    metadata:
      labels:
        app: example
    spec:
      tolerations:
      - key: node.kubernetes.io/unreachable
        operator: Exists
        effect: NoExecute
      containers:
      - name: example-container
        image: nginx:latest

那么,DaemonSet 又是如何保证每个 Node 节点上有且只有一个被管理的 Pod 的呢?这是一个典型的“控制器模型”能够处理的问题。

以上面 YAML 为例

1.DaemonSet Controller,首先从 Etcd 中获取所有 Node 列表,然后遍历所有的 Node,查找检查是否有 app: example标签的 Pod 在运行。

这个查找检查过程有三种情况:

  • 没有这种 Pod,那就需要在该 Node 节点上创建一个 Pod;
  • 有这种 Pod,需要判断是否为 1,大于 1 就删除;
  • 正好有这种 Pod,说明这个节点正常。

2.当查找到有这种 Pod 时,删除节点上多余的 Pod,很容易;当查找到没有这种 Pod 时,如何让 Pod 在指定 Node 节点上创建呢?通过两种方式:

2.1. 配置 DaemonSet 的节点亲和性(nodeAffinity)规则,指定它应该运行在哪些节点上。

节点亲和性(nodeAffinity):可以通俗的理解为,你更喜欢谁,就和谁靠的更近从而在一起(这属于调度内容,详细内容之后章节展开)。

Kubernetes 集群中的网络插件(calico)或者 kube-porxy 组件,它们都是 DaemonSet 控制器方式部署的。我们可以查看它们所管理的 Pod ,如图:

  • 可以看到 spec.affinity.nodeAffinity这个字段是 DaemonSet 默认为 Pod 添加的字段,是它创建 Pod 的机制。
  • requiredDuringSchedulingIgnoredDuringExecution:它的意思是说,这个 nodeAffinity 必须在每次调度的时候予以考虑。

上图中的 matchFields 字段(匹配字段)是我们的匹配 Node 节点的机制,上图中 key: metadata.namevalues: [master01]配置的哪里?看下图,它匹配的是 Node 节点的 YAML 文件中的 metadata.name字段。

2.2 此外,DaemonSet 还会给这个 Pod 自动加上另外一个与调度相关的字段,叫作 tolerations。这个字段意味着这个 Pod,会“容忍”(Toleration)某些 Node 的“污点”(Taint)。

Toleration 和 Taint(容忍和污点):可以通俗的理解为,你能忍受理解某人的缺点,也就不在意它的缺点了。

下面是 DaemonSet 自动生成的一组 tolerations 字段的完整格式:

tolerations:
- key: node.kubernetes.io/not-ready
  operator: Exists
  effect: NoExecute
- key: node.kubernetes.io/unreachable
  operator: Exists
  effect: NoExecute
- key: node.kubernetes.io/disk-pressure
  operator: Exists
  effect: NoSchedule
- key: node.kubernetes.io/memory-pressure
  operator: Exists
  effect: NoSchedule
- key: node.kubernetes.io/unschedulable
  operator: Exists
  effect: NoSchedule

上述 tolerations 字段包含了一系列的 toleration 条目,每个条目描述了容忍一个特定污点的规则。例如:

operator: Exists 表示只要存在该污点,就容忍该节点。

effect: NoSchedule 表示不在该节点上进行新的调度。可是,DaemonSet 自动地给被管理的 Pod 加上了这个特殊的 Toleration,就使得这些 Pod 可以忽略这个限制,继而保证每个节点上都会被调度一个 Pod。

  • node.kubernetes.io/not-ready :表示容忍 NotReady 状态的节点。
  • node.kubernetes.io/unreachable:容忍节点处于 Unreachable 状态。
  • node.kubernetes.io/disk-pressure:容忍节点存在磁盘压力。
  • node.kubernetes.io/memory-pressure:容忍节点存在内存压力。
  • node.kubernetes.io/unschedulable:容忍节点标记为不可调度。

这些 tolerations 使得 DaemonSet 的 Pod 能够在带有这些污点的节点上正常运行。

查看 calico 网络插件 的 Pod 上的 Toleration:

这时,你会想到,我在前面提到的 DaemonSet 的“过人之处”,其实就是依靠 Toleration 实现的。

三、DaemonSet 的镜像版本如何维护

  1. 创建 DaemonSet 的 YAML 文件:
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: example-daemonset
  labels:
    app: example
spec:
  selector:
    matchLabels:
      app: example
  template:
    metadata:
      labels:
        app: example
    spec:
      containers:
      - name: example-container
        image: nginx:latest
        imagePullPolicy: IfNotPresent

可以看到,现在每个 Node 节点上都有一个 example-daemonset(DaemonSet) 所管理的 Pod:

[root@master01 ~]# kubectl apply -f daemonSet.yaml
daemonset.apps/example-daemonset created

[root@master01 ~]# kubectl get pod -owide
NAME                      READY   STATUS    RESTARTS   AGE    IP              NODE       NOMINATED NODE   READINESS GATES
example-daemonset-bmfs5   1/1     Running   0          2m5s   10.244.5.14     worker01   <none>           <none>
example-daemonset-dgtp4   1/1     Running   0          2m5s   10.244.241.82   master01   <none>           <none>
  1. 镜像更新

DaemonSet 与 Deployment 一样都能进行版本管理。使用 kubectl rollout history查看:

[root@master01 ~]# kubectl rollout history daemonset example-daemonset
daemonset.apps/example-daemonset
REVISION  CHANGE-CAUSE
1         <none>

使用 kubectl set image命令修改镜像版本:

[root@master01 ~]# kubectl set image daemonset/example-daemonset --record example-container=nginx:alpine
Flag --record has been deprecated, --record will be removed in the future
daemonset.apps/example-daemonset image updated

使用kubectl rollout history命令再次查看更新版本记录:

[root@master01 ~]# kubectl rollout history daemonset example-daemonset
daemonset.apps/example-daemonset
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image daemonset/example-daemonset example-container=nginx:alpine --record=true

一切皆对象

Deployment 管理这些版本,靠的是“一个版本对应一个 ReplicaSet 对象”。可是,DaemonSet 控制器操作的直接就是 Pod。那么,它的这些版本又是如何维护的呢?

所谓,一切皆对象!

在 Kubernetes 项目中,任何你觉得需要记录下来的状态,都可以被用 API 对象的方式实现。当然,“版本”也不例外。

Kubernetes v1.7 之后添加了一个 API 对象,叫 ControllerRevision,专门用来记录某种 Controller 对象的版本。

[root@master01 ~]# kubectl get controllerrevision
NAME                          CONTROLLER                         REVISION   AGE
example-daemonset-67d867976   daemonset.apps/example-daemonset   2          10m
example-daemonset-d8494f4bd   daemonset.apps/example-daemonset   1          20m

[root@master01 ~]# kubectl describe controllerrevision example-daemonset-67d867976

我们查看版本 2 是否是我们对应的版本:

  • 可以看到,Annotations 记录了,我们 kubectl 修改镜像版本的命令;以及 data 字段保存了该版本对应的完整的 DaemonSet 的 API 对象

将 DaemonSet 回滚到 Revision=1 时的状态:

  • kubectl describe controllerrevision可以看到它的 Revision 字段,而 kubectl rollout undo实际上读取到了 的 ControllerRevision 的对象保存的 Data 字段。而这个 Data 字段里保存的信息,就是 Revision=1 时这个 DaemonSet 的完整 API 对象。
[root@master01 ~]# kubectl rollout undo daemonset/example-daemonset --to-revision=1
daemonset.apps/example-daemonset rolled back
[root@master01 ~]#

[root@master01 ~]# kubectl describe controllerrevision example-daemonset-d8494f4bd

在执行完这次回滚完成后,你会发现,DaemonSet 的 Revision 并不会从 Revision=2 退回到 1,而是会增加成 Revision=3。这是因为,一个新的 ControllerRevision 被创建了出来。

[root@master01 ~]# kubectl rollout history daemonset/example-daemonset
daemonset.apps/example-daemonset
REVISION  CHANGE-CAUSE
2         kubectl set image daemonset/example-daemonset example-container=nginx:alpine --record=true
3         <none>

[root@master01 ~]# kubectl get controllerrevision
NAME                          CONTROLLER                         REVISION   AGE
example-daemonset-67d867976   daemonset.apps/example-daemonset   2          31m
example-daemonset-d8494f4bd   daemonset.apps/example-daemonset   3          41m

总结

通过上面的介绍,DaemonSet 的工作过程。

首先,是它的控制循环,查找检查所有 Node 节点上的 Pod 的情况,来决定是否创建或者删除一个 Pod;

其次,在创建 Pod 时,DaemonSet 会自动给这个 Pod 加上一个 nodeAffinity 和 Toleration,来保证 Pod 在指定节点运行,并且忽略 unschedulable “污点”;

最后,DaemonSet 使用 ControllerRevision,来保存和管理对应的“版本”。

StatefulSet 也是直接控制 Pod 对象的,那么它是不是也在使用 ControllerRevision 进行版本管理呢?

没错。在 Kubernetes 项目里,ControllerRevision 其实是一个通用的版本管理对象。这样,Kubernetes 项目就巧妙地避免了每种控制器都要维护一套冗余的代码和逻辑的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/699550.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

selenium模拟!看这篇就够了

介绍 Selenium是一个用于自动化Web浏览器测试的开源工具&#xff0c;它支持多种Web浏览器&#xff08;如Google Chrome、Firefox、Safari等&#xff09;和操作系统&#xff08;如Windows、Mac和Linux&#xff09;。Selenium可以模拟用户在Web浏览器中的行为&#xff0c;例如点…

ssm汉语言学习应用系统APP -计算机毕设 附源码80400

ssm汉语言学习应用系统APP 摘 要 在信息飞速发展的今天&#xff0c;网络已成为人们重要的信息交流平台。每天都有大量的农产品需要通过网络发布&#xff0c;为此&#xff0c;本人开发了一个基于Android模式的汉语言学习应用系统。 对于本汉语言学习应用系统的设计来说&#x…

十、云尚办公系统-员工端审批

云尚办公系统&#xff1a;员工端审批 B站直达【为尚硅谷点赞】: https://www.bilibili.com/video/BV1Ya411S7aT 本博文以课程相关为主发布&#xff0c;并且融入了自己的一些看法以及对学习过程中遇见的问题给出相关的解决方法。一起学习一起进步&#xff01;&#xff01;&…

回收站删除的文件怎么恢复?4招快速搞定!

求救求救&#xff01;我刚刚一个不小心就把回收站清空了&#xff01;但是我回收站里还有需要恢复的文件&#xff0c;这次一不小心清空了回收站&#xff0c;我的重要文件还有机会找回来吗&#xff1f;希望大家帮帮我! 对于部分朋友来说&#xff0c;回收站可能不仅仅是一个垃圾文…

Selenium 不开启浏览器页面执行测试用例

实际工作中会遇到不开启浏览器页面来执行测试用例的情况&#xff0c;可以通过ChromeOptions来实现 ChromeOptions是chromedriver支持的浏览器启动选项 Google 针对 Chrome 浏览器 59版 新增加的Chrome-headless 模式&#xff0c;可以在不打开UI界面的情况下使用 Chrome 浏览器…

【Java高级编程】多线程

多线程 1、基本概念&#xff1a;程序、进程、线程1.1、程序1.2、进程1.3、线程1.4、单核CPU和多核CPU的理解1.5、并行与并发1.6、使用多线程的优点1.7、何时需要多线程 2、线程的创建和使用2.1、创建多线程的方式一&#xff1a;继承Thread类2.2、Thread类的有关方法2.3、线程的…

选择高考志愿:聚焦计算机科学与技术,规避土木工程

选择高考志愿&#xff1a;聚焦计算机科学与技术&#xff0c;规避土木工程 高考季已至&#xff0c;各地高考成绩陆续公布&#xff0c;许多毕业生和家长开始面临疑惑&#xff1a;如何填报志愿、选专业还是选学校、什么专业好就业&#xff1f;张雪峰曾提到&#xff1a;“普通家庭…

机房动环是什么?内附最新机房动环监控系统报价

伴随着计算机信息化的发展和物联网的广泛运营&#xff0c;为了减少人员维护成本&#xff0c;实现智能化监控管理&#xff0c;机房动环监控系统逐渐被应用开来。通过一套完整的机房动环监控系统&#xff0c;一个偌大的机房就可以实现24小时无人值守。机房动环是什么&#xff1f;…

【Redis】介绍及安装

&#x1f3af;简介 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的高性能键值对&#xff08;key-value&#xff09;存储数据库&#xff0c;它支持多种数据类型&#xff0c;如字符串、列表、集合、哈希表和有序集合等。 Redis通常用于缓存、消息队列、实时…

移动设备管理 (MDM)工具

移动设备管理 &#xff08;MDM&#xff09;可帮助管理员通过无线方式管理和保护组织的移动设备群&#xff0c;而不会影响最终用户体验。现代 MDM 解决方案还可以控制应用程序、内容和安全性&#xff0c;因此员工可以无后顾之忧地在托管设备上工作。移动设备管理软件可有效管理个…

华为HUAWEI MateBook D 2018 黑苹果Monterey 12.6.5的安装过程

HUAWEI MateBook D 2018 黑苹果系统的安装 HUAWEI MateBook D 2018版,配置列表如下&#xff1a;安装Monterey 12.6.5流程1. 打开balenaEtcher&#xff0c;选择好系统镜像和U盘&#xff0c;将镜像刻录到U盘中&#xff0c;点击Flash等待刻录完成&#xff1b;2. 使用DiskGenius将下…

vue3.2+vite+elementPlus,build引入CDN依赖包,提升打包速率,vite-plugin-cdn-import

一.概述 使用CDN的好处缓解服务器的压力,将首屏加载时的请求分摊给其它的服务器优化打包后verdor.js过大问题加快首屏加载速度加快打包速度尤其是Vue3新的Tree-Shaking技术,只打包需加载的模块module,搭配CDN后如虎添翼! 二.CDN网站分享 根据需要自行切换相关CDN 依赖引用并…

【easyswoole代码自动生成crud】我写了一个控制器用来生成增删改查

easyswoole代码自动生成crud 根据表生成模型和控制器根据表生成模型根据表生成控制器控制器模板核心控制器代码curd.php 根据表生成模型和控制器 会在 App/Model目录下生成驼峰方式命名的模型文件 会在App/HttpController/Api 目录下生成驼峰方式命名的控制文件 curl http:lo…

React V6分环境打包

功能背景 例如想要在react也要实现不同环境使用不同的api接口地址这样的想法&#xff0c;那么就需要根据命令自动区分环境了。 代码实现 比如我这又三种环境&#xff0c;那么创建三个文件&#xff0c;如图&#xff1a; 分别是dev:开发环境&#xff0c;formal&#xff1a;UAT环境…

【力扣】DP:1186. 删除一次得到子数组最大和

【力扣】DP&#xff1a;1186. 删除一次得到子数组最大和 文章目录 【力扣】DP&#xff1a;1186. 删除一次得到子数组最大和1. 题目描述2. 题解2.1 不可行2.2 DP 参考 1. 题目描述 给你一个整数数组&#xff0c;返回它的某个非空子数组&#xff08;连续元素&#xff09;在执行一…

画一个足球场,尺寸已标注好

画一个有标注的足球场 上面是一个带有标注的足球场俯视图&#xff0c;下面是实现代码。 import matplotlib.pyplot as plt from matplotlib.patches import Arc, Circle, Rectangle# 创建一个灰色背景的子图 fig, ax plt.subplots(facecolorgrey)# 设置x轴和y轴的范围 ax.set…

基于PaddleOCR的工件字符识别

目录 1.工业工件字符识别 1.2 难点 1.3 基于深度学习的OCR技术 2.基于Paddleocr的字符识别 &#x1f31f; 特性 2.1 PP-OCRv3介绍 3.本文工件字符识别数据集介绍 4.PaddleOCR工件字符 4.1 字符检测 1.工业工件字符识别 在复杂的工业制造环境中&#xff0c;为了更好的追踪…

SAP-MM未清PO调取

SAP未清PO调取 SAP查询open PO(未清采购清单)可以通过ME2M(PO per material),ME2L(PO per vendor),ME2N(PO per document number)进行查询。 未清订单一般指未完成收货或者已收货未完成发票校验的订单,在输入以上任一事务代码之后,在选择参数Selection Parameters…

十二、项目总结

项目总结 B站直达【为尚硅谷点赞】: https://www.bilibili.com/video/BV1Ya411S7aT 本博文以课程相关为主发布&#xff0c;并且融入了自己的一些看法以及对学习过程中遇见的问题给出相关的解决方法。一起学习一起进步&#xff01;&#xff01;&#xff01; 文章目录 项目总结1…

在 Jetpack Compose 中创建 Drawer

Jetpack Compose 是一个现代的构建 Android UI 的工具集&#xff0c;它使得构建 UI 变得更加简单快速。在本篇博客中&#xff0c;我们将讨论如何在 Jetpack Compose 中创建 Drawer&#xff0c;也就是我们常见的侧边抽屉。 什么是 Drawer&#xff1f; Drawer 是一个提供导航选项…