首页 > 其他分享 >一文读懂DaemonSet以及实践攻略

一文读懂DaemonSet以及实践攻略

时间:2024-09-19 21:21:21浏览次数:12  
标签:fluentd Fluentd 读懂 DaemonSet 攻略 Pod kubectl 节点

一文读懂DaemonSet以及实践攻略

目录

❤️ 摘要: 在 Kubernetes 集群中,DaemonSet 是用于在每个(或特定)节点上运行一个 Pod 副本的控制器。通常情况下,DaemonSet 用于部署集群中的基础服务,如日志收集、监控代理、网络插件等。这些服务需要在每个节点上运行,以确保对整个集群的全面覆盖和管理。这篇博客会带着读者将详细了解 DaemonSet 的核心概念、适用场景,并展示如何通过实际案例来创建和管理 DaemonSet。

❤️ 如果想对比Deployment、StatefulSet、DaemonSet三种工作负载,可以浏览相关文章。《一文读懂Deployment以及实践攻略》《一文读懂StatefulSet以及实践攻略》

1 概念

1.1 什么是DaemonSet

DaemonSet 是 Kubernetes 中的一种常见控制器,会规定在每个(或特定)节点上都运行一个或几个 同样Pod 。想象一下,你是一名Kubernetes小镇的管理员,你的职责是确保每个Node街区居民都能收到邮件。为了完成这个任务,你需要一个DaemonSet邮件分派系统,这个系统会自动给小镇中的每一街区安排一个Pod邮递员,不管小镇以后扩建了多少新街区,都会有新的Pod邮递员分派到该街区完成派件任务。

1.2 DaemonSet 的工作机制

DaemonSet 的核心功能是确保指定 Pod 在集群中的每个节点上都运行一个副本,当有新节点加入时,DaemonSet 会自动在新节点上调度一个 Pod 副本,并确保其正常运行。当节点从集群中删除时,这些 Pod 就会被垃圾收集。

DaemonSet 具备以下特性:

  • 自动部署到新节点:当集群中有新的节点加入时,DaemonSet 自动在该节点上运行指定的 Pod 副本。
  • 支持特定节点:可以通过节点选择器(NodeSelector)或节点亲和性(NodeAffinity)指定 DaemonSet 仅在某些节点上运行。
  • 独立管理和更新:可以独立管理和更新集群中的系统服务,而不影响应用层的服务。

1.3 适用场景

DaemonSet 主要用于需要在每个节点上运行相同任务的场景,例如:

  • 日志收集器:如 Fluentd、Filebeat,用于在每个节点上收集日志。
  • 监控代理:如 Prometheus Node Exporter,用于在每个节点上收集监控数据。
  • 网络插件:如 Calico、Weave 等,负责网络的配置和管理。
  • 存储系统:如 Ceph 或 GlusterFS 的代理进程,用于在每个节点上进行存储管理。

1.4 DaemonSet 与 Deployment 的区别

DaemonSet 与 Deployment 是类似的,都会创建非终止性 Pod,而DaemonSet 与 Deployment 的主要区别在于它确保在每个节点上运行一个副本,则Deployment 的副本数是固定的,并且可以分布在任意节点上。以下的特点对比:

特性DaemonSetDeployment
副本数每个节点一个副本(可以是所有节点或指定节点)。副本数是固定的,并分布在任意节点。
Pod 分布自动在每个(或特定)节点上创建 Pod。根据调度器在节点上分布 Pod。
主要用途集群范围内的系统服务(监控、日志收集等)。无状态或有状态的应用服务。

此外,官方也给出其他替代DaemonSet的方法,作为了解:

  1. Init 脚本
    • 通过传统的系统服务管理工具(如 initsystemd)在每个节点上启动守护进程。这是 DaemonSet 的传统替代方式,但与 Kubernetes 的 Pod 管理工具(如 kubectl)集成度较低。使用 DaemonSet 能获得更好的监控和日志管理,还可以利用容器的资源隔离特性。
  2. 裸 Pod
    • 可以直接创建固定在某个节点上的 Pod,但这种方式缺少 DaemonSet 的自愈能力。比如当节点故障或进行维护时,裸 Pod 不会自动重新调度到其他节点,而 DaemonSet 会自动管理这些场景。
  3. 静态 Pod
    • 静态 Pod 是由 Kubelet 直接管理的 Pod,通常用于集群启动时的场景。它们不依赖 Kubernetes API,也不能通过 kubectl 管理。尽管静态 Pod 有一定的用例,但未来可能会被弃用。

1.5 DaemonSet的通信模式

