kubernete编排技术五:DaemonSet

本文涉及的产品
Elasticsearch Serverless通用抵扣包,测试体验金 200元
简介: kubernete编排技术五:DaemonSet

微信图片_20221212135205.jpg写留言这篇文章我们来介绍kubernete的一个编排对象,叫DaemonSet,从名字上就能看出,这是一个守护进程。它的作用是在kubernete集群的每个节点上都会创建一个Daemon Pod,而且仅有一个。


作为容器的守护进程,这个Daemon Pod的典型应用是运行网络插件、存储插件、监控和日志组件等。


yaml文件


DaemonSet在yaml中的声明很简单,只要声明api对象的kind是DaemonSet即可。我们写一个文件daemonset.yaml,内容如下:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # this toleration is to have the daemonset runnable on master nodes
      # remove it if your masters can't run pods
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

上面这个yaml文件来自官网。可以看到上面的kind是DaemonSet。这个DaemonSet,管理的pod中的镜像是fluentd-elasticsearch镜像,这个镜像的作用是通过fluentd将Docker容器里的日志收集到ElasticSearch。


下面我对这个yaml文件做一个说明:

  • 文件中定义了一个template,这个template声明了labels是fluentd-elasticsearch。
  • DaemonSet的yaml文件中,RestartPolicy要不不指定,如果指定必须指定为always,其实不指定默认也是always。
  • DaemonSet的yaml文件中必须定义.spec.selector,这个selector跟pod中的selector含义是一样的,包括2个元素,matchLabels(跟replicas中一样)和matchExpressions(通过键值列表构建更复杂的选择器)。这个选项是用来匹配携带.spec.template.metadata.labels标签中的api对象。


调度策略


Daemon pod由kubernete scheduler调度到需要的node上,然后由DaemonSet Controller在node上进行创建和调度。


DaemonSet Controller首先从Etcd里获取所有的Node列表,然后依次遍历Node,如果当前node上没有携带name=fluentd-elasticsearch标签的pod,就创建一个,如果有多余一个,就删除多余的。


跟普通pod不一样的是,Daemon pod在创建之前不会进入pending状态。


那DaemonSet怎么控制pod在指定节点上运行呢?它是通过nodeAffinity这个标签来管理的。在Daemon pod中增加NodeAffinity元素来取代.spec.nodeName,就可以使用默认的scheduler来取代DaemonSet Controller来对DaemonSets进行调度,然后默认的调度器再把pod调度到需要的节点上。如下:

nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchFields:
      - key: metadata.name
        operator: In
        values:
        - target-host-name

如果node上已经存在affinity的pod,则默认调度器会用新创建的pod取代它。而DaemonSet controller不会这么做。

上面的requiredDuringSchedulingIgnoredDuringExecution是说,这个nodeAffinity必须在每次调度的时候都进行考虑,而在运行阶段不用考虑。而且这个pod只允许运行在metadata.name是target-host-name的节点上创建。


注:上面的operator的语法非常丰富,这里用in是包含关系,也可以是Equal,等于关系。


DaemonSet还会给Daemon Pod加上Tolerations,它的意思是可以容忍一些Taints(污点)

apiVersion: v1
kind: Pod
metadata:
  name: with-toleration
spec:
  tolerations:
  - key: node.kubernetes.io/unschedulable
    operator: Exists
    effect: NoSchedule

这段代码中,effect: NoSchedule就是指node一个Taints即不能被任何pod调度,但是DaemonSet给管理的pod加上Toleration后,Daemon pod就会忽略这个限制,继续对有这个node上的pod进行调度。

这就是DaemonSet的特殊之处,它能够通过tolerations来对有Taints限制的节点上的pod进行调度,比如,我们要对有node.kubernetes.io/network-unavailableTaints的节点进行网络调度,就可以定义如下的tolerations

template:
    metadata:
      labels:
        name: network-plugin-agent
    spec:
      tolerations:
      - key: node.kubernetes.io/network-unavailable
        operator: Exists
        effect: NoSchedule

虽然DaemonSet可以在yaml中声明式的定义toleration,但是下面的toleration会自动添加到DaemonSet创建的pod中,如下图:

微信图片_20221212135348.png

创建、升级和回滚


执行下面命令,创建Daemon pod


kubectl apply -f daemonset.yaml

过几分钟查看pods,如下:

