pod 중단 예산에 의해 차단된 노드 삭제

특정 조건에서는 Pod 중단 예산(PDB) 정책으로 인해 노드 풀에서 노드가 삭제되지 못할 수 있습니다. 이러한 조건에서 노드는 삭제되더라도 노드 상태는 Ready,SchedulingDisabled를 보고합니다.

pod 중단 예산과 사용 가능한 pod 수가 충돌합니다.

PDB 정책은 시스템 변경 시 pod가 동시에 다운되지 않도록 하여 앱 성능을 보장합니다. 따라서 PDB 정책은 복제된 애플리케이션에서 동시에 사용할 수 없는 pod 수를 제한합니다.

그러나 PDB 정책은 노드를 삭제하면 정책을 위반하게 되어 노드 삭제를 차단할 수도 있습니다.

예를 들어 PDB 정책은 항상 시스템에 사용 가능한 Pod 두 개가 있어야 한다고 정의할 수 있습니다(.spec.minAvailable는 2). 그러나 Pod가 2개만 있고 이들 중 하나가 포함된 노드를 삭제하려고 하면 PDB 정책이 적용되고 노드 삭제가 방지됩니다.

마찬가지로 PDB 정책이 사용할 수 없는 Pod(.spec.maxUnavailable이 0)가 없어야 한다고 정의하면 정책은 모든 관련 노드가 삭제되지 않도록 합니다 Pod를 한 번에 하나씩 제거하려고 해도 PDB 정책이 영향을 받는 노드를 삭제할 수 없도록 합니다.

해결 방법: PDB 정책 사용 중지 및 다시 사용 설정

이러한 충돌을 해결하려면 PDB 정책을 백업한 다음 제거합니다. PDB가 성공적으로 삭제되면 노드가 드레이닝되고 연결된 Pod가 삭제됩니다. 원하는 대로 변경한 후 PDB 정책을 다시 사용 설정할 수 있습니다.

다음 예시에서는 이 조건에서 노드를 삭제하는 방법을 보여줍니다. 이렇게 하면 베어메탈용 Anthos 클러스터의 모든 클러스터 유형(관리자, 하이브리드, 독립형, 사용자 클러스터)에 영향을 줄 수 있습니다.

모든 클러스터 유형에 동일한 일반 절차가 적용됩니다. 그러나 관리자, 하이브리드 또는 독립형 클러스터의 관리자 클러스터 노드 풀에서 노드를 삭제하는 특정 명령어는 사용자 클러스터 노드 풀에서 노드를 삭제하는 명령어와 약간 다릅니다.

여러 클러스터 유형의 명령어 변형

쉽게 읽을 수 있도록 다음 명령어에서 자리표시자 ${KUBECONFIG}를 기록해 둡니다. 클러스터 유형에 따라 관리자 클러스터 kubeconfig(ADMIN_KUBECONFIG) 또는 사용자 클러스터 kubeconfig(USER_CLUSTER_CONFIG) 경로를 $(KUBECONFIG)로 내보내고 아래 단계를 따릅니다.

  • 사용자 클러스터에서 노드를 삭제하려면 export KUBECONFIG=USER_CLUSTER_CONFIG를 실행합니다.
  • 관리자 클러스터에서 노드를 삭제하려면 export KUBECONFIG=ADMIN_KUBECONFIG를 실행합니다.
  1. (선택사항): 사용자 클러스터 노드 풀에서 노드를 삭제하는 경우 다음 명령어를 실행하여 사용자 클러스터 kubeconfig 파일을 추출합니다. ADMIN_KUBECONFIG 변수는 관리자 클러스터 kubeconfig의 경로를 지정하고 USER_CLUSTER_NAME 변수는 클러스터의 이름을 지정합니다.

    kubectl --kubeconfig ADMIN_KUBECONFIG -n cluster-USER_CLUSTER_NAME  \
    get secret USER_CLUSTER_NAME-kubeconfig  \
    -o 'jsonpath={.data.value}' | base64 -d > USER_CLUSTER_CONFIG
    
  2. 노드 풀에서 노드를 삭제한 후 노드 상태를 확인합니다. 영향을 받는 노드는 Ready, SchedulingDisabled를 보고합니다.

    kubectl get nodes --kubeconfig ${KUBECONFIG}
    

    노드 상태는 다음과 유사합니다.

    NAME        STATUS                    ROLES      AGE      VERSION
    abmnewCP2   Ready                     Master     11m      v.1.18.6-gke.6600
    abmnewCP3   Ready,SchedulingDisabled  <none>     9m22s    v.1.18.6-gke.6600
    abmnewCP4   Ready                     <none>     9m18s    v.1.18.6-gke.6600
    
  3. 클러스터의 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
     ```
    
  4. 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"}}}
    
  5. 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    abmnewCP3
    stackdriver-log-aggregator-1    abmnewCP3
    
  6. 영향을 받은 Pod를 확인한 후 PDB 정책의 백업 사본을 만듭니다. 이 예시에서는 log-aggregator 정책입니다.

    kubectl get pdb log-aggregator --kubeconfig ${KUBECONFIG} -n kube-system  \
    -o yaml >> log-aggregator.yaml
    
  7. 특정 PDB 정책을 삭제합니다. 이 예시에서는 log-aggregator 정책입니다.

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

    PDB 정책을 삭제하면 노드가 드레이닝을 진행합니다. 하지만 노드가 완전히 삭제되려면 약간의 시간(최대 30분)이 걸릴 수 있으므로 노드 상태를 계속 확인하세요.

    노드를 영구적으로 삭제하고 노드와 연결된 스토리지 리소스도 삭제하려면 PDB 정책을 복원하기 전에 삭제할 수 있습니다. 스토리지 리소스 삭제를 참조하세요.

  8. 사본에서 PDB 정책을 복원합니다.

    kubectl apply -f log-aggregator.yaml --kubeconfig ${KUBECONFIG}
    
  9. 삭제된 Pod가 성공적으로 다시 생성되었는지 확인합니다. 이 예시에서는 2개의 stackdriver-log-aggregator-x Pod가 있는 경우 이러한 Pod가 다시 생성됩니다.

    kubectl get pods -o wide --kubeconfig ${KUBECONFIG} -A
    

노드를 복원하려면 적절한 노드 풀 구성을 수정하고 노드 IP 주소를 복원합니다.

영구 삭제된 노드에서 스토리지 리소스 삭제

노드를 영구적으로 삭제하고 시스템을 복원하지 않으려는 경우 이 노드와 연결된 스토리지 리소스도 삭제할 수 있습니다.

다음 명령어에서 다음 변수를 확인합니다.

  • ADMIN-KUBECONFIG는 관리자 클러스터 경로를 지정합니다.
  • USER_CLUSTER_CONFIG는 클러스터 구성 YAML 파일의 경로를 지정합니다.
  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}