目前官方给出几种与 DaemonSet 中的 Pod 进行通信的常见模式:

  1. Push(推送模式)
    • DaemonSet 中的 Pod 被配置为将信息推送到另一个服务(如数据库)。这种模式下,DaemonSet 的 Pod 是主动发送信息的,类似于Fluentd 收集日志并推送到 Elasticsearch,不需要其他客户端直接与这些 Pod 交互。
  2. NodeIP 和已知端口
    • DaemonSet 中的 Pod 可以通过 hostPort 暴露端口,这样每个节点上的 Pod 就能通过节点的 IP 和指定的端口直接访问。例如Prometheus 的 Node Exporter 通过节点 IP 和端口进行访问并收集每个节点的资源利用率数据。
  3. DNS
    • 使用无头服务(headless service)来为 DaemonSet Pod 提供 DNS 发现。客户端可以通过 Kubernetes 的 endpoints 资源或 DNS 中的多个 A 记录来发现并与这些 Pod 进行通信。无头服务不创建 Cluster IP,而是直接通过 Pod 的 IP 进行通信。
  4. Service(服务)
    • 通过 Kubernetes 服务来访问 DaemonSet 中的 Pod。服务会随机选择一个 Pod 来处理请求,这意味着客户端不能选择具体的节点进行访问。这种模式适合不依赖于节点的具体性,更多地关注负载均衡的场景。

2 实践案例:部署和更新 Fluentd 日志收集器

以下是如何通过 DaemonSet 来部署一个 Fluentd 日志收集器的案例,它会在每个 Kubernetes 节点上运行,用于收集节点和应用的日志数据。

2.1 部署Fluentd DaemonSet

2.1.1 定义Fluentd DaemonSet

首先,定义一个Fluent的配置文件,后续将该配置挂载到pod上。

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
data:
  fluent.conf: |
    <source>
      @type tail
      path /var/log/*.log
      pos_file /var/log/td-agent/var_log.pos
      tag var.log.*
      <parse>
        @type none
      </parse>
    </source>

    <source>
      @type tail
      path /var/lib/docker/containers/*/*.log
      pos_file /var/log/td-agent/docker_containers.pos
      tag docker.containers.*
      <parse>
        @type json
      </parse>
    </source>

我们再定义一个 DaemonSet,确保 Fluentd 能在每个节点上部署并运行:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  labels:
    app: fluentd
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      containers:
      - name: fluentd
        image: harbor.zx/hcie/fluentd:v3.4.0
        volumeMounts:
        - name: varlog
          mountPath: /var/log
          readOnly: true
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: config-volume
          mountPath: /etc/fluent/config.d/fluent.conf
          subPath: fluent.conf
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: config-volume
        configMap:
          name: fluentd-config

❔ 参数说明: fluent的每个pod都挂载两个主机卷做volume

  • varlog:是节点路径/var/log,存放当前节点的系统日志和应用日志。
  • varlibdockercontainers: 是节点路径/var/lib/docker/containers,存在当前节点所有运行Containerd的日志和配置文件。
  • config-volume: 是fluent的配置文件
  • fluent对这两个目录权限是只读权限。

2.1.2 部署 DaemonSet

执行以下命令将定义的 DaemonSet 部署到 Kubernetes 集群中:

kubectl apply -f fluentd-configmap.yaml
kubectl apply -f fluentd-daemonset.yaml

2.1.3 验证 DaemonSet 部署

你可以通过以下命令查看 DaemonSet 的 Pod 状态:

kubectl get pods -l app=fluentd

输出将显示 Fluentd Pod 在每个节点上的分布情况:

NAME            READY   STATUS    RESTARTS   AGE
fluentd-lhjbn   1/1     Running   0          6m4s
fluentd-m58wd   1/1     Running   0          6m4s
fluentd-p979h   1/1     Running   0          6m4s
fluentd-qjq29   1/1     Running   0          6m4s
fluentd-rz7q8   1/1     Running   0          6m5s

也可以通过以下命令查看 DaemonSet 的 状态:

 kubectl get ds -l app=fluentd

输出将显示 Fluentd DaemonSet总体情况:

NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
fluentd   5         5         5       5            5           <none>          6m24s

2.1.4 验证日志收集

检查 Fluentd 是否在正确收集日志数据。你可以查看 Fluentd Pod 的日志来确认:

kubectl logs fluentd-abc12

日志输出将显示 Fluentd 成功从 /var/log/var/lib/docker/containers 中收集日志数据。