[root@master k8s]# kubectl get pod -n kube-system -l name=fluentd-elasticsearch
NAME                          READY   STATUS    RESTARTS   AGE
fluentd-elasticsearch-5mgqr   1/1     Running   0          147m
fluentd-elasticsearch-6nwlp   1/1     Running   0          147m

可以看到DaemonSet创建了2个pod,而我本地的kubernete集群只有2个节点,一个master和一个普通节点,这2个节点都调度了一个Daemon pod,而普通pod是不能调度到master节点的,这就是DaemonSet的tolerations生效了。

我们可以向Deployment那样管理DaemonSet的版本,如下:


kubectl rollout history daemonset fluentd-elasticsearch -n kube-system

接着我们把fluentd-elasticsearch镜像的版本升级到v2.2.0


kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=k8s.gcr.io/fluentd-elasticsearch:v2.2.0 --record -n=kube-system

这时我们再查看版本更新的历史,如下:

[root@worker1 ~]# kubectl rollout history daemonset fluentd-elasticsearch -n kube-system
daemonset.apps/fluentd-elasticsearch 
REVISION  CHANGE-CAUSE
2         kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=k8s.gcr.io/fluentd-elasticsearch:v2.2.0 --record=true --namespace=kube-system
3         <none>

总结


DaemonSet的调度策略其实是在创建Daemon pod时给这个Pod加上一个nodeAffinity,从而保证这个Pod能够在指定节点上启动。通过给这个Pod加上一个 Toleration,从而保证pod能在有Taints限制的节点上创建。

DaemonSet的升级和回滚策略跟Deployment非常相似,不同的是,它管理版本用的是ControllerRevision对象。

一般情况下,Daemon pod跟普通的pod功能一样,但是如果给守护进程做程序配置、监控和日志收集,使用DaemonSet更合适一些。有时候我们要指定一些节点创建pod,也可以使用DaemonSet。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
消息中间件 负载均衡 网络协议
ActiveMQ详细配置方案
本文总结ActiveMQ重要的一些配置,包括高可用failover配置、消息策略等。
1185 0
|
前端开发 测试技术 对象存储
Grafana Loki查询加速:如何在不添加资源的前提下提升查询速度
Grafana Loki查询加速:如何在不添加资源的前提下提升查询速度
460 59
|
存储 NoSQL Java
分布式session-SpringSession的应用
Spring Session 提供了一种创建和管理 Servlet HttpSession 的方案,默认使用外置 Redis 存储 Session 数据,解决了 Session 共享问题。其特性包括:API 及实现用于管理用户会话、以应用容器中性方式替换 HttpSession、简化集群会话支持、管理单个浏览器实例中的多个用户会话以及通过 headers 提供会话 ID 以使用 RESTful API。Spring Session 通过 SessionRepositoryFilter 实现,拦截请求并转换 request 和 response 对象,从而实现 Session 的创建与管理。
322 0
分布式session-SpringSession的应用
|
前端开发 NoSQL Java
面试官:如何防止短信盗刷和短信轰炸?
面试官:如何防止短信盗刷和短信轰炸?
651 1
|
安全 物联网 Linux
学习Linux对网络安全的重要性
**学习Linux对网络安全至关重要:** 1. 开源操作系统广泛应用于服务器、网络设备,掌握Linux是安全专家必备技能。 2. Linux内置安全特性,如最小权限和防火墙,加上丰富的安全工具,提供强大保障。 3. 可定制性允许灵活配置,满足安全需求,开源社区提供持续更新和教育资源。 4. 学习Linux能提升攻防能力,用于系统加固和渗透测试,适应跨平台安全场景。 5. 随着云计算和物联网发展,Linux在网络安全中的角色日益关键。
389 3
|
存储 数据库 索引
Elasticsearch ILM 索引生命周期管理常见坑及避坑指南
Elasticsearch ILM 索引生命周期管理常见坑及避坑指南
|
Web App开发 域名解析 监控
前端可观测性的宣讲-1022
前端可观测性的宣讲-1022
658 0
前端可观测性的宣讲-1022
|
Kubernetes Linux 网络架构
局域网与Kubernetes内部网络如何互通
K8S搭建完毕之后,碰到个问题,如何进行远程debug(别在生产环境远程debug哦)?那就需要打通局域网和K8S内部网络了。本文主要介绍Pod通信、K8S网络插件、局域网和K8S网络如何打通。
局域网与Kubernetes内部网络如何互通