Поиск по сайту:

Как уйти от Dockershim в Kubernetes v1.24 и более поздних версиях


Kubernetes v1.24 и более поздние выпуски поставляются без Dockershim после его устаревания в выпуске v1.20 в декабре 2020 года. Dockershim больше не доступен в качестве встроенной среды выполнения контейнеров. Вместо этого вам нужно использовать другую поддерживаемую среду выполнения, например containerd, CRI-O или Docker Engine с адаптером cri-dockerd.

В этой статье мы покажем, как проверить, затронуты ли вы, а затем объясним, как вы можете перейти на другую среду выполнения. Вы должны выполнить эти действия перед обновлением до Kubernetes версии 1.24 или более поздней версии, чтобы это не повлияло на рабочие нагрузки вашего кластера.

Что такое Докершим?

Dockershim был разработан как необходимый компонент, чтобы Kubernetes мог поддерживать больше сред выполнения контейнеров. В начале проекта Kubernetes работал только с Docker Engine. Это ограничение было снято введением стандарта CRI. Любая среда выполнения, совместимая с CRI, теперь может использоваться с Kubernetes, включая containerd и CRI-O, реализацию стандарта OCI.

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

Перемещение контейнеров теперь намного больше, чем Docker, как демонстрирует первоначальный толчок Kubernetes к CRI. Сам Docker разделен на отдельные компоненты, а его среда выполнения извлечена как containerd, выпускник Cloud Native Computing Foundation (CNCF).

containerd полностью поддерживается Kubernetes и больше подходит для автономного использования в облачных средах. Kubernetes не требует интерфейса командной строки Docker и множества его функций для запуска ваших модулей; все, что ему нужно, — это возможность запускать и запускать контейнеры на относительно низком уровне. Dockershim был удален, потому что его было сложно поддерживать. Его использование создавало хрупкий код, тесно связанный с реализацией Docker Engine.

Проверка того, используете ли вы Dockershim

Недавно созданные кластеры на современных платформах вряд ли будут использовать Dockershim. Сюда входят кластеры, управляемые популярными облачными провайдерами, такими как Amazon EKS, Azure AKS, Google GKE и DigitalOcean DOKS.

Скорее всего, вам придется принять меры, если вы поддерживаете свой собственный кластер и впервые настроили его несколько лет назад. Вы можете проверить, используете ли вы Dockershim в качестве среды выполнения для любого из ваших узлов, выполнив эту команду Kubectl:

$ kubectl get nodes -o wide
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

В этом примере один из узлов использует containerd, и его можно оставить как есть. Другой узел настроен с помощью Docker и может быть затронут удалением Dockershim. Вы можете проверить, выполнив эту команду на узле:

$ tr \\0 ' ' < /proc/"$(pgrep kubelet)"/cmdline | grep "\-\-container\-runtime"

Ваш узел использует Dockershim для запуска контейнеров, если ничего не отображается. Если вы все же получили какие-то выходные данные, проверьте отображаемое значение флага --container-runtime-endpoint, чтобы определить, активен ли Dockershim. Конечная точка времени выполнения unix:///run/containerd/containerd.sock сигнализирует о том, что используется containerd, поэтому миграция не требуется.

Изменение времени выполнения узла

Узлы, использующие Dockershim, необходимо обновить, чтобы использовать другую среду выполнения. Сначала снизьте рабочие нагрузки узла с помощью Kubectl, чтобы ваши поды были перенесены на другие узлы в вашем кластере. Вы также должны оцепить узел, чтобы предотвратить планирование любых новых модулей.

$ kubectl cordon node-1
$ kubectl drain node-1 --ignore-daemonsets

Затем выполните следующие команды на самом узле. Начните с остановки демона Docker и рабочего процесса Node Kubelet:

$ systemctl stop kubelet
$ systemctl disable docker.service --now

Теперь вы можете установить новую среду выполнения.

Использование контейнера

containerd обычно является предпочтительным решением для текущих кластеров. У вас должна быть возможность перейти на containerd, если вы не полагаетесь на определенные функции Docker Engine. Если да, перейдите к следующему разделу и вместо этого установите cri-dockerd.

Добавьте репозиторий Docker в свою систему, если он еще не включен в ваши списки пакетов. containerd распространяется в репозитории 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

