美文网首页k8s in action实践笔记
4.4 使用DaemonSet在每个节点上运行一个pod

4.4 使用DaemonSet在每个节点上运行一个pod

作者: 众神开挂 | 来源:发表于2021-07-16 08:06 被阅读0次

Replicationcontroller和ReplicaSet都用于在Kubernetes集群上运行部署特定数量的pod。但是,当你希望pod在集群中的每个节点上运行时,就会出现某些情况。

这些情况包括pod执行系统级别的与基础结构相关的操作。例如,希望在每个节点上运行日志收集器和资源监控器。另一个典型的例子是Kubernetes自己的kube-proxy进程,它需要运行在所有节点上才能使服务工作。

在Kubernetes之外,此类进程通常在节点启动期间通过系统初始化脚本或systemd守护进程启动。在Kubernetes节点上,仍然可以使用systemd运行系统进程,但这样就不能利用所有的Kubernetes特性了。

4.4.1 使用DaemonSet在每个节点上运行一个pod

要在所有集群节点上运行一个pod,需要创建一个DaemonSet对象,这很像一个ReplicationController或ReplicaSet,除了由DaemonSet创建的pod,已经有一个指定的目标节点并跳过Kubernetes调度程序。它们不是随机分布在集群上的。

DaemonSet确保创建足够的pod,并在自己的节点上部署每个pod,如图4.8所示。

尽管ReplicaSet(或ReplicationController)确保集群中存在期望数量的pod副本,但DaemonSet并没有期望的副本数的概念。它不需要,因为它的工作是确保一个pod匹配它的选择器并在每个节点上运行。

如果节点下线,DaemonSet不会在其他地方重新创建pod。但是,当将一个新节点添加到集群中时,DaemonSet会立刻部署一个新的pod实例。如果有人无意中删除了一个pod,那么它也会重新创建一个新的pod。与ReplicaSet一样,DaemonSet从配置的pod模板创建pod。

4.4.2 使用DaemonSet只在特定的节点上运行pod

DaemonSet将pod部署到集群中的所有节点上,除非指定这些pod只在部分节点上运行。这是通过pod模板中的nodeSelector属性指定的,这是DaemonSet定义的一部分(类似于ReplicaSet或ReplicationController中的pod模板)。

在第3章中,已经使用了节点选择器将pod部署到特定的节点上。DaemonSet中的节点选择器与之相似——它定义了DaemonSet必须将其pod部署到的节点。

注意 在本书的后面,你将了解到节点可以被设置为不可调度的,防止pod被部署到节点上。DaemonSet甚至会将pod部署到这些节点上,因为无法调度的属性只会被调度器使用,而DaemonSet管理的pod则完全绕过调度器。这是预期的,因为DaemonSet的目的是运行系统服务,即使是在不可调度的节点上,系统服务通常也需要运行。

用一个例子来解释DaemonSet

让我们假设有一个名为ssd-monitor的守护进程,它需要在包含固态驱动器(SSD)的所有节点上运行。你将创建一个DaemonSet,它在标记为具有SSD的所有节点上运行这个守护进程。集群管理员已经向所有此类节点添加了disk=ssd的标签,因此你将使用节点选择器创建DaemonSet,该选择器只选择具有该标签的节点

创建一个DaemonSet YAML定义文件

你将创建一个运行模拟的ssd-monitor监控器进程的DaemonSet,该进程每5秒会将“SSD OK”打印到标准输出。笔者已经准备了模拟容器镜像并将它推到Docker Hub,因此无须构建而直接使用。为DaemonSet创建一个YAML文件,如下面的代码清单所示。

FROM busybox
ENTRYPOINT while true; do echo 'SSD OK'; sleep 5; done

代码清单4.10 一个DaemonSet的YAML:ssd-monitor-daemonset.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ssd-monitor
  namespace: custom2
  labels:
    k8s-app: ssd-monitor
spec:
  selector:
    matchLabels:
      app: ssd-monitor
  template:
    metadata:
      labels:
        app: ssd-monitor
    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: ssd-monitor
        image: luksa/ssd-monitor
      nodeSelector:
        disk: ssd

你正在定义一个DaemonSet,它将运行一个基于luksa/ssd-monitor容器镜像的单容器pod。该pod的实例将在每个具有disk=ssd标签的节点上创建。

创建DaemonSet

创建一个DaemonSet就像从YAML文件创建资源那样:

$ kubectl create -f ssd-monitor-daemonset.yaml

我们来看一下创建的DaemonSet:

$ kubectl get ds

这些0看起来很奇怪。DaemonSet不应该部署pod吗?现在列出pod:

$ kubectl get po

pod在哪里呢?知道发生了什么吗?是的,忘记给节点打上disk=ssd标签了。打上标签之后,DaemonSet将检测到节点的标签已经更改,并将pod部署到有匹配标签的所有节点。让我们来看一下。

向节点上添加所需的标签

无论你使用的是Minikube、GKE或其他多节点集群,都需要首先列出节点,因为在标记时需要知道节点的名称:

$ kubectl get node

现在像这样给节点添加disk=ssd标签:

$ kubectl label node minikube disk=ssd

注意 如果你没有使用Minikube,用你的节点名替换minikube。

DaemonSet现在应该已经创建pod了,让我们来看一下:

$ kubectl get po

现在看起来一切正常。如果你有多个节点并且其他的节点也加上了同样的标签,将会看到DaemonSet在每个节点上都启动pod。

从节点上删除所需的标签

现在假设你给其中一个节点打错了标签。它的硬盘是磁盘而不是SSD。这时你修改了标签会发生什么呢?

$ kubectl label node minikube disk=hdd --overwrite

看一下更改是否影响了运行在节点上的pod:

$ kubectl get po

pod如预期中正在被终止。这里对DaemonSet的探索就要结束了,因此可能想要删除ssd-monitor DaemonSet。如果还有其他的pod在运行,删除DaemonSet也会一起删除这些pod。

相关文章

网友评论

    本文标题:4.4 使用DaemonSet在每个节点上运行一个pod

    本文链接:https://www.haomeiwen.com/subject/ecpvpltx.html