当前位置: 代码网 > 服务器>服务器>云虚拟主机 > 理解k8s控制器DaemonSet创建及使用场景

理解k8s控制器DaemonSet创建及使用场景

2024年05月21日 云虚拟主机 我要评论
daemonset 简介daemonset 的主要作用,是在 kubernetes 集群里,运行一个 daemon pod。 daemonset 只管理 pod 对象,然后通过 nodeaffinit

daemonset 简介

daemonset 的主要作用,是在 kubernetes 集群里,运行一个 daemon pod。 daemonset 只管理 pod 对象,然后通过 nodeaffinity 和 toleration 这两个调度器参数的功能,保证了每个节点上有且只有一个 pod。

daemonset 是一种面向特定应用场景的 pod 控制器,尽管它也可以管理 pod 的多个副本,但它主要用于保证一个 node 上只运行一个 pod 的场景:

daemonset 使用场景

每个节点上只有一个这样的 daemon pod 实例,然后当有新的节点加入 kubernetes 集群后,该 pod 会自动地在新节点上被创建出来。当旧节点被删除后,它上面的 pod 也会相应地被回收掉。

daemon pod 的意义确实是非常重要的。比如的作用:

  • 网络插件的 agent 组件,都必须运行在每一个节点上,用来处理这个节点上的容器网络。
  • 存储插件的 agent 组件,也必须运行在每一个节点上,用来在这个节点上挂载远程存储目录,操作容器的 volume 目录,比如:glusterd、ceph。
  • 监控组件和日志组件,也必须运行在每一个节点上,负责这个节点上的监控信息和日志搜集,比如:fluentd、logstash、prometheus 等。

daemonset 创建

k8s 环境搭建参考网上教程,这里就不再赘述了。

先来个简单的例子快速体验 daemonset 控制器是如何应用的。

一个简单的 daemonset 配置如下:

apiversion: apps/v1
kind: daemonset
metadata:
  name: nginx-daemonset
  labels:
    app: nginx
spec:
  selector:
    matchlabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.0

初步看,这份配置跟 deployment 基本类似,唯一一个显著的差异是 daemonset 不需要指定副本数,因为它的副本数取决于工作节点数。

daemonset 配置中 spec.selector 和 spec.template 作用我们已在介绍 deployment 时介绍过,在此不再赘述。

该份配置将创建一个 daemonset 对象,然后 daemonset 控制器会根据该对象信息分别在每个节点上创建一个 pod 副本。

接下来使用kubectl create命令将该配置提次给 kube-apiserver,如下所示:

[root@k8s-master]# kubectl create -f daemonset.yaml
daemonset.apps/nginx-daemonset created

查看 daemonset

首先查看刚刚创建的 daemonset 对象:

[root@k8s-master]# kubectl get daemonset
name  desired   current   ready   up-to-date   available   node selector   age
nginx-daemonset     3     3     3     3     3      <none>          1m3s

命令行输出中各字段含义如下:

  • name: daemonset 对象名称,同配置中的 metadata.name;
  • desired:需求副本个数,由于没有刻意筛选节点,所以副本个数等同于节点个数(默认);
  • current:当前已创建的副本个数;
  • ready:处于 ready 状态的副本个数;
  • up-to-date:已按最新 pod 模版创建的 pod 个数;
  • available:可用的副本个数;
  • node selector:节点选择器,本例中我们没有选择,值为空;
  • age:创建至今经历的时间。

上面的字段中,除了 node selector 以外,我们已在前面的章节中介绍过。其实 node selector 并不是 daemonset 对象特有的配置,它是 pod 模版中用于为 pod 匹配节点的配置,daemonset 控制器使用该 node selector 来筛选需要创建副本的节点,如果没有指定,则默认选择全部节点。

接着,查看 daemonset 控制器所创建的 pod 副本信息:

[root@k8s-master]# kubectl get pods -o wide
name                    ready   status    restarts   age     ip           node           nominated node   readiness gates
nginx-daemonset-66dbc   1/1     running   0          5m13s   10.135.3.2   k8s-master   <none>           <none>
nginx-daemonset-akpdg   1/1     running   0          5m13s   10.135.1.2   k8s-node1   <none>           <none>
nginx-daemonset-l3wnd   1/1     running   0          5m13s   10.135.2.2   k8s-node2    <none>           <none>

可以看到,在每个节点上均创建了一个副本,是符合预期的。

更新 daemonset