2024-09-19 08:20:59 +0000 [info]: #0 starting fluentd worker pid=17 ppid=1 worker=0
2024-09-19 08:20:59 +0000 [error]: #0 unexpected error error_class=Errno::EROFS error="Read-only file system @ dir_s_mkdir - /var/log/td-agent"
  2024-09-19 08:20:59 +0000 [error]: #0 /usr/local/lib/ruby/2.7.0/fileutils.rb:247:in `mkdir'
  2024-09-19 08:20:59 +0000 [error]: #0 /usr/local/lib/ruby/2.7.0/fileutils.rb:247:in `fu_mkdir'
  2024-09-19 08:20:59 +0000 [error]: #0 /usr/local/lib/ruby/2.7.0/fileutils.rb:228:in `block (2 levels) in mkdir_p'
  2024-09-19 08:20:59 +0000 [error]: #0 /usr/local/lib/ruby/2.7.0/fileutils.rb:226:in `reverse_each'
  2024-09-19 08:20:59 +0000 [error]: #0 /usr/local/lib/ruby/2.7.0/fileutils.rb:226:in `block in mkdir_p'

2.2 配置节点选择器(可选)

如果你希望 Fluentd 只运行在特定的节点上,可以为 DaemonSet 添加节点选择器。比如我们想让 Fluentd 只运行在标签为 logging=true 的节点上:

spec:
  template:
    spec:
      nodeSelector:
        logging: "true"

或者使用节点亲和性与容忍度(Taints & Tolerations),可以将DaemonSet只部署在控制平面的节点上:

  tolerations:
  # these tolerations are to have the daemonset runnable on control plane nodes
  # remove them if your control plane nodes should not run pods
  - key: node-role.kubernetes.io/control-plane
    operator: Exists
    effect: NoSchedule
  - key: node-role.kubernetes.io/master
    operator: Exists
    effect: NoSchedule

❔ 说明: 关于节点亲和度和容忍度在后续文章详细说明。

2.3 资源限制(可选)

每个 运行的DaemonSet Pod 都会消耗节点的资源,确保为其分配足够的 CPU 和内存,避免影响应用的正常运行。

如果要对pod进行资源的配额和限制,可以添加以下参数:

      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi

❔ 说明: 关于pod的资源QOS在后续文章详细说明。


2.4 更新DaemonSet

2.4.1 更新策略

DaemonSet的更新策略与StatefulSet的一致,支持OnDeleteRollingUpdate两种类型。

  1. 设置更新策略为OnDelete, DaemonSet控制器不会自动更新 Pod。用户必须手动删除 Pod ,控制器会对 按DaemonSet 的.spec.template更新的内容创建新 Pod。
  2. 设置更新策略为RollingUpdate,DaemonSet会控制Pod的生命周期,按照更新的模板和更新策略参数自动完成更新流程。以下是更新策略参数说明:
参数说明可能值
.spec.updateStrategy.rollingUpdate.partition控制平面会在 Pod 准备就绪后继续等待该时间,然后再继续。如果应用启动还要加载第三方组件等, 建议设置该值,或者使用就绪探针。默认是0s
.spec.updateStrategy.rollingUpdate.maxSurge指定在更新期间可以拥有更新的 DaemonSet pod的数量,可以是数值或者百分数,与maxUnavailable互斥该字段适用于0到replicas - 1,默认是0
.spec.updateStrategy.rollingUpdate.maxUnavailable指定以下参数来控制更新期间不可用的最大 Pod 数量,可以是数值或者百分数,与maxSurge互斥该字段适用于0到replicas - 1范围内的所有 Pod,默认是1

2.4.2 查看更新策略

我们沿用上面部署的daemonSet例子,执行以下命令查看默认策略:

kubectl get ds/fluentd -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'

输出如下:

RollingUpdate

2.4.3 更新DaemonSet镜像

kubectl set image ds/fluentd fluentd=harbor.zx/hcie/fluentd:v4.6

2.4.4 查看滚动更新状态

kubectl rollout status ds/fluentd

更新完成后,输出类似于以下内容:

Waiting for daemon set "fluentd" rollout to finish: 1 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 1 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 2 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 2 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 2 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 3 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 3 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 4 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 4 out of 5 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 4 of 5 updated pods are available...
daemon set "fluentd" successfully rolled out


查看更新后的daemonSet信息

[root@k8s-master1 hcie]# kubectl describe ds
Name:           fluentd
Selector:       app=fluentd
Node-Selector:  <none>
Labels:         app=fluentd
Annotations:    deprecated.daemonset.template.generation: 2
Desired Number of Nodes Scheduled: 5
Current Number of Nodes Scheduled: 5
Number of Nodes Scheduled with Up-to-date Pods: 5
Number of Nodes Scheduled with Available Pods: 5
Number of Nodes Misscheduled: 0
Pods Status:  5 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=fluentd
  Containers:
   fluentd:
     Image:        harbor.zx/hcie/fluentd:v4.6

