Este tutorial apresenta práticas recomendadas para criar uma aplicação com estado e atualizar o cluster do Google Kubernetes Engine (GKE) que está a executar a aplicação. Este tutorial usa o Redis como exemplo para implementar uma aplicação com estado, mas os mesmos conceitos são aplicáveis a outros tipos de aplicações com estado implementadas no GKE.
Crie um cluster do GKE inscrito num canal de lançamento
Para criar o cluster do GKE, conclua os seguintes passos:
Crie um cluster com o nome
redis-test
com três nós:gcloud container clusters create redis-test \ --location CONTROL_PLANE_LOCATION \ --num-nodes=3 \ --release-channel regular
Substitua CONTROL_PLANE_LOCATION pela localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.
Depois de criar o cluster, deve ver um resultado semelhante ao seguinte exemplo:
NAME: redis-test LOCATION: us-central1-c MASTER_VERSION: 1.22.10-gke.600 MASTER_IP: 34.69.67.7 MACHINE_TYPE: e2-medium NODE_VERSION: 1.22.10-gke.600 NUM_NODES: 3 STATUS: RUNNING
Configure o
kubectl
para comunicar com o cluster:gcloud container clusters get-credentials redis-test
Crie um cluster do Redis no GKE
Nesta secção, adiciona um cluster Redis sobre o cluster GKE que criou anteriormente implementando um ConfigMap, um StatefulSet e um serviço sem cabeça.
Para criar um cluster Redis, conclua estes passos:
Consulte o ficheiro ConfigMap (
redis-configmap.yaml
) que armazena a configuração do Redis. O fragmento abaixo mostra os scripts da sonda de prontidão e da sonda de atividade.Os scripts
readiness.sh
eliveness.sh
usam redis-cli ping para verificar se o servidor redis está em execução ou não. Se devolverPONG
, o servidor Redis está a funcionar. Estes scripts vão ser usados noredis-cluster.yaml
.Para saber mais acerca dos parâmetros do Redis neste ConfigMap, consulte a secção de parâmetros de configuração do cluster Redis no tutorial do cluster Redis.
Implemente o ConfigMap:
kubectl apply -f redis-configmap.yaml
Consulte o fragmento do StatefulSet (
redis-cluster.yaml
) abaixo, que mostra a utilização da sondagem de disponibilidade e da sondagem de atividade.Para saber como configurar sondas no Kubernetes, consulte o artigo Configure sondas.
Recomendamos vivamente que use sondas de prontidão e de atividade quando atualizar conjuntos de nós. Isto garante que os seus pods estão prontos durante uma atualização.
Implemente o StatefulSet:
kubectl apply -f redis-cluster.yaml
O serviço sem interface chamado
redis-service.yaml
destina-se à ligação dos nós do Redis. O campoclusterIP
está definido comoNone
para criar um serviço sem interface.Implemente o serviço:
kubectl apply -f redis-service.yaml
Aguarde aproximadamente dois minutos e verifique se todos os pods estão em execução através do seguinte comando:
kubectl get pods
Deverá ver uma saída semelhante ao seguinte exemplo:
NAME READY STATUS RESTARTS AGE redis-0 1/1 Running 0 2m29s redis-1 1/1 Running 0 2m8s redis-2 1/1 Running 0 107s redis-3 1/1 Running 0 85s redis-4 1/1 Running 0 54s redis-5 1/1 Running 0 23s
Verifique se os volumes persistentes foram criados executando o seguinte comando:
kubectl get pv
Deverá ver uma saída semelhante ao seguinte exemplo:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-HASH 1Gi RWO Delete Bound default/data-redis-5 standard 75s pvc-HASH 1Gi RWO Delete Bound default/data-redis-1 standard 2m59s pvc-HASH 1Gi RWO Delete Bound default/data-redis-3 standard 2m16s pvc-HASH 1Gi RWO Delete Bound default/data-redis-2 standard 2m38s pvc-HASH 1Gi RWO Delete Bound default/data-redis-0 standard 3m20s pvc-HASH 1Gi RWO Delete Bound default/data-redis-4 standard 104s
Neste resultado, HASH representa um hash anexado a cada nome de volume persistente.
Atribua funções ao seu Redis Cluster
Assim que a configuração estiver concluída, atribua funções ao cluster Redis.
O script seguinte obtém os endereços IP dos pods e, em seguida, atribui as funções de líder e seguidor transmitindo cada um dos endereços IP dos pods para o comando:
Para atribuir funções ao seu cluster Redis, conclua estes passos:
Execute o script:
chmod +x ./roles.sh ./roles.sh
Escreva
yes
quando lhe for pedido.Inicie sessão num nó do Redis para verificar a respetiva função. Por exemplo, para verificar se
redis-0
tem uma função de líder, execute o seguinte comando:kubectl exec -it redis-0 -- redis-cli role
Deverá ver uma saída semelhante ao seguinte exemplo:
1) "master" 2) (integer) 574 3) 1) 1) "10.28.2.3" 2) "6379" 3) "574"
Implemente a aplicação cliente Redis
Para implementar a sua aplicação no cluster do GKE que criou, defina uma implementação para a sua aplicação.
O ficheiro denominado app-deployment.yaml
contém a definição de implementação da aplicação.
Para saber mais sobre as sondas e as regras de afinidade de pods usadas nesta implementação, consulte o artigo Práticas recomendadas do GKE: conceber e criar clusters de elevada disponibilidade.
Para criar a implementação, conclua os seguintes passos:
Aplique a implementação:
kubectl apply -f app-deployment.yaml
Exponha a aplicação através de um balanceador de carga:
kubectl expose deployment hello-web \ --type=LoadBalancer \ --port 80 \ --target-port 8080
Aguarde aproximadamente um minuto e obtenha o endereço IP externo da aplicação executando o seguinte comando:
kubectl get service
Na saída, copie o valor indicado na coluna
hello-web's
EXTERNAL-IP
:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-web LoadBalancer 10.13.10.55 EXTERNAL_IP 80:30703/TCP 166m
Valide se a aplicação está a funcionar colando o EXTERNAL_IP no navegador de Internet. Deverá ver uma saída semelhante ao seguinte exemplo:
I have been hit [1] times since deployment!
Tome nota do número da visita. Tem de a usar na secção Testar a interrupção da aplicação.
Defina uma variável para o EXTERNAL_IP que acabou de copiar. Use este valor quando criar scripts para testar a sua aplicação na secção seguinte:
export IP=EXTERNAL_IP
Configure as práticas recomendadas para atualizações de node pools
Siga estas práticas recomendadas para aplicações com estado para otimizar a disponibilidade durante as atualizações do conjunto de nós.
Configure o Pod Disruption Budget (PDB)
Crie um orçamento de interrupção de pods para limitar o número de pods replicados que estão inativos em simultâneo durante uma interrupção voluntária. Isto é útil para aplicações com estado em que tem de existir um quórum para o número de réplicas estar disponível durante uma atualização.
Numa definição de PDB:
app
especifica a que aplicação se aplica este PDB.minAvailable
define o número mínimo de pods a estar disponível durante uma interrupção. Pode ser um valor ou uma percentagem (por exemplo, 30%).maxUnavailable
define o número máximo de agrupamentos que podem estar indisponíveis durante uma interrupção. Também pode ser um valor ou uma percentagem.
Para configurar a PDB, conclua estes passos:
Implemente o PDB:
kubectl apply -f pdb-minavailable.yaml
Verifique se o PDB foi criado:
kubectl get pdb
Configure os períodos de manutenção e as exclusões
As atualizações automáticas de nós simplificam o processo de atualização e mantêm os nós no cluster atualizados quando o painel de controlo é atualizado automaticamente. Esta funcionalidade está ativada por predefinição. Para saber mais, consulte o artigo Atualizar automaticamente os nós.
Use janelas de manutenção e exclusões de manutenção para configurar intervalos de tempo e controlar quando a manutenção pode e não pode ocorrer em clusters do GKE:
Configure uma janela de manutenção que comece às 02:00 UTC de 19 de agosto de 2022 e termine quatro horas mais tarde. Este período de manutenção é executado diariamente. Durante este período, é permitida a manutenção automática.
gcloud container clusters update redis-test \ --maintenance-window-start 2022-08-19T02:00:00Z \ --maintenance-window-end 2022-08-19T06:00:00Z \ --maintenance-window-recurrence FREQ=DAILY
Configure um período de exclusão que impeça a manutenção durante o feriado do Ano Novo. Esta exclusão de manutenção usa o âmbito
no_upgrades
. Durante este período, não é permitida qualquer manutenção automática. Para saber mais, consulte o artigo Âmbito da manutenção a excluir.gcloud container clusters update redis-test \ --add-maintenance-exclusion-name new-year \ --add-maintenance-exclusion-start 2022-12-26T00:00:00Z \ --add-maintenance-exclusion-end 2023-01-02T02:00:00Z \ --add-maintenance-exclusion-scope no_upgrades
Confirme se a janela de manutenção e as exclusões foram aplicadas. Procure em
maintenancePolicy:
gcloud container clusters describe redis-test
Para saber mais, consulte o artigo Configure janelas de manutenção e exclusões.
Configure uma estratégia de atualização de nós
Existem duas estratégias de atualização de nós que pode usar para os conjuntos de nós no seu cluster do GKE: atualizações azul-verde e atualizações de picos. Para saber mais, consulte o artigo Estratégias de atualização de nós.
Atualizações azul-verde
Escolha atualizações azul-verde se as cargas de trabalho forem menos tolerantes a interrupções e um aumento temporário do custo devido a uma utilização mais elevada de recursos for aceitável.
Execute o seguinte comando para alterar os conjuntos de nós atuais para a estratégia de atualização azul-verde.
gcloud container node-pools update default-pool \
--cluster=redis-test \
--enable-blue-green-upgrade \
--location CONTROL_PLANE_LOCATION \
--node-pool-soak-duration=120s
A duração da imersão do conjunto de nós está definida como dois minutos para poupar tempo durante a fase de imersão do conjunto de nós para efeitos deste tutorial. Esta fase é usada para validar o estado de funcionamento da carga de trabalho depois de os nós do conjunto azul terem sido esvaziados. Recomendamos que defina a duração da preparação do conjunto de nós para uma hora (3600 segundos) ou uma duração mais adequada à aplicação.
Para mais informações sobre a gestão da atribuição de pods, consulte os artigos Implemente um pod num conjunto de nós específico e Implementar serviços em conjuntos de nós específicos.
Para mais informações sobre a configuração de atualizações azul-verde, consulte o artigo Configure atualizações azul-verde.
Atualizações de aumentos
Escolha atualizações rápidas se a otimização de custos for importante e se as cargas de trabalho puderem tolerar um encerramento normal em menos de 60 minutos (o GKE respeita o PDB até 60 minutos).
Execute o seguinte comando para alterar os conjuntos de nós atuais para a estratégia de atualização rápida.
gcloud container node-pools update default-pool \
--max-surge-upgrade=1 \
--max-unavailable-upgrade=0 \
--cluster=redis-test
Com esta configuração (maxSurge=1
e maxUnavailable=0
), só é possível adicionar um nó de pico ao conjunto de nós durante uma atualização, pelo que só é possível atualizar um nó de cada vez. Esta definição acelera os reinícios de pods durante as atualizações, ao mesmo tempo que
progride de forma conservadora.
Para mais informações sobre a configuração de aumentos súbitos, consulte o artigo Configure aumentos súbitos.
Verifique a configuração atual do conjunto de nós:
gcloud container node-pools describe default-pool \
--cluster redis-test \
--location CONTROL_PLANE_LOCATION
Para mais informações sobre a visualização de pools de nós, consulte o artigo Veja pools de nós num cluster.
Teste a aplicação
Nesta secção, usa dois scripts: um que envia pedidos para a sua aplicação e outro que mede a taxa de êxito dos pedidos. Use estes scripts para medir o que acontece quando atualiza o cluster.
Para criar os scripts:
Altere para o diretório que contém os scripts:
cd cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts
Consulte o script denominado
generate_load.sh
que envia um pedido de consultas por segundo (CPS) à sua aplicação. O script guarda o código de resposta HTTP no diretório atual num ficheiro denominadooutput
. O valor deoutput
é usado no script que criar no passo seguinte.Consulte o script denominado
print_error_rate.sh
que calcula a taxa de êxito com base no resultado gerado porgenerate_load.sh
.Conceda autorização para executar os scripts:
chmod u+x generate_load.sh print_error_rate.sh
Defina uma variável para o número de CPS. Este valor é usado no script
generate_load.sh
, tal como a variável que definiu para EXTERNAL_IP. Recomendamos que defina um valor de 40.export QPS=40
Execute o script
generate_load.sh
para começar a enviar QPS:./generate_load.sh $IP $QPS 2>&1
Deixe o script
generate_load.sh
em execução e abra um novo terminal. No novo terminal, execute o scriptprint_error_rate.sh
para verificar a taxa de erros:cd cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts watch ./print_error_rate.sh
Deve ver uma taxa de êxito de 100% e taxas de erro de 0% à medida que as QPS são feitas.
Deixe ambos os scripts em execução e abra um terceiro terminal em preparação para a secção seguinte.
Atualize o cluster
Para atualizar o cluster, conclua estes passos:
Determine a versão do GKE que o cluster
redis-test
está a usar:V=$(gcloud container clusters describe redis-test | grep "version:" | sed "s/version: //") echo $V
Deverá ver uma saída semelhante ao seguinte exemplo:
1.22.9-gke.2000
.Apresente uma lista das versões do Kubernetes disponíveis:
gcloud container get-server-config
Na lista de versões, localize a secção
validMasterVersions:
e procure a versãoredis-test
que obteve no passo anterior. Para evitar violar a política de variação da versão do GKE, escolha uma versão incompatível com os nós. Copie a versão da lista apresentada imediatamente antes da versãoredis-test
.Atualize o painel de controlo do cluster para a versão que selecionou e escreva
y
quando lhe for pedido:gcloud container clusters upgrade redis-test \ --master \ --cluster-version VERSION
Substitua VERSION pela versão que selecionou na lista no passo anterior.
A atualização do plano de controlo demora vários minutos.
Atualize os nós do cluster para a versão que selecionou e escreva
y
quando lhe for pedido:gcloud container clusters upgrade redis-test \ --cluster-version=VERSION \ --node-pool=default-pool
Substitua VERSION pela versão que selecionou na lista.
Teste a interrupção da carga de trabalho
Nesta secção, testa o estado da sua aplicação e observa a interrupção da carga de trabalho.
Regresse à janela do terminal que está a executar
./print_error_rate.sh
e observe como a taxa de êxito mudou durante a atualização. Deve notar uma ligeira diminuição na taxa de êxito e um ligeiro aumento na taxa de erros da rede de apps à medida que os nós são desativados para serem atualizados.No campo
Success rate
, vê quantas visitas foram feitas com êxito ao Website. Tome nota deste valor.Impeça a execução de ambos os scripts introduzindo
CTRL+C
nos terminais relevantes.Regresse ao Website da sua aplicação introduzindo o respetivo endereço IP (este é o EXTERNAL_IP que copiou durante a secção Implemente a aplicação cliente Redis) no seu navegador.
Observe o número de visitas da sua aplicação. O número que vê deve ser igual a:
ORIGINAL_VISIT_NUMBER + SUCCESSFUL_VISIT_NUMBER
onde ORIGINAL_VISIT_NUMBER é o número que registou no passo final de Implemente a aplicação cliente Redis e SUCCESSFUL_VISIT_NUMBER é o valor que registou no primeiro passo desta secção.