Implantar um cluster do Redis no GKE


Neste tutorial, apresentamos as práticas recomendadas para criar um aplicativo com estado e fazer upgrade do cluster do Google Kubernetes Engine (GKE) que executa o aplicativo. Neste tutorial, usamos o Redis como exemplo de implantação de um aplicativo com estado, mas os mesmos conceitos se aplicam a outros tipos de aplicativos com estado implantados no GKE.

Objetivos

Este tutorial inclui as etapas a seguir:

  1. Crie um cluster do GKE inscrito em um canal de lançamento.
  2. Crie um cluster do Redis no GKE.
  3. Implante o aplicativo cliente Redis no GKE.
  4. Execute estas práticas recomendadas para upgrades do pool de nós:
    1. Configure o Orçamento de interrupção de pod (PDB).
    2. Configure a janela de manutenção e exclusões.
    3. Configure a estratégia de upgrade de nós para upgrade súbito ou upgrade azul-verde.
  5. Testar o aplicativo.
  6. Faça upgrade do cluster.
  7. Teste a interrupção da carga de trabalho.

O diagrama a seguir mostra uma visualização de alto nível da arquitetura de cluster para este tutorial:

Diagrama da arquitetura

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

Crie o projeto

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the GKE API.

    Enable the API

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the GKE API.

    Enable the API

Definir padrões para a Google Cloud CLI

  1. No console do Google Cloud, inicie uma instância do Cloud Shell:
    Abrir o Cloud Shell

  2. Faça o download do código-fonte para este app de amostra:

     git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
     cd kubernetes-engine-samples/quickstarts/hello-app-redis/manifests
    
  3. Defina as variáveis de ambiente padrão:

     gcloud config set project PROJECT-ID
     gcloud config set compute/zone COMPUTE-ZONE
    

    Substitua os seguintes valores:

Criar um cluster do GKE inscrito em um canal de lançamento

Para criar o cluster do GKE, siga estas etapas:

  1. Crie um cluster chamado redis-test com três nós:

    gcloud container clusters create redis-test \
        --num-nodes=3 \
        --release-channel regular
    

    Depois que o cluster for criado, você verá uma saída 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
    
  2. Configure kubectl para se comunicar com o cluster:

    gcloud container clusters get-credentials redis-test
    

Criar um cluster do Redis no GKE

Nesta seção, você adiciona um cluster do Redis sobre o cluster do GKE criado anteriormente, implantando um ConfigMap , StatefulSet , eserviço headless.

Para criar um cluster do Redis, siga estas etapas:

  1. Consulte o arquivo ConfigMap (redis-configmap.yaml), que armazena a configuração do Redis. O snippet abaixo mostra a sondagem de prontidão e os scripts de sondagem de atividade.

    readiness.sh: |-
      #!/bin/sh
    
      pingResponse="$(redis-cli -h localhost ping)"
      if [ "$?" -eq "124" ]; then
        echo "PING timed out"
        exit 1
      fi
    
      if [ "$pingResponse" != "PONG"]; then
        echo "$pingResponse"
        exit 1
      fi
    liveness.sh: |-
      #!/bin/sh
    
      pingResponse="$(redis-cli -h localhost ping | head -n1 | awk '{print $1;}')"
      if [ "$?" -eq "124" ]; then
        echo "PING timed out"
        exit 1
      fi
    
      if [ "$pingResponse" != "PONG"] && [ "$pingResponse" != "LOADING" ] && [ "$pingResponse" != "MASTERDOWN" ]; then
        echo "$pingResponse"
        exit 1
      fi

    Os scripts readiness.sh e liveness.sh usam ping redis-cli para verificar se o servidor redis está em execução ou não. Se retornar PONG, o servidor Redis está em execução. Esses scripts serão usados em redis-cluster.yaml.

    Para saber mais sobre os parâmetros do Redis neste ConfigMap, consulte a seção de parâmetros de configuração do cluster do Redis no tutorial do cluster do Redis (em inglês).

  2. Implante o ConfigMap:

    kubectl apply -f redis-configmap.yaml
    
  3. Consulte o snippet StatefulSet (redis-cluster.yaml) abaixo, que mostra o uso da sondagem de prontidão e da sondagem de atividade.

    Para saber como configurar sondagens no Kubernetes, consulte Configurar sondagens.

    startupProbe:
      periodSeconds: 5
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 20
      tcpSocket:
        port: redis
    livenessProbe:
      periodSeconds: 5
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 5
      exec:
        command: ["sh", "-c", "/probes/liveness.sh"]
    readinessProbe:
      periodSeconds: 5
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 5
      exec:
        command: ["sh", "-c", "/probes/readiness.sh"]

    Recomendamos que você use sondagens de prontidão e atividade ao fazer upgrade dos pools de nós. Isso garante que seus pods estejam prontos durante um upgrade.

  4. Implante o StatefulSet:

    kubectl apply -f redis-cluster.yaml
    
  5. O serviço headless chamado redis-service.yaml é para a conexão dos nós do Redis. O campo clusterIP é definido como None para criar um serviço headless.

    Implante o serviço:

    kubectl apply -f redis-service.yaml
    
  6. Aguarde cerca de dois minutos e verifique se todos os pods estão em execução usando o seguinte comando:

    kubectl get pods
    

    Você 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
    
  7. Verifique se os volumes permanentes foram criados executando o seguinte comando:

    kubectl get pv
    

    Você 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
    

    Nessa saída, HASH representa um hash anexado a cada nome de volume permanente.