2.5 回滚DaemonSet

DaemonSet回滚的流程大致跟StatefulSet一致,以下案例也是将DaemonSet更新错镜像版本,然后验证如何回滚的过程。

现在我们引入一个错误的 Fluentd 镜像,故意将版本号设置为一个不存在的版本,观察更新失败的情况。

2.5.1 引入错误的 Fluentd 镜像:

修改 fluentd-daemonset.yaml,将 Fluentd 镜像改为不存在的版本 v9.99.0

kubectl set image ds/fluentd fluentd=harbor.zx/hcie/fluentd:v4.7.0

查看滚动更新的状态:

kubectl rollout status daemonset/fluentd

验证 Pod 的状态:

kubectl get pods m -o wide

❔说明: 因为 Kubernetes 无法拉取 fluent/fluentd:v4.7.0 镜像,Pod 状态会显示 ImagePullBackOff 错误。

使用 describe 命令查看失败原因:

kubectl describe pod fluentd-mhqhb

输出如下:

Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  2m40s                default-scheduler  Successfully assigned default/fluentd-mhqhb to k8s-worker2
  Warning  Failed     82s (x6 over 2m36s)  kubelet            Error: ImagePullBackOff
  Normal   Pulling    70s (x4 over 2m37s)  kubelet            Pulling image "harbor.zx/hcie/fluentd:v4.7.0"
  Warning  Failed     70s (x4 over 2m37s)  kubelet            Failed to pull image "harbor.zx/hcie/fluentd:v4.7.0": rpc error: code = NotFound desc = failed to pull and unpack image "harbor.zx/hcie/fluentd:v4.7.0": failed to resolve reference "harbor.zx/hcie/fluentd:v4.7.0": harbor.zx/hcie/fluentd:v4.7.0: not found
  Warning  Failed     70s (x4 over 2m37s)  kubelet            Error: ErrImagePull
  Normal   BackOff    56s (x7 over 2m36s)  kubelet            Back-off pulling image "harbor.zx/hcie/fluentd:v4.7.0"


回滚DaemonSet 到之前的版本

当引入错误后,Pod 无法正常运行,我们可以回滚到之前的 v4.6 版本。

查看**DaemonSet **历史稳定版本:

kubectl rollout history daemonset fluentd

输出如下:

daemonset.apps/fluentd
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

当前状态版本是最新的版本,如果不确定,可以执行以下命令

kubectl rollout history daemonset fluentd --revision=3

输出如下:

daemonset.apps/fluentd with revision #3
Pod Template:
  Labels:       app=fluentd
  Containers:
   fluentd:
    Image:      harbor.zx/hcie/fluentd:v4.7.0
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>

执行回滚操作:

kubectl rollout undo daemonset fluentd

❔ 参数说明: --to-revision指定历史版本,如果未指定则是默认上一版本。

查看滚动更新的状态,确保所有 Pod 都已经恢复正常:

kubectl rollout status daemonset/fluentd 

如果输入如下,证明回滚成功;

daemon set "fluentd" successfully rolled out

验证 Pod 是否恢复正常:

kubectl get pods -o wide

输入如下:

NAME            READY   STATUS    RESTARTS   AGE   IP               NODE          NOMINATED NODE   READINESS GATES
fluentd-26ksx   1/1     Running   0          78m   172.16.194.65    k8s-worker1   <none>           <none>
fluentd-8wnhj   1/1     Running   0          76m   172.16.224.59    k8s-master2   <none>           <none>
fluentd-ddxbp   1/1     Running   0          75m   172.16.159.155   k8s-master1   <none>           <none>
fluentd-hmqds   1/1     Running   0          79m   172.16.135.242   k8s-master3   <none>           <none>
fluentd-xhl7b   1/1     Running   0          55s   172.16.126.12    k8s-worker2   <none>           <none>


3 总结

DaemonSet 是 Kubernetes 中用于集群范围部署的一种强大的控制器,特别适用于那些需要在每个节点上运行系统服务的场景。通过本文的介绍,你可以轻松地部署日志收集器、监控代理等服务,实现对集群的全面监控和日志管理。

4 参考资料

[1]DaemonSet

[2]Perform a Rolling Update on a DaemonSet

[3]Perform a Rollback on a DaemonSet

