티스토리 뷰

728x90
반응형

How to force deletion of pods on namespace

문제 상황

이전 게시글인 삭제되지 않는 네임스페이스 Namespace 강제로 삭제하기 를 통해 네임스페이를 삭제하는 방법을 알아 보았다.

이번 경우는 확실하게 눈으로 확인할 수 있는 파드 Pod 들이 남아 있고 Terminating 상태로 삭제되지 않는 문제가 발생했다. 테스트 했던 M3 오퍼레이터 Operator 를 장시간 유지하면서 etcd 클러스터가 응답하지 않는 상태가 발생했고, 삭제를 했지만 삭제되지 않는 문제인 상태다.

$ kubectl -n m3cluster get pods
NAME                READY   STATUS            RESTARTS   AGE
...
etcd-0            1/1     Terminating   2          16d
etcd-1            1/1     Terminating   2          16d
etcd-2            1/1     Terminating   2          16d
...

문제 원인 확인과 처리 방법

정상적으로 삭제될 수 있는 시간을 지나서도 Terminating 상태로 남아있는 상태는 대부분은 아래와 같은 원인으로 발생한다.

  • 파드에 처리되지 않는 파이널라이저 Finalizer 가 연결된 경우
  • 파드가 종료 시그널에 응답하지 않는 경우

이런 상황에서 정보를 확인해야 한다.

  1. 정보 출력

    $ kubectl -n <namespace_name> get pod -p <pod_name> -o yml [> undeleted_pod.yaml]

    화면에 출력을 사용하던지 아니면 화일로 출력해서 내용 중에서 status 부분과 metadata.finalizer 내용을 검토한다.

  2. 파이널라이저 확인

    status 상에 별다른 문제가 없다면 출력된 정보에서 파이널라이저가 존재하는지 확인하고 아래의 명령을 사용해서 해당 파이널라이저를 제거한다.

    $ kubectl -n <namepsace_name> patch pod <pod_name> -p '{"metadata":{"finalizers":null}}'
  3. 노드 상태 확인

    파드가 정상적인 상태로 판단이 되면 노드를 확인해 봐야 한다. 출력물에서 spec.nodeName 을 통해서 배정된 노드 명을 확인하고 쿠버네티스 대시보드 등을 통해서 노드에 배정된 모든 파드가 Terminating 상태인지를 확인해야 한다.

    이 상황이라면 쿠버네티스 마스터를 통해서 삭제 요청된 내용이 해당 노드가 응답할 수 있는 상태가 되어야 처리될 수 있으므로 노드를 재 부팅하는 등으로 처리하면 된다.

  4. 포드 강제 삭제

    위의 모든 상황이 정상적이라면 종료 시그널에 응답하지 않는 상태인 것으로 일반적으로는 다음과 같은 상황일 수 있다.

    • 인터럽트 신호를 허용하지 않는 사용자 공간의 루프 실행 중
    • 애플리케이션 런타임의 유지 관리 프로세스 진행 중 (예를 들면 가비지 수집 등)

    이런 경우라면 강제로 종료 시키는 방법을 사용할 수 있다. 그러나 이런 처리는 향후 예상치 않은 문제가 발생할 수도 있다.

    $ kubectl -n <namespace_name> delete pod <pod_name> --grace-period=0 --force

    하나의 파드라면 위의 명령을 사용하면 되지만 여러 개의 파드가 대상이라면 아래와 같이 일괄처리도 가능하다.

    for p in $(kubectl -n <namespace_name> get pods | grep Terminating | awk '{print $1}'); do kubectl -n <namespace_name> delete pod $p --grace-period=0 --force; done
  5. kubelet 재 시작

    마지막으로 해 볼 수 있는 것은 종료 시그널이 실제 배정된 노드의 kubelet 과 연결되지 못해서 처리가 안되는 경우로 SSH를 통해 해당 노드로 접근해서 kubelet을 재 시작하는 것이다.

    당연히 이를 처리하기 위한 권한이 존재해야 하고, 처리하기 전에 kubelet 로그를 확인해서 의심되는 상황이 존재하는지를 우선 검토하도록 한다.

728x90
반응형
댓글
댓글쓰기 폼