Гид по технологиям

Как перейти от Dockershim в Kubernetes

9 min read Kubernetes Обновлено 19 Dec 2025
Переход от Dockershim в Kubernetes
Переход от Dockershim в Kubernetes

Логотип Kubernetes

Быстрые ссылки

  • Что такое Dockershim?
  • Как проверить, используется ли Dockershim
  • Переход на другой runtime на узле
  • Playbook миграции
  • Решение проблем и откат
  • Выводы

Краткое введение

Kubernetes v1.24 и последующие выпуски больше не поставляются с встроенным Dockershim — компонентом, который ранее обеспечивал совместимость Kubernetes с Docker Engine. Если у вас старые самоуправляемые кластеры, созданные несколько лет назад, они могут полагаться на Dockershim. Если вы используете управляемые кластерные сервисы (EKS, AKS, GKE, DOKS и т.п.), скорее всего, ничего делать не нужно.

Цель статьи — дать практическую инструкцию: проверить, какие узлы затронуты, и безопасно перевести их на поддерживаемый runtime (containerd) или развернуть standalone-адаптер cri-dockerd, если вам необходима совместимость с Docker Engine.

Что такое Dockershim?

Dockershim — это адаптер, который позволял Kubernetes взаимодействовать с Docker Engine до того, как был введён стандарт CRI (Container Runtime Interface). CRI сделал возможной поддержку других runtime (containerd, CRI-O и т.д.). Dockershim представлял собой временное, тесно связанное с реализацией Docker решение; оно усложняло сопровождение Kubernetes и было удалено.

Ключевые моменты:

  • CRI — интерфейс, определяющий, как kubelet общается с контейнерным runtime.
  • Docker Engine исторически не поддерживал CRI напрямую; Dockershim устранял этот разрыв.
  • Containerd — самостоятельный runtime, вышедший из экосистемы Docker и полностью поддерживаемый Kubernetes.
  • Cri-dockerd — отдельный проект (Mirantis + Docker) с тем же принципом работы, что Dockershim, но как отдельный компонент.

Важно: удаление Dockershim не влияет на форматы контейнерных образов — Kubernetes по‑прежнему запускает OCI‑совместимые образы, созданные с помощью docker build или других инструментов.

Как проверить, используется ли Dockershim

  1. Сравните runtime узлов:
$ kubectl get nodes -o wide

В колонке CONTAINER-RUNTIME вы увидите строки вроде docker://19.3.1 или containerd://1.4.13.

Пример:

NAME STATUS VERSION CONTAINER-RUNTIME

node-1 Ready v1.22.8 docker://19.3.1

