6.7. 了解节点重新引导

若要在重新引导节点时不造成平台上应用程序中断运行,务必要先撤离(evacuate)相关的 pod。对于由路由层提供高可用性的 pod,不需要执行其他操作。对于需要存储的其他 pod(通常是数据库),务必要确保它们能够在一个 pod 临时下线时仍然保持运作。尽管为有状态 pod 实现可持续运行的方法会视不同应用程序而异,但在所有情形中,都要将调度程序配置为使用节点反关联性,从而确保 pod 在可用节点之间合理分布。

另一个挑战是如何处理运行关键基础架构的节点,比如路由器或 registry。相同的节点撤离过程同样适用于这类节点,但必须要了解某些边缘情况。

6.7.1. 关于重新引导运行关键基础架构的节点

在重启托管关键 OpenShift Container Platform 基础架构组件(如路由器 Pod、registry pod 和监控 pod)的节点时,请确保至少有三个节点可用于运行这些组件。

以下场景演示了,在只有两个节点可用时,在 OpenShift Container Platform 上运行的应用程序可能会发生服务中断:

  • 节点 A 标记为不可调度,所有 pod 都被撤离。
  • 该节点上运行的 registry pod 现在重新部署到节点 B 上。Node B 现在同时运行两个 registry pod。
  • 节点 B 现在标记为不可调度,并且被撤离。
  • 在节点上公开两个 pod 端点的服务在短时间内丢失所有端点,直到它们被重新部署到节点 A。

当将三个节点用于基础架构组件时,此过程不会造成服务中断。但是,由于 pod 调度,被撤离并返回到轮转的最后一个节点没有 registry pod。其他节点中的一个会有两个 registry pod。要将第三个 registry pod 调度到最后一个节点上,请使用 pod 反关联性以防止将两个 registry pod 放置在同一节点上。

附加信息

6.7.2. 使用 pod 反关联性重新引导节点

Pod 反关联性和节点反关联性稍有不同。如果没有其他适当的位置来部署 pod,则可以违反节点反关联性。Pod 反关联性可以设置为必要的或偏好的。

在这个版本中,如果只有两个基础架构节点可用,且一个节点被重新引导,容器镜像 registry Pod 将无法在另一个节点上运行。oc get pods 将 pod 报告为 unready,直到有合适的节点可用为止。一旦某个节点可用,并且所有 pod 恢复到就绪状态,下一个节点就可以重启。

流程

使用 pod 反关联性重新引导节点:

  1. 编辑节点规格以配置 pod 反关联性:

    apiVersion: v1
    kind: Pod
    metadata:
      name: with-pod-antiaffinity
    spec:
      affinity:
        podAntiAffinity: 1
          preferredDuringSchedulingIgnoredDuringExecution: 2
          - weight: 100 3
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: registry 4
                  operator: In 5
                  values:
                  - default
              topologyKey: kubernetes.io/hostname
    #...
    1
    用于配置 pod 反关联性的小节。
    2
    定义偏好规则。
    3
    为偏好规则指定权重。优先选择权重最高的节点。
    4
    描述用来决定何时应用反关联性规则的 pod 标签。指定标签的键和值。
    5
    运算符表示现有 pod 上的标签和新 pod 规格中 matchExpression 参数的值集合之间的关系。可以是 InNotInExistsDoesNotExist

    本例假定容器镜像 registry pod 具有 registry=default 标签。Pod 反关联性可以使用任何 Kubernetes 匹配表达式。

  2. 在调度策略文件中启用 MatchInterPodAffinity 调度程序 predicate。
  3. 对节点执行正常重启。

6.7.3. 了解如何重新引导运行路由器的节点

在大多数情况下,运行 OpenShift Container Platform 路由器的 pod 会公开一个主机端口。

PodFitsPorts 调度程序 predicate 确保没有使用相同端口的其他路由器 pod 在同一节点上运行,并且达成 pod 反关联性。如果路由器依赖 IP 故障转移来实现高可用性,则不需要任何其他操作。

如果路由器 pod 依赖 AWS Elastic Load Balancing 等外部服务来实现高可用性,则由该服务负责响应路由器 pod 重启。

在极少见的情形中,路由器 pod 可能没有配置主机端口。这时,务必要按照推荐的基础架构节点重启流程来进行操作。

6.7.4. 正常重新引导节点

在重启节点前,建议备份 etcd 数据以避免该节点上出现数据丢失。

注意

对于需要用户执行 oc login 命令而不是 kubeconfig 文件中的证书来管理集群的单节点 OpenShift 集群,oc adm 命令在封锁并排空节点后可能无法使用。这是因为 openshift-oauth-apiserver pod 没有运行,因为 cordon。您可以使用 SSH 访问节点,如以下步骤所示。

在单节点 OpenShift 集群中,在封锁和排空时无法重新调度 Pod。但是,这样做会为 pod(特别是您的工作负载 pod)提供一定的时间来正确停止和释放相关资源。

流程

执行节点正常重启:

  1. 将节点标记为不可调度:

    $ oc adm cordon <node1>
  2. 排空节点以删除所有正在运行的 pod:

    $ oc adm drain <node1> --ignore-daemonsets --delete-emptydir-data --force

    您可能会收到与自定义 pod 中断预算(PDB)关联的 pod 无法被驱除的错误。

    错误示例

    error when evicting pods/"rails-postgresql-example-1-72v2w" -n "rails" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.

    在这种情况下,再次运行 drain 命令,添加 disable-eviction 标记,这将绕过 PDB 检查:

    $ oc adm drain <node1> --ignore-daemonsets --delete-emptydir-data --force --disable-eviction
  3. 以 debug 模式访问节点:

    $ oc debug node/<node1>
  4. 将您的根目录改为 /host

    $ chroot /host
  5. 重启节点:

    $ systemctl reboot

    目前,节点进入 NotReady 状态。

    注意

    在一些单节点 OpenShift 集群中,oc 命令在 cordon 和 drain 节点后可能无法使用,因为 openshift-oauth-apiserver pod 没有运行。您可以使用 SSH 连接到节点并执行重启。

    $ ssh core@<master-node>.<cluster_name>.<base_domain>
    $ sudo systemctl reboot
  6. 重启完成后,运行以下命令将节点标记为可以调度:

    $ oc adm uncordon <node1>
    注意

    在一些单节点 OpenShift 集群中,oc 命令在 cordon 和 drain 节点后可能无法使用,因为 openshift-oauth-apiserver pod 没有运行。您可以使用 SSH 连接到节点并取消封锁它。

    $ ssh core@<target_node>
    $ sudo oc adm uncordon <node> --kubeconfig /etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/localhost.kubeconfig
  7. 验证节点是否已就绪:

    $ oc get node <node1>

    输出示例

    NAME    STATUS  ROLES    AGE     VERSION
    <node1> Ready   worker   6d22h   v1.18.3+b0068a8

附加信息

有关 etcd 数据备份的详情,请参考备份 etcd 数据