标签:fluentd,Fluentd,读懂,DaemonSet,攻略,Pod,kubectl,节点
From: https://blog.csdn.net/u013522701/article/details/142370278

相关文章

  • 互联网算法备案必要性+攻略全流程详解【附件+流程】
    一、算法备案的重要性算法备案是指相关企业或组织向有关部门提交其使用的算法的相关信息,以接受监管和审查。这一举措有助于确保算法的公正性、透明性和合法性,保护用户的权益,促进数字经济的健康发展。算法备案必要性强制性例如,在推荐系统中,如果算法存在偏见或歧视,可能会导致......
  • cisp-pte考试靶场及通关攻略(附靶场源码)
    cisp-pte考试靶场及通关攻略(附靶场源码)靶机安装关注后回复【pte靶场】即可,有网安交流群,要进群的小伙伴后台加群即可vm启动后改静态ipservicenetworkrestart或者重启reboot第一题【sql注入】注意这个文件路径,待会要获取答案orderby判断字段数量union判断,被过滤发......
  • 【渗透测试】ATT&CK靶场一,phpmyadmin,域渗透,内网横向移动攻略
    前言VulnStack,作为红日安全团队匠心打造的知识平台,其独特优势在于全面模拟了国内企业的实际业务场景,涵盖了CMS、漏洞管理及域管理等核心要素。这一设计理念源于红日安全团队对ATT&CK红队评估设计模式的深刻理解和巧妙应用。靶场环境的构建与题目设计均围绕环境搭建、漏洞利用、内......
  • 加速你答题效率的海外问卷调查攻略!
    海外问卷调查是一种在多国公司与机构间广泛应用的数据收集方式,通常以商业目的为主。大家好,我是向阳海外问卷。许多人在接触海外问卷时常感到困惑,难以适应或理解问题,甚至会将其视为一种专业考试。其实,海外问卷调查并没有那么复杂,核心目标只是进行各种市场调查而已。那么......
  • 学霸必备:这些Zotero插件全攻略,让你的研究如鱼得水
     插件管理Zotero有非常丰富的插件zotero官方推荐插件,网页链接:zotero官方推荐插件GitHub官网插件下载链接:GitHub官网下载1.Scholaread靠岸学术——文献翻译手机阅读scholaread靠岸学术插件下载:Scholaread靠岸学术插件下载Scholaread靠岸学术官网:Scholaread靠岸学术官网S......
  • xss-labs靶场:level11攻略 抓包工具的巧妙利用
    攻略第十关后稍作休整,我们继续来看第十一关:和上一关一样,提供给我们的仅有的参数是URL中的keyword,很明显,这个参数是无法利用的,我们查看页面源代码发现依然是有一个隐藏表单的存在,但是,我们发现表单中多了一个参数t_ref即<formid="search"><inputname="t_link"value=""t......
  • 亚马逊广告指南:类型攻略与效果优化宝典
    据最新发布的《2024年媒体广告报告》显示,亚马逊不仅在全球最具价值品牌榜单中跃居第五位,更已成为广告领域核心平台之一。鉴于此趋势,做好亚马逊广告,是跨境卖家实现商品热销和品牌推广的关键步骤。本文将分享亚马逊广告的类型并给出选择建议,同时给予优化亚马逊广告投放效果的方法......
  • 《幸福工厂》风灵月影使用指南:无限生命、最大背包空间、忽略生产要求攻略
    本指南旨在帮助您了解如何安全有效地使用风灵月影这一辅助工具,以增强您的游戏体验。请注意,使用修改器可能会影响游戏的平衡性和成就感,建议仅在需要时或特定情况下使用。第一步:下载与安装1.访问官方或可信资源:首先,确保从官方网站或其他可靠的游戏修改器平台下载最新版本的修......
  • 红帽RHCA认证什么级别?红帽认证等级细分攻略
    Linux系统作为开源软件的杰出典范,于服务器、云计算、大数据等诸多领域占据着至关重要的地位。对于矢志在Linux领域精研深耕的技术人才而言,红帽认证无疑是擢升技能与职业竞争力的关键密钥。今日,我们即将深度剖析RHCA红帽认证架构师这一顶级认证,以及红帽认证的等级细分策略。RHC......
  • 红帽RHCA认证什么级别?红帽认证等级细分攻略
    Linux系统作为开源软件的杰出典范,于服务器、云计算、大数据等诸多领域占据着至关重要的地位。对于矢志在Linux领域精研深耕的技术人才而言,红帽认证无疑是擢升技能与职业竞争力的关键密钥。今日,我们即将深度剖析RHCA红帽认证架构师这一顶级认证,以及红帽认证的等级细分策......