排查 AlloyDB Omni for Kubernetes 中发生 crashloop 的数据库 pod

选择文档版本:

本页面介绍了在遇到以下情况时,如何解决 AlloyDB Omni for Kubernetes 的问题:

  • 您在 Kubernetes 中有一个处于崩溃循环状态的数据库集群,并且知道该数据库的名称和命名空间、其内部实例和 Pod。
  • 您需要访问数据库 pod 中的文件,但崩溃循环阻止了访问。

陷入 crashlooping 状态的数据库 pod 是指反复启动、崩溃,然后由 Kubernetes 自动重启的 pod。此循环会无限期地持续下去,直到根本问题得到解决。在此过程中,数据库会变得不可用且不稳定。

准备工作

在按照本文档中的问题排查指南进行操作之前,请尝试以下解决方案:

  • 如果高可用性 (HA) 可用,则触发故障切换。借助高可用性,同步备用实例可随时替换主实例。
  • 从备份中恢复(如果有)。这种方法是自动化的,而且不易出错。

无法访问处于崩溃循环状态的数据库 pod 中的文件

说明:Kubernetes 集群中的数据库 Pod 进入 CrashLoopBackOff 状态。此状态会阻止您使用 kubectl exec 访问数据库容器的文件系统以进行调试。

建议的解决方法:如需解决此问题,请通过修补 pod 的 StatefulSet 来替换容器的命令,暂时停止崩溃循环。在继续操作之前,请考虑更简单的替代方案,例如触发故障转移或从备份中恢复(如果可用)。

如需访问 pod,请按以下步骤操作:

  1. 暂停所有面向用户的相关 AlloyDB Omni 资源,以防止它们干扰恢复过程。

    1. 列出所有 AlloyDB Omni Kubernetes 自定义资源定义:

      kubectl get crd | grep alloydbomni.dbadmin
      
    2. 查看数据库集群的资源列表。记录您暂停的资源,以便日后取消暂停。您必须至少暂停 dbclusters.alloydbomni.dbadmin.goog 资源。

    3. 通过添加 ctrlfwk.internal.gdc.goog/pause 注释,分别暂停每个资源。

      kubectl annotate RESOURCE_TYPE -n NAMESPACE RESOURCE_NAME ctrlfwk.internal.gdc.goog/pause=true
      

      替换以下内容:

      • RESOURCE_TYPE:要暂停的资源的类型,例如 dbclusters.alloydbomni.dbadmin.goog
      • NAMESPACE:数据库集群的命名空间。
      • RESOURCE_NAME:要暂停的资源的名称。
  2. 暂停管理崩溃循环 Pod 的内部实例。

    1. 查找内部实例的名称。

      kubectl get instances.alloydbomni.internal.dbadmin.goog -n NAMESPACE
      

      替换以下内容:

      • NAMESPACE:您感兴趣的命名空间的名称。
    2. 暂停实例。ctrlfwk.internal.gdc.goog/pause=true 注解会告知 AlloyDB Omni 控制器暂停对资源的管理。这样可防止控制器在您手动执行问题排查步骤(例如修补底层 StatefulSet)时自动协调或更改资源。

      kubectl annotate instances.alloydbomni.internal.dbadmin.goog -n NAMESPACE INSTANCE_NAME ctrlfwk.internal.gdc.goog/pause=true
      

      替换以下内容:

      • NAMESPACE:您感兴趣的命名空间的名称。
      • INSTANCE_NAME:您找到的实例的名称。
  3. 防止 pod 进入崩溃循环。

    修补 pod 的 StatefulSet 以替换主容器的命令。 此更改可防止应用启动和崩溃,从而让您能够访问 pod。

    1. 确认发生崩溃循环的 pod 的名称。

      kubectl get pod -n NAMESPACE
      

      NAMESPACE 替换为您感兴趣的命名空间的名称。

    2. 找到拥有相应 pod 的 StatefulSet 的名称。

      kubectl get pod -n NAMESPACE POD_NAME -ojsonpath='{.metadata.ownerReferences[0].name}'
      

      替换以下内容:

      • NAMESPACE:您感兴趣的命名空间的名称。
      • POD_NAME:发生崩溃循环的 pod 的名称。
    3. 修补 StatefulSet 以将数据库容器的命令替换为 sleep infinity

      kubectl patch statefulset STATEFULSET_NAME -n NAMESPACE --type='strategic' -p '
      {
        "spec": {
          "template": {
            "spec": {
              "containers": [
                {
                  "name": "database",
                  "command": ["sleep"],
                  "args": ["infinity"],
                  "livenessProbe": null,
                  "startupProbe": null
                }
              ]
            }
          }
        }
      }
      '
      

      替换以下内容:

      • NAMESPACE:您感兴趣的命名空间的名称。
      • STATEFULSET_NAMEStatefulSet 的名称。
    4. 删除 pod 以应用补丁。

      kubectl delete pod -n NAMESPACE POD_NAME
      

      替换以下内容:

      • NAMESPACE:您感兴趣的命名空间的名称。
      • POD_NAME:发生崩溃循环的 pod 的名称。
  4. 访问 pod 中的数据库。

    kubectl exec -ti -n NAMESPACE POD_NAME -c database -- bash
    

    替换以下内容:

    • NAMESPACE:您感兴趣的命名空间的名称。
    • POD_NAME:发生崩溃循环的 pod 的名称。

    新 pod 启动后,它会运行 sleep 命令,而不是数据库应用。您现在可以访问 pod 的 shell 了。

  5. 取消暂停所有组件。

    调查完成后,移除 pause 注释以恢复原始状态。您需要以暂停资源的相反顺序取消暂停资源;例如,先取消暂停实例,然后再取消暂停 DBCluster。 此操作会协调资源并使用其原始命令重启数据库 pod。

    1. 对于您暂停的每个资源,请通过在注释名称后附加连字符来移除注释。以下示例从实例中移除了注解:

      kubectl annotate instances.alloydbomni.internal.dbadmin.goog -n NAMESPACE INSTANCE_NAME ctrlfwk.internal.gdc.goog/pause-
      

      替换以下内容:

      • NAMESPACE:您感兴趣的命名空间的名称。
      • INSTANCE_NAME:您在上一步中找到的实例的名称。
    2. 针对您在第一步中暂停的所有其他资源重复此流程。