6.2. 机器删除阶段的生命周期 hook

机器生命周期 hook 协调一个集群的协调生命周期中的一个点,在其可以中断正常的生命周期。在机器 Deleting 阶段,这些中断为组件提供了修改机器删除过程的机会。

6.2.1. 术语和定义

要了解机器删除阶段的生命周期 hook 行为,您必须了解以下概念:

协调
协调是控制器尝试使集群实际状态及其组成的对象与对象规格中的要求匹配的过程。
机器控制器

机器控制器管理机器的协调生命周期。对于云平台上的机器,机器控制器是 OpenShift Container Platform 控制器和云供应商的特定操作器的组合。

在删除机器的情况下,机器控制器执行以下操作:

  • 排空机器支持的节点。
  • 从云供应商中删除机器实例。
  • 删除 Node 对象。
生命周期 hook

生命周期 hook 是解决正常生命周期对象的协调生命周期中定义的点。组件可以使用生命周期 hook 将更改注入进程,以完成所需的结果。

机器 删除 阶段有两个生命周期 hook:

  • 在机器支持的节点可以排空前,必须先解决 preDrain 生命周期 hook。
  • 在从基础架构供应商中删除实例前,必须先解决 preTerminate 生命周期 hook。
hook 实现控制器

hook 实现控制器是机器控制器以外的控制器,可以与生命周期 hook 交互。hook 实现控制器可以执行以下操作之一或多个操作:

  • 添加生命周期 hook。
  • 响应生命周期 hook。
  • 删除生命周期 hook。

每个生命周期 hook 都有一个 hook 实现控制器,但 hook 实现控制器可以管理一个或多个 hook。

6.2.2. 机器删除处理顺序

在 OpenShift Container Platform 4.12 中,机器删除阶段有两个生命周期 hook:preDrainpreTerminate。删除给定生命周期点的所有 hook 时,协调会正常进行。

图 6.1. 机器删除流

机器 "Deleting" 阶段的事件序列。

机器 Deleting 阶段按以下顺序进行:

  1. 由于以下原因之一,现有机器被移除:

    • 具有 cluster-admin 权限的用户使用 oc delete machine 命令。
    • 机器获取 machine.openshift.io/delete-machine 注解。
    • 管理机器的机器集会标记它,以减少副本数作为协调的一部分。
    • 集群自动扩展会识别一个不需要满足集群的部署需求的节点。
    • 机器健康检查被配置为替换不健康的机器。
  2. 机器进入 Deleting 阶段,在其中标记为删除,但仍然存在于 API 中。
  3. 如果存在 preDrain 生命周期 hook,则 hook 实现了控制器来管理它执行指定操作。

    在满足所有 preDrain 生命周期 hook 前,机器状态条件 Drainable 被设置为 False

  4. 没有未解析的 preDrain 生命周期 hook,机器状态条件 Drainable 被设置为 True
  5. 机器控制器尝试排空由机器支持的节点。

    • 如果排空失败,Drained 被设置为 False,机器控制器会尝试再次排空该节点。
    • 如果排空成功,Drained 被设置为 True
  6. 机器状态条件 Drained 设置为 True
  7. 如果存在 preTerminate 生命周期 hook,则管理它的 hook 实现控制器将执行指定操作。

    在满足所有 preTerminate 生命周期 hook 前,机器状态条件 Terminable 被设置为 False

  8. 没有未解析的 preTerminate 生命周期 hook,机器状态条件 Terminable 被设置为 True
  9. 机器控制器从基础架构供应商中删除实例。
  10. 机器控制器会删除 Node 对象。

6.2.3. 删除生命周期 hook 配置

以下 YAML 片段演示了机器集内删除生命周期 hook 配置的格式和放置:

YAML 片断展示了一个 preDrain 生命周期 hook

apiVersion: machine.openshift.io/v1beta1
kind: Machine
metadata:
  ...
spec:
  lifecycleHooks:
    preDrain:
    - name: <hook_name> 1
      owner: <hook_owner> 2
  ...

1
preDrain 生命周期 hook 的名称。
2
管理 preDrain 生命周期 hook 的 hook 实施控制器。

YAML 片段展示了一个 preTerminate 生命周期 hook

apiVersion: machine.openshift.io/v1beta1
kind: Machine
metadata:
  ...
spec:
  lifecycleHooks:
    preTerminate:
    - name: <hook_name> 1
      owner: <hook_owner> 2
  ...

1
preTerminate 生命周期 hook 的名称。
2
管理 preTerminate 生命周期 hook 的 hook 实施控制器。
生命周期 hook 配置示例

以下示例演示了中断机器删除过程的多个特殊生命周期 hook 的实现:

生命周期 hook 配置示例

apiVersion: machine.openshift.io/v1beta1
kind: Machine
metadata:
  ...
spec:
  lifecycleHooks:
    preDrain: 1
    - name: MigrateImportantApp
      owner: my-app-migration-controller
    preTerminate: 2
    - name: BackupFileSystem
      owner: my-backup-controller
    - name: CloudProviderSpecialCase
      owner: my-custom-storage-detach-controller 3
    - name: WaitForStorageDetach
      owner: my-custom-storage-detach-controller
  ...

