命令记不住

登陆

k8s 资源对象 DaemonSet

k8s资源对象DaemonSet

1.DaemonSet架构设计

  • 首先如果希望每个节点都运行同样一个 pod 怎么办?
  • 如果新节点加入集群的时候,想要立刻感知到它,然后去部署一个 pod,帮助我们初始化一些东西,这个需求如何做?
  • 如果有节点退出的时候,希望对应的 pod 会被删除掉,应该怎么操作?
  • 如果 pod 状态异常的时候,我们需要及时地监控这个节点异常,然后做一些监控或者汇报的一些动作,那么这些东西运用什么控制器来做?
1.DaemonSet:守护进程控制器

DaemonSet 也是 Kubernetes 提供的一个 default controller,它实际是做一个守护进程的控制器,它能帮我们做到以下几件事情:

  • 首先能保证集群内的每一个节点都运行一组相同的 pod;
  • 同时还能根据节点的状态保证新加入的节点自动创建对应的 pod;
  • 在移除节点的时候,能删除对应的 pod;
  • 而且它会跟踪每个 pod 的状态,当这个 pod 出现异常、Crash 掉了,会及时地去 recovery 这个状态。
2.适用场景
  • 集群存储进程:glusterd ceph
  • 日志收集进程:fluentd logstash
  • 需要在每个节点运行的监控收集器

2.DaemonSet 管理模式

  • DaemonSet Controller负责根据配置创建Pod
  • DaemonSet Controller跟踪job状态,根据配置及时重试Pod或者继续创建
  • DaemonSet Controller会自动添加affinity&label来跟踪对应的pod,并根据配置在每个节点或者适合的部分创建Pod

2.DaemonSet 控制器

当有 node 状态节点发生变化时,它会通过一个内存消息队列发进来,然后DaemonSet controller 会去 watch 这个状态,看一下各个节点上是都有对应的 Pod,如果没有的话就去创建。当然它会去做一个对比,如果有的话,它会比较一下版本,然后加上刚才提到的是否去做 RollingUpdate?如果没有的话就会重新创建,Ondelete 删除 pod 的时候也会去做 check 它做一遍检查,是否去更新,或者去创建对应的 pod。

当然最后的时候,如果全部更新完了之后,它会把整个 DaemonSet 的状态去更新到 API Server 上,完成最后全部的更新。

3.daemonSet语法

matchLabel,通过 matchLabel 去管理对应所属的 pod,这个 pod.label 也要和这个 DaemonSet.controller.label 想匹配,它才能去根据 label.selector 去找到对应的管理 Pod

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
labels:
 k8s-app: fluentd-logging
spec:
selector:
matchLabels:
  name: fluentd-elasticsearch
template:
 metadata:
   labels:
     name: fluentd-elasticsearch
 spec:
   containers:
      - name: fluentd-elasticsearch
        image: nginx 

官方示例

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
        operator: Exists
        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

.

4.daemonSet相关操作

fluentd 做例子。DaemonSet 最常用的点在于以下几点内容:

  • 首先是存储,GlusterFS 或者 Ceph 之类的东西,需要每台节点上都运行一个类似于 Agent 的东西,DaemonSet 就能很好地满足这个诉求;
  • 另外,对于日志收集,比如说 logstash 或者 fluentd,这些都是同样的需求,需要每台节点都运行一个 Agent,这样的话,我们可以很容易搜集到它的状态,把各个节点里面的信息及时地汇报到上面;
  • 还有一个就是,需要每个节点去运行一些监控的事情,也需要每个节点去运行同样的事情,比如说 Promethues 这些东西,也需要 DaemonSet 的支持。
1.查看DaemonSet状态

kubectl get DaemonSet(DaemonSet 缩写为 ds)。可以看到 DaemonSet 返回值和 deployment 特别像,即它当前一共有正在运行的几个,然后我们需要几个,READY 了几个。当然这里面,READY 都是只有 Pod,所以它最后创建出来所有的都是 pod。

参数分别是:

需要的 pod 个数、当前已经创建的 pod 个数、就绪的个数,以及所有可用的、通过健康检查的 pod;

还有 NODE SELECTOR,因为 NODE SELECTOR 在 DaemonSet 里面非常有用。

有时候我们可能希望只有部分节点去运行这个 pod 而不是所有的节点,所以有些节点上被打了标的话,DaemonSet 就只运行在这些节点上。

比如,我只希望 master 节点运行某些 pod,或者只希望 Worker 节点运行某些 pod,就可以使用这个 NODE SELECTOR。

2.更新DaemonSet

DaemonSet 和 deployment 特别像,它也有两种更新策略:一个是 RollingUpdate,另一个是 OnDelete。

  • RollingUpdate 其实比较好理解,就是会一个一个的更新。先更新第一个 pod,然后老的 pod 被移除,通过健康检查之后再去见第二个 pod,这样对于业务上来说会比较平滑地升级,不会中断;
  • OnDelete 其实也是一个很好的更新策略,就是模板更新之后,pod 不会有任何变化,需要我们手动控制。我们去删除某一个节点对应的 pod,它就会重建,不删除的话它就不会重建,这样的话对于一些我们需要手动控制的特殊需求也会有特别好的作用。
推荐阅读