k8s之DaemonSet

news2025/1/17 5:55:03

写在前面

假定现在有一个这样的需求,需要收集每个Node的运行状态信息,并进行上报,假设有4个节点,我们可以使用Deployment 来实现吗?好像是可以的,我们只需要将repliacas设置为4不就行了,但是deployment只能保证有4个POD在运行,不能保证4个POD是分布在4个Node上的,即deployment的POD分布和节点是没有关系的,那怎么办呢?能否让deployment具备这种功能,然后在yaml中提供相关的配置参数就行了?行是行,但是这样就违背了单一职责的原则,使得单一对象功能过于复杂,维护成本高,因此我们就需要另外一个API对象来完成这个功能,k8s提供的这个API对象就是DaemonSet,也是本文的绝对主角。

1:k8s集群说明

我本地k8s集群一共有2个Node,一个Maser Node,一个Worker Node,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl get node
NAME         STATUS   ROLES                  AGE   VERSION
mongodaddy   Ready    control-plane,master   43h   v1.23.3
mongomummy   Ready    <none>                 29h   v1.23.3

2:apply

先看下DaemonSet的API定义:

dongyunqi@mongodaddy:~/k8s$ kubectl api-resources | egrep "DaemonSet|KIND"
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
daemonsets                        ds           apps/v1                                true         DaemonSet

还是老套路来生成API模板:

dongyunqi@mongodaddy:~/k8s$ export out="--dry-run=client -o yaml" && kubectl create ds info $out
Error: must specify one of -f and -k

error: unknown command "ds info"
See 'kubectl create -h' for help and examples

竟然提示error: unknown command "ds info",难道是不支持缩写,用全称试下:

dongyunqi@mongodaddy:~/k8s$ export out="--dry-run=client -o yaml" && kubectl create DaemonSet info $out
Error: must specify one of -f and -k

error: unknown command "DaemonSet info"
See 'kubectl create -h' for help and examples
dongyunqi@mongodaddy:~/k8s$ export out="--dry-run=client -o yaml" && kubectl create daemonsets info $out
Error: must specify one of -f and -k

error: unknown command "daemonsets info"
See 'kubectl create -h' for help and examples

都是一样的错误,其实就是因为k8s不支持生成ds的yaml模板文件,我想可能是k8s漏掉了吧!故意不支持实在是没有任何道理。这个时候我们该怎么办呢?可以抄啊! 可以在kubenetes的官网 找到一份这样的yaml然后我们再稍作修改就可以了,最终如下:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: redis-ds
  labels:
    app: redis-ds

spec:
  selector:
    matchLabels:
      name: redis-ds

  template:
    metadata:
      labels:
        name: redis-ds
    spec:
      containers:
      - image: redis:5-alpine
        name: redis
        ports:
        - containerPort: 6379

其实daemonset的yaml和deployment的yaml相比就少了replicas这个指定API对象实例个数的属性,这也很好理解,因为daemonset的API对象的个数是和节点数一样的,且一个Node一个API对象实例,通过下图对比会更加明显:

在这里插入图片描述

yaml编写完毕后我们就可以apply了,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl apply -f daemon.yml 
daemonset.apps/redis-ds created
dongyunqi@mongodaddy:~/k8s$ kubectl get ds
NAME       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
redis-ds   1         1         0       1            0           <none>          13s
稍等一会就READY了:
dongyunqi@mongodaddy:~/k8s$ kubectl get daemonset
NAME       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
redis-ds   1         1         1       1            1           <none>          3m22s

但是我们注意到ds API对象的个数只有1个,不是应该和节点的个数一样吗?出现这个现象的原因是k8s默认是不向master node部署API对象实例的,这又是怎么实现的呢?要想解释清楚这个问题,我们就得先来看下k8s中的另外两个概念污点 taint容忍度 toleration。污点是k8s集群的Node一个标签,其实就是一个字符串,但污点Node可以配置也可以不配置,通过命令kubectl describe node nodename/hostname可以查看Node配置的污点信息,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl describe node mongodaddy | grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
dongyunqi@mongodaddy:~/k8s$ kubectl describe node mongomummy | grep Taints
Taints:             <none>

mongodaddy是我本地master node的主机名,mongomummy是我本地worker node的主机名,需要根据自己的来修改,否则会报找不到节点错误。

可以看到master node配置了污点node-role.kubernetes.io/master:NoSchedule,而worker node没有配置任何污点,是一个非常纯洁的Node。什么是容忍度呢?容忍度是POD上的概念,即允许Node上有哪些污点自己才会在其上创建,默认POD是非常挑剔的,不允许Node有任何的污点,这是为什么DaemonSet的Pod没有在master node上部署的原因,知道了这个,我们只需要让master node没有污点,是不是非常挑剔的POD就会向已经变得纯洁的master node部署pod了呢,我们试一下,要想去除master node的污点,我们需要使用命令 kubectl taint node nodename/hostname node-role.kubernetes.io/master:NoSchedule-,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl taint node mongodaddy node-role.kubernetes.io/master:NoSchedule-
node/mongodaddy untainted