1
包含单一生命周期 hook 的 preDrain 生命周期 hook 小节。
2
包含三个生命周期 hook 的 preTerminate 生命周期 hook 小节。
3
管理两个 preTerminate 生命周期 hook 的 hook 实现控制器:CloudProviderSpecialCaseWaitForStorageDetach

6.2.4. Operator 开发人员的机器删除生命周期 hook 示例

Operator 可以在机器删除阶段使用生命周期 hook 来修改机器删除过程。以下示例演示了 Operator 可以使用此功能的方法。

preDrain 生命周期 hook 用例示例
主动替换机器
Operator 可以使用 preDrain 生命周期 hook 来确保,在删除一个已删除机器的实例前,替代的集群已成功创建并加入集群。这可降低机器替换或不立即初始化的替换实例期间中断的影响。
实现自定义排空逻辑

Operator 可以使用 preDrain 生命周期 hook 将机器控制器排空逻辑替换为不同的排空控制器。通过替换排空逻辑,Operator 会具有更大的灵活性并控制每个节点的工作负载生命周期。

例如,机器控制器排空库不支持排序,但自定义排空供应商可以提供此功能。通过使用自定义排空供应商,Operator 可以在排空节点前优先选择移动关键任务应用程序,以确保在集群容量有限的情况下服务中断最小化。

preTerminate 生命周期 hook 用例示例
验证存储分离
Operator 可以使用 preTerminate 生命周期 hook 来确保,附加到机器的存储在从基础架构供应商中移除前已分离。
提高日志可靠性

节点排空后,日志导出器守护进程需要一些时间才能将日志同步到集中式日志记录系统。

日志记录 Operator 可以使用 preTerminate 生命周期 hook,在节点排空的时间和机器从基础架构供应商中删除的时间直接添加一个延迟。此延迟为 Operator 提供了一个时间,以确保主工作服务被删除,且不再被添加到日志中。如果没有将新数据添加到日志,日志导出器可以在同步过程中捕获,从而确保捕获所有应用程序日志。

6.2.5. 使用机器生命周期 hook 进行仲裁保护

对于使用 Machine API Operator 的 OpenShift Container Platform 集群,etcd Operator 使用机器删除阶段的生命周期 hook 来实现仲裁保护机制。

通过使用 preDrain 生命周期 hook,etcd Operator 可以控制 control plane 机器上的 pod 排空和删除的时间。为了保护 etcd 仲裁,etcd Operator 会阻止删除 etcd 成员,直到该成员迁移到集群中的新节点。

此机制允许 etcd Operator 对 etcd 仲裁的成员进行精确控制,并允许 Machine API Operator 在不需要 etcd 集群的特定操作了解的情况下安全地创建和删除 control plane 机器。

6.2.5.1. 使用仲裁保护处理顺序删除 control plane

当在使用 control plane 机器集的集群中替换 control plane 机器时,集群会临时有四个 control plane 机器。当第四个 control plane 节点加入集群时,etcd Operator 会在替换节点上启动新的 etcd 成员。当 etcd Operator 观察到旧的 control plane 机器已被标记为删除时,它会停止旧节点上的 etcd 成员,并提升替换 etcd 成员以加入集群的仲裁。

control plane 机器 Deleting 阶段按以下顺序进行:

  1. control plane 机器会停止以进行删除。
  2. control plane 机器进入 Deleting 阶段。
  3. 为了满足 preDrain 生命周期 hook,etcd Operator 会执行以下操作:

    1. etcd Operator 等待第四个 control plane 机器作为 etcd 成员添加到集群中。这个新 etcd 成员的状态为 Running 而不是 ready,直到它从 etcd leader 接收到了完整的数据库更新。
    2. 当新 etcd 成员收到完整数据库更新时,etcd Operator 会将新的 etcd 成员提升到投票成员,并从集群中移除旧的 etcd 成员。

    完成此转换后,旧的 etcd pod 及其数据是安全的,因此会删除 preDrain 生命周期 hook。

  4. control plane 机器状态条件 Drainable 设置为 True
  5. 机器控制器尝试排空由 control plane 机器支持的节点。

    • 如果排空失败,Drained 被设置为 False,机器控制器会尝试再次排空该节点。
    • 如果排空成功,Drained 被设置为 True
  6. control plane 机器状态条件 Drained 设置为 True
  7. 如果没有其他 Operator 添加了 preTerminate 生命周期 hook,control plane 机器状态条件 Terminable 被设置为 True
  8. 机器控制器从基础架构供应商中删除实例。
  9. 机器控制器会删除 Node 对象。

YAML 片断演示 etcd 仲裁保护 preDrain 生命周期 hook

apiVersion: machine.openshift.io/v1beta1
kind: Machine
metadata:
  ...
spec:
  lifecycleHooks:
    preDrain:
    - name: EtcdQuorumOperator 1
      owner: clusteroperator/etcd 2
  ...

1
preDrain 生命周期 hook 的名称。
2
管理 preDrain 生命周期 hook 的 hook 实施控制器。