Kubernetes namespace의 phase가 Terminating에서 멈춰있을 때

원인, 해결책 분석

  1. custom finalizer가 정리되지 않는 케이스

    1. Namespace .spec.finalizers 내용을 확인했을 때 배열에 kubernetes 를 제외한 다른 element가 남아있다면 어떤 extension controller가 namespace를 초기화는 하고 정리는 못한 케이스.

    2. 이 케이스는 우선 현재 클러스터에 namespace finalizer를 붙이는 controller가 무엇인가를 먼저 파악하고 수정해야한다.

  2. kubernetes finalizer가 정리되지 않는 케이스

    1. kubernetes 는 기본 finalizer로 namespace 내부의 모든 리소스가 정리되면 삭제된다. 그런데 이 finalizer가 삭제되지 않는다는 이야기는 리소스 정리 과정에서 에러가 발생했다는 이야기가 된다.

    2. 따라서 우선 namespace에 진짜 모든 리소스가 삭제된건지 확인해봐야한다. kubectl get all 의 경우 category all인 리소스들만 보여주므로 진짜로 모든 리소스를 보여주는게 아니다. kubectl api-resources --namespaced=true -o name 명령어로 체크해야될 모든 리소스의 이름을 확인할 수 있다. 확인 과정에서 삭제되지않고 있는 리소스가 있다면 그 리소스가 삭제되지 못하고 있는 이유를 확인해야한다. 보통은 .metadata.finalizers 에 원인이 있을 가능성이 높다.

    3. 위에서 확인해본 결과 모든 리소스가 삭제된게 맞다면 이번에는 admission webhook이나 extension api server 에서 에러가 발생했다는 이야기다. namespace가 삭제될 때 각 리소스를 삭제하기 위해서 보내는 요청은 delete가 아니라 delete-collection이므로 delete-collection에 대해서 제대로 처리했는지 다시 한번 확인해야한다.

참고로 namespace의 .spec.finalizers 는 sub resource이기 때문에 kubectl edit 또는 kubectl update 으로 수정되지 않는다. 따라서 curl 등을 통해서 직접 finalizers sub resources api를 호출해야 한다.

사용한 스크립트

모든 리소스 체크용 스크립트

#!/usr/bin/env bash
die() {
  echo "$*" 1>&2
  exit 1
}
need() {
  command -v "$1" &>/dev/null || die "Binary '$1' is missing but required"
}

need "kubectl"

echo "------------------------------------------------"
echo "get all resources in namespace..."
echo "------------------------------------------------"
FOUND=""
NOT_FOUND=""
ERROR=""
RESOURCES=$(kubectl api-resources --namespaced=true -o name)
for resource in $RESOURCES; do
  if [[ $resource =~ "metrics" ]]; then
    continue
  fi

  found=$(kubectl get "$resource" 2>&1)
  if [[ "$found" == "No resources found." ]]; then
    echo "$resource: $found"
    NOT_FOUND="$NOT_FOUND\n$resource"
  elif [[ $found =~ "Error" ]]; then
    echo "$resource: $found"
    ERROR="$ERROR\n$resource"
  else
    printf ">> %s:\n%s" "$resource" "$found"
    FOUND="$FOUND\n$resource"
  fi
done

echo "------------------------------------------------"
echo "summary"
echo "------------------------------------------------"
printf ">> found: %b\n" "$FOUND"
echo "------------------------------------------------"
printf ">> not found: %b\n" "$NOT_FOUND"
echo "------------------------------------------------"
printf ">> error: %b\n" "$ERROR"

namespace finalizers 강제로 비우는 스크립트

Last updated