Kubernetes: namespace висит в Terminating и неочевидности с metrics-server

Автор: | 03/23/2021
 

Столкнулся с весьма интересной проблемой при удалении Kubernetes Namespace.

При попытке удалить неймспейс — он зависает в статусе Terminating, и никакие попытки его удалить не помогали.

Рассмотрим варианты удаления, и докопаемся до причины.

Создаём тестовый namespace:

kubectl create namespace test-ns
namespace/test-ns created

Пробуем его удалить — и удаление зависает:

kubectl delete namespace test-ns
namespace "test-ns" deleted

Проверяем — висит в Terminating:

kubectl get ns test-ns
NAME      STATUS        AGE
test-ns   Terminating   50s

При этом в логах API-сервера никаких ошибок толком нет.

Попытки удаления Namespace

 --force и --grace-period

Может, там какие-то ресурсы, удаления которых ждёт Kubernetes? Проверяем:

kubectl -n test-ns get all
No resources found.

Нет, ничего.

Да и удаление с --force и --grace-period=0 не помогает:

kubectl delete namespace test-ns --force --grace-period=0

Неймспейс всё ещё на месте, всё в том же статусе Terminating.

Очистка finalizers

Гуглим, 99% результатов советуют удалить kubernetes из  finalizers — редактируем неймспейс:

kubectl edit ns test-ns

И удаляем:

...
spec:
  finalizers:
  - kubernetes
...

Сохраняем — и ничего не меняется. Неймспейс в том же состоянии, а finalizers=kubernetes возвращается обратно.

APIs: custom.metrics.k8s.io/v1beta1: the server is currently unable to handle the request

Дальше — интереснее.

Если выполнить kubectl api-resources, то получим ошибку с custom.metrics.k8s.io:

kubectl api-resources
error: unable to retrieve the complete list of server APIs: custom.metrics.k8s.io/v1beta1: the server is currently unable to handle the request

Это и натолкнуло на направление дальнейшего копания — что-то не так с metrics-server.

Версия metrics-server?

Первая мысль — у нас старая его версия, и он не работает, в нашей автоматизации до сих пор 0.3.6:

grep -r metrics-server ../roles/controllers/ | grep github
../roles/controllers/tasks/main.yml:  command: "kubectl --kubeconfig={{ kube_config_path }} apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.6/components.yaml"

Переустанавливаем версию 0.4.2, последнюю:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.4.2/components.yaml

Не помогает.

Аргументы metrics-server?

Может, проблема с подключением к metrics-server?

Пробуем изменить --kubelet-insecure-tls, --kubelet-preferred-address-types=InternalIP и даже hostNetwork=true, выглядело как-то так:

...
    spec:
      hostNetwork: true
      containers:
      - args:
        - --cert-dir=/tmp
        - --secure-port=4443
        - --kubelet-preferred-address-types=InternalIP
        - --kubelet-use-node-status-port
        - --kubelet-insecure-tls
...

Не помогает.

При этом kubectl top работает:

kubectl top node
NAME                                         CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
ip-10-22-35-66.eu-west-3.compute.internal    136m         7%     989Mi           13%
ip-10-22-53-197.eu-west-3.compute.internal   125m         6%     925Mi           12%

Значит, Kubernetes метрики получает.

Значит — с metrcis-server всё в порядке? Коннекты есть, данные к нему и от него проходят?

Kubernetes apiservices

Вернёмся к ошибке:

custom.metrics.k8s.io/v1beta1: the server is currently unable to handle the request

Проверяем сам apiservice v1beta1.custom.metrics.k8s.io:

kubectl get apiservices v1beta1.custom.metrics.k8s.io
NAME                            SERVICE                      AVAILABLE                 AGE
v1beta1.custom.metrics.k8s.io   monitoring/prometheus-adapter   False (ServiceNotFound)   9m7s

Ага, вот эти ребята:

monitoring/prometheus-adapter False (ServiceNotFound)

Он должен обращаться к сервису monitoring/prometheus-adapter — проверяем его наличие:

kk -n monitoring get svc
NAME                                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)            AGE
prometheus-grafana                      ClusterIP   172.20.167.133   <none>        80/TCP             12m
prometheus-kube-state-metrics           ClusterIP   172.20.32.255    <none>        8080/TCP           12m
prometheus-operated                     ClusterIP   None             <none>        9090/TCP           11m
prometheus-prometheus-node-exporter     ClusterIP   172.20.228.75    <none>        9100/TCP           12m
prometheus-prometheus-oper-operator     ClusterIP   172.20.131.64    <none>        8080/TCP,443/TCP   12m
prometheus-prometheus-oper-prometheus   ClusterIP   172.20.205.138   <none>        9090/TCP           12m

А prometheus-adapter-то и нету.

Соответственно, и не работает ендпоинт custom.metrics.k8s.io.

Устанавливаем адаптер:

helm -n monitoring install prometheus-adapter stable/prometheus-adapter

Проверяем ещё раз сервисы:

kk -n monitoring get svc
NAME                                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)            AGE
prometheus-adapter                      ClusterIP   172.20.59.130    <none>        443/TCP            21s
...

И apiservices:

kubectl get apiservices v1beta1.custom.metrics.k8s.io
NAME                            SERVICE                         AVAILABLE   AGE
v1beta1.custom.metrics.k8s.io   monitoring/prometheus-adapter   True        56s

И наш неймспейс:

kk get ns test-ns
NAME      STATUS        AGE
test-ns   Terminating   19m

И через минуту:

kk get ns test-ns
Error from server (NotFound): namespaces "test-ns" not found

Готово.