Atribuir papéis ao cluster do Redis

Quando a configuração estiver concluída, atribua papéis ao cluster do Redis.

O script a seguir busca os endereços IP do pod e, em seguida, atribui os papéis de líder e seguidor transmitindo cada um dos endereços IP do pod ao comando:

#!/bin/bash
# Usage: ./roles.sh

urls=$(kubectl get pods -l app=redis -o jsonpath='{range.items[*]}{.status.podIP} ')
command="kubectl exec -it redis-0 -- redis-cli --cluster create --cluster-replicas 1 "

for url in $urls
do
    command+=$url":6379 "
done

echo "Executing command: " $command
$command

Para atribuir papéis ao cluster do Redis, siga estas etapas:

  1. Execute o script:

    chmod +x ./roles.sh
    ./roles.sh
    
  2. Digite yes quando solicitado.

  3. Faça login em um nó do Redis para verificar o papel dele. Por exemplo, para verificar se redis-0 tem um papel de líder, execute o seguinte comando:

    kubectl exec -it redis-0 -- redis-cli role
    

    O resultado será semelhante a:

    1) "master"
    2) (integer) 574
    3) 1) 1) "10.28.2.3"
           2) "6379"
           3) "574"
    

Implante o aplicativo cliente Redis

Para implantar o aplicativo no cluster do GKE que você criou, defina uma implantação para o aplicativo. O arquivo chamado app-deployment.yaml contém a definição de implantação do aplicativo.

Para saber mais sobre as sondagens e as regras de afinidade de pod usadas nesta implantação, consulte Práticas recomendadas do GKE: como projetar e criar clusters altamente disponíveis (em inglês).

Para criar a implantação, conclua as etapas a seguir:

  1. Aplique a implantação:

    kubectl apply -f app-deployment.yaml
    
  2. Exponha o aplicativo por meio de um balanceador de carga:

    kubectl expose deployment hello-web \
        --type=LoadBalancer \
        --port 80 \
        --target-port 8080
    
  3. Aguarde cerca de um minuto e recupere o endereço IP externo do aplicativo executando o seguinte comando:

    kubectl get service
    

    Na saída, copie o valor listado 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
    
  4. Para verificar se o aplicativo está funcionando, cole EXTERNAL_IP no navegador da Web. O resultado será semelhante a:

    I have been hit [1] times since deployment!
    

    Anote o número da visita. Você precisa usá-lo na seção Como testar a interrupção do aplicativo.

  5. Defina uma variável para o EXTERNAL_IP que você acabou de copiar. Use esse valor quando criar scripts para testar o aplicativo na próxima seção:

    export IP=EXTERNAL_IP
    

Configurar práticas recomendadas para upgrades do pool de nós

Siga estas práticas recomendadas para aplicativos com estado que otimizam a disponibilidade durante os upgrades do pool de nós.

Configurar o orçamento de interrupção de pod (PDB)

Crie um orçamento de interrupção de pod para limitar o número de pods replicados que ficam desativados simultaneamente durante uma interrupção voluntária. Isso é útil para aplicativos com estado em que é preciso que haja um quórum para que o número de réplicas fique disponível durante um upgrade.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: redis-pdb
spec:
  minAvailable: 3
  selector:
    matchLabels:
      app: redis

Em uma definição de PDB:

  • app especifica a que aplicativo esse PDB se aplica.
  • minAvailable define o número mínimo de pods disponíveis durante uma interrupção. Pode ser um valor ou uma porcentagem (por exemplo, 30%).
  • maxUnavailable define o número máximo de pods que podem ficar indisponíveis durante uma interrupção. Também pode ser um valor ou um percentual.

Para configurar o PDB, siga estas etapas:

  1. Implante o PDB:

    kubectl apply -f pdb-minavailable.yaml
    
  2. Verifique se o PDB foi criado:

    kubectl get pdb
    

Configurar as janelas e exclusões de manutenção

Os upgrades automáticos de nós simplificam o processo de upgrade e mantêm os nós atualizados no cluster quando o plano de controle é atualizado em seu nome. Esse recurso é ativado por padrão. Para saber mais, consulte Como fazer o upgrade automático dos nós.

