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

Перевод нод k3s в maintenance режим

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

  • Cordon — пометить ноду как недоступную для планировщика (scheduler), чтобы новые поды на неё не назначались.

  • Drain — корректно «освободить» ноду: завершить все поды и перезапустить их на других доступных нодах.

1. Перевод ноды в maintenance mode

  1. Получите список всех нод и определите имя ноды, для которой требуется провести техническое обслуживание.

    kubectl get node

    В результате будет выведен список нод. В примере далее используется нода ift04-agent03:

    NAME             STATUS   ROLES                       AGE   VERSION
    ift04-agent01    Ready    <none>                      13d   v1.32.3+k3s1
    ift04-agent02    Ready    <none>                      13d   v1.32.3+k3s1
    ift04-agent03    Ready    <none>                      13d   v1.32.3+k3s1
    ift04-lb01       Ready    <none>                      13d   v1.32.3+k3s1
    ift04-lb02       Ready    <none>                      13d   v1.32.3+k3s1
    ift04-server01   Ready    control-plane,etcd,master   13d   v1.32.3+k3s1
    ift04-server02   Ready    control-plane,etcd,master   13d   v1.32.3+k3s1
    ift04-server03   Ready    control-plane,etcd,master   13d   v1.32.3+k3s1
  2. Пометьте ноду как недоступную для планировщика (Cordon):

    kubectl cordon ift04-agent03
  3. Проверьте статус ноды:

    kubectl get node

    Ожидаемый результат — статус Ready,SchedulingDisabled:

    ift04-agent03   Ready,SchedulingDisabled   <none>   13d   v1.32.3+k3s1
  4. Освободите ноды от подов (Drain). Для этого выполните корректное выселение подов с ноды:

kubectl drain ift04-agent03 --ignore-daemonsets --delete-emptydir-data --force

+ Описание флагов команды:

+ * --ignore-daemonsets — обязательный флаг. Игнорирует поды, управляемые DaemonSet, которые не могут быть удалены стандартным drain. * --delete-emptydir-data — подтверждает удаление данных из томов emptyDir. * --force — позволяет удалить поды, не управляемые контроллерами.

Команда drain выполняется некоторое время, так как Kubernetes ожидает корректного завершения приложений (отправляется сигнал SIGTERM). После успешного завершения команды можно приступать к техническому обслуживанию ноды.

Для контроля количества и состояния подов используйте команду:

kubectl get pods --all-namespaces -o wide | grep ift04-agent03

2. Особенности работы с Pod Disruption Budget (PDB)

Во время выполнения drain могут появляться сообщения следующего вида:

evicting pod longhorn-system/instance-manager-8d67a70794045e17b23e8127df2cb927
error when evicting pods/"instance-manager-8d67a70794045e17b23e8127df2cb927" -n "longhorn-system" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.

Pod Disruption Budget (PDB) — механизм Kubernetes, предназначенный для поддержания высокой доступности приложений во время плановых операций (обслуживание нод, обновления и т.д.). PDB определяет минимальное количество реплик подов, которые должны оставаться доступными.

В данном примере удаление пода невозможно, так как в PDB задано значение minAvailable: 1, то есть должна всегда оставаться хотя бы одна рабочая реплика.

Для решения проблемы:

  1. Временно измените значение minAvailable на 0.

  2. После выселения пода верните значение обратно на 1.

kubectl -n longhorn-system edit pdb instance-manager-90c139d0386a23c4e6878abc8458385a
k3s node

3. Возвращение ноды в строй (Uncordon)

После завершения всех работ необходимо снова разрешить планировщику назначать поды на ноду:

kubectl uncordon ift04-agent03

После этого статус ноды должен измениться на Ready.

4. Возможные проблемы и решения

Проблема: Поды зависли в статусе "Terminating"

Возможные причины:

  • у пода нет контроллера;

  • приложение не реагирует на сигнал SIGTERM.

Решение: Удалите поды принудительно:

kubectl delete pod <pod-name> --namespace <namespace> --force