下面我们适当的调整下 pod 部署策略,只希望 pod 运行在名为 k8s-node 的节点上,这样我们只需要配置 daemonset 对象的 spec.template.spec.nodeselector 来选择节点即可。

在 k8s-node 的节点中存在一个标识节点的 label:

kubernetes.io/hostname: k8s-node1

使用 kubectl edit 命令修改配置的 spec.template.spec.nodeselector 参数如下:

apiversion: apps/v1
kind: daemonset
metadata:
  ...
spec:
  ...
  template:
    ...
    spec:
      ...
      nodeselector:
        kubernetes.io/hostname: k8s-node1

然后再次观察 daemonset 对象和 pod 副本:

[root@k8s-master]# kubectl get daemonsets
name              desired   current   ready   up-to-date   available   node selector                        age
nginx-daemonset   1         1         1       1            1           kubernetes.io/hostname=k8s-node1   37m
[root@k8s-master]# kubectl get pods -o wide
name                    ready   status    restarts   age   ip           node          nominated node   readiness gates
nginx-daemonset-66gk2   1/1     running   0          10s   10.135.2.3   k8s-node1   <none>           <none>

可以发现 daemonset 状态中,node selector 正确地展示了上面的修改,而且需求的 pod 副本数也变成了 1 个,符合预期。

原来运行的 3 个 pod 副本减少到 1 个,而且只在我们配置选定的节点(k8s-node1)上运行。

删除 daemonset

像其他 pod 控制器一样,当删除 daemonset 对象时,其所管理的 pod 默认也会被删除,操作如下所示:

[root@k8s-master ~]# kubectl delete daemonsets nginx-daemonset
daemonset.apps "nginx-daemonset" deleted
[root@k8s-master ~]# kubectl get pods
no resources found in default namespace.

其它使用场景

容忍性 toleration 使用

daemonset 还会给这个 pod 自动加上另外一个与调度相关的字段,叫作 tolerations。这个字段意味着这个 pod,会“容忍”(toleration)某些 node 的“污点”(taint)。

toleration 使用 yaml 配置如下:

apiversion: v1
kind: pod
metadata:
  name: with-toleration
spec:
  tolerations:
  - key: node.kubernetes.io/unschedulable
    operator: exists
    effect: noschedule

在正常情况下,被标记了 unschedulable“污点”的 node,是不会有任何 pod 被调度上去的(effect: noschedule)。

可是,daemonset 自动地给被管理的 pod 加上了这个特殊的 toleration,就使得这些 pod 可以忽略这个限制,继而保证每个节点上都会被调度一个 pod。

当然,如果这个节点有故障的话,这个 pod 可能会启动失败,而 daemonset 则会始终尝试下去,直到 pod 启动成功。

主要作用:

通过这样一个 toleration,调度器在调度这个 pod 的时候,就会忽略当前节点上的“污点”,从而成功地将一些组件调度到这台机器上启动起来。

这种机制,正是我们在部署 kubernetes 集群的时候,能够先部署 kubernetes 本身、再部署网络插件的根本原因:因为当时我们所创建的 weave 的 yaml,实际上就是一个 daemonset。

节点亲和性 nodeaffinity 使用

正常情况下 daemonset controller 会在创建 pod 的时候,自动在这个 pod 的 api 对象里,加上这样一个 nodeaffinity 定义。

在这个 pod 里,声明了一个 spec.affinity 字段,然后定义了一个 nodeaffinity。其中,spec.affinity 字段,是 pod 里跟调度相关的一个字段。

nodeaffinity 使用 yaml 配置如下:

apiversion: v1
kind: pod
metadata:
  name: demo-node-affinity
spec:
  affinity:
    nodeaffinity:
      requiredduringschedulingignoredduringexecution:
        nodeselectorterms:
        - matchexpressions:
          - key: metadata.name
            operator: in
            values:
            - demo-node

以上关键参数含义:

  • requiredduringschedulingignoredduringexecution 这个代表 nodeaffinity 必须在每次调度的时候予以考虑,同时,这也意味着可以设置在某些情况下不考虑这个 nodeaffinity;
  • 这个 pod,将来只允许运行在“metadata.name”是“demo-node”的节点上。

总结

daemonset 其实就是依靠 nodeaffinity 和 toleration 实现的。这是一种不需要增加设计结构,而直接使用标签等方式完成的 daemon 进程。这样的结构非常符合 kubernetes 的控制器模式,正所谓一切皆对象。

以上就是k8s控制器daemonset理解的详细内容,更多关于k8s控制器daemonset的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com