移除被 PodDisruptionBudgets 屏蔽的节点

在某些情况下,PodDisruptionBudget (PDB) 政策可以阻止从节点池中成功移除节点。在此类条件下,即使已移除,节点状态仍会报告 Ready,SchedulingDisabled。本文档介绍如何从 GKE on Bare Metal 集群中移除当前被 PDB 问题阻止的节点。

如果您需要其他帮助,请与 Cloud Customer Care 联系。

PDB 与可用 Pod 数量冲突

PDB 政策通过阻止在更改系统的同时同时关闭 Pod 来确保应用的性能。因此,PDB 政策会限制复制应用中同时不可用的 Pod 的数量。

但是,如果您通过移除节点来违反政策,PDB 政策有时可以防止您想要执行的节点删除操作。

例如,PDB 政策可以定义系统中应始终有两个可用的 Pod(.spec.minAvailable 为 2)。但是,如果您只有两个 Pod,并且尝试移除包含其中一个 Pod 的节点,则 PDB 政策会生效并阻止移除该节点。

同样,当 PDB 政策定义所有 Pod 均不可用时(.spec.maxUnavailable 为 0),它还会阻止删除任何关联节点。即使您一次尝试移除一个 Pod,PDB 政策也会阻止您删除受影响的节点。

停用并重新启用 PDB 政策

如需解决 PDB 冲突,请备份并移除 PDB 政策。成功删除 PDB 后,系统会排空节点并移除关联的 Pod。然后,您可以按需进行更改,并重新启用 PDB 政策。

以下示例展示了如何在此条件下删除节点,这会影响所有类型的 GKE on Bare Metal 集群:管理员集群、混合集群、独立集群和用户集群。

相同的常规流程适用于所有集群类型。但是,从管理员集群节点池(对于管理员集群、混合集群或独立集群)中删除节点所使用的特定命令与从用户集群节点池中删除节点所使用的命令略有不同。

  1. 为便于读取,以下命令中使用了 ${KUBECONFIG} 变量。

    根据集群类型,将管理员集群 kubeconfig (ADMIN_KUBECONFIG) 或用户集群 kubeconfig (USER_CLUSTER_CONFIG) 路径导出到 $(KUBECONFIG),并完成以下步骤:

    • 如需从用户集群中删除节点,请设置 export KUBECONFIG=USER_CLUSTER_CONFIG
    • 如需从管理员集群中删除节点,请设置 export KUBECONFIG=ADMIN_KUBECONFIG
  2. 可选:如果要从用户集群节点池中删除节点,请运行以下命令以提取用户集群 kubeconfig 文件:

    kubectl --kubeconfig ADMIN_KUBECONFIG -n cluster-USER_CLUSTER_NAME \
      get secret USER_CLUSTER_NAME-kubeconfig  \
      -o 'jsonpath={.data.value}' | base64 -d > USER_CLUSTER_CONFIG
    

    将以下条目替换为特定于您的集群环境的信息:

    • ADMIN_KUBECONFIG:管理员集群 kubeconfig 文件的路径。
    • CLUSTER_NAME:您要截取其快照的集群的名称。
    • USER_CLUSTER_CONFIG:用户集群配置文件的路径。
  3. 从节点池中移除节点后,请检查节点状态。受影响的节点会报告 Ready, SchedulingDisabled

    kubectl get nodes --kubeconfig ${KUBECONFIG}
    

    节点状态类似于以下示例输出:

    NAME   STATUS                    ROLES      AGE      VERSION
    CP2    Ready                     Master     11m      v.1.18.6-gke.6600
    CP3    Ready,SchedulingDisabled  <none>     9m22s    v.1.18.6-gke.6600
    CP4    Ready                     <none>     9m18s    v.1.18.6-gke.6600
    
  4. 检查集群中的 PDB:

    kubectl get pdb --kubeconfig ${KUBECONFIG} -A
    

    系统会报告类似于以下示例输出中所示的 PDB:

    NAMESPACE     NAME             MIN AVAILABLE    MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
    gke-system    istio-ingress    1                N/A               1                     19m
    gke-system    istiod           1                N/A               1                     19m
    kube-system   coredns          1                N/A               0                     19m
    kube-system   log-aggregator   N/A              0                 0                     19m
    kube-system   prometheus       N/A              0                 0                     19m
    
  5. 检查 PDB。查找 PDB 中的 Pod 标签与节点中的匹配 Pod 之间的匹配项。这种匹配可确保您停用正确的 PDB 以成功移除节点:

    kubectl --kubeconfig ${KUBECONFIG} get pdb log-aggregator -n kube-system -o 'jsonpath={.spec}'
    

    系统会在 PDB 政策中返回匹配的标签结果:

    {"maxUnavailable":0,"selector":{"matchLabels":{"app":"stackdriver-log-aggregator"}}}
    
  6. 找到与 PDB 政策标签匹配的 Pod:

    kubectl --kubeconfig ${KUBECONFIG} get pods -A --selector=app=stackdriver-log-aggregator  \
      -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}'
    

    该命令会返回与 PDB 标签匹配的 Pod 列表,并验证您需要移除的 PDB 政策:

    stackdriver-log-aggregator-0    CP3
    stackdriver-log-aggregator-1    CP3
    
  7. 确认受影响的 Pod 后,请创建 PDB 政策的备份副本。以下示例会备份 log-aggregator 政策:

    kubectl get pdb log-aggregator --kubeconfig ${KUBECONFIG} -n kube-system  \
      -o yaml >> log-aggregator.yaml
    
  8. 删除特定的 PDB 政策。同样,以下示例会删除 log-aggregator 政策:

    kubectl delete pdb log-aggregator --kubeconfig ${KUBECONFIG} -n kube-system
    

    删除 PDB 政策后,节点将继续排空。但是,完全删除节点最多可能需要 30 分钟。继续检查节点状态,确认该过程已成功完成。

    如果您要永久移除该节点,同时移除与该节点关联的存储资源,则可以在恢复 PDB 政策之前执行此操作。如需了解详情,请参阅移除存储资源

  9. 从副本中恢复 PDB 政策:

    kubectl apply -f log-aggregator.yaml --kubeconfig ${KUBECONFIG}
    
  10. 验证已删除的 Pod 是否已成功重新创建。在以下示例中,如果有两个 stackdriver-log-aggregator-x Pod,则系统会重新创建它们:

    kubectl get pods -o wide --kubeconfig ${KUBECONFIG} -A
    
  11. 若要恢复节点,请修改相应的节点池配置并恢复节点 IP 地址。

从永久删除的节点中移除存储资源

如果您永久删除了某个节点,并且不想将其恢复到您的系统中,则还可以删除与该节点关联的存储资源。

  1. 查看并获取与节点关联的永久性卷 (PV) 的名称:

    kubectl get pv --kubeconfig ${KUBECONFIG}  \
      -A -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{.spec.claimRef.name}{":\t}  \
      {.spec.nodeAffinity.required.nodeSelectorTerms[0].matchExpressions[0].values}{"\n"}{end}'
    
  2. 删除与节点关联的 PV:

    kubectl delete pv PV_NAME --kubeconfig ${KUBECONFIG}
    

    PV_NAME 替换为要删除的永久性卷的名称。

后续步骤

如果您需要其他帮助,请与 Cloud Customer Care 联系。