Execute cargas de trabalho de pilha completa em grande escala no GKE


Neste tutorial, mostramos como executar um aplicativo da Web apoiado por um banco de dados relacional altamente disponível em grande escala no Google Kubernetes Engine (GKE).

O aplicativo de amostra usado neste tutorial é o Bank of Anthos, um aplicativo da Web baseado em HTTP que simula a rede de processamento de pagamentos de um banco. O Bank of Anthos usa vários serviços para funcionar. O foco deste tutorial é o front-end do site e os bancos de dados relacionais do PostgreSQL que apoiam os serviços do Banco do Anthos. Para saber mais sobre o Bank of Anthos, incluindo a arquitetura e os serviços implantados, consulte Bank of Anthos no GitHub.

Objetivos

  • Criar e configurar um cluster do GKE.
  • Implantar um aplicativo da Web de exemplo e um banco de dados PostgreSQL altamente disponível.
  • Configurar o escalonamento automático do aplicativo da Web e do banco de dados.
  • Simule picos de tráfego usando um gerador de carga.
  • Observe como os serviços são escalonados verticalmente e reduzidos.

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

  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. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

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

  6. Enable the GKE API:

    gcloud services enable container.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

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

  11. Enable the GKE API:

    gcloud services enable container.googleapis.com
  12. Instale a CLI do Helm (em inglês).

Prepare o ambiente

  1. Clone o repositório de amostra usado neste tutorial:

    git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git
    cd bank-of-anthos/
    
  2. Defina as variáveis de ambiente:

    PROJECT_ID=PROJECT_ID
    GSA_NAME=bank-of-anthos
    GSA_EMAIL=bank-of-anthos@${PROJECT_ID}.iam.gserviceaccount.com
    KSA_NAME=default
    

    Substitua PROJECT_ID pelo ID do projeto do Google Cloud.

Configurar as contas de serviço e cluster

  1. Crie um cluster:

    gcloud container clusters create-auto bank-of-anthos --region=us-central1
    

    O cluster pode levar até cinco minutos para ser iniciado.

  2. Crie uma conta de serviço do IAM:

    gcloud iam service-accounts create bank-of-anthos
    
  3. Revogue o acesso à conta de serviço do IAM:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --role roles/cloudtrace.agent \
      --member "serviceAccount:bank-of-anthos@PROJECT_ID.iam.gserviceaccount.com"
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --role roles/monitoring.metricWriter \
      --member "serviceAccount:bank-of-anthos@PROJECT_ID.iam.gserviceaccount.com"
    gcloud iam service-accounts add-iam-policy-binding "bank-of-anthos@PROJECT_ID.iam.gserviceaccount.com" \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[default/default]"
    

    Esta etapa concede o seguinte acesso:

    • roles/cloudtrace.agent: grava dados de rastreamento, como informações de latência, no Trace.
    • roles/monitoring.metricWriter: grava métricas no Cloud Monitoring.
    • roles/iam.workloadIdentityUser: permite que uma conta de serviço do Kubernetes use a federação da identidade da carga de trabalho do GKE para atuar como a conta de serviço do IAM.
  4. Configure a conta de serviço do Kubernetes default no namespace default para atuar como a conta de serviço do IAM que você criou:

    kubectl annotate serviceaccount default \
        iam.gke.io/gcp-service-account=bank-of-anthos@PROJECT_ID.iam.gserviceaccount.com
    

    Isso permite que os pods que usam a conta de serviço default do Kubernetes no namespace default acessem os mesmos recursos do Google Cloud que a conta de serviço do IAM.

Implante o banco do Anthos e o PostgreSQL