Use janelas e exclusões de manutenção para configurar períodos e controlar quando a manutenção pode ou não ocorrer nos clusters do GKE:

  1. Configure uma janela de manutenção que comece às 2h UTC em 19 de agosto de 2022 e termine quatro horas depois. Essa janela de manutenção é executada diariamente. Durante esse período, a manutenção automática é permitida.

    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
    
  2. Configurar uma janela de exclusão que impeça a manutenção durante o feriado de Ano Novo. Esta exclusão de manutenção usa o escopo no_upgrades. Durante esse período, nenhum tipo de manutenção automática é permitido. Para saber mais, consulte Escopo da manutenção a ser excluída.

    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
    
  3. Verifique se a janela de manutenção e as exclusões estão aplicadas. Procure abaixo de maintenancePolicy:

    gcloud container clusters describe redis-test
    

Para saber mais, consulte Configurar janelas e exclusões de manutenção.

Configurar uma estratégia de upgrade de nó

Há duas estratégias de upgrade de nós que podem ser usadas para os pools de nós no cluster do GKE: upgrades azul-verde e upgrades súbitos. Para saber mais, consulte Estratégias de upgrade de nós.

Upgrades azuis-verdes

Escolha upgrades azul-verde se as cargas de trabalho forem menos tolerantes a interrupções e um aumento temporário do custo devido ao maior uso de recursos for aceitável.

Execute o comando a seguir para alterar os pools de nós atuais para a estratégia de upgrade azul-verde.

gcloud container node-pools update default-pool \
--cluster=redis-test \
--enable-blue-green-upgrade \
--zone COMPUTE-ZONE \
--node-pool-soak-duration=120s

A duração do pool de nós é definida como dois minutos para economizar tempo durante a fase de pool de nós para fins deste tutorial. Essa fase é usada para verificar a integridade da carga de trabalho depois que os nós do pool azul forem drenados. Recomendamos configurar a duração da drenagem do pool de nós para uma hora (3.600 segundos) ou uma duração mais adequada ao aplicativo.

Para mais informações sobre como gerenciar a alocação de pods, consulte Implantar um pod em um pool de nós específico e Como implantar serviços em pools de nós específicos.

Para saber mais sobre a configuração dos upgrades azul-verde, consulte Configurar upgrades azul-verde.

Upgrades de sobretensão

Escolha upgrades súbitos se a otimização de custos for importante e se as cargas de trabalho puderem tolerar um encerramento otimizado em menos de 60 minutos (o GKE respeita o PDB até 60 minutos).

Execute o comando a seguir para alterar os pools de nós atuais para a estratégia de upgrade súbito.

gcloud container node-pools update default-pool \
--max-surge-upgrade=1 \
--max-unavailable-upgrade=0 \
--cluster=redis-test

Com essa configuração (maxSurge=1 e maxUnavailable=0), apenas um nó súbito pode ser adicionado ao pool de nós durante um upgrade, para que apenas um nó possa ser atualizado por vez. Essa configuração acelera as reinicializações do pod durante os upgrades e avança de maneira moderada.

Para saber mais sobre a configuração do upgrade, acesse Configurar o upgrade súbito.

Verifique a configuração atual do pool de nós:

   gcloud container node-pools describe default-pool \
   --cluster redis-test \
   --zone COMPUTE-ZONE

Para ver mais informações sobre a visualização de pools de nós, consulte Ver pools de nós em um cluster.

Testar o aplicativo

Nesta seção, você usa dois scripts, um que envia solicitações ao aplicativo e outro que mede a taxa de sucesso das solicitações. Eles são usados para medir o que acontece quando você faz upgrade do cluster.