Теперь обновите файл конфигурации Node Kubelet, чтобы использовать новую среду выполнения. Откройте /var/lib/kubelet/kubeadm-flags.env. Найдите или добавьте флаги --container-runtime и --container-runtime-endpoint со следующими значениями:

  • --container-runtime=remote
  • --container-runtime-endpoint=unix:///run/containerd/containerd.sock

Затем измените аннотацию сокета, сохраненную для объекта Node в плоскости управления Kubernetes:

$ kubectl edit node node-1

В открывшемся файле найдите аннотацию kubeadm.alpha.kubernetes.io/cri-socket и измените ее на unix:///run/containerd/containerd.sock. . Сохраните и закройте файл, чтобы обновить объект узла.

Теперь перезапустите Kubelet:

$ systemctl start kubelet

Подождите несколько секунд, пока узел запустится и подключится к плоскости управления Kubernetes. Вы сможете повторить команду get nodes и увидеть, что теперь используется containerd.

$ kubectl get nodes -o wide
NAME    STATUS  VERSION     CONTAINER-RUNTIME
node-1  Ready   v1.22.8     containerd://1.4.13
node-2  Ready   v1.22.8     containerd://1.4.13

Наконец, удалите оцепление, которое вы разместили вокруг узла, чтобы он мог начать получать модули:

$ kubectl uncordon node-1

Использование cri-dockerd

cri-dockerd — это среда выполнения, совместно разработанная Docker и Mirantis. По сути, это отдельная версия Dockershim, которая поддерживается независимо. Это позволяет вам продолжать использовать знакомые функции, не обременяя проект Kubernetes требованиями обслуживания Dockershim.

Убедитесь, что у вас уже установлен Docker Engine. Затем установите cri-dockerd, загрузив последний бинарный файл из выпусков GitHub:

$ 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/

Затем загрузите, установите и включите конфигурации службы 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

Теперь вы можете изменить конфигурацию Kubelet вашего узла, чтобы использовать cri-dockerd. Это похоже на настройку узла для использования containerd.

Откройте /var/lib/kubelet/kubeadm-flags.env. Найдите или добавьте флаги --container-runtime и --container-runtime-endpoint со следующими значениями:

  • --container-runtime=remote
  • --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock

Затем измените аннотацию сокета объекта Node:

$ kubectl edit node node-1

В открывшемся файле найдите аннотацию kubeadm.alpha.kubernetes.io/cri-socket и измените ее на unix:///var/run/cri-dockerd.sock. Сохраните и закройте файл, чтобы обновить объект узла.

Теперь перезапустите Kubelet:

$ systemctl start kubelet

Подождите несколько секунд, а затем используйте Kubectl, чтобы проверить, работает ли узел. Он по-прежнему будет отображать среду выполнения Docker, но теперь он основан на автономном cri-dockerd, а не на Dockershim, интегрированном с Kubernetes.

$ kubectl get nodes -o wide
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

Теперь вы можете удалить кордон, который вы установили вокруг узла. Он снова начнет принимать запросы на планирование Pod.

$ kubectl uncordon node-1

Заключение

Kubernetes v1.24 удалил компонент Dockershim, который ранее интегрировал совместимость CRI для Docker Engine. Хотя самые последние кластеры не будут затронуты, вам следует проверить, используете ли вы Dockershim перед обновлением до новой версии.

Среда выполнения, на которую нужно переключиться, зависит от того, как вы в настоящее время используете свой кластер. containerd обычно является хорошим выбором, если вы не используете функции Docker. Вы можете использовать cri-dockerd, чтобы вернуть интеграцию, подобную Dockershim, если вам нужно поддерживать совместимость с существующими инструментами, которые зависят от Docker Engine. Это также помогает, если вы монтируете сокет демона Docker (/var/run/docker.sock) в свои контейнеры для запуска рабочих процессов Docker-in-Docker.

Удаление Dockershim не влияет на то, как вы создаете и используете образы контейнеров. Kubernetes по-прежнему может запускать образы, созданные с помощью docker build, и они совместимы со всеми поддерживаемыми средами выполнения. Среды выполнения CRI работают с любым образом в формате OCI, выводимым Docker и другими сборщиками образов.