Nesta seção, você instalará o Bank of Anthos e um banco de dados PostgreSQL no modo altamente disponível (HA, na sigla em inglês), que permite escalonar réplicas automaticamente do servidor de banco de dados. Se você quiser ver os scripts, o gráfico Helm e os manifestos do Kubernetes usados nesta seção, verifique o repositório do Bank of Anthos no GitHub.

  1. Implante o esquema do banco de dados e um script de linguagem de definição de dados (DDL, na sigla em inglês):

    kubectl create configmap initdb \
        --from-file=src/accounts/accounts-db/initdb/0-accounts-schema.sql \
        --from-file=src/accounts/accounts-db/initdb/1-load-testdata.sql \
        --from-file=src/ledger/ledger-db/initdb/0_init_tables.sql \
        --from-file=src/ledger/ledger-db/initdb/1_create_transactions.sh
    
  2. Instale o PostgreSQL usando a amostra de gráfico do Helm:

    helm repo add bitnami https://charts.bitnami.com/bitnami
    helm install accounts-db bitnami/postgresql-ha \
        --version 10.0.1 \
        --values extras/postgres-hpa/helm-postgres-ha/values.yaml \
        --set="postgresql.initdbScriptsCM=initdb" \
        --set="postgresql.replicaCount=1" \
        --wait
    

    Este comando cria um cluster do PostgreSQL com uma contagem de réplicas inicial de 1. Mais adiante neste tutorial, você escalonará o cluster com base nas conexões recebidas. Esta operação pode levar dez minutos ou mais para ser concluída.

  3. Implantar o Bank of Anthos:

    kubectl apply -f extras/jwt/jwt-secret.yaml
    kubectl apply -f extras/postgres-hpa/kubernetes-manifests
    

    Essa operação pode levar alguns minutos para ser concluída.

Checkpoint: validar sua configuração

  1. Verifique se todos os pods do Bank of Anthos estão em execução:

    kubectl get pods
    

    O resultado será assim:

    NAME                                  READY   STATUS
    accounts-db-pgpool-57ffc9d685-c7xs8   3/3     Running
    accounts-db-postgresql-0              1/1     Running
    balancereader-57b59769f8-xvp5k        1/1     Running
    contacts-54f59bb669-mgsqc             1/1     Running
    frontend-6f7fdc5b65-h48rs             1/1     Running
    ledgerwriter-cd74db4cd-jdqql          1/1     Running
    pgpool-operator-5f678457cd-cwbhs      1/1     Running
    transactionhistory-5b9b56b5c6-sz9qz   1/1     Running
    userservice-f45b46b49-fj7vm           1/1     Running
    
  2. Verifique se você pode acessar o front-end do site:

    1. Encontre o endereço IP externo do serviço frontend:

      kubectl get ingress frontend
      

      O resultado será assim:

      NAME       CLASS    HOSTS   ADDRESS         PORTS   AGE
      frontend   <none>   *       203.0.113.9     80      12m
      
    2. Em um navegador, acesse o endereço IP externo. A página de login do Bank do Anthos é exibida. Se tiver curiosidade, conheça o aplicativo.

      Se você receber um erro 404, aguarde alguns minutos para que os microsserviços sejam provisionados e tente novamente.

Escalonar automaticamente o app da Web e o banco de dados PostgreSQL

O Autopilot do GKE escalona automaticamente os recursos de computação do cluster com base no número de cargas de trabalho no cluster. Para escalonar automaticamente o número de pods no cluster com base em métricas de recursos, é preciso implementar o escalonamento automático de pods horizontais do Kubernetes. É possível usar as métricas integradas de CPU e memória do Kubernetes ou as métricas personalizadas, como solicitações HTTP por segundo ou a quantidade de instruções SELECT, coletadas do Cloud Monitoring.

Nesta seção, você realizará as ações a seguir:

  1. Configurar o escalonamento automático horizontal de pods para os microsserviços do Bank of Anthos usando métricas integradas e personalizadas.
  2. Simule o carregamento no aplicativo do Bank of Anthos para acionar eventos de escalonamento automático.
  3. Observe como o número de pods e os nós no cluster são ajustados automaticamente em escala vertical de acordo com a carga.

Configurar a coleta de métricas personalizadas

