Como fazer atualizações graduais

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

Visão geral

É possível executar uma atualização gradual para modificar imagens, configuração, rótulos, anotações e limites/solicitações de recursos das cargas de trabalho nos clusters. Essas atualizações substituem gradualmente os pods do recurso por outros novos, que são programados em nós com recursos disponíveis. As atualizações graduais foram projetadas para modificar as cargas de trabalho sem inatividade.

Os objetos a seguir representam cargas de trabalho do Kubernetes. Atualize o modelo do pod para acionar uma atualização gradual nessas cargas de trabalho:

  • 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 pretendido dos pods. Atualize o spec: template do objeto para acionar uma lançamento de atualização.

O modelo de pod inclui os campos abaixo:

Consulte a documentação do PodTemplateSpec (em inglês) para saber mais sobre o modelo de pod.

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

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

Defina configurações gcloud padrão usando um dos métodos a seguir:

  • Use gcloud init se você quer orientações para definir os padrões.
  • Use gcloud config para definir separadamente a região, a zona e o ID do projeto.

Como usar o gcloud init

  1. Execute gcloud init e siga as instruções:

    gcloud init

    Se você usa o SSH em um servidor remoto, utilize a sinalização --console-only para impedir que o comando inicie um navegador:

    gcloud init --console-only
  2. Siga as instruções para autorizar a gcloud a usar sua conta do Google Cloud.
  3. Crie uma nova configuração ou selecione uma atual.
  4. Escolha um projeto do Google Cloud.
  5. Escolha uma zona padrão do Compute Engine.

Como usar o gcloud config

  • 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, você vê como atualizar um aplicativo usando o Console do Google Cloud ou a kubectl.

kubectl set

Use o kubectl set (em inglês) para alterar os campos image, resources (recurso de computação, como CPU e memória) ou selector de um objeto.

Por exemplo, para atualizar um Deployment 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 do Deployment, um de cada vez.

Como outro exemplo, para definir os limites e as solicitações de recurso do Deployment:

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 o kubectl apply (em inglês) para atualizar um objeto ao aplicar 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 pretendidas nos rótulos do objeto ou no modelo de pod.

  5. Clique em Salvar.

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

Use o kubectl rollout (em inglês) para inspecionar um lançamento enquanto ele ocorre, para pausá-lo e retomá-lo, para reverter uma atualização e para visualizar o histórico de lançamentos de um objeto.

Como inspecionar um lançamento com kubectl rollout status

Use o comando kubectl rollout status para inspecionar o status de um lançamento.

Por exemplo, execute o comando a seguir para inspecionar o lançamento do Deployment do nginx.

kubectl rollout status deployment nginx

A resposta será assim:

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 do lançamento estão em execução. A resposta será assim:

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 um lançamento.

Por exemplo, execute o comando a seguir para pausar o lançamento do Deployment 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 lançamento de um objeto.

Por exemplo, execute o comando a seguir para visualizar o histórico de lançamentos do Deployment 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 o lançamento de um objeto.

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

kubectl rollout undo deployments nginx

Ou, como outro exemplo, para reverter para a terceira revisão do Deployment, execute o comando abaixo:

kubectl rollout undo deployment nginx --to-revision 3

Considerações sobre StatefulSets e DaemonSets

Os StatefulSets, desde o Kubernetes 1.7, e os DaemonSets, desde o Kubernetes 1.6, usam uma estratégia de atualização para configurar e desativar atualizações graduais e automáticas de contêineres, rótulos, limites e solicitações de recursos e anotações de 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 o controlador criar novos que reflitam suas mudanças. OnDelete será útil se você preferir atualizar os pods manualmente.

RollingUpdate implementa atualizações graduais e automáticas dos pods no StatefulSet. RollingUpdate faz o controlador excluir e recriar cada um dos pods dele, um de cada vez. Ele espera até que um pod atualizado esteja em execução e pronto antes para atualizar o anterior.

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á assim:

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 partition 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 organizar uma atualização, lançar um canário ou executar um lançamento 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 os 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 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 o Deployment.

A seguir