Como migrar do Dockershim no Kubernetes v1.24 e posterior

0
16


O Kubernetes v1.24 e posterior é enviado sem o Dockershim após sua descontinuação na v1.20 em dezembro de 2020. O Dockershim não está mais disponível como um ambiente de execução de contêiner integrado. Em vez disso, você deve usar um tempo de execução compatível diferente, como containerd, CRI-O ou Docker Engine com o cri-dockerd adaptador.

Install Your Own KMS Container Usin...
Install Your Own KMS Container Using Portainer Docker

Neste artigo, mostraremos como verificar se você foi afetado e, em seguida, explicaremos como você pode migrar para um tempo de execução diferente. Você deve seguir estes passos antes de Atualize para o Kubernetes v1.24 ou posterior para que as cargas de trabalho do cluster não sejam afetadas.

O que era Dockershim?

O Dockershim foi desenvolvido como um componente necessário para o Kubernetes oferecer suporte a mais tempos de execução de contêiner. No início do projeto, o Kubernetes trabalhava apenas com o Docker Engine. Essa restrição foi removida com a introdução do padrão CRI. Qualquer runtime compatível com CRI agora pode ser usado com Kubernetes, incluindo containerd e CRI-O, uma implementação OCI do padrão.

Embora o CRI tenha trazido nova flexibilidade ao Kubernetes, ele apresentou um problema para os clusters existentes. O Docker não tinha suporte para o padrão CRI, então o Dockershim foi criado para permitir que a equipe do Kubernetes superasse a compatibilidade. O Dockershim foi uma integração direta com o Docker Engine que sempre teve a intenção de ser uma medida temporária.

A movimentação de contêineres agora é muito mais do que o Docker, como demonstra o impulso original do Kubernetes para o CRI. O Docker foi dividido em componentes individuais com seu tempo de execução minerado como containerd, graduado pela Cloud Native Computing Foundation (CNCF).

O containerd é totalmente compatível com Kubernetes e é mais adequado para uso autônomo em ambientes de nuvem. O Kubernetes não requer a CLI do Docker e seu conjunto de recursos para executar seus pods; tudo que você precisa é a capacidade de iniciar e executar contêineres em um nível relativamente baixo. O Dockershim foi removido porque era difícil de manter. Seu uso criou um código frágil que estava intimamente relacionado à implementação do Docker Engine.

Verifique se você está usando o Dockershim

É muito improvável que clusters recém-criados em plataformas modernas usem o Dockershim. Isso inclui clusters gerenciados por provedores de nuvem populares como Amazon EKS, Azure AKS, Google GKE e DigitalOcean DOKS.

Você provavelmente precisará agir se mantiver seu próprio cluster e configurá-lo pela primeira vez há vários anos. Você pode verificar se está usando o Dockershim como o tempo de execução para qualquer um de seus nós executando este comando 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

Neste exemplo, um dos nós usa containerd e pode ser deixado como está. O outro nó é configurado usando o Docker e pode ser afetado pela remoção do Dockershim. Você pode verificar executando este comando no nó:

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

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

Seu nó está usando o Dockershim para executar contêineres se nenhum resultado for retornado. Se você obtiver algum resultado, inspecione o mostrado --container-runtime-endpoint valor do sinalizador para determinar se o Dockershim está ativo. Um endpoint de tempo de execução de unix:///run/containerd/containerd.sock O contêiner de token é usado, portanto, nenhuma migração é necessária.

Alterar o tempo de execução de um nó

Os nós que usam o Dockershim devem ser atualizados para usar um tempo de execução diferente. Primeiro, drene as cargas de trabalho do nó com o Kubectl, para que seus pods sejam reprogramados para outros nós em seu cluster. Você também deve isolar o nó para evitar que novos pods sejam agendados.

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

Em seguida, execute os seguintes comandos no próprio Node. Comece interrompendo o daemon do Docker e o processo de trabalho do Kubelet do nó:

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

Agora você pode instalar seu novo runtime.

Usando contêineres

containerd é geralmente a solução preferida para os clusters atuais. Você poderá migrar para containerd se não confiar em recursos específicos do Docker Engine. Nesse caso, vá para a próxima seção e instale o cri-dockerd.

Adicione o repositório do Docker ao seu sistema se suas listas de pacotes ainda não o incluírem. containerd é distribuído no repositório do 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

Instale o recipiente:

$ sudo apt update
$ sudo apt install containerd

Agora atualize o arquivo de configuração Kubelet do nó para usar o novo tempo de execução. Abrir /var/lib/kubelet/kubeadm-flags.env. Encontre ou adicione o --container-runtime S --container-runtime-endpoint flags com os seguintes valores:

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

Em seguida, altere a anotação do soquete salva no objeto Node no plano de controle do Kubernetes:

$ kubectl edit node node-1

No arquivo que se abre, localize o kubeadm.alpha.kubernetes.io/cri-socket anotação e altere para unix:///run/containerd/containerd.sock. Salve e feche o arquivo para atualizar o objeto do nó.

Agora reinicie o Kubelet:

$ systemctl start kubelet

Permita que o nó inicialize e se conecte ao plano de controle do Kubernetes por alguns momentos. Eu deveria ser capaz de repetir o get nodes comando e veja que containerd está sendo usado agora.

$ 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

Por fim, remova o cabo que você colocou ao redor do Node para que ele possa começar a receber Pods:

$ kubectl uncordon node-1

Usando cri-dockerd

cri-dockerd é um runtime desenvolvido em conjunto pelo Docker e Mirantis. É efetivamente uma versão autônoma do Dockershim que é mantida de forma independente. Ele permite que você continue usando funcionalidades familiares sem sobrecarregar seu projeto Kubernetes com os requisitos de manutenção do Dockershim.

Verifique se você já tem o Docker Engine instalado. Em seguida, instale o cri-dockerd baixando as versões binárias mais recentes do 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/

Em seguida, baixe, instale e habilite as configurações do serviço cri-dockerd systemd:

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

Agora você pode modificar a configuração do Kubelet do seu nó para usar o cri-dockerd. Isso é semelhante a configurar um Node para usar containerd.

Abrir /var/lib/kubelet/kubeadm-flags.env. Encontre ou adicione o --container-runtime S --container-runtime-endpoint flags com os seguintes valores:

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

Em seguida, altere a anotação de soquete do objeto Node:

$ kubectl edit node node-1

No arquivo que se abre, localize o kubeadm.alpha.kubernetes.io/cri-socket anotação e altere para unix:///var/run/cri-dockerd.sock. Salve e feche o arquivo para atualizar o objeto do nó.

Agora reinicie o Kubelet:

$ systemctl start kubelet

Aguarde alguns momentos e use o Kubectl para verificar se o Node está ativo. Ele ainda mostrará o tempo de execução do Docker, mas agora é baseado no cri-dockerd autônomo, em vez do Dockershim integrado ao 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

Agora você pode remover o cordão que colocou ao redor do Node. Ele começará a aceitar solicitações de agendamento de pod novamente.

$ kubectl uncordon node-1

conclusão

O Kubernetes v1.24 removeu o componente Dockershim que anteriormente criava suporte a CRI para o Docker Engine. Embora os clusters mais novos não sejam afetados, você deve verificar se está usando o Dockershim antes de atualizar para a nova versão.

O ambiente de tempo de execução para alternar depende de como você usa seu cluster atualmente. containerd geralmente é uma boa escolha se você não estiver usando recursos do Docker. Você pode usar o cri-dockerd para trazer de volta uma integração semelhante ao Dockershim se precisar manter a compatibilidade com as ferramentas existentes que dependem do Docker Engine. Isso também ajuda se você estiver montando o soquete do daemon do Docker (/var/run/docker.sock) em seus contêineres para potencializar os fluxos de trabalho do Docker-in-Docker.

A remoção do Dockershim não afeta a maneira como você cria e usa imagens de contêiner. O Kubernetes ainda pode executar imagens criadas com docker build e são compatíveis com todos os tempos de execução suportados. Os tempos de execução do CRI funcionam com qualquer imagem no formato OCI, como resultado do Docker e de outros construtores de imagem.