此时我们再查看POD是否在master node创建了:

dongyunqi@mongodaddy:~/k8s$ kubectl get daemonset
NAME       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
redis-ds   2         2         2       2            2           <none>          43m

可以看到确实创建了,也可以看下是不是在master node上创建的,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl get pod -o wide -l 'app!=ngx-dep'
NAME             READY   STATUS    RESTARTS   AGE   IP           NODE         NOMINATED NODE   READINESS GATES
redis-ds-6ldlr   1/1     Running   0          18m   10.10.0.4    mongodaddy   <none>           <none>
redis-ds-w5bmk   1/1     Running   0          44m   10.10.1.10   mongomummy   <none>           <none>

但是这种方式影响太大了,改变了master node的污点,会直接影响到其它所有的API对象,因此我们最好还是不要这样搞,所以,还是把master node的污点恢复比较好,而恢复污点使用命令kubectl taint node nodename/hostname node-role.kubernetes.io/master:NoSchedule,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl taint node mongodaddy node-role.kubernetes.io/master:NoSchedule
node/mongodaddy tainted

这个时候污点已经加回去了,那daemonset在master node部署的POD是不是就该被剔除了呢,看下:

dongyunqi@mongodaddy:~/k8s$ kubectl get daemonset
NAME       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
redis-ds   1         1         1       1            1           <none>          51m
dongyunqi@mongodaddy:~/k8s$ kubectl get pod -o wide -l 'app!=ngx-dep'
NAME             READY   STATUS    RESTARTS   AGE   IP           NODE         NOMINATED NODE   READINESS GATES
redis-ds-6ldlr   1/1     Running   0          30m   10.10.0.4    mongodaddy   <none>           <none>
redis-ds-w5bmk   1/1     Running   0          56m   10.10.1.10   mongomummy   <none>           <none>

可以看到kubectl get daemonset的结果已经变成了1,但pod还依然在,不知道这算不算是k8s的一个bug,为什么pod没有被删除,不过也没有关系,我们就手动先把master node上的删除吧:

dongyunqi@mongodaddy:~/k8s$ kubectl delete pod redis-ds-6ldlr
pod "redis-ds-6ldlr" deleted

我们继续往后看,既然修改master node让其变的纯洁影响太大,那么我们能不能只修改POD呢?让它不那么挑剔,这就需要修改其容忍度了,如下:

tolerations:
- key: node-role.kubernetes.io/master
  effect: NoSchedule
  operator: Exists

意思就是容忍存在Exists通过key和effect指定的污点,这里设置的就是master node当前的污点node-role.kubernetes.io/master:NoSchedule,修改yaml后如下:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: redis-ds
  labels:
    app: redis-ds

spec:
  selector:
    matchLabels:
      name: redis-ds

  template:
    metadata:
      labels:
        name: redis-ds
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
        operator: Exists
      containers:
      - image: redis:5-alpine
        name: redis
        ports:
        - containerPort: 6379

重新apply,如下:

dongyunqi@mongodaddy:~/k8s$ kubectl apply -f daemon.yml 
daemonset.apps/redis-ds configured
dongyunqi@mongodaddy:~/k8s$ kubectl get daemonset
NAME       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
redis-ds   2         2         1       2            1           <none>          80m
dongyunqi@mongodaddy:~/k8s$ kubectl get daemonset
NAME       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
redis-ds   2         2         2       2            2           <none>          81m

可以看到成功了。

3:静态POD

daemonset会在每个NODE上都部署一个POD,k8s中还有一种方式能够在指定的Node上部署POD,这种方式是静态POD,想要生成静态POD的话只需要在/etc/kubernetes/manifests目录下创建需要的yaml就行了,系统会自动检测并生成POD,如下是当前的:

dongyunqi@mongodaddy:~/k8s$ ll /etc/kubernetes/manifests
total 24
drwxr-xr-x 2 root root 4096  1月  8 21:45 ./
drwxr-xr-x 4 root root 4096  1月  8 21:45 ../
-rw------- 1 root root 2229  1月  8 21:45 etcd.yaml
-rw------- 1 root root 4014  1月  8 21:45 kube-apiserver.yaml
-rw------- 1 root root 3514  1月  8 21:45 kube-controller-manager.yaml
-rw------- 1 root root 1435  1月  8 21:45 kube-scheduler.yaml

可以看到master node的主要组件都是通过这种方式来运行的,但这种POD游离于集群之外,不容易管控,所以最好还是不要使用。

