【K8S系列】深入解析DaemonSet

本文涉及的产品
Elasticsearch Serverless通用抵扣包,测试体验金 200元
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【K8S系列】深入解析DaemonSet

1 基础介绍

1.1 概念介绍

Kubernetes是一个容器编排平台,其中DaemonSet是Kubernetes中的一个重要概念。DaemonSet是一种控制器,用于在集群内运行一组Pod,并确保每个节点上都有一个Pod副本在运行

1.2 常用特性

下面是一些DaemonSet的常用特性:

  1. 只在特定的节点上运行Pod:可以使用NodeSelector或者NodeAffinity来限制DaemonSet的Pod只在特定的节点上运行。
  2. 根据节点的标签更新Pod:如果在集群中添加或删除了节点,Kubernetes会通过DaemonSet自动添加或删除Pod。同时,也可以通过添加或移除节点标签来更新DaemonSet中的Pod。
  3. 确保每个节点只运行一个Pod:可以使用PodAntiAffinity来确保每个节点上只有一个Pod在运行。
  4. 限制DaemonSet的Pod数量:可以使用MaxUnavailable和MaxSurge字段来限制DaemonSet的Pod的最大数量和最小数量。

1.3 简单总结

总之,DaemonSet是一种非常有用的控制器,可以确保集群中每个节点上都有一个Pod副本在运行

它可以自动地根据节点的状态添加或删除Pod,并且可以通过各种方式来控制Pod的位置和数量。

2 工作原理

DaemonSet的工作原理是监听节点的变化,通过监听节点的变化,当新的节点加入集群时,DaemonSet会自动在该节点上创建一个Pod副本。而当节点从集群中删除时,DaemonSet会自动删除该节点上的Pod副本。

这样,DaemonSet保证了集群中每个节点都会运行指定的Pod。有且只有一个pod

2.1 原理介绍

DaemonSet的工作原理如下

  1. 控制器监视节点的状态:DaemonSet控制器会监视集群中的节点状态,一旦有新的节点加入集群,或者节点状态发生变化(例如节点重新启动),控制器就会触发一些操作。
  2. 创建Pod:当控制器检测到新节点时,它会创建一个新的Pod,并将其调度到该节点上。控制器还会确保每个节点上只运行一个Pod实例
  3. 更新Pod:如果DaemonSet的配置发生变化,例如更新了镜像版本或者修改了Pod的配置文件,控制器会自动更新每个节点上的Pod实例。
  4. 删除Pod:如果节点发生故障或者被删除,控制器会自动删除节点上的Pod实例。
  5. 扩容和缩容:DaemonSet还支持扩容和缩容,可以根据需要增加或减少Pod的数量。扩容和缩容的过程与其他控制器类似,控制器会根据指定的副本数和当前的实际Pod数量来调整Pod的数量。

3 使用场景

3.1 场景介绍

DaemonSet用于在集群中运行一组Pod,确保每个节点都有一个Pod在运行。它通常用于运行一些系统级别的服务或者监控应用程序,例如:

  1. 日志收集器:DaemonSet可以在每个节点上运行日志收集器,例如Fluentd或者Filebeat,从而收集所有节点的日志数据,并将其发送到中心日志服务器进行存储和分析。
  2. 监控代理:DaemonSet可以在每个节点上运行监控代理,例如Prometheus Node Exporter或者cAdvisor,从而收集所有节点的运行状态数据,并将其发送到中心监控服务器进行分析和展示。
  3. 网络代理:DaemonSet可以在每个节点上运行网络代理,例如kube-proxy或者Istio Sidecar,从而负责节点之间的网络通信和流量管理。
  4. 安全代理:DaemonSet可以在每个节点上运行安全代理,例如Sysdig Falco或者Aqua Security,从而检测所有节点的安全事件,并及时报警或者进行防御。

总之,DaemonSet适用于需要在每个节点上运行一组Pod的场景可以使集群中的服务更加健壮和可靠。

4 案例讲解

4.1 日志收集

日志收集器是Kubernetes集群中一个重要的组件,它负责在每个节点上运行日志收集器的容器,收集节点和容器的日志数据,并将这些数据发送到集中式的日志系统中。

日志收集方案

  1. 原生方式:使用 kubectl logs 直接在查看本地保留的日志,或者通过docker engine的 log driver 把日志重定向到文件、syslog、fluentd等系统中。
  2. Sidecar方式:一个POD中运行一个sidecar的日志agent容器,用于采集该POD主容器产生的日志。
  3. DaemonSet方式:在K8S的每个node上部署日志agent,由agent采集所有容器的日志到服务端。