Para criar os scripts:

  1. Acesse o diretório que contém os scripts:

    cd
    cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts
    
  2. Consulte o script chamado generate_load.sh, que envia uma solicitação de consulta por segundo (QPS, na sigla em inglês) ao aplicativo. O script salva o código de resposta HTTP no diretório atual em um arquivo chamado output. O valor de output é usado no script que você criará na próxima etapa.

    #!/bin/bash
    # Usage: ./generate_load.sh <IP> <QPS>
    
    IP=$1
    QPS=$2
    
    while true
      do for N in $(seq 1 $QPS)
        do curl -I -m 5 -s -w "%{http_code}\n" -o /dev/null http://${IP}/ >> output &
        done
      sleep 1
    done
  3. Consulte o script chamado print_error_rate.sh, que calcula a taxa de sucesso com base na saída gerada por generate_load.sh.

    #!/bin/bash
    # Usage: watch ./print_error_rate.sh
    
    TOTAL=$(cat output | wc -l);
    SUCCESS=$(grep "200" output |  wc -l);
    ERROR1=$(grep "000" output |  wc -l)
    ERROR2=$(grep "503" output |  wc -l)
    ERROR3=$(grep "500" output |  wc -l)
    SUCCESS_RATE=$(($SUCCESS * 100 / TOTAL))
    ERROR_RATE=$(($ERROR1 * 100 / TOTAL))
    ERROR_RATE_2=$(($ERROR2 * 100 / TOTAL))
    ERROR_RATE_3=$(($ERROR3 * 100 / TOTAL))
    echo "Success rate: $SUCCESS/$TOTAL (${SUCCESS_RATE}%)"
    echo "App network Error rate: $ERROR1/$TOTAL (${ERROR_RATE}%)"
    echo "Resource Error rate: $ERROR2/$TOTAL (${ERROR_RATE_2}%)"
    echo "Redis Error rate: $ERROR3/$TOTAL (${ERROR_RATE_3}%)"
  4. Dê a si mesmo a permissão para executar os scripts:

    chmod u+x generate_load.sh print_error_rate.sh
    
  5. Defina uma variável para o número de QPS. Esse valor é usado no script generate_load.sh como a variável definida para EXTERNAL_IP. Recomendamos que você defina um valor de 40.

    export QPS=40
    
  6. Execute o script generate_load.sh para começar a enviar QPS:

    ./generate_load.sh $IP $QPS 2>&1
    
  7. Deixe o script generate_load.sh em execução e abra um novo terminal. No novo terminal, execute o script print_error_rate.sh para verificar a taxa de erros:

    cd
    cd kubernetes-engine-samples/quickstarts/hello-app-redis/scripts
    watch ./print_error_rate.sh
    

    Você verá uma taxa de sucesso de 100% e taxas de erro de 0% durante a realização de QPS.

  8. Deixe os dois scripts em execução e abra um terceiro terminal a fim de se preparar para a próxima seção.

Fazer upgrade do cluster

Para fazer upgrade do cluster, siga estas etapas:

  1. Determine a versão do GKE que o cluster redis-test está usando:

    V=$(gcloud container clusters describe redis-test | grep "version:" | sed "s/version: //")
    echo $V
    

    Você verá uma saída semelhante ao seguinte exemplo: 1.22.9-gke.2000.

  2. Recupere uma lista de versões disponíveis do Kubernetes:

    gcloud container get-server-config
    
  3. Na lista de versões, localize a seção validMasterVersions: e procure a versão redis-test recuperada na etapa anterior. Para evitar violar a política de distorção de versão do GKE escolhendo uma versão incompatível com os nós, copie a versão da lista listada imediatamente antes da versão redis-test.

  4. Faça upgrade do plano de controle do cluster para a versão selecionada e digite y quando solicitado:

    gcloud container clusters upgrade redis-test \
        --master \
        --cluster-version VERSION
    

    Substitua VERSION pela versão selecionada na lista na etapa anterior.

    O upgrade do plano de controle leva vários minutos.

  5. Faça upgrade dos nós do cluster para a versão selecionada e digite y quando solicitado:

    gcloud container clusters upgrade redis-test \
        --cluster-version=VERSION \
        --node-pool=default-pool
    

    Substitua VERSION pela versão selecionada na lista.

Testar a interrupção da carga de trabalho

Nesta seção, você testará o status do seu aplicativo e observará a interrupção da carga de trabalho.

  1. Retorne à janela do terminal executando ./print_error_rate.sh e observe como a taxa de sucesso mudou durante o upgrade. Você observará uma ligeira redução na taxa de sucesso e um pequeno aumento na taxa de erros de rede do app, já que os nós são reduzidos para o upgrade.

    No campo Success rate, você verá quantas visitas foram feitas ao site. Anote esse valor.

  2. Para interromper a execução de ambos os scripts, insira CTRL+C nos terminais relevantes.

  3. Retorne ao site do seu aplicativo digitando o endereço IP dele (este é o EXTERNAL_IP que você copiou durante a seção Implantar o aplicativo cliente Redis) no seu navegador.

  4. Observe o número de visitas do aplicativo. O número exibido precisa ser igual a:

    ORIGINAL_VISIT_NUMBER + SUCCESSFUL_VISIT_NUMBER

    em que ORIGINAL_VISIT_NUMBER é o número que você registrou na etapa final de Implantar o aplicativo cliente Redis e SUCCESSFUL_VISIT_NUMBER é o valor registrado na primeira etapa desta seção.

Limpar

Depois de concluir o tutorial, você pode limpar os recursos que criou para que eles parem de usar a cota e gerar cobranças. Nas seções a seguir, você aprenderá a excluir e desativar esses recursos.

Exclua o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto, faça o seguinte:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Exclua o cluster

Para excluir o cluster criado neste tutorial, execute o seguinte comando:

gcloud container clusters delete redis-test

A seguir