Como migrar cargas de trabalho para tipos de máquina diferentes


Neste tutorial, demonstramos como migrar cargas de trabalho em execução em um cluster do Google Kubernetes Engine (GKE) para um novo conjunto de nós no mesmo cluster sem causar inatividade do aplicativo. Isso é útil se você quiser migrar cargas de trabalho para nós com um tipo de máquina diferente.

Contexto

Um pool de nós é um subconjunto de máquinas que têm a mesma configuração, incluindo os escopos de autorização do tipo de máquina (CPU e memória). Os pools de nós representam um subconjunto de nodes em um cluster. Um cluster de contêineres pode conter um ou mais pools de nós.

Quando precisar alterar o perfil da máquina do cluster do Compute Engine, você poderá criar um pool de nós e migrar as cargas de trabalho para ele.

Para migrar as cargas de trabalho sem que ocorra inatividade, é preciso que você:

  • marque o pool de nós existente como não programável;
  • esvazie as cargas de trabalho em execução no pool de nós;
  • exclua o pool de nós.

O Kubernetes, que é o sistema de orquestração de clusters do GKE, reprograma automaticamente os pods removidos para o novo pool de nós à medida que esvazia o pool de nós atual.

Objetivos

  • Crie um cluster do GKE.
  • Implante o aplicativo da Web de amostra no cluster.
  • Crie um novo pool de nós.
  • Migre os pods para o novo pool de nós sem causar inatividade.

Antes de começar

Siga estas etapas para ativar a API do Kubernetes Engine:
  1. Acesse a página do Kubernetes Engine no Console do Google Cloud.
  2. Crie ou selecione um projeto.
  3. Aguarde a ativação da API e dos serviços relacionados. Isso pode levar alguns minutos.
  4. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como confirmar se o faturamento está ativado para o projeto.

Instale as ferramentas de linha de comando a seguir usadas neste tutorial:

  • gcloud é usado para criar e excluir clusters do Kubernetes Engine. gcloud está incluído no SDK do Google Cloud.
  • O kubectl é usado para gerenciar o Kubernetes, o sistema de orquestração de cluster usado pelo Kubernetes Engine. É possível instalar kubectl usando gcloud:
    gcloud components install kubectl

Clone o código de amostra do GitHub:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/migrating-node-pool

Definir padrões para a ferramenta de linha de comando gcloud

Para poupar tempo, em vez de digitar o ID do projeto e as opções de zona do Compute Engine na ferramenta de linha de comando gcloud, defina os padrões:
gcloud config set project project-id
gcloud config set compute/zone compute-zone

crie um cluster do GKE;

A primeira etapa é criar um cluster de contêiner para executar cargas de trabalho de aplicativo. O comando a seguir cria um novo cluster com cinco nós com o tipo de máquina padrão (e2-medium):

gcloud container clusters create migration-tutorial --num-nodes=5

Como executar uma implantação de aplicativo replicado

No manifesto a seguir, veja uma implantação de seis réplicas da imagem de contêiner do aplicativo da Web de amostra:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 6
  selector:
    matchLabels:
      app: hello-app
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

Para implantar esse manifesto, execute:

kubectl apply -f node-pools-deployment.yaml

Para recuperar a lista de pods iniciados, execute:

kubectl get pods
Saída:
NAME                   READY     STATUS    RESTARTS   AGE
web-2212180648-80q72   1/1       Running   0          10m
web-2212180648-jwj0j   1/1       Running   0          10m
web-2212180648-pf67q   1/1       Running   0          10m
web-2212180648-pqz73   1/1       Running   0          10m
web-2212180648-rrd3b   1/1       Running   0          10m
web-2212180648-v3b18   1/1       Running   0          10m

Como criar um pool de nós com um tipo de máquina grande

Por padrão, o GKE cria um pool de nós chamado default-pool para cada novo cluster:

gcloud container node-pools list --cluster migration-tutorial
Saída:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  e2-medium      100           1.16.13-gke.401

Para introduzir instâncias com uma configuração diferente, como um tipo de máquina distinto ou outros escopos de autenticação, é necessário criar um novo pool de nós.

O comando a seguir cria um novo pool de nós chamado larger-pool com cinco instâncias de alta memória do tipo de máquina e2-highmem-2:

gcloud container node-pools create larger-pool \
  --cluster=migration-tutorial \
  --machine-type=e2-highmem-2 \
  --num-nodes=5

O cluster de contêineres agora tem dois pools de nós:

gcloud container node-pools list --cluster migration-tutorial
Saída:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  e2-medium      100           v1.16.13-gke.401
larger-pool   e2-highmem-2   100           v1.16.13-gke.401

Você pode ver as instâncias do novo pool de nós adicionado ao cluster do GKE:

kubectl get nodes
Saída:
NAME                                                STATUS    AGE       VERSION
gke-migration-tutorial-default-pool-56e3af9a-059q   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready     4m        v1.16.13-gke.401

Como migrar as cargas de trabalho

Depois de criar um novo pool de nós, suas cargas de trabalho ainda estão em execução no default-pool. Os Pods não são reprogramados pelo Kubernetes, contanto que estejam em execução e disponíveis.

Execute o seguinte comando para ver em qual nó os pods são executados. Consulte a coluna NODE:

kubectl get pods -o=wide
Saída:
NAME                          READY     STATUS    IP         NODE
web-2212180648-80q72          1/1       Running   10.8.3.4   gke-migration-tutorial-default-pool-56e3af9a-k6jm
web-2212180648-jwj0j          1/1       Running   10.8.2.5   gke-migration-tutorial-default-pool-56e3af9a-0ng4
web-2212180648-pf67q          1/1       Running   10.8.4.4   gke-migration-tutorial-default-pool-56e3af9a-lkrv
web-2212180648-pqz73          1/1       Running   10.8.2.6   gke-migration-tutorial-default-pool-56e3af9a-0ng4
web-2212180648-rrd3b          1/1       Running   10.8.4.3   gke-migration-tutorial-default-pool-56e3af9a-lkrv
web-2212180648-v3b18          1/1       Running   10.8.1.4   gke-migration-tutorial-default-pool-56e3af9a-p9j4

Para migrar esses pods para o novo pool de nós, faça o seguinte:

  1. Demarque o pool de nós existente: esta operação marca os nós no pool de nós existente (default-pool) como não programáveis. O Kubernetes para de programar novos pods para esses nós quando você os marca como não programáveis.

  2. Drene o pool de nós existente: esta operação remove as cargas de trabalho em execução nos nós do pool de nós existente (default-pool) normalmente.

Com as etapas anteriores, os Pods em execução no pool de nós são encerrados, e o Kubernetes faz a reprogramação deles em outros nós disponíveis. Nesse caso, os únicos nós disponíveis estão no pool de nós larger-pool.

Para garantir que o Kubernetes encerre seus aplicativos normalmente, seus contêineres devem manipular o sinal SIGTERM. Use-o para fechar conexões ativas aos clientes e confirmar ou cancelar transações do banco de dados de maneira limpa. No manifesto do pod, use o campo spec.terminationGracePeriodSeconds para especificar quanto tempo o Kubernetes precisa aguardar antes de interromper os contêineres no pod. O padrão é 30 segundos. Leia mais sobre o encerramento de pods na documentação do Kubernetes.

Primeiro, demarque os nós no default-pool. Execute o comando a seguir para ver uma lista de nós nesse pool:

kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool

Em seguida, demarque cada nó executando um comando kubectl cordon NODE (substitua NODE pelos nomes do comando anterior). O comando a seguir itera em cada nó e os marca como não programáveis:

for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl cordon "$node";
done
Saída:
node "gke-migration-tutorial-default-pool-56e3af9a-059q" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-0ng4" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-k6jm" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-lkrv" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-p9j4" cordoned

Agora, você verá que os nós default-pool têm o status SchedulingDisabled na lista de nós:

kubectl get nodes
Saída:
NAME                                                STATUS                     AGE       VERSION
gke-migration-tutorial-default-pool-56e3af9a-059q   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready                      1h        v1.16.13-gke.401

Em seguida, drene os Pods em cada nó. Para executar a drenagem, use o comando kubectl drain que remove os pods em cada nó.

Você pode executar kubectl drain --force NODE substituindo NODE pela mesma lista de nomes transmitidos ao comando kubectl cordon.

O comando shell a seguir itera cada nó em default-pool e os esvazia removendo pods com um período de encerramento de 10 segundos:

for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl drain --force --ignore-daemonsets --delete-emptydir-data --grace-period=10 "$node";
done

Quando esse comando for concluído, você verá que os pods estão sendo executados nos nós de larger-pool:

kubectl get pods -o=wide
Saída:
NAME                   READY     STATUS    IP         NODE
web-2212180648-3n9hz   1/1       Running   10.8.9.4   gke-migration-tutorial-larger-pool-b8ec62a6-cx9q
web-2212180648-88q1c   1/1       Running   10.8.7.4   gke-migration-tutorial-larger-pool-b8ec62a6-2rhk
web-2212180648-dlmjc   1/1       Running   10.8.9.3   gke-migration-tutorial-larger-pool-b8ec62a6-cx9q
web-2212180648-hcv46   1/1       Running   10.8.5.4   gke-migration-tutorial-larger-pool-b8ec62a6-hs6p
web-2212180648-n0nht   1/1       Running   10.8.6.4   gke-migration-tutorial-larger-pool-b8ec62a6-7fl0
web-2212180648-s51jb   1/1       Running   10.8.8.4   gke-migration-tutorial-larger-pool-b8ec62a6-4bb2

Como excluir o pool de nós antigo

Depois que o Kubernetes reagendar todos os pods em Deployment de web para larger-pool, será seguro excluir default-pool porque ele não será mais necessário. Execute o comando a seguir para excluir o default-pool:

gcloud container node-pools delete default-pool --cluster migration-tutorial

Quando esta operação for concluída, você terá um único pool de nós para seu cluster de contêiner, que é o larger-pool:

gcloud container node-pools list --cluster migration-tutorial
Saída:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
larger-pool   e2-highmem-2   100           1.16.13-gke.401

Limpeza

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

  • Exclua o cluster de contêineres: nessa etapa, os recursos que compõem o cluster de contêineres, como instâncias de computação, discos e recursos de rede, são excluídos.

    gcloud container clusters delete migration-tutorial

A seguir