Para ler métricas personalizadas do Monitoring, é necessário implantar o adaptador do adaptador de métricas personalizadas do Stackdriver no cluster.

  1. Implante o adaptador:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter.yaml
    
  2. Configure o adaptador para usar a federação de identidade da carga de trabalho do GKE e obter as métricas:

    1. Configure a conta de serviço do IAM:

      gcloud projects add-iam-policy-binding PROJECT_ID \
          --member "serviceAccount:bank-of-anthos@PROJECT_ID.iam.gserviceaccount.com" \
          --role roles/monitoring.viewer
      gcloud iam service-accounts add-iam-policy-binding bank-of-anthos@PROJECT_ID.iam.gserviceaccount.com \
          --role roles/iam.workloadIdentityUser \
          --member "serviceAccount:PROJECT_ID.svc.id.goog[custom-metrics/custom-metrics-stackdriver-adapter]"
      
    2. Anote a conta de serviço do Kubernetes que o adaptador usa:

      kubectl annotate serviceaccount custom-metrics-stackdriver-adapter \
          --namespace=custom-metrics \
        iam.gke.io/gcp-service-account=bank-of-anthos@PROJECT_ID.iam.gserviceaccount.com
      
    3. Reinicie a implantação do adaptador para propagar as alterações:

      kubectl rollout restart deployment custom-metrics-stackdriver-adapter \
          --namespace=custom-metrics
      

Configurar o escalonamento automático do banco de dados

Ao implantar o Bank of Anthos and PostgreSQL anteriormente neste tutorial, o banco de dados foi implantado como um StatefulSet com uma réplica de leitura/gravação principal para processar todas as instruções SQL recebidas. Nesta seção, você configura o escalonamento automático horizontal de pods para adicionar novas réplicas somente leitura em espera para processar instruções SELECT recebidas. Uma boa maneira de reduzir a carga em cada réplica é distribuir instruções SELECT, que são operações de leitura. A implantação do PostgreSQL inclui uma ferramenta chamada Pgpool-II que possibilita esse balanceamento de carga e melhora a capacidade do sistema.

O PostgreSQL exporta a métrica de instrução SELECT como uma métrica do Prometheus. Você usará um exportador de métricas leve chamado prometheus-to-sd para enviar essas métricas ao Cloud Monitoring em um formato compatível.

  1. Revise o objeto HorizontalPodAutoscaler:

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: accounts-db-postgresql
    spec:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0
          policies:
          - type: Percent
            value: 100
            periodSeconds: 5
          selectPolicy: Max
      scaleTargetRef:
        apiVersion: apps/v1
        kind: StatefulSet
        name: accounts-db-postgresql
      minReplicas: 1
      maxReplicas: 5
      metrics:
      - type: External
        external:
          metric:
            name: custom.googleapis.com|mypgpool|pgpool2_pool_backend_stats_select_cnt
          target:
              type: AverageValue
              averageValue: "15"
    

    Esse manifesto faz o seguinte:

    • Define o número máximo de réplicas durante um escalonamento vertical como 5.
    • Define o número mínimo de durante uma redução de escala como 1.
    • Usa uma métrica externa para tomar decisões de escalonamento. Nesta amostra, a métrica é o número de instruções SELECT. Um evento de escalonamento vertical ocorre se a contagem de instruções SELECT recebida ultrapassar 15.
  2. Aplique o manifesto ao cluster:

    kubectl apply -f extras/postgres-hpa/hpa/postgresql-hpa.yaml
    

Configurar o escalonamento automático para a interface da Web

Em Implantar banco do Anthos e PostgreSQL, você implantou a interface da Web do banco. Quando o número de usuários aumenta, o serviço userservice consome mais recursos de CPU. Nesta seção, você configurará o escalonamento automático horizontal de pods para a implantação userservice quando os pods atuais usarem mais de 60% da CPU solicitada e para a implantação frontend quando o número das solicitações HTTP recebidas para o balanceador de carga é mais de cinco por segundo.

