Docker 18.01 CE: containerd как основной runtime и что это значит для Swarm
Docker 18.01 CE - containerd становится основным runtime вместо docker-containerd. Проверяем совместимость с нашим Swarm-кластером перед переходом на Kubernetes.
Docker 18.01 CE - переход на Moby и containerd как основной runtime
Docker 18.01 CE вышел в середине января, и он интереснее, чем кажется по номеру версии. Главное изменение - containerd 1.0 становится официальным основным runtime. Не как дополнительная опция, не как эксперимент - а как штатный путь. Для нас это поводом стало провести небольшую ревизию пайплайна и посмотреть, что происходит с нашими Swarm-кластерами до того, как мы их тронем.
Moby и containerd - что изменилось архитектурно
Несколько слов про контекст, потому что маркетинг Docker Inc. тут несколько запутал картину. Moby - это open-source проект, из которого собирается Docker CE. Если раньше имя «Docker» относилось и к open-source компонентам, и к продукту компании - теперь это разделено: Moby это набор компонентов, Docker CE и Docker EE это собранные продукты. Переименование произошло ещё в 2017 году, 18.01 - это первый выпуск, где оно чувствуется по-настоящему.
containerd - это отдельный проект под CNCF, который реализует управление жизненным циклом контейнеров: pull образов, создание/старт/стоп контейнеров, управление снапшотами. В Docker до 17.x он присутствовал как docker-containerd - форк внутри монорепозитория. Начиная с 18.01 Docker использует upstream containerd 1.0, и граница между ними становится более чёткой.
На уровне процессов это выглядит так:
dockerd -> containerd -> containerd-shim -> runc -> контейнер
Раньше эта цепочка была похожей, но containerd жил внутри Docker и их версии были жёстко связаны. Теперь containerd - отдельный процесс с собственным сокетом (/run/containerd/containerd.sock), отдельным бинарником и отдельным релизным циклом.
Что это значит практически
Обновили тестовый узел с Docker 17.12 до 18.01. Процедура стандартная - репозиторий docker-ce, apt-get upgrade, рестарт. Ничего не сломалось, существующие контейнеры поднялись нормально.
Что бросилось в глаза после обновления:
- Процесс
dockerdтеперь форкает containerd при старте, если тот не запущен. Можно также запустить containerd как отдельный systemd-сервис - и тогда dockerd подключается к нему. docker infoтеперь явно показывает версию containerd в выводе. На обновлённой машине:containerd: 1.0.0+unknown- что немного настораживает суффиксом unknown, но это, судя по тредам в GitHub, особенность debian-пакета.- Поведение при перезапуске dockerd изменилось: если containerd работает как отдельный сервис, рестарт dockerd не убивает запущенные контейнеры. Это хорошая новость для сценариев обновления демона без даунтайма.
Swarm-кластер: смотрим внимательно
У нас в продакшне несколько Swarm-кластеров под клиентские задачи - managed-сервис, типовые стеки сервисов на docker stack deploy. Вопрос перед обновлением: как containerd как первичный runtime влияет на networking, overlay-сети, volume-моунты и healthcheck-поведение в Swarm.
Ответ, который мы получили после тестирования на dev-кластере: в большинстве случаев ничего не меняется, потому что Swarm взаимодействует с dockerd, а не с containerd напрямую. containerd - это деталь реализации ниже уровнем.
Несколько конкретных наблюдений:
- Overlay-сети работают как раньше. VXLAN-инкапсуляция и DNS-resolution между сервисами не изменились.
- Volume-моунты - никаких проблем. Проверяли как named volumes, так и bind-моунты.
- Healthcheck в docker-compose / stack deploy ведёт себя идентично. Это важно - у нас есть сервисы, у которых логика rolling update завязана на healthcheck.
- Логи (
docker service logs) - работают, формат не изменился.
Единственный момент, который стоит проверить отдельно - это сценарий обновления самого Docker на узлах Swarm без вывода из кластера. Мы делаем это через docker node update --availability drain, обновляем, возвращаем. С 18.01 это работает нормально, но containerd-процесс при обновлении пакета перезапускается - на несколько секунд новые контейнеры на этом узле не стартуют.
Ещё одно наблюдение: ctr
С containerd 1.0 появился ctr - CLI для прямого взаимодействия с containerd, минуя dockerd. Можно дёргать образы, смотреть запущенные контейнеры на уровне containerd, запускать контейнеры напрямую через runc.
В повседневной работе ctr нам не нужен - у нас есть docker. Но в контексте диагностики, когда dockerd по какой-то причине не отвечает, а нужно понять что происходит с контейнерами - полезная штука. Добавили в набор инструментов для отладки.
Где стоим
18.01 выглядит как добросовестный инкрементальный выпуск, без сюрпризов. Архитектурные изменения под капотом серьёзные, но для операционного использования прозрачны - если не лезть в кишки намеренно.
Обновление Swarm-кластеров планируем по стандартному протоколу - по одному узлу, с дренажем и наблюдением. Спешки нет.
Фоновый контекст: наши Swarm-кластеры живут в режиме «до Kubernetes». Мы смотрим на Kubernetes 1.9 и готовим почву - там containerd тоже фигурирует как потенциальный runtime через CRI. Так что понимать архитектуру containerd полезно независимо от того, через сколько мы фактически двинемся в ту сторону.