写在后面

总结

本文分析了daemonset API对象,介绍了其在每个Node部署一个POD的特点,并引入了POD选择Node时相关的误点taint和容忍度toleration概念,并给出了具体的例子,最后作为对比引出了静态POD的概念,知道了master node的apiserver,etcd,controller manager,scheduler组件都是以这种方式运行的。最后,希望这篇文章能够帮助到你。

多知道一点

污点的格式是key:NoSchedule,如node-role.kubernetes.io/master:NoSchedule,k8s还定义了很多其他的污点,可以参考官网 。

参考文章列表

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

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

相关文章

怎样让公司全员贡献结构化内容?

- 1 - 问题 一个朋友在一个生产型企业的文档团队负责产品文档&#xff0c;他们使用DITA来编写各类文档&#xff0c;比如&#xff1a;公司管理文档、产品介绍、产品使用说明、产品安装手册等。 DITA 是基于XML的体系结构&#xff0c;用于编写、制作、交付面向主题的信息类型…

【NI Multisim 14.0 操作实例——音量控制电路】

目录 序言 一、音量控制电路 &#x1f34a;1.设置工作环境 &#x1f34a; 2.设置原理图图纸 &#x1f34a; 3.设置图纸的标题栏 &#x1f34a; 4.放置元器件 &#x1f34a; 5.编辑元器件属性 &#x1f34a; 6. 布局元器件 序言 NI Multisim最突出的特点之一就是用户界面…

数字IC设计、验证、FPGA笔试必会 - Verilog经典习题 (一)四选一多路器

数字IC设计、验证、FPGA笔试必会 - Verilog经典习题 &#xff08;一&#xff09;四选一多路器 &#x1f508;声明&#xff1a; &#x1f603;博主主页&#xff1a;王_嘻嘻的CSDN博客 &#x1f9e8;未经作者允许&#xff0c;禁止转载 &#x1f511;系列专栏&#xff1a; &#x…

Mercurius <11.5.0 存在拒绝服务漏洞(CVE-2023-22477)

漏洞描述 Mercurius 是NPM仓库中的开源组件&#xff0c;用作于 Fastify Web 框架的 GraphQL 适配器。 11.5.0 之前版本的 Mercurius 开启“订阅”功能时&#xff0c;任何 Mercurius 用户都可以通过 WebSocket 向 /graphql 端点&#xff08;如&#xff1a;ws://127.0.0.1:1337…

【屏幕驱动移植】点亮OLED屏幕并播放视频

写在前面 硬件软件准备: 名称备注屏幕SSD1106本文章所使用的的屏幕型号&#xff0c;仅仅作为驱动移植示例&#xff0c;其他型号的都可以按照本文的方法推广树莓派3B用于驱动屏幕&#xff0c;树莓派2B3B4B等型号都可以ESP32开发板用于驱动屏幕&#xff0c;具体是ESP32还是ESP32…

都2023年啦~用python来玩一次股票.....

人生苦短&#xff0c;我用python 这不是2023年已经来了吗&#xff1f; 总不能空着手回去吧&#xff1f; 这次简单用python来玩一下股票~ 本章源码更多电子书点击文末名片~ 准备工作 我们需要使用这些模块&#xff0c;通过pip安装即可。 后续使用的其它的模块都是Python自…

启动jeecg-boot框架(vue3版本)

jeecg-boot框架&#xff08;vue3版本&#xff09;一、简介二、项目启动1.前端模组&#xff1a;jeecgboot-vue3-master2.后端模组&#xff1a;jeecg-boot-master3.环境要求&#xff1a;4.数据库准备&#xff1a;5.前端启动&#xff1a;6.redis启动&#xff1a;7.后端启动&#x…

(Matlab实现)基于蒙特卡诺和拉格朗日乘子法的电动车调度【有序、无序充放电】

目录 1 概述 2 蒙特卡洛模拟方法介绍 3 拉格朗日乘子法 4 规模化电动汽车充电负荷预测计算方法 5 Matlab代码实现 1 概述 电动汽车EV(Electric Vehicle)具有清洁环保、高效节能的优点,不仅能缓解化石能源危机,而且能够有效地减少温室气体的排放。2015年10月&#xff0c;国…

Day 7 Spring 整合第三方框架

xml整合第三方框架有两种整合方案:不需要自定义名空间&#xff0c;不需要使用Spring的配置文件配置第三方框架本身内容&#xff0c;例如: MyBatis;需要引入第三方框架命名空间&#xff0c;需要使用Spring的配置文件配置第三方框架本身内容&#xff0c;例如: Dubbo.1 整合MyBati…

Apollo星火计划学习笔记——Control 专项讲解(PID)