Configurar o escalonamento automático para a implantação de serviço do usuário

  1. Revise o manifesto HorizontalPodAutoscaler da implantação userservice::

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: userservice
    spec:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0
          policies:
            - type: Percent
              value: 100
              periodSeconds: 5
          selectPolicy: Max
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: userservice
      minReplicas: 5
      maxReplicas: 50
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 60
    

    Esse manifesto faz o seguinte:

    • Define o número máximo de réplicas durante um escalonamento vertical como 50.
    • Define o número mínimo de durante uma redução de escala como 5.
    • Usa uma métrica integrada do Kubernetes para tomar decisões de escalonamento. Nesta amostra, a métrica é a utilização da CPU e a utilização de destino é 60%, o que evita o uso excessivo e insuficiente.
  2. Aplique o manifesto ao cluster:

    kubectl apply -f extras/postgres-hpa/hpa/userservice.yaml
    

Configurar o escalonamento automático para a implantação de front-end

  1. Revise o manifesto HorizontalPodAutoscaler da implantação userservice::

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: frontend
    spec:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0
          policies:
            - type: Percent
              value: 100
              periodSeconds: 5
          selectPolicy: Max
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: frontend
      minReplicas: 5
      maxReplicas: 25
      metrics:
        - type: External
          external:
            metric:
              name: loadbalancing.googleapis.com|https|request_count
              selector:
                matchLabels:
                  resource.labels.forwarding_rule_name: FORWARDING_RULE_NAME
            target:
              type: AverageValue
              averageValue: "5"
    

    Esse manifesto usa os seguintes campos:

    • spec.scaleTargetRef: o recurso do Kubernetes a ser escalonado.
    • spec.minReplicas: o número mínimo de réplicas, que é 5 nessa amostra.
    • spec.maxReplicas: o número máximo de réplicas, que é 25 nessa amostra.
    • spec.metrics.*: a métrica a ser usada. Nesta amostra, esse é o número de solicitações HTTP por segundo, que é uma métrica personalizada do Cloud Monitoring fornecida pelo adaptador implantado.
    • spec.metrics.external.metric.selector.matchLabels: o rótulo de recursos específico a ser filtrado ao fazer o escalonamento automático.
  2. Encontre o nome da regra de encaminhamento do balanceador de carga para a implantação frontend:

    export FW_RULE=$(kubectl get ingress frontend -o=jsonpath='{.metadata.annotations.ingress\.kubernetes\.io/forwarding-rule}')
    echo $FW_RULE
    

    O resultado será assim:

    k8s2-fr-j76hrtv4-default-frontend-wvvf7381
    
  3. Adicione a regra de encaminhamento ao manifesto:

    sed -i "s/FORWARDING_RULE_NAME/$FW_RULE/g" "extras/postgres-hpa/hpa/frontend.yaml"
    

    Esse comando substitui FORWARDING_RULE_NAME pela regra de encaminhamento salva.

  4. Aplique o manifesto ao cluster:

    kubectl apply -f extras/postgres-hpa/hpa/frontend.yaml
    

Checkpoint: validar a configuração de escalonamento automático

Verifique o estado dos recursos HorizontalPodAutoscaler:

kubectl get hpa

O resultado será assim:

NAME                     REFERENCE                            TARGETS             MINPODS   MAXPODS   REPLICAS   AGE
accounts-db-postgresql   StatefulSet/accounts-db-postgresql   10905m/15 (avg)     1         5         2          5m2s
contacts                 Deployment/contacts                  1%/70%              1         5         1          11m
frontend                 Deployment/frontend                  <unknown>/5 (avg)   5         25        1          34s
userservice              Deployment/userservice               0%/60%              5         50        5          4m56s

Neste ponto, o aplicativo e o escalonamento automático estão configurados. Agora, o front-end e o banco de dados podem ser escalonados com base nas métricas fornecidas.

Simular carga e observar o escalonamento do GKE

O Bank of Anthos inclui um serviço loadgenerator que permite simular o tráfego para testar o escalonamento do aplicativo sob carga. Nesta seção, você vai implantar o serviço loadgenerator, gerar uma carga e observar o escalonamento resultante.

Implantar o gerador de testes de carga

  1. Crie uma variável de ambiente com o endereço IP do balanceador de carga do Bank of Anthos:

    export LB_IP=$(kubectl get ingress frontend -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo $LB_IP
    

    O resultado será assim:

    203.0.113.9
    
  2. Adicione o endereço IP do balanceador de carga ao manifesto:

    sed -i "s/FRONTEND_IP_ADDRESS/$LB_IP/g" "extras/postgres-hpa/loadgenerator.yaml"
    
  3. Aplique o manifesto ao cluster:

    kubectl apply -f  extras/postgres-hpa/loadgenerator.yaml
    

O gerador de carga começa a adicionar um usuário a cada segundo, até 250 usuários.

Simular carga

Nesta seção, você usa um gerador de carga para simular picos no tráfego e observar o número de réplicas e a escala de nós para acomodar o aumento da carga ao longo do tempo. Depois, encerre o teste e observe a redução da contagem de réplicas e nós em resposta.

  1. Exponha a interface da Web do gerador de carga localmente:

    kubectl port-forward svc/loadgenerator 8080
    

    Se uma mensagem de erro for exibida, tente novamente quando o pod estiver em execução.

  2. Em um navegador, abra a interface da Web do gerador de carga.

    • Se você estiver usando um shell local, abra um navegador e acesse http://127.0.0.1:8080.
    • Se você estiver usando o Cloud Shell, clique em Visualização na Web e, em seguida, clique em Visualizar na porta 8080.
  3. Clique na guia Gráficos para observar o desempenho ao longo do tempo.

  4. Abra uma nova janela do terminal e observe a contagem de réplicas dos seus escalonadores automáticos de pods horizontais:

    kubectl get hpa -w
    

    O número de réplicas aumenta conforme a carga aumenta. O escalonamento pode levar aproximadamente dez minutos.

    NAME                     REFERENCE                            TARGETS          MINPODS   MAXPODS   REPLICAS
    accounts-db-postgresql   StatefulSet/accounts-db-postgresql   8326m/15 (avg)   1         5         5
    contacts                 Deployment/contacts                  51%/70%          1         5         2
    frontend                 Deployment/frontend                  5200m/5 (avg)    5         25        13
    userservice              Deployment/userservice               71%/60%          5         50        17
    
  5. Abra outra janela do terminal e verifique o número de nós no cluster:

    gcloud container clusters list \
        --filter='name=bank-of-anthos' \
        --format='table(name, currentMasterVersion, currentNodeVersion, currentNodeCount)' \
        --region="us-central1"
    
  6. O número de nós aumentou da quantidade inicial de três nós para acomodar as novas réplicas.

  7. Abra a interface do gerador de carga e clique em Parada para finalizar o teste.

  8. Verifique a contagem de réplicas e a contagem de nós novamente e observe como os números são reduzidos com a carga reduzida. A redução da escala pode levar algum tempo, porque a janela de estabilização padrão para réplicas no recurso HorizontalPodAutoscaler do Kubernetes é de cinco minutos. Para mais informações, consulte Janela de estabilização.

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Excluir recursos individuais

O Google Cloud cria recursos, como balanceadores de carga, com base nos objetos do Kubernetes que você cria. Para excluir todos os recursos deste tutorial, faça o seguinte:

  1. Exclua os recursos de amostra do Kubernetes:

    kubectl delete \
        -f extras/postgres-hpa/loadgenerator.yaml \
        -f extras/postgres-hpa/hpa \
        -f extras/postgres-hpa/kubernetes-manifests \
        -f extras/jwt/jwt-secret.yaml \
        -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter.yaml
    
  2. Exclua o banco de dados PostgreSQL:

    helm uninstall accounts-db
    kubectl delete pvc -l "app.kubernetes.io/instance=accounts-db"
    kubectl delete configmaps initdb
    
  3. Exclua o cluster do GKE e a conta de serviço do IAM:

    gcloud iam service-accounts delete "bank-of-anthos@PROJECT_ID.iam.gserviceaccount.com" --quiet
    gcloud container clusters delete "bank-of-anthos" --region="us-central1" --quiet
    

Excluir o projeto

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

A seguir