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

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

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

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

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

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

[simterm]

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

[/simterm]

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

[simterm]

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

[/simterm]

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

[simterm]

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

[/simterm]

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

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

 --force и --grace-period

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

[simterm]

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

[/simterm]

Нет, ничего.

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

[simterm]

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

[/simterm]

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

Очистка finalizers

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

[simterm]

$ kubectl edit ns test-ns

[/simterm]

И удаляем:

...
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:

[simterm]

$ 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

[/simterm]

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

Версия metrics-server?

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

[simterm]

$ 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"

[/simterm]

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

[simterm]

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

[/simterm]

Не помогает.

Аргументы 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 работает:

[simterm]

$ 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%

[/simterm]

Значит, 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:

[simterm]

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

[/simterm]

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

monitoring/prometheus-adapter False (ServiceNotFound)

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

[simterm]

$ 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

[/simterm]

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

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

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

[simterm]

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

[/simterm]

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

[simterm]

$ 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
...

[/simterm]

И apiservices:

[simterm]

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

[/simterm]

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

[simterm]

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

[/simterm]

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

[simterm]

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

[/simterm]

Готово.