在Kubernetes集群中使用日志收集器,DaemonSet方式:会使用DaemonSet来确保每个节点上都有一个日志收集器在运行。

下面是一个使用日志收集器的DaemonSet的示例代码:

apiVersion: v1
kind: ConfigMap #资源类型
metadata:
  name: fluentd-config
  namespace: kube-system
data:
  fluent.conf: |
    <source>
      @type tail
      path /var/log/containers/*.log
      pos_file /var/log/fluentd-containers.log.pos
      time_format %Y-%m-%dT%H:%M:%S.%NZ
      tag kubernetes.*
      read_from_head true
      <parse>
        @type json
        time_key time
        time_format %Y-%m-%dT%H:%M:%S.%NZ
        keep_time_key true
      </parse>
    </source>
    <match kubernetes.**>
      @type elasticsearch
      host elasticsearch.default.svc.cluster.local
      port 9200
      index_name fluentd
      type_name fluentd
      logstash_format true
      logstash_prefix kubernetes
      include_tag_key true
      tag_key kubernetes.tag
      flush_interval 10s
      max_retry_wait 30
      disable_retry_limit
    </match>
---
apiVersion: apps/v1
kind: DaemonSet #资源类型
metadata:
  name: fluentd
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      k8s-app: fluentd-logging
  template:
    metadata:
      labels:
        k8s-app: fluentd-logging
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1.6-debian-elasticsearch7-1.1
        env:
        - name: FLUENT_UID
          value: "0"
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: fluentdconfig
          mountPath: /fluentd/etc/
        resources:
          limits:
            memory: 512Mi
        securityContext:
          privileged: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: fluentdconfig
        configMap:
          name: fluentd-config

上面的示例代码中,首先定义了一个名为fluentd-config的ConfigMap用于存储Fluentd的配置文件。

配置文件中定义了一个名为tail的输入源,它会读取每个容器的日志文件,并使用JSON格式解析日志数据。

配置文件中还定义了一个名为elasticsearch的输出目标,它会将日志数据发送到Elasticsearch中。


接着定义了一个名为fluentd的DaemonSet,它会在每个节点上运行一个fluentd容器。在fluentd容器中,使用了ConfigMap中定义的配置文件,并挂载了/var/log和/var/lib/docker/containers目录,这些目录包含了节点和容器的日志数据。

同时,由于使用了DaemonSet,确保每个节点上都有一个日志收集器在运行,从而提高了集群的可靠性和稳定性。


通过这个示例代码,可以在Kubernetes集群中使用Fluentd作为日志收集器,收集节点和容器的日志数据,并将这些数据发送到集中式的日志系统中。

同时,由于使用了DaemonSet,确保每个节点上都有一个日志收集器在运行,从而提高了集群的可靠性和稳定性。


4.2 监控代理

监控代理是Kubernetes集群中另一个重要的组件,它负责在每个节点上运行监控代理的容器,收集节点和容器的监控数据,并将这些数据发送到集中式的监控系统中。

在Kubernetes集群中使用监控代理,使用DaemonSet来确保每个节点上都有一个监控代理在运行。

下面是一个使用监控代理的DaemonSet的示例代码:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: node-exporter
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-exporter
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: node-exporter
subjects:
- kind: ServiceAccount
  name: node-exporter
  namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet #资源类型
metadata:
  name: node-exporter
  namespace: kube-system
  labels:
    k8s-app: node-exporter
spec:
  selector:
    matchLabels:
      k8s-app: node-exporter
  template:
    metadata:
      labels:
        k8s-app: node-exporter
    spec:
      serviceAccountName: node-exporter
      hostNetwork: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.2.2
        args:
        - --path.procfs=/host/proc
        - --path.sysfs=/host/sys
        - --collector.textfile.directory=/var/lib/node-exporter/textfile_collector
        ports:
        - name: metrics
          containerPort: 9100
          hostPort: 9100
        volumeMounts:
        - name: proc-mount
          mountPath: /host/proc
          readOnly: true
        - name: sys-mount
          mountPath: /host/sys
          readOnly: true
        - name: textfile-collector
          mountPath: /var/lib/node-exporter/textfile_collector
      volumes:
      - name: proc-mount
        hostPath:
          path: /proc
      - name: sys-mount
        hostPath:
          path: /sys
      - name: textfile-collector
        configMap:
          name: node-exporter-textfile-collector

上面的示例代码中,首先定义了一个名为node-exporter的ServiceAccount和一个名为node-exporter的ClusterRoleBinding,用于授权node-exporter在集群中进行操作

接着定义了一个名为node-exporter的DaemonSet,它会在每个节点上运行一个node-exporter容器。

在node-exporter容器中,使用了--path.procfs和--path.sysfs选项来指定了/proc和/sys目录的路径,这些目录包含了节点和容器的监控数据。

同时,使用了--collector.textfile.directory选项来指定了一个目录,用于存储可以通过文本文件方式收集的监控数据。

node-exporter容器还需要挂载/proc和/sys目录以及用于存储文本文件的目录。

通过这个示例代码,在Kubernetes集群中使用node-exporter作为监控代理,收集节点和容器的监控数据,并将这些数据发送到集中式的监控系统中。

同时,由于使用了DaemonSet,确保每个节点上都有一个监控代理在运行,从而提高了集群的可靠性和稳定性。

4.3 网络代理

网络代理是Kubernetes集群中的重要组件之一,它负责实现节点之间的网络通信和流量管理。

Kubernetes中内置了一个网络代理组件kube-proxy,它使用iptables或者IPVS来实现节点之间的流量转发和负载均衡。

在Kubernetes集群中使用kube-proxy,通常会使用DaemonSet来确保每个节点上都有一个网络代理在运行。

下面是一个使用kube-proxy的DaemonSet的示例代码:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: kube-proxy
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kube-proxy
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:node-proxier
subjects:
- kind: ServiceAccount
  name: kube-proxy
  namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet #资源类型
metadata:
  name: kube-proxy
  namespace: kube-system
  labels:
    k8s-app: kube-proxy
spec:
  selector:
    matchLabels:
      k8s-app: kube-proxy
  template:
    metadata:
      labels:
        k8s-app: kube-proxy
    spec:
      serviceAccountName: kube-proxy
      hostNetwork: true
      containers:
      - name: kube-proxy
        image: k8s.gcr.io/kube-proxy:v1.22.0
        command:
        - /usr/local/bin/kube-proxy
        args:
        - --config=/var/lib/kube-proxy/config.conf
        securityContext:
          privileged: true
        volumeMounts:
        - name: kube-proxy-config
          mountPath: /var/lib/kube-proxy
          readOnly: true
        - name: xtables-lock
          mountPath: /run/xtables.lock
          readOnly: false
          subPath: xtables.lock
      volumes:
      - name: kube-proxy-config
        configMap:
          name: kube-proxy-config
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock

上面的示例代码中,首先定义了一个名为kube-proxy的ServiceAccount和一个名为kube-proxy的ClusterRoleBinding用于授权kube-proxy在集群中进行操作

接着定义了一个名为kube-proxy的DaemonSet,它会在每个节点上运行一个kube-proxy容器。

在kube-proxy容器中,使用了--config选项来指定了配置文件的路径,这个配置文件可以通过一个名为kube-proxy-config的ConfigMap来动态生成。

kube-proxy容器还需要挂载/run/xtables.lock文件来确保在使用iptables或者IPVS时不会发生竞争条件

通过这个示例代码,在Kubernetes集群中使用kube-proxy作为网络代理,实现节点之间的流量转发和负载均衡

同时,由于使用了DaemonSet,确保每个节点上都有一个网络代理在运行,从而提高了集群的可靠性和稳定性。

4.4 安全代理

安全代理是Kubernetes集群中另一个重要的组件,它负责在每个节点上运行安全代理的容器,保护节点和容器的网络流量安全,并确保集群中的网络流量只能访问授权的服务和资源。

在Kubernetes集群中使用安全代理,使用DaemonSet来确保每个节点上都有一个安全代理在运行。

下面是一个使用安全代理的DaemonSet的示例代码:

apiVersion: apps/v1
kind: DaemonSet #资源类型
metadata:
  name: envoy
  namespace: kube-system
  labels:
    k8s-app: envoy
spec:
  selector:
    matchLabels:
      k8s-app: envoy
  template:
    metadata:
      labels:
        k8s-app: envoy
    spec:
      containers:
      - name: envoy
        image: envoyproxy/envoy:v1.19.1
        ports:
        - containerPort: 8080
          name: http
        - containerPort: 8443
          name: https
        volumeMounts:
        - name: envoy-config
          mountPath: /etc/envoy
        - name: envoy-tls
          mountPath: /etc/envoy-tls
          readOnly: true
        securityContext:
          runAsUser: 10001
      terminationGracePeriodSeconds: 30
      volumes:
      - name: envoy-config
        configMap:
          name: envoy-config
        - name: envoy-tls
          secret:
            secretName: envoy-tls

上面的示例代码中,首先定义了一个名为envoy-config的ConfigMap,用于存储Envoy的配置文件。

接着定义了一个名为envoy-tls的Secret,用于存储Envoy的TLS证书和私钥。

然后定义了一个名为envoy的DaemonSet它会在每个节点上运行一个envoy容器

在envoy容器中,使用了ConfigMap中定义的配置文件,并挂载了/etc/envoy和/etc/envoy-tls目录,这些目录包含了Envoy的配置文件和TLS证书和私钥。

同时,由于使用了DaemonSet,确保每个节点上都有一个安全代理在运行,从而提高了集群的安全性和可靠性。

通过这个示例代码,可以在Kubernetes集群中使用Envoy作为安全代理,保护节点和容器的网络流量安全,并确保集群中的网络流量只能访问授权的服务和资源。

同时,由于使用了DaemonSet,确保每个节点上都有一个安全代理在运行,从而提高了集群的安全性和可靠性。

5 总结

DaemonSet 的主要作用,是让你在 Kubernetes 集群里,运行一个 Daemon Pod

所以,这个 Pod 有如下三个特征:

  1. 这个 Pod 运行在 Kubernetes 集群里的每一个节点(Node)上
  2. 每个节点上只有一个这样的 Pod 实例
  3. 当有新的节点加入 Kubernetes 集群后,该 Pod 会自动地在新节点上被创建出来;而当旧节点被删除后,它上面的该 Pod 也相应地会被回收掉。

Daemon Pod机制听起来很简单,但的意义确实是非常重要的。列举几个例子:

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

DaemonSet 其实是一个非常简单的控制器。在它的控制循环中,只需要遍历所有节点,然后根据节点上是否有被管理 Pod 的情况,来决定是否要创建或者删除一个 Pod。

相比于 Deployment,DaemonSet 只管理 Pod 对象,然后通过 nodeAffinity 和 Toleration 这两个调度器的小功能,保证了每个节点上有且只有一个 Pod。

与此同时,DaemonSet 使用 ControllerRevision,来保存和管理自己对应的“版本”。

这种“面向 API 对象”的设计思路,大大简化了控制器本身的逻辑,也正是 Kubernetes 项目“声明式 API”的优势所在

6 投票

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
9月前
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
|
11月前
|
Kubernetes 监控 调度
【赵渝强老师】K8s的DaemonSet控制器
DaemonSet控制器确保每个节点上运行一个Pod副本,适用于监控、日志收集等场景。通过示例创建DaemonSet并查看Pod信息,展示了其自动扩展和回收的能力。视频讲解和代码示例详细说明了DaemonSet的使用方法和调度机制。
148 1
|
11月前
|
Kubernetes 监控 API
深入解析Kubernetes及其在生产环境中的最佳实践
深入解析Kubernetes及其在生产环境中的最佳实践
576 93
|
Kubernetes API 调度
Kubernetes 架构解析:理解其核心组件
【8月更文第29天】Kubernetes(简称 K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用。它提供了一个可移植、可扩展的环境来运行分布式系统。本文将深入探讨 Kubernetes 的架构设计,包括其核心组件如何协同工作以实现这些功能。
844 2
|
Kubernetes 监控 调度
在K8S中,DaemonSet类型资源特性?
在K8S中,DaemonSet类型资源特性?
|
9月前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
2358 11
|
11月前
|
运维 Kubernetes Cloud Native
Kubernetes云原生架构深度解析与实践指南####
本文深入探讨了Kubernetes作为领先的云原生应用编排平台,其设计理念、核心组件及高级特性。通过剖析Kubernetes的工作原理,结合具体案例分析,为读者呈现如何在实际项目中高效部署、管理和扩展容器化应用的策略与技巧。文章还涵盖了服务发现、负载均衡、配置管理、自动化伸缩等关键议题,旨在帮助开发者和运维人员掌握利用Kubernetes构建健壮、可伸缩的云原生生态系统的能力。 ####
|
11月前
|
存储 Kubernetes 调度
深度解析Kubernetes中的Pod生命周期管理
深度解析Kubernetes中的Pod生命周期管理
|
12月前
|
存储 Kubernetes 监控
深度解析Kubernetes在微服务架构中的应用与优化
【10月更文挑战第18天】深度解析Kubernetes在微服务架构中的应用与优化
418 0
|
Prometheus Kubernetes 监控
在K8S中,DaemonSet类型的资源特性有哪些?
在K8S中,DaemonSet类型的资源特性有哪些?

热门文章

最新文章

推荐镜像

更多