node-2 Ready v1.22.8 containerd://1.4.13

  1. На подозрительном узле (с docker://) выполните проверку конфигурации kubelet. На хосте узла выполните:
$ tr \\0 ' ' < /proc/"$(pgrep kubelet)"/cmdline | grep "\-\-container\-runtime"

Примечание: если команда не выводит ничего, это индикатор того, что kubelet запускается без явного флага --container-runtime и, возможно, использует встроенный (удалённый) Dockershim в старых конфигурациях kubelet. Если вывод есть — посмотрите значение --container-runtime-endpoint:

  • unix:///run/containerd/containerd.sock → используется containerd; миграция не требуется.
  • unix:///var/run/cri-dockerd.sock → используется standalone cri-dockerd.
  • отсутствует явный endpoint и виден docker:// в kubectl get nodes → узел вероятно использует встроенный Dockershim и требует действия.

Когда нужно действовать немедленно

  • Вы планируете обновление кластера до Kubernetes v1.24 или выше.
  • У вас есть узлы с контейнерным runtime, обозначенным как docker:// и без явного cri-socket на объекте Node.

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

Переход runtime на узле — общий план действий

Общий план безопасной миграции одного узла:

  1. Подготовка: убедиться, что на других узлах есть ресурсы для перезапуска Pod’ов.
  2. Пометить узел как unschedulable: kubectl cordon .
  3. Дренировать рабочие нагрузки: kubectl drain --ignore-daemonsets.
  4. Остановить kubelet и docker сервисы на хосте.
  5. Установить выбранный runtime (containerd или cri-dockerd).
  6. Обновить конфигурацию /var/lib/kubelet/kubeadm-flags.env и аннотацию Node kubeadm.alpha.kubernetes.io/cri-socket.
  7. Перезапустить kubelet и проверить состояние: kubectl get nodes -o wide.
  8. Если всё корректно — снять cordon: kubectl uncordon .

Дальше — подробные инструкции для containerd и cri-dockerd.

Переход на containerd (рекомендуемый путь)

Когда выбирать containerd:

  • Вы не используете специфичные Docker‑фичи (docker CLI‑тулза, dockerd API, docker.sock внутри контейнеров).
  • Вы хотите минимизировать поверхностные зависимости и упростить сопровождение.

Шаги:

  1. Cordon и drain узла:
$ kubectl cordon node-1
$ kubectl drain node-1 --ignore-daemonsets
  1. На самом узле остановите kubelet и docker:
$ systemctl stop kubelet
$ systemctl disable docker.service --now
  1. Установите containerd. На Debian/Ubuntu пример установки через репозиторий Docker:
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg lsb-release
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt update
$ sudo apt install containerd
  1. Настройте kubelet для работы с контейнерным runtime remote. Откройте /var/lib/kubelet/kubeadm-flags.env и добавьте или измените флаги:
  • --container-runtime=remote
  • --container-runtime-endpoint=unix:///run/containerd/containerd.sock

Файл обычно выглядит как одна строка с KUBELET_KUBEADM_ARGS="..." — внесите изменения аккуратно.

  1. Обновите аннотацию на объекте Node:
$ kubectl edit node node-1

Найдите kubeadm.alpha.kubernetes.io/cri-socket и установите значение unix:///run/containerd/containerd.sock.

  1. Перезапустите kubelet и проверьте состояние:
$ systemctl start kubelet
$ kubectl get nodes -o wide

Пример ожидаемого вывода:

NAME STATUS VERSION CONTAINER-RUNTIME

node-1 Ready v1.22.8 containerd://1.4.13

  1. Снимите cordon:
$ kubectl uncordon node-1

Советы:

  • Перед массовой миграцией протестируйте процесс на одной ноде (non‑production) и убедитесь, что DaemonSet’ы корректно запускаются.
  • Проверьте работу сетевых плагинов (CNI), так как некоторые из них могут требовать дополнительных шагов при смене runtime.

Установка и использование cri-dockerd (если вам нужна совместимость с Docker Engine)

Когда выбирать cri-dockerd:

  • Вы используете инструменты, которые ожидают наличия Docker API (например, некоторые CI/CD решения, сторонние аддоны, приложения, монтирующие /var/run/docker.sock).
  • Вы не готовы переписывать интеграции и вам нужна быстрая совместимость при обновлениях Kubernetes.

Cri-dockerd — это отдельно поддерживаемый адаптер, который предоставляет CRI-интерфейс поверх Docker Engine.

Шаги установки (пример):

  1. Убедитесь, что Docker Engine установлен и работает.
  2. Скачать релиз cri-dockerd (пример v0.2.0):
$ wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.0/cri-dockerd-v0.2.0-linux-amd64.tar.gz
$ tar xvf cri-dockerd-v0.2.0-linux-amd64.tar.gz
$ mv cri-dockerd /usr/local/bin/
  1. Установите systemd‑юниты для cri-dockerd:
$ wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.service
$ wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.socket
$ sudo mv cri-docker.socket cri-docker.service /etc/systemd/system/
$ sudo sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable cri-docker.service
$ sudo systemctl enable --now cri-docker.socket
  1. Обновите /var/lib/kubelet/kubeadm-flags.env:
  • --container-runtime=remote
  • --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock
  1. Обновите аннотацию Node:
$ kubectl edit node node-1

Установите kubeadm.alpha.kubernetes.io/cri-socket в unix:///var/run/cri-dockerd.sock.

  1. Перезапустите kubelet и проверьте состояние:
$ systemctl start kubelet
$ kubectl get nodes -o wide

Вы увидите, что runtime всё ещё отображается как docker://..., но теперь запросы идут через standalone cri-dockerd, а не через встроенный Dockershim.

  1. Снимите cordon:
$ kubectl uncordon node-1

Замечания:

  • Cri-dockerd даёт обратную совместимость, но это дополнительный компонент, за которым нужно следить и обновлять.
  • Для долгосрочной стратегии рекомендуется постепенно перейти на containerd, если это возможно.

Playbook миграции (SOP для команды)

Минимальный playbook для отдельного узла:

  1. Предусловия:
    • Доступ к консоли узла (SSH).
    • Резервные копии критичных данных и манифестов.
    • Мониторинг и алерты настроены для быстрого обнаружения проблем.
  2. Проверка текущего состояния:
    • kubectl get nodes -o wide
    • kubectl describe node — поиск аннотации cri-socket.
  3. Снять планировщик: kubectl cordon .
  4. Дренировать: kubectl drain --ignore-daemonsets.
  5. На узле: остановить kubelet и docker.
  6. Установить containerd или cri-dockerd.
  7. Обновить /var/lib/kubelet/kubeadm-flags.env и аннотацию Node.
  8. Запустить kubelet и убедиться, что Node в Ready и показывает корректный runtime.
  9. Снять cordon и мониторить нагрузку и логи.

Критерии приёмки:

  • Node возвращается в состояние Ready.
  • CONTAINER-RUNTIME показывает containerd:// или docker:// с cri-dockerd как endpoint.
  • Все Pod’ы, за исключением DaemonSet’ов, успешно перезапустились на других узлах и позже вернулись на мигрированный узел при uncordon.

Резервный план и откат (runbook)

Если после перезапуска kubelet узел ушёл в NotReady или Pods не запускаются:

  1. Просмотрите логи kubelet: journalctl -u kubelet -xe.
  2. Убедитесь, что сокет runtime существует и доступен с правами, ожидаемыми kubelet (проверить ls -l /run/containerd/containerd.sock или /var/run/cri-dockerd.sock).
  3. Если проблема связана с отсутствием Docker API и вы устанавливали cri-dockerd, убедитесь, что dockerd запущен: systemctl status docker.
  4. В крайнем случае откат:
    • Верните предыдущую конфигурацию /var/lib/kubelet/kubeadm-flags.env.
    • Восстановите аннотацию Node к предыдущему значению (если помните или сохранили резервную копию объекта Node — используйте kubectl apply -f node-backup.yaml).
    • Перезапустите docker и kubelet: systemctl start docker && systemctl start kubelet.

Важно: всегда сохраняйте резервную копию оригинальной конфигурации Node перед изменениями:

$ kubectl get node node-1 -o yaml > node-1-backup.yaml

Решение типичных проблем

Проблема: Node в статусе NotReady после смены runtime

  • Проверить логи kubelet и логи runtime.
  • Убедиться, что аннотация cri-socket корректна.
  • Убедиться, что CNI плагины совместимы с новым runtime.

Проблема: Pods не запускаются из‑за привязки к docker.sock

  • Подумайте о сохранении cri-dockerd или о рефакторинге приложений, чтобы не монтировать /var/run/docker.sock.

Проблема: DaemonSet’ы не мигрируются

  • При дренировании используйте флаг --ignore-daemonsets, DaemonSet запущенные на узле останутся, и вам нужно обеспечить их поддержку при смене runtime.

Сравнение: containerd vs cri-dockerd (обзор)

Критерийcontainerdcri-dockerd
Поддержка в Kubernetesнативная, рекомендованопредоставляет совместимость с Docker API через адаптер
Поддержка docker.sockнет (dockerd отсутствует)да (нужен docker daemon)
Сложность сопровожденияниже (меньше компонентов)выше (ещё один внешний компонент)
Сценарии примененияоблачные среды, современные рабочие нагрузкисуществующие интеграции, docker-in-docker, legacy tooling

Выбор зависит от вашего стека и наличия зависимостей от Docker API.

Ментальные модели и эвристики при принятии решения

  • Если ваша инфраструктура минимально зависит от Docker API и вы хотите снизить операционные риски — выбирайте containerd.
  • Если у вас много инструментов, которые напрямую используют Docker API и быстро переписать их нельзя — используйте cri-dockerd как промежуточное решение.
  • Планируйте долгосрочный переход на CRI‑совместимые решения и минимизируйте использование docker.sock в контейнерах.

Роли и задачи (чек‑листы)

SRE / Инженер по платформе:

  • Проверить список узлов и runtime.
  • Подготовить план миграции и окно работ.
  • Обновить образы и конфигурации DaemonSet/CNI при необходимости.
  • Выполнить миграцию по шагам и мониторить метрики.

Разработчик приложения:

  • [ ] Проверить, не монтируется ли /var/run/docker.sock.
  • Убедиться, что контейнеры не зависят от специфичных для Docker образов или настроек.
  • Тестировать приложение в среде с containerd.

Операционный менеджер:

  • Убедиться, что есть коммуникация с командами о времени простоя.
  • Планировать резервные ресурсы и откат.

Безопасность и конфиденциальность

  • Монтирование docker.sock даёт контейнерам привилегированный доступ к хост‑демону Docker — это риск безопасности. По возможности избегайте таких паттернов.
  • При использовании cri-dockerd сервер Docker по‑прежнему должен быть защищён и обновлён.
  • Обновляйте cri-dockerd и containerd в рамках политики обновлений и ревью уязвимостей.

Критерии приёмки

  • Узел возвращается в Ready и отображает ожидаемый runtime.
  • Контейнеры запускаются корректно и проходят проверку состояния (Liveness/Readiness).
  • Метрики и логирование не показывают аномалий после миграции.
  • План отката проверен и готов к выполнению при необходимости.

Диаграмма принятия решения

flowchart TD
  A[Нужна ли совместимость с Docker API?] -->|Да| B[Установить cri-dockerd]
  A -->|Нет| C[Можно ли обновить интеграции?]
  C -->|Да| D[Перейти на containerd]
  C -->|Нет| B
  B --> E[Обновить kubelet и аннотацию Node]
  D --> E
  E --> F[Перезапустить kubelet и проверить Node]

(Схема показывает упрощённый выбор между containerd и cri-dockerd)

Короткий глоссарий

  • CRI — интерфейс, который kubelet использует для взаимодействия с контейнерным runtime.
  • Dockershim — старый адаптер для Docker Engine, удалённый из Kubernetes.
  • containerd — легковесный контейнерный runtime, рекомендованный для Kubernetes.
  • cri-dockerd — standalone адаптер, предоставляющий CRI поверх Docker Engine.

Выводы

  • Проверьте текущие runtime ваших узлов перед планируемым обновлением Kubernetes до v1.24+.
  • Для большинства сред containerd — предпочтительный путь: он проще в поддержке и нативно интегрируется с Kubernetes.
  • Если вам нужна совместимость с Docker API, используйте cri-dockerd как промежуточное решение, но планируйте долгосрочный переход.
  • Всегда тестируйте миграцию на выделенной ноде и имейте план отката.

Важно: перед массовыми изменениями убедитесь, что у вас есть резервные копии манифестов и сохранённое состояние объектов Node (yaml-файл), чтобы в экстренной ситуации можно было вернуть исходную конфигурацию.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Повторяющиеся поля в Word — руководство и шаблон
Office

Повторяющиеся поля в Word — руководство и шаблон

Как увидеть посещённые рестораны в Google Maps
Навигация

Как увидеть посещённые рестораны в Google Maps

Find My на Mac — настройка, поиск и восстановление
Руководство

Find My на Mac — настройка, поиск и восстановление

Отключить уведомления Snapchat — пошагово
Социальные сети

Отключить уведомления Snapchat — пошагово

Как переключиться на Bash в macOS
macOS

Как переключиться на Bash в macOS

Индекс UV: что это и как проверить
Погода

Индекс UV: что это и как проверить