文章目录1. PID算法介绍1.1 时间连续与时间离散1.2 位置式与增量式1.3 PID算法扩展2. PID调试方法3. APOLLO代码介绍3.1 PID算法3.2 积分饱和问题3.3 纵向控制代码3.3.1 构造函数3.3.2 加载各种纵向控制的配置参数3.3.3 二阶巴特沃斯低通滤波器《数字信号处理》3.3.4 插值出油门…

PMP考试是什么?适合哪些人来学呢?

PMP&#xff0c;根据PMI的解释&#xff0c;就是项目管理专业人士资格认证&#xff0c;全称如下图&#xff1a;PMP考试是由PMI发起、组织和出题&#xff0c;严格评估项目管理专业人士知识技能是否具有高品质的资格认证考试。PMI&#xff1a;美国项目管理协会&#xff08;Project…

【小米路由器3】breed刷机救砖-nand flash硬改SPI flash-编程器救砖(解决ttl无法救砖问题)

大家好&#xff0c;我是老子姓李&#xff01;&#xff08;gzh&#xff1a;楠瘦&#xff09; 本博文带来【小米路由器3】变砖&#xff0c;ttl无法救砖&#xff0c;硬改焊接一块SPI flash&#xff0c;使用编程器刷入小米路由器mini的breed最终成功救砖。 目录1.引言1.1 背景1.2回…

07MEMS传感器技术 讲座

把同步现象应用于传感器设计。 什么是MEMS&#xff1f; 1.mems芯片是什么意思 MEMS是Micro-Electro-Mechanical System的缩写&#xff0c;中文名称是微机电系统。MEMS芯片简而言之&#xff0c;就是用半导体技术在硅片上制造电子机械系统&#xff0c;再形象一点说就是做一个微…

Vue3——第十一章(内置组件:KeepAlive、Transition、TransitionGroup)

一、KeepAlive <KeepAlive> 是一个内置组件&#xff0c;它的功能是在多个组件间动态切换时缓存被移除的组件实例。 1、基本使用 默认情况下&#xff0c;一个组件实例在被替换掉后会被销毁。这会导致它丢失其中所有已变化的状态——当这个组件再一次被显示时&#xff0…

elementui el-table表格实现翻页和搜索均保持勾选状态(后端分页)

需求&#xff1a;不管是页面切换还是通过搜索获取数据&#xff0c;都要保持已选中的行保持勾选状态&#xff0c;同时将选中行的内容以标签的形式显示出来&#xff0c;当点击关闭标签时可以对应取消选中状态&#xff0c;点击行中的任意位置也可以切换选中状态&#xff0c;单独勾…

柳叶刀重磅:30年来首个基于新机制的降压药,可持续降压近一年

全球范围内高血压患者约有13亿&#xff0c;其中10%的患者&#xff08;超过1亿&#xff09;为难治性高血压&#xff0c;即接受了3种以上不同种类的降压药治疗后&#xff0c;血压仍然控制不佳。长期不受控的高血压可能对心脏和血管均会造成损伤&#xff0c;进而增加患者发生心脏病…

Learning Saliency Propagation for Semi-Supervised Instance Segmentation

Abstract 实例分割对于建模和注释来说都是一项具有挑战性的任务。由于注释成本高&#xff0c;建模变得更加困难&#xff0c;因为监督的数量有限。我们的目标是利用大量的检测监督来提高现有实例分割模型的准确性。我们提出了ShapeProp&#xff0c;它学习激活对象检测中的显著区…

【CocosCreator入门】CocosCreator下载安装 | 使用Cocos DashBoard下载各个版本的CocosCreator

Cocos Creator 从 v2.3.2 开始接入了全新的 Dashboard 系统&#xff0c;能够同时对多版本引擎和项目进行统一升级和管理&#xff01;Cocos Dashboard 将做为 Creator 各引擎统一的下载器和启动入口&#xff0c;方便大家升级和管理多个版本的 Creator。此外还集成了统一的项目管…

进程间通信的方式(附代码分析)

进程间通信的方式 1. 进程间通信的几种方式 管道 比如 ls | grep 1;也就是将 进程 ls 拿到的结果作为 grep 1 这个进程的输入。实现了进程间的通信。 消息队列 消息队列就是我们的内核给我们创建的一种消息队列。我们可以往其中发送消息&#xff0c;也可以从其中接收消息。 …

C语言实现有序序列判断

一个数组&#xff0c;判断是否有序看上去很简单&#xff0c;有很多种方法。但实际上有一个很严重的问题&#xff0c;就是重复数会影响判断结果。 我这里提供的思路是取连续的三个数进行比较&#xff0c;a, b, c&#xff0c;假设一共n个元素&#xff0c;数组名是arr&#xff0c…