Стручки застряли в состоянии завершения

Я устал удалять контроллер репликации с 12 модулями, и я мог видеть, что некоторые блоки остаются в состоянии завершения. Моя настройка Kubernetes состоит из одного мастера и трех минонов, установленных в Ubuntu VMS. В чем может быть причина этой проблемы?

NAME        READY     STATUS        RESTARTS   AGE
pod-186o2   1/1       Terminating   0          2h
pod-4b6qc   1/1       Terminating   0          2h
pod-8xl86   1/1       Terminating   0          1h
pod-d6htc   1/1       Terminating   0          1h
pod-vlzov   1/1       Terminating   0          1h

27 ответов

Решение

Вы можете использовать следующую команду для принудительного удаления POD.

kubectl удалить модуль ИМЯ --grace-period=0 --force

Исходный вопрос: "Вчем может быть причина этой проблемы?", И ответ обсуждается на https://github.com/kubernetes/kubernetes/issues/51835 и https://github.com/kubernetes/kubernetes/issues/65569 и см. https://www.bountysource.com/issues/33241128-unable-to-remove-a-stopped-container-device-or-resource-busy

Это вызвано утечкой докера в другое пространство имен.

Вы можете войти в систему на хосте пода, чтобы исследовать.

minikube ssh
docker container ps | grep <id>
docker container stop <id> 

Принудительно удалить стручок:

kubectl delete pod --grace-period=0 --force --namespace <NAMESPACE> <PODNAME>

--force Флаг обязателен.

Я нашел эту команду более простой:

for p in $(kubectl get pods | grep Terminating | awk '{print $1}'); do kubectl delete pod $p --grace-period=0 --force;done

Он удалит все модули в состоянии завершения в пространстве имен по умолчанию.

В моем случае --force вариант не совсем сработал. Я все еще мог видеть стручок! Он застрял в режиме завершения / неизвестности. Итак, после запуска

kubectl delete pods <pod> -n redis --grace-period=0 --force

Я побежал

kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'

Удалить блок финализаторов из ресурса (модуль, развертывание,ds и т. Д.) Yaml:

"finalizers": [
  "foregroundDeletion"
]

Я наткнулся на это недавно, чтобы освободить ресурс в моем кластере. Вот команда, чтобы удалить их всех.

kubectl get pods --all-namespaces | grep Terminating | while read line; do 
pod_name=$(echo $line | awk '{print $2}' ) name_space=$(echo $line | awk 
'{print $1}' ); kubectl delete pods $pod_name -n $name_space --grace-period=0 --force; 
done

надеюсь, это поможет кому-то, кто читает это

Практический ответ - вы всегда можете удалить завершающий модуль, выполнив:

kubectl delete pod NAME --grace-period=0

Исторический ответ. В версии 1.1 существовала проблема, из-за которой иногда блоки оказывались в состоянии завершения, если их узлы нечисто удалялись из кластера.

в моем случае мне не нравится обходной путь. Итак, шаги:

  • k get pod -o wide -> это покажет, на каком узле работает под
  • k get nodes -> Проверить статус этого узла ... Я понял NotReady

Я пошел и исправил этот узел ... в моем случае это просто перезапуск kubelet:

  • ssh that-node -> беги swapoff -a && systemctl restart kubelet

теперь удаление модуля должно работать без принудительного удаления модуля «Плохой».

попробуйте команду ниже: kubectl patch pod -p '{"metadata":{"finalizers":null}}'

Чтобы удалить все модули в состоянии «Завершение» во всех пространствах имен:

      kubectl get pods --all-namespaces | awk '/Terminating/{print $1 " " $2}' | while read -r namespace pod; do kubectl delete pod "$pod" -n "$namespace" --grace-period=0 --force;done

Если --grace-period=0 не работает, то вы можете сделать:

kubectl delete pods <pod> --grace-period=0 --force

Принудительно удалить ВСЕ модули в пространстве имен:

      kubectl delete pods --all -n <namespace> --grace-period 0 --force

