×

作为管理员,您可以创建和使用 DaemonSet 在 OpenShift Dedicated 集群中的特定节点或所有节点上运行 Pod 的副本。

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

您可以使用 DaemonSet 创建共享存储、在集群中的每个节点上运行日志 Pod 或在每个节点上部署监控代理。

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

有关 DaemonSet 的更多信息,请参阅 Kubernetes 文档

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

由默认调度器调度

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

  • 不一致的 Pod 行为:等待调度的普通 Pod 被创建并处于 Pending 状态,但 DaemonSet Pod 不会处于 `Pending` 状态。这会让用户感到困惑。

  • Pod 抢占由默认调度器处理。启用抢占时,DaemonSet 控制器将在不考虑 Pod 优先级和抢占的情况下做出调度决策。

**ScheduleDaemonSetPods** 功能(在 OpenShift Dedicated 中默认启用)允许您通过向 DaemonSet Pod 添加 `NodeAffinity` 项(而不是 `spec.nodeName` 项)来使用默认调度器而不是 DaemonSet 控制器来调度 DaemonSet。然后使用默认调度器将 Pod 绑定到目标主机。如果 DaemonSet Pod 的节点亲和性已存在,则将其替换。DaemonSet 控制器仅在创建或修改 DaemonSet Pod 时执行这些操作,并且不会对 DaemonSet 的 `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` 容忍度会自动添加到 DaemonSet Pod。默认调度器在调度 DaemonSet Pod 时会忽略不可调度的节点。

创建 DaemonSet

创建 DaemonSet 时,使用 `nodeSelector` 字段指示 DaemonSet 应在其上部署副本的节点。

先决条件
  • 在开始使用 DaemonSet 之前,请通过将命名空间注释 `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: ''
    #...
步骤

创建 DaemonSet

  1. 定义 DaemonSet 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 属于 DaemonSet 的标签选择器。
    2 Pod 模板的标签选择器。必须与上面的标签选择器匹配。
    3 确定应在哪些节点上部署 Pod 副本的节点选择器。节点上必须存在匹配的标签。
  2. 创建 DaemonSet 对象

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

    1. 查找 DaemonSet 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
  • 如果您更新 DaemonSet Pod 模板,现有 Pod 副本不会受到影响。

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

  • 如果您更改节点标签,DaemonSet 会向与新标签匹配的节点添加 Pod,并从与新标签不匹配的节点删除 Pod。

要更新 DaemonSet,请通过删除旧副本或节点来强制创建新的 Pod 副本。