Kubernetes отказывается от Docker для выполнения контейнеров после версии 1.20. (Прим. переводчика: в декабре мы уже писали о том, как это изменение повлияет на задачи разработчиков и инженеров эксплуатации: «Docker is deprecated — и как теперь быть?»)
Без паники. Контейнеры Docker все еще поддерживаются, но без dockershim/Docker — слоя между Kubernetes и containerd, который будет удален, начиная с версии 1.22+.
Если вы используете Docker, нужно перейти на поддерживаемый интерфейс container runtime interface (CRI). Хорошим вариантом будет containerd — он уже есть у вас на ноде Kubernetes, если вы работаете с Docker.
Дополнительное преимущество — меньше издержек благодаря отсутствию dockershim и уровней преобразования Docker, как видно на иллюстрации.
Переход с dockershim на containerd CRI
Как мигрировать?
Сначала проверяем, какая среда запуска контейнеров (container runtime) у нас используется. Это можно сделать командой kubectl get nodes -o wide
Как видите, здесь у нас Docker.
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-cn01 Ready control-plane,master 78m v1.20.4 10.65.79.164 <none> Ubuntu 20.04.2 LTS 5.4.0-67-generic docker://20.10.5
k8s-wn01 Ready <none> 64m v1.20.4 10.65.79.131 <none> Ubuntu 20.04.2 LTS 5.4.0-67-generic docker://20.10.5
k8s-wn02 Ready <none> 4m16s v1.20.4 10.65.79.244 <none> CentOS Linux 8 4.18.0-240.15.1.el8_3.centos.plus.x86_64 docker://20.10.5
kubectl get nodes -o wide
Проверим, есть ли у нас containerd CLI /usr/bin/ctr
и неймспейс moby из Docker.
NAME LABELS
moby
ctr namespace list
Можно посмотреть запущенные контейнеры в этом неймспейсе.
CONTAINER IMAGE RUNTIME
04f9500885c473c9cb2b4f8d09dc4feea5c24838519b9a01251011830bab16a2 - io.containerd.runc.v2
57d4c75ab9947829228a087b857b203c48a9d1c83de0a1b49af3624fb08c9d33 - io.containerd.runc.v2
934c007a259018a5cbda56dd8e066a66f2c9cfcb8003e7f8d25833fe462582fd - io.containerd.runc.v2
94315822d8f8a05e1be5adb7e5c18add33cbf2604057100c87572b5fc55169cd - io.containerd.runc.v2
dfa01906e845239c74a0b35d457e845382468dd9ad6e99dd0c16be30f8a23a2d - io.containerd.runc.v2
ctr --namespace moby container list
Если все выглядит нормально, можно изменить CRI. Меняем по одной ноде за раз, начиная с рабочих нод и заканчивая мастером. Если мастер только один, вы временно потеряете доступ к кластеру, но он восстановится сам.
Cordon и drain
Выполняем cordon и drain для нод, чтобы перенести поды на другие ноды.
root@k8s-cn01:~# kubectl cordon k8s-wn01
node/k8s-wn01 cordoned
root@k8s-cn01:~# kubectl drain k8s-wn01 --ignore-daemonsets
node/k8s-wn01 already cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/kube-proxy-9wnh4, kube-system/weave-net-pgptm
evicting pod default/nginx-6799fc88d8-r44x9
pod/nginx-6799fc88d8-r44x9 evicted
node/k8s-wn01 evicted
root@k8s-cn01:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-cn01 Ready control-plane,master 138m v1.20.4
k8s-wn01 Ready,SchedulingDisabled <none> 124m v1.20.4
k8s-wn02 Ready <none> 64m v1.20.4
Останавливаем сервисы
systemctl stop kubelet
systemctl stop docker
stop kubelet and docker
Удаляем Docker (по желанию)
Удалять Docker не обязательно, но так все будет понятнее, на диске освободится немного места, а риска ошибок будет меньше.
apt purge docker-ce docker-ce-cli
OR
yum remove docker-ce docker-ce-cli
remove docker
Конфигурация containerd
Отключим строку disabled_plugins в /etc/containerd/config.toml
, чтобы CRI загрузился.
#disabled_plugins = ["cri"]
/etc/containerd/config.tom
Если для cotainerd нет файла конфигурации, создайте новый дефолтный файл.
containerd config default > /etc/containerd/config.toml
generate new config
Перезапустим containerd.
systemctl restart containerd
restart containerd
Меняем среду запуска
Правим файл /var/lib/kubelet/kubeadm-flags.env
и добавляем среду containerd во флаги — --container-runtimeremote
и --container-runtimeendpoint=unix:///run/containerd/containerd.sock"
Файл kubeadm-flags будет выглядеть как-то так:
KUBELET_KUBEADM_ARGS="--cgroup-driver=systemd --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.2
--resolv-conf=/run/systemd/resolve/resolv.conf --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
/var/lib/kubelet/kubeadm-flags.env
Запускаем kubelet
Изменив среду запуска, запускаем сервис kubelet.
systemctl start kubelet
start kubelet
Проверяем
Запускаем kubectl get nodes -o wide
и видим, что у измененной ноды новая среда запуска.
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-cn01 Ready control-plane,master 131m v1.20.4 10.65.79.164 <none> Ubuntu 20.04.2 LTS 5.4.0-67-generic docker://20.10.5
k8s-wn01 Ready,,SchedulingDisabled <none> 117m v1.20.4 10.65.79.131 <none> Ubuntu 20.04.2 LTS 5.4.0-67-generic containerd://1.4.4
k8s-wn02 Ready <none> 57m v1.20.4 10.65.79.244 <none> CentOS Linux 8 4.18.0-240.15.1.el8_3.centos.plus.x86_64 docker://20.10.5
Измененная нода все еще имеет статус cordoned. Отменим его.
root@k8s-cn01:~# kubectl uncordon k8s-wn01
node/k8s-wn01 uncordoned
root@k8s-cn01:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-cn01 Ready control-plane,master 143m v1.20.4
k8s-wn01 Ready <none> 129m v1.20.4
k8s-wn02 Ready <none> 69m v1.20.4
Если проверить неймспейсы на ноде сейчас, увидим k8s.io. Неймспейс moby теперь пуст, никакие контейнеры в нем не выполняются — все мигрировало в k8s.io.
root@k8s-wn01:~# ctr namespaces list
NAME LABELS
k8s.io
moby
root@k8s-wn01:~# ctr --namespace moby container list
CONTAINER IMAGE RUNTIME
root@k8s-wn01:~# ctr --namespace k8s.io container list
CONTAINER IMAGE RUNTIME
08d4b5ca1f0ddd08fff7f64ea4eb12be66b8ec860d119565e553c84d16942d26 docker.io/weaveworks/weave-kube:2.8.1 io.containerd.runc.v2
1c9e3f61f542b12abb4b849075b084fb7fe3f69b89ce668d73022c2cd647bcd1 k8s.gcr.io/pause:3.2 io.containerd.runc.v2
1f8e0c5a6f8219de1c8f25bbb28d5d5c71b74e9ccfb9620007701847d29f23a2 k8s.gcr.io/kube-proxy:v1.20.4 io.containerd.runc.v2
39296ebd6017a7c83cd58004c94708c927f10a996a4e6ba0bbf003c6713fe713 docker.io/weaveworks/weave-kube:2.8.1 io.containerd.runc.v2
67f812954f46fa5c1f6ab39e681e2481f868309f28bd1b8ba44cce53f5c0071c docker.io/weaveworks/weave-npc:2.8.1 io.containerd.runc.v2
9caed1d57d40cedef736e45adf550eda6a0befd32712e5b6af5d711681ba71f0 k8s.gcr.io/pause:3.2 io.containerd.runc.v2
view new k8s.io containerd namespace
Мы успешно изменили CRI, теперь можно повторить все то же самое для следующей ноды.
Bytamine
Удивительной простоты совет. Как понять, что всё выглядит нормально?