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 реально уберут.
- containerd 1.4: переводим dev-кластер с dockershim на прямой CRI runtime · 27 августа 2020
- Kubernetes 1.19 GA: обновляем production с extensions/v1beta1 на Ingress v1 · 3 сентября 2020