Я недавно наткнулся на это, когда удалял пространство имен rook ceph - оно застряло в состоянии Terminating.

Единственное, что помогло, - это удалить финализатор kubernetes, напрямую вызвав api k8s с curl, как предложено здесь.

  • kubectl get namespace rook-ceph -o json > tmp.json
  • удалить kubernetes финализатор в tmp.json (оставить пустой массив "finalizers": [])
  • бежать kubectl proxy в другом терминале для целей аутентификации и выполните следующий запрос curl к возвращенному порту
  • curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json 127.0.0.1:8001/k8s/clusters/c-mzplp/api/v1/namespaces/rook-ceph/finalize
  • пространство имен ушло

Подробный демонтаж ладьи ceph здесь.

У меня была такая же проблема в производственном кластере Kubernetes.

Модуль на некоторое время застрял в фазе завершения:

      pod-issuing   mypod-issuing-0   1/1     Terminating   0  27h

Я попытался проверить журналы и события с помощью команды:

      kubectl describe pod mypod-issuing-0 --namespace pod-issuing
kubectl logs mypod-issuing-0 --namespace pod-issuing

но ни один не был доступен для просмотра

Как я это исправил:

Я выполнил команду ниже, чтобы принудительно удалить модуль:

      kubectl delete pod <PODNAME> --grace-period=0 --force --namespace <NAMESPACE>

Это немедленно удалило модуль и начало создание нового. Однако я столкнулся с ошибкой ниже, когда создавался другой модуль:

Невозможно подключить или смонтировать тома: размонтированные тома=[данные], неприкрепленные тома=[данные mypod-issuing-token-5swgg aws-iam-token]: истекло время ожидания условия

Мне пришлось ждать от 7 до 10 минут , чтобы том отсоединился от предыдущего модуля, который я удалил, чтобы он стал доступным для этого нового модуля, который я создавал.

Я использовал эту команду для удаления стручков

      kubectl delete pod --grace-period=0 --force --namespace <NAMESPACE> <PODNAME>

Но когда я попытался запустить другой модуль, он не сработал, он застрял в состоянии «Ожидание», похоже, что сам узел застрял.

Для меня решением было воссоздать файл node. Я просто зашел в консоль GKE и удалил узел из кластера, после чего GKE запустил другой.

После этого все снова стало нормально работать.

вы можете использовать awk :

      kubectl get pods --all-namespaces | awk '{if ($4=="Terminating") print "oc delete pod " $2 " -n " $1 " --force --grace-period=0 ";}' | sh

Прежде чем выполнять принудительное удаление, я бы сначала проверил. 1- состояние узла: получите имя узла, на котором работает ваш узел, вы можете увидеть это с помощью следующей команды:

"kubectl -n YOUR_NAMESPACE describe pod YOUR_PODNAME"

Под меткой "Узел" вы увидите имя узла. С этим вы можете:

kubectl describe node NODE_NAME

Если вы заметили что-нибудь странное, проверьте поле "условия". Если все в порядке, вы можете перейти к шагу, повторить:

"kubectl -n YOUR_NAMESPACE describe pod YOUR_PODNAME"

Проверьте причину зависания, вы можете найти ее в разделе "События". Я говорю это, потому что вам может потребоваться предпринять предварительные действия перед принудительным удалением модуля, при принудительном удалении модуля удаляется только сам модуль, а не базовый ресурс (например, застрявший контейнер докера).

Одной из причин, ПОЧЕМУ это происходит, может быть отключение узла (без его истощения). Исправление в этом случае - снова включить узел; тогда прекращение должно быть успешным.

Я собираюсь попробовать самый развернутый ответ, потому что ни одно из вышеперечисленных не является неправильным, но они не работают во всех случаях.

Обычный способ положить конец терминирующему струку :

      kubectl delete pod -n ${namespace} ${pod} --grace-period=0 

Но вам может потребоваться удалить финализаторы, которые могут препятствовать остановке POD, используя:

      kubectl -n ${namespace} patch pod ${pod} -p '{"metadata":{"finalizers":null}}'

Если ничего из этого не работает, вы можете удалить модуль из etcd с помощью etcdctl:

      # Define variables
ETCDCTL_API=3
certs-path=${HOME}/.certs/e
etcd-cert-path=${certs-path}/etcd.crt
etcd-key-path=${certs-path}/etcd.key
etcd-cacert-path=${certs-path}/etcd.ca
etcd-endpoints=https://127.0.0.1:2379
namespace=myns
pod=mypod

# Call etcdctl to remove the pod
etcdctl del \
--endpoints=${etcd-endpoints}\
--cert ${etcd-cert-path} \
--key ${etcd-client-key}\
--cacert ${etcd-cacert-path} \
--prefix \
/registry/pods/${namespace}/${pod} 

Этот последний случай следует использовать в качестве последнего ресурса, в моем случае мне пришлось это сделать из-за взаимоблокировки, которая не позволяла запускать calico в узле из-за того, что поды находятся в состоянии завершения. Эти модули не будут удалены до тех пор, пока не будет запущен калико, но они зарезервировали достаточно ЦП, чтобы избежать инициализации калико или любого другого модуля.

Я бы не рекомендовал принудительно удалять модули, если контейнер еще не вышел.

  1. Проверьте журналы kubelet, чтобы узнать, что вызывает проблему "journalctl -u kubelet"
  2. Проверьте журналы докеров: journalctl -u docker.service
  3. Проверьте, существуют ли точки монтирования тома модуля и есть ли у кого-нибудь блокировка.
  4. Убедитесь, что хосту не хватает памяти или диска

После команды с awkа также xargsможно использовать вместе с --grace-period=0 --forceчтобы удалить все модули в состоянии завершения .

      kubectl get pods|grep -i terminating | awk '{print $1}' | xargs kubectl delete --grace-period=0 --force pod

go шаблоны будут работать без awk, у меня он работает без --grace-period=0 --forceно добавь если хочешь

это выведет команду для удаления завершенных модулей.

      kubectl get pods --all-namespaces -otemplate='{{ range .items }}{{ if eq .status.reason  "Terminated" }}{{printf "kubectl delete pod -n %v %v\n" .metadata.namespace .metadata.name}}{{end}}{{end}}'

если вы довольны результатом, вы добавляете кота | sh -выполнить его. следующим образом:

      kubectl get pods --all-namespaces -otemplate='{{ range .items }}{{ if eq .status.reason  "Terminated" }}{{printf "kubectl delete pod -n %v %v\n" .metadata.namespace .metadata.name}}{{end}}{{end}}' |sh -

Мои модули застряли в состоянии «Завершение», даже после того, как я попытался перезапустить докер и перезапустить сервер. Решено после редактирования модуля и удаления элементов ниже «финализатора».

      $ kubectl -n mynamespace edit pod/my-pod-name

для меня команда ниже решила проблему

oc patch pvc pvc_name -p '{"metadata":{"finalizers":null}}

У меня работает только вот это:

При исправлении финализаторов и удалении модулей, находящихся в завершающем состоянии.

принудительное удаление-терминированных-pods.sh

      #!/usr/bin/env bash
kubectl get pods --all-namespaces | grep Terminating | awk '{print $2 " --namespace=" $1}' | xargs kubectl patch pod -p '{"metadata":{"finalizers":null}}'
kubectl get pods --all-namespaces | grep Terminating | awk '{print $2 " --namespace=" $1}' | xargs kubectl delete pod

В моем случае некоторые PersistentVolumes и Ingress зависли из-за финализаторов.

PersistentVolumes активировал контроль удаления. Входные файлы использовали общий ALB и не могли их удалить, поэтому они зависали.

После очистки этих измельчителей я смог удалить POD.

Другие вопросы по тегам