Como fazer atualizações graduais

Nesta página, explicamos como executar atualizações graduais de aplicativos no Google Kubernetes Engine.

Visão geral

É possível executar um upgrade contínuo para atualizar imagens, configuração, marcadores, anotações e limites/solicitações de recursos das cargas de trabalho nos clusters. Os upgrades contínuos substituem gradualmente os pods do recurso por outros novos, que são agendados em nós com recursos disponíveis. Os upgrades contínuos foram projetados para atualizar as cargas de trabalho sem inatividade.

Os objetos a seguir representam cargas de trabalho do Kubernetes. É possível acionar uma atualização contínua nessas cargas de trabalho atualizando o modelo de pod:

  • DaemonSets
  • Implantações
  • StatefulSets

Cada um desses objetos tem um modelo de pod representado pelo campo spec: template no manifesto do objeto. O campo "Modelo de pod" tem uma especificação criada pelo controlador para perceber o estado ou comportamento desejado para os pods. Atualize o spec: template do objeto para acionar uma implantação de atualização.

O modelo de pod inclui os campos abaixo:

Consulte a documentação do PodTemplateSpec para saber mais sobre o modelo de pod.

Escalonar um recurso ou atualizar campos fora do modelo de pod não aciona uma implantação.

Antes de começar

Prepare-se para a tarefa tomando as seguintes medidas:

  • Verifique se você ativou a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Verifique se o SDK do Cloud está instalado.
  • Defina o ID do projeto padrão:
    gcloud config set project [PROJECT_ID]
  • Se você estiver trabalhando com clusters zonais, defina a zona do Compute padrão:
    gcloud config set compute/zone [COMPUTE_ZONE]
  • Se você estiver trabalhando com clusters regionais, defina a região do Compute padrão:
    gcloud config set compute/region [COMPUTE_REGION]
  • Atualize gcloud para a versão mais recente:
    gcloud components update

Como atualizar um aplicativo

Na seção a seguir, explicamos como atualizar um aplicativo usando o Console do Google Cloud ou o kubectl.

kubectl set

Use kubectl set para fazer alterações nos campos image, resources (recurso de computação, como CPU e memória) ou selector.

Por exemplo, para atualizar uma implantação do nginx versão 1.7.9 para 1.9.1, execute este comando:

kubectl set image deployment nginx nginx=nginx:1.9.1

O comando kubectl set image atualiza a imagem nginx dos pods da implantação, um de cada vez.

Como outro exemplo, para definir os limites e as solicitações de recurso da implantação:

kubectl set resources deployment nginx --limits cpu=200m,memory=512Mi --requests cpu=100m,memory=256Mi

Ou para remover as solicitações de recurso da implantação:

kubectl set resources deployment nginx --limits cpu=0,memory=0 --requests cpu=0,memory=0

kubectl apply

Use kubectl apply para atualizar um objeto aplicando um arquivo de manifesto novo ou atualizado.

Para aplicar um novo arquivo de manifesto, execute o comando abaixo:

kubectl apply -f [MANIFEST]

em que [MANIFEST] é o arquivo de manifesto atualizado.

Console

Para editar a configuração em tempo real de um aplicativo, siga as etapas a seguir:

  1. Acesse o menu Cargas de trabalho do Google Kubernetes Engine no Console do Cloud.

    Acesse o menu Cargas de trabalho

  2. Selecione a carga de trabalho desejada.

  3. Clique em Editar.

  4. Use o editor para fazer as mudanças desejadas nos rótulos do objeto ou no modelo de pod.

  5. Clique em Salvar.

Como gerenciar uma implantação de atualização

Use kubectl rollout para inspecionar uma implantação enquanto ela ocorre, para pausar e retomar uma implantação, para reverter uma atualização e para visualizar o histórico de implantações de um objeto.

Como inspecionar uma implantação com kubectl rollout status

Use o comando kubectl rollout status para inspecionar o status de uma implantação.

Por exemplo, execute o comando a seguir para inspecionar a implantação do nginx.

kubectl rollout status deployment nginx

A resposta será semelhante a:

Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx" successfully rolled out

Após a conclusão bem-sucedida, execute kubectl get deployment nginx para verificar se todos os pods dela estão em execução. A resposta será semelhante a:

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx              3         3         3            3           36s

Como pausar e retomar uma implantação

Use kubectl rollout pause para pausar uma implantação.

Por exemplo, execute o comando a seguir para pausar a implantação do nginx:

kubectl rollout pause deployment nginx

Para continuar, execute o comando abaixo:

kubectl rollout resume deployment nginx

Como visualizar o histórico de implantações com kubectl rollout history

Use kubectl rollout history para visualizar o histórico de implantações de um objeto.

Por exemplo, execute o comando a seguir para visualizar o histórico de implantações do nginx.

kubectl rollout history deployment nginx

Para consultar o histórico da terceira revisão, execute o comando abaixo:

kubectl rollout history deployment nginx --revision 3

Reverter uma atualização com kubectl rollout undo

Use o comando kubectl rollout undo para reverter a implantação de um objeto.

Por exemplo, execute o comando a seguir para reverter à versão anterior da implantação do nginx:

kubectl rollout undo deployments nginx

Ou, como outro exemplo, para reverter para a terceira revisão da implantação, execute o comando abaixo:

kubectl rollout undo deployment nginx --to-revision 3

Considerações sobre StatefulSets e DaemonSets

O StatefulSets, desde o Kubernetes 1.7, e o DaemonSets, desde o Kubernetes 1.6, usam uma estratégia de atualização para configurar e desativar atualizações graduais e automáticas para contêineres, marcadores, limites e solicitações de recursos e anotações para os pods. A estratégia de atualização é configurada usando o campo spec.updateStrategy.

O campo spec.updateStrategy.type aceita OnDelete ou RollingUpdate como valores.

OnDelete é o comportamento padrão quando spec.updateStrategy.type não é especificado. OnDelete impede que o controlador atualize automaticamente os pods dele. É necessário excluir manualmente os pods para fazer com que o controlador crie novos pods que reflitam suas mudanças. OnDelete será útil se você preferir atualizar os pods manualmente.

RollingUpdate implementa atualizações graduais e automáticas para os pods no StatefulSet. RollingUpdate faz com que o controlador exclua e recrie cada um dos pods dele, um por vez. Ele espera até que um pod atualizado esteja em execução e pronto antes para atualizar o antecessor.

O controlador do StatefulSet atualiza todos os pods em ordem numérica inversa, respeitando as garantias dele.

Como usar a estratégia RollingUpdate

Use a estratégia RollingUpdate para atualizar automaticamente todos os pods em um StatefulSet ou DaemonSet.

Por exemplo, para corrigir o StatefulSet web para aplicar a estratégia RollingUpdate, execute este comando:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'

Em seguida, faça uma alteração no spec.template do StatefulSet. Por exemplo, use kubectl set para alterar a imagem do contêiner. No exemplo a seguir, o StatefulSet web é definido para fazer o contêiner nginx executar a imagem nginx-slim:0.7:

kubectl set image statefulset web nginx=nginx-slim:0.7

Para verificar se os pods no StatefulSet que executa o contêiner nginx estão sendo atualizados, execute este comando:

kubectl get pods -l app=nginx -w

A resposta será semelhante a:

NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          7m
web-1     1/1       Running   0          7m
web-2     1/1       Running   0          8m
web-2     1/1       Terminating   0         8m
web-2     1/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Pending   0         0s
web-2     0/1       Pending   0         0s
web-2     0/1       ContainerCreating   0         0s
web-2     1/1       Running   0         19s
web-1     1/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         6s
web-0     1/1       Terminating   0         7m
web-0     1/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Pending   0         0s
web-0     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         10s

Os pods no StatefulSet são atualizados em ordem numeral inversa. O controlador do StatefulSet encerra cada pod e espera que ele fique em execução e pronto antes de atualizar o próximo.

Como particionar um RollingUpdate

É possível especificar um parâmetro partition para um campo RollingUpdate do StatefulSet.

Se você especificar uma partition, todos os pods com um número ordinal maior ou igual ao valor de serão atualizados. Todos os pods com um número ordinal inferior ao valor de partition não serão atualizados e, mesmo se forem excluídos, serão recriados na versão anterior.

Se um valor de partition for maior que o número de replicas, as atualizações não serão propagadas para os pods. O particionamento é útil se você quer fazer uma atualização, implantar um canário ou executar uma implantação gradual.

Por exemplo, para particionar o StatefulSet web, execute este comando:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'

Isso faz com que pods com um número ordinal maior ou igual a 3 sejam atualizados.

Parâmetro maxUnavailable do DaemonSet

O parâmetro maxUnavailable opcional do DaemonSet é um filho do campo rollingUpdate.

maxUnavailable determina o número máximo de pods do DaemonSet que podem ficar indisponíveis durante as atualizações. O valor padrão, se omitido, é 1. O valor não pode ser 0. O valor pode ser um número absoluto ou uma porcentagem.

Como atualizar com a estratégia OnDelete

Se preferir atualizar um StatefulSet ou DaemonSet manualmente, omita spec.updateStrategy, que instrui o controlador a usar a estratégia OnDelete.

Para atualizar um controlador que usa a estratégia OnDelete, exclua manualmente os pods dele depois de fazer alterações no modelo de pod.

Por exemplo, defina o StatefulSet web para usar a imagem nginx-slim:0.7:

kubectl set image statefulset web nginx=nginx-slim:0.7

Em seguida, exclua o primeiro pod web com este comando:

kubectl delete pod web-0

Para acompanhar conforme o pod é recriado pelo StatefulSet e fica em execução e pronto, execute o comando a seguir:

kubectl get pod web-0 -w

A saída deste comando é semelhante a:

NAME      READY     STATUS               RESTARTS   AGE
web-0     1/1       Running              0          54s
web-0     1/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Pending              0         0s
web-0     0/1       Pending              0         0s
web-0     0/1       ContainerCreating    0         0s
web-0     1/1       Running              0         3s

Como atualizar um job

Quando você atualiza a configuração de um job, o novo job e os pods dele são executados com a nova configuração. Depois de atualizar um job, é necessário excluir manualmente o job antigo e os pods dele, se você quiser.

Para excluir um job e todos os pods dele, execute o comando abaixo:

kubectl delete job my-job

Para excluir um job, mas manter os pods em execução, especifique a sinalização --cascade=false:

kubectl delete job my-job --cascade=false

Também é possível executar kubectl describe deployment nginx, que gera ainda mais informações sobre a implantação.

A seguir