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 GKE para um novo conjunto de nós no mesmo cluster sem incorrer em inatividade para o 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 com 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 (ambos em inglês) removidos para o novo pool de nós, à medida que esvazia o pool de nós atual.

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 Platform.
  2. Crie ou selecione um projeto.
  3. Aguarde a ativação da API e dos serviços relacionados. Isso pode demorar alguns minutos.
  4. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform.

    Saiba como ativar o faturamento

Instale as seguintes ferramentas de linha de comando usadas neste tutorial:

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

Definir padrões da ferramenta de linha de comando gcloud

Para não perder tempo digitando 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_ENGINE_ZONE]

Etapa 1: criar 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 contendo cinco nós com o tipo de máquina padrão (n1-standard-1):

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

Etapa 2: executar uma implantação de aplicativo replicado

O comando a seguir criará uma implantação de seis réplicas da imagem de contêiner de aplicativos da Web de exemplo:

kubectl run web --image=gcr.io/google-samples/hello-app:1.0 \
  --replicas=6 --limits='cpu=100m,memory=80Mi'

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

Etapa 3: criar um pool de nós com um tipo de máquina grande

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

gcloud container node-pools list --cluster migration-tutorial
Resposta:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  n1-standard-1  100           1.5.7

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 seguinte comando cria um novo pool de nós chamado larger-pool contendo cinco instâncias de alta de memória com o tipo de máquina n1-highmem-2 (um tipo de máquina maior do que a n1-standard-1, padrão do GKE):

gcloud container node-pools create larger-pool \
  --cluster=migration-tutorial \
  --machine-type=n1-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  n1-standard-1  100           1.5.7
larger-pool   n1-highmem-2   100           1.5.7

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.5.7
gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready     40m       v1.5.7
gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready     40m       v1.5.7
gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready     40m       v1.5.7
gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready     40m       v1.5.7
gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready     4m        v1.5.7
gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready     4m        v1.5.7
gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready     4m        v1.5.7
gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready     4m        v1.5.7
gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready     4m        v1.5.7

Etapa 4: migrar as cargas de trabalho

Depois que você cria um pool de nós, as 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. Restrinja o pool de nós atual: com essa operação, os nós do pool atual (default-pool) são marcados 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. Esvazie o pool de nós atual: use essa operação para remover normalmente as cargas de trabalho em execução nos nós do pool atual (default-pool).

Com as etapas acima, os pods em execução no pool de nós atual são encerrados, e o Kubernetes faz a reprogramação deles em outros nós disponíveis. Nesse caso, os únicos nodes disponíveis são aqueles no larger-pool, criados na Etapa 3.

Para certificar-se de que os aplicativos sejam encerrados pelo Kubernetes, o sinal SIGTERM precisa ser processado pelos contêineres. 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 encerrar os contêineres no pod. O padrão é de 30 segundos. Leia mais sobre o encerramento de pods na documentação do Kubernetes.

Primeiro, feche os nodes 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, restrinja todos os nós 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

Você verá que os nós default-pool têm o status SchedulingDisabled na lista:

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

Em seguida, esvazie os pods em cada nó normalmente. Para drenar, use o comando kubectl drain, que elimina pods em cada node.

É possível executar kubectl drain --force NODE substituindo NODE pela mesma lista de nomes transmitida para o comando kubectl cordon.

O seguinte comando de shell itera cada nó em default-pool e os esvazia eliminando pods com um período de término normal fixado 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-local-data --grace-period=10 "$node";
done

Depois que o comando é concluído, veja se os pods estão em execução 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

Etapa 5: excluir o pool de nós antigo

Com todos os pods reprogramados pelo Kubernetes na implantação da web para o larger-pool, é seguro excluir o default-pool, já que ele não é mais necessário. Execute o seguinte comando para excluir o default-pool:

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

Quando a operação é concluída, você tem um único pool de nós para o cluster de contêineres, que é o larger-pool:

gcloud container node-pools list --cluster migration-tutorial
Saída:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
larger-pool   n1-highmem-2   100           1.5.7

Como fazer a limpeza

Para evitar cobranças dos recursos usados neste tutorial na conta do Google Cloud Platform:

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

    gcloud container clusters delete migration-tutorial

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Tutoriais do Kubernetes Engine