ADG Оставить заявку
Блог DevOps 4 мин чтения

Kubernetes 1.20 RC: dockershim deprecated - инвентаризируем кластеры и тестируем containerd

Kubernetes 1.20 официально объявил dockershim deprecated. Разбираем что это значит на практике: инвентаризируем кластеры, составляем roadmap перехода на containerd 1.4.

Контекст момента

Kubernetes 1.20 RC объявил dockershim deprecated - Docker как container runtime для kubelet устарел официально

Вышел release candidate Kubernetes 1.20, и главная новость там - не фичи, а официальная deprecation notice на dockershim. Kubernetes-команда дала понять прямым текстом: прослойка между kubelet и Docker daemon будет убрана в следующих версиях. Это не слухи и не roadmap-мечтания, это warning в changelog с конкретным намерением.

Мы следили за этим треком давно - ещё в августе гоняли containerd 1.4 на dev-кластере и убедились, что переход реален. Но одно дело - эксперимент на трёх нодах, другое - когда deprecation официально зафиксирована в RC и нужно понимать, что делать со всеми кластерами под managed-сопровождением.

Что именно происходит

Коротко про механику для тех, кто ещё не погружался. Kubelet общается с container runtime через CRI - стандартный интерфейс. Docker CRI не реализует напрямую, поэтому kubelet шёл через dockershim: специальную прослойку, которая переводила CRI-вызовы в Docker API. dockershim жил прямо в коде kubelet - это встроенный переходник, не отдельный сервис.

containerd и CRI-O реализуют CRI нативно. Там цепочка короче: kubelet -> containerd socket, без промежуточных рукопожатий. В 1.20 RC эта разница оформляется официально: dockershim получает статус deprecated, код помечается соответствующим образом.

Для пользователей это значит: если kubelet настроен на --container-runtime=docker и --docker-endpoint, это работает сейчас, но работать будет не всегда.

Первый шаг: инвентаризация

Первое что мы сделали - прошлись по всем кластерам и зафиксировали текущее состояние. Инструмент простой:

kubectl get nodes -o wide

Колонка CONTAINER-RUNTIME показывает что используется на каждой ноде. У нас картина оказалась примерно такой, как ожидали: старые кластеры на docker://19.x, кластеры созданные после августа - уже на containerd://1.4.x.

Дальше полезно посмотреть на конкретной ноде:

kubectl get node <node-name> -o jsonpath='{.status.nodeInfo.containerRuntimeVersion}'

По результатам инвентаризации у нас получилось три категории:

  • Кластеры на containerd - там ничего делать не надо, они уже в нужном состоянии.
  • Dev/staging кластеры на Docker - приоритет средний, там можно мигрировать в рабочем порядке.
  • Production-кластеры на Docker - там нужен план и окно для каждого кластера.

Тестируем containerd 1.4 на staging

Один staging-кластер переключили параллельно с инвентаризацией - именно тот, где живут копии production-workload-ов. Процедура та же, что описывали в августе: drain ноды, ставим containerd 1.4, прописываем SystemdCgroup = true в конфиге, меняем параметры kubelet, uncordon.

Что заметили на staging-нагрузке по сравнению с dev-экспериментом в августе:

Поведение runtime в целом - без сюрпризов. Поды поднялись, сети работают, volume-ы монтируются. Разница в поведении минимальна - как и ожидали от зрелого runtime.

Логи - всё тот же формат сдвига. Filebeat на этом кластере мы уже заранее проверили после августовского опыта - pipeline был настроен с учётом containerd CRI format. Сработало без дополнительных правок.

Startup time контейнеров - несколько команд попросили замерить. Разница есть, но в пределах шума: убирается лишний слой Docker daemon, но это не то место, которое определяло latency в наших workload-ах. Радикальных улучшений не ждали - и не получили.

crictl как замена docker ps - привыкли быстро. Из неожиданного: дежурный инженер одного из клиентов написал скрипт для health-check, который внутри делал docker inspect. Пришлось его переписать на crictl - занял час, но это хороший повод провести аудит всех скриптов на нодах, которые касаются container runtime напрямую.

Roadmap перехода

На основе инвентаризации собрали план по кластерам. Принципы которых придерживаемся:

Один кластер за раз, одна нода за раз. Никаких rolling update всего парка одновременно. После каждой ноды - наблюдение за метриками и логами минимум 24 часа перед следующим шагом.

Staging идёт первым. Для каждого production-кластера должен пройти соответствующий staging. Если staging нет - создаём тестовый контур специально.

Аудит скриптов на нодах. Всё что обращается к Docker API напрямую надо найти и переписать до начала миграции. Это дороже по времени, чем сам переход runtime, но без этого первый же инцидент будет о скриптах, а не о containerd.

Документируем каждый переход. Не ради бюрократии - ради чек-листа, который будет работать на следующем кластере без повторного разбирательства.

1.20 GA будет примерно через месяц. Deprecation notice уже в RC - это нормальный сигнал для того, чтобы начать движение, а не откладывать до момента, когда dockershim реально уберут.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.