×

作为管理员,您可以创建和使用守护程序集,以便在 OpenShift Container Platform 集群中的特定节点或所有节点上运行 Pod 的副本。

守护程序集确保所有(或某些)节点运行 Pod 的副本。当节点添加到集群时,Pod 会添加到集群。当节点从集群中移除时,这些 Pod 将通过垃圾回收移除。删除守护程序集将清理它创建的 Pod。

您可以使用守护程序集来创建共享存储,在集群中的每个节点上运行日志记录 Pod,或在每个节点上部署监控代理。

出于安全原因,集群管理员和项目管理员可以创建守护程序集。

有关守护程序集的更多信息,请参阅Kubernetes 文档

守护程序集调度与项目的默认节点选择器不兼容。如果您未能禁用它,则守护程序集将通过与默认节点选择器合并而受到限制。这会导致在被合并的节点选择器取消选择的节点上频繁重新创建 Pod,从而给集群带来不必要的负载。

由默认调度器调度

守护程序集确保所有符合条件的节点都运行 Pod 的副本。通常,Pod 运行的节点由 Kubernetes 调度器选择。但是,守护程序集 Pod 由守护程序集控制器创建和调度。这会带来以下问题

  • 不一致的 Pod 行为:正在等待调度的普通 Pod 已创建并处于 Pending 状态,但守护程序集 Pod 并非在 Pending 状态下创建。这对用户来说令人困惑。

  • Pod 抢占由默认调度器处理。启用抢占时,守护程序集控制器将进行调度决策,而不会考虑 Pod 优先级和抢占。

ScheduleDaemonSetPods 功能在 OpenShift Container Platform 中默认启用,它允许您通过向守护程序集 Pod 添加 NodeAffinity 项(而不是 spec.nodeName 项)来使用默认调度器而不是守护程序集控制器调度守护程序集。然后使用默认调度器将 Pod 绑定到目标主机。如果守护程序集 Pod 的节点亲和性已存在,则将其替换。守护程序集控制器仅在创建或修改守护程序集 Pod 时执行这些操作,并且不会对守护程序集的 spec.template 进行任何更改。

kind: Pod
apiVersion: v1
metadata:
  name: hello-node-6fbccf8d9-9tmzr
#...
spec:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchFields:
        - key: metadata.name
          operator: In
          values:
          - target-host-name
#...

此外,node.kubernetes.io/unschedulable:NoSchedule 容忍度会自动添加到守护程序集 Pod。默认调度器在调度守护程序集 Pod 时会忽略不可调度的节点。

创建守护程序集

创建守护程序集时,nodeSelector 字段用于指示守护程序集应在其上部署副本的节点。

先决条件
  • 在开始使用守护程序集之前,请通过将命名空间注释 openshift.io/node-selector 设置为空字符串来禁用命名空间中的默认项目范围节点选择器

    $ oc patch namespace myproject -p \
        '{"metadata": {"annotations": {"openshift.io/node-selector": ""}}}'

    或者,您可以应用以下 YAML 来禁用命名空间的默认项目范围节点选择器

    apiVersion: v1
    kind: Namespace
    metadata:
      name: <namespace>
      annotations:
        openshift.io/node-selector: ''
    #...
  • 如果您正在创建新项目,请覆盖默认节点选择器

    $ oc adm new-project <name> --node-selector=""
步骤

创建守护程序集

  1. 定义守护程序集 yaml 文件

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: hello-daemonset
    spec:
      selector:
          matchLabels:
            name: hello-daemonset (1)
      template:
        metadata:
          labels:
            name: hello-daemonset (2)
        spec:
          nodeSelector: (3)
            role: worker
          containers:
          - image: openshift/hello-openshift
            imagePullPolicy: Always
            name: registry
            ports:
            - containerPort: 80
              protocol: TCP
            resources: {}
            terminationMessagePath: /dev/termination-log
          serviceAccount: default
          terminationGracePeriodSeconds: 10
    #...
    1 确定哪些 Pod 属于守护程序集的标签选择器。
    2 Pod 模板的标签选择器。必须与上面的标签选择器匹配。
    3 确定应在哪些节点上部署 Pod 副本的节点选择器。节点上必须存在匹配的标签。
  2. 创建守护程序集对象

    $ oc create -f daemonset.yaml
  3. 要验证 Pod 是否已创建以及每个节点是否都有 Pod 副本

    1. 查找守护程序集 Pod

      $ oc get pods
      示例输出
      hello-daemonset-cx6md   1/1       Running   0          2m
      hello-daemonset-e3md9   1/1       Running   0          2m
    2. 查看 Pod 以验证 Pod 是否已放置到节点上

      $ oc describe pod/hello-daemonset-cx6md|grep Node
      示例输出
      Node:        openshift-node01.hostname.com/10.14.20.134
      $ oc describe pod/hello-daemonset-e3md9|grep Node
      示例输出
      Node:        openshift-node02.hostname.com/10.14.20.137
  • 如果更新守护程序集 Pod 模板,则不会影响现有 Pod 副本。

  • 如果删除守护程序集,然后使用不同的模板但相同的标签选择器创建新的守护程序集,它会识别任何现有 Pod 副本具有匹配的标签,因此即使 Pod 模板不匹配,也不会更新它们或创建新的副本。

  • 如果更改节点标签,则守护程序集会将 Pod 添加到与新标签匹配的节点,并从与新标签不匹配的节点删除 Pod。

要更新守护程序集,请强制创建新的 Pod 副本,方法是删除旧的副本或节点。