Otimize a escala automática de pods com base em métricas


Este tutorial demonstra como dimensionar automaticamente as suas cargas de trabalho do Google Kubernetes Engine (GKE) com base nas métricas disponíveis no Cloud Monitoring.

Neste tutorial, pode configurar o ajuste automático com base numa das seguintes métricas:

Pub/Sub

Atraso do Pub/Sub

Escale com base numa métrica externa que comunique o número de mensagens não reconhecidas restantes numa subscrição do Pub/Sub. Isto pode reduzir eficazmente a latência antes de se tornar um problema, mas pode usar relativamente mais recursos do que o dimensionamento automático com base na utilização da CPU.

Métrica personalizada

Métrica Prometheus personalizada

Escalar com base numa métrica personalizada definida pelo utilizador, exportada no formato Prometheus através do Prometheus gerido pela Google. A sua métrica do Prometheus tem de ser do tipo Gauge.

O dimensionamento automático consiste fundamentalmente em encontrar um equilíbrio aceitável entre o custo e a latência. Pode experimentar uma combinação destas métricas e de outras para encontrar uma política que funcione para si.

Objetivos

Este tutorial abrange as seguintes tarefas:

  1. Como implementar o adaptador de métricas personalizadas.
  2. Como exportar métricas a partir do código da sua aplicação.
  3. Como ver as suas métricas na interface do Cloud Monitoring.
  4. Como implementar um recurso HorizontalPodAutoscaler (HPA) para dimensionar a sua aplicação com base nas métricas do Cloud Monitoring.

Custos

Neste documento, usa os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custos com base na sua utilização projetada, use a calculadora de preços.

Os novos Google Cloud utilizadores podem ser elegíveis para uma avaliação gratuita.

Quando terminar as tarefas descritas neste documento, pode evitar a faturação contínua eliminando os recursos que criou. Para mais informações, consulte o artigo Limpe.

Antes de começar

Siga os passos abaixo para ativar a API Kubernetes Engine:
  1. Visite a página do Kubernetes Engine na Google Cloud consola.
  2. Crie ou selecione um projeto.
  3. Aguarde até que a API e os serviços relacionados sejam ativados. Esta ação pode demorar vários minutos.
  4. Verify that billing is enabled for your Google Cloud project.

Pode seguir este tutorial através da Cloud Shell, que vem pré-instalada com as ferramentas de linha de comandos gcloud e kubectl usadas neste tutorial. Se usar o Cloud Shell, não precisa de instalar estas ferramentas de linha de comandos na sua estação de trabalho.

Para usar o Cloud Shell:

  1. Aceda à Google Cloud consola.
  2. Clique no botão Ativar Cloud Shell Ativar botão Shell na parte superior da janela da Google Cloud consola.

    É aberta uma sessão do Cloud Shell num novo frame na parte inferior da Google Cloud consola e é apresentado um comando.

    Sessão do Cloud Shell

Configurar o seu ambiente

  1. Defina a zona predefinida para a CLI gcloud:

    gcloud config set compute/zone zone
    

    Substitua o seguinte:

    • zone: escolha uma zona mais próxima de si. Para mais informações, consulte o artigo Regiões e zonas.
  2. Defina as variáveis de ambiente PROJECT_ID e PROJECT_NUMBER para o seu Google Cloud ID do projeto e número do projeto:

    export PROJECT_ID=project-id
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)')
    
  3. Defina a zona predefinida para a CLI gcloud:

    gcloud config set project $PROJECT_ID
    
  4. Crie um cluster do GKE

    Prática recomendada:

    Para maior segurança ao aceder aos Google Cloud serviços, ative a federação de identidade da carga de trabalho para o GKE no seu cluster. Embora esta página inclua exemplos que usam o método antigo (com a Workload Identity Federation para o GKE desativada), a sua ativação melhora a proteção.

    Workload Identity

    Para criar um cluster com a federação de identidade da carga de trabalho para o GKE ativada, execute o seguinte comando:

    gcloud container clusters create metrics-autoscaling --workload-pool=$PROJECT_ID.svc.id.goog
    

    Autenticação antiga

    Para criar um cluster com a federação de identidade da carga de trabalho para o GKE desativada, execute o seguinte comando:

    gcloud container clusters create metrics-autoscaling
    

Implementar o adaptador de métricas personalizadas

O adaptador de métricas personalizadas permite que o cluster envie e receba métricas com o Cloud Monitoring.

Pub/Sub

O procedimento de instalação do adaptador de métricas personalizadas difere para clusters com ou sem a Workload Identity Federation para o GKE ativada. Selecione a opção correspondente à configuração que escolheu quando criou o cluster.

Workload Identity

Conceda ao utilizador a capacidade de criar funções de autorização necessárias:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

Implemente o adaptador de métricas personalizadas no cluster:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

O adaptador usa a conta de serviço do Kubernetes no espaço de nomes custom-metrics.custom-metrics-stackdriver-adapter Permita que esta conta de serviço leia as métricas do Cloud Monitoring atribuindo a função de Leitor de monitorização:

gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
  --role roles/monitoring.viewer \
  --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter

Autenticação antiga

Conceda ao utilizador a capacidade de criar funções de autorização necessárias:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

Implemente o adaptador de métricas personalizadas no cluster:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

Métrica personalizada

O procedimento de instalação do adaptador de métricas personalizadas difere para clusters com ou sem a Workload Identity Federation para o GKE ativada. Selecione a opção correspondente à configuração que escolheu quando criou o cluster.

Workload Identity

Conceda ao utilizador a capacidade de criar funções de autorização necessárias:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

Implemente o adaptador de métricas personalizadas no cluster:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

O adaptador usa a conta de serviço do Kubernetes no espaço de nomes custom-metrics.custom-metrics-stackdriver-adapter Permita que esta conta de serviço leia as métricas do Cloud Monitoring atribuindo a função de Leitor de monitorização:

gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
  --role roles/monitoring.viewer \
  --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter

Autenticação antiga

Conceda ao utilizador a capacidade de criar funções de autorização necessárias:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

Implemente o adaptador de métricas personalizadas no cluster:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml

Implementar uma aplicação com métricas

Transfira o repositório que contém o código da aplicação para este tutorial:

Pub/Sub

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
cd kubernetes-engine-samples/databases/cloud-pubsub

Métrica personalizada

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
cd kubernetes-engine-samples/observability/custom-metrics-autoscaling/google-managed-prometheus

O repositório contém código que exporta métricas para o Cloud Monitoring:

Pub/Sub

Esta aplicação consulta uma subscrição do Pub/Sub para novas mensagens, confirmando-as à medida que chegam. As métricas de subscrição do Pub/Sub são recolhidas automaticamente pelo Cloud Monitoring.

from google import auth
from google.cloud import pubsub_v1


def main():
    """Continuously pull messages from subsciption"""

    # read default project ID
    _, project_id = auth.default()
    subscription_id = 'echo-read'

    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(
        project_id, subscription_id)

    def callback(message: pubsub_v1.subscriber.message.Message) -> None:
        """Process received message"""
        print(f"Received message: ID={message.message_id} Data={message.data}")
        print(f"[{datetime.datetime.now()}] Processing: {message.message_id}")
        time.sleep(3)
        print(f"[{datetime.datetime.now()}] Processed: {message.message_id}")
        message.ack()

    streaming_pull_future = subscriber.subscribe(
        subscription_path, callback=callback)
    print(f"Pulling messages from {subscription_path}...")

    with subscriber:
        try:
            streaming_pull_future.result()
        except Exception as e:
            print(e)

Métrica personalizada

Esta aplicação responde a qualquer pedido Web para o caminho /metrics com uma métrica de valor constante usando o formato Prometheus.

metric := prometheus.NewGauge(
	prometheus.GaugeOpts{
		Name: *metricName,
		Help: "Custom metric",
	},
)
prometheus.MustRegister(metric)
metric.Set(float64(*metricValue))

http.Handle("/metrics", promhttp.Handler())
log.Printf("Starting to listen on :%d", *port)
err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)

O repositório também contém um manifesto do Kubernetes para implementar a aplicação no seu cluster. Uma implementação é um objeto da API Kubernetes que lhe permite executar várias réplicas de pods distribuídas entre os nós num cluster:

Pub/Sub

O manifesto difere para clusters com ou sem a Workload Identity Federation para o GKE ativada. Selecione a opção correspondente à configuração escolhida quando criou o cluster.

Workload Identity

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      serviceAccountName: pubsub-sa
      containers:
      - name: subscriber
        image: us-docker.pkg.dev/google-samples/containers/gke/pubsub-sample:v2

Autenticação antiga

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      volumes:
      - name: google-cloud-key
        secret:
          secretName: pubsub-key
      containers:
      - name: subscriber
        image: us-docker.pkg.dev/google-samples/containers/gke/pubsub-sample:v2
        volumeMounts:
        - name: google-cloud-key
          mountPath: /var/secrets/google
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /var/secrets/google/key.json

Métrica personalizada

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: custom-metrics-gmp
  name: custom-metrics-gmp
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      run: custom-metrics-gmp
  template:
    metadata:
      labels:
        run: custom-metrics-gmp
    spec:
      containers:
      # sample container generating custom metrics
      - name: prometheus-dummy-exporter
        image: us-docker.pkg.dev/google-samples/containers/gke/prometheus-dummy-exporter:v0.2.0
        command: ["./prometheus-dummy-exporter"]
        args:
        - --metric-name=custom_prometheus
        - --metric-value=40
        - --port=8080

Com o recurso PodMonitoring, o Google Cloud Managed Service for Prometheus exporta as métricas do Prometheus para o Cloud Monitoring:

apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  name: "custom-metrics-exporter"
spec:
  selector:
    matchLabels:
      run: custom-metrics-gmp
  endpoints:
  - port: 8080
    path: /metrics
    interval: 15s

A partir da versão 1.27 do GKE Standard ou da versão 1.25 do GKE Autopilot, o Google Cloud Managed Service for Prometheus está ativado. Para ativar o Google Cloud Managed Service for Prometheus em clusters de versões anteriores, consulte o artigo Ative a recolha gerida.

Implemente a aplicação no cluster:

Pub/Sub

O procedimento para implementar a sua aplicação difere para clusters com ou sem a Workload Identity Federation para o GKE ativada. Selecione a opção correspondente à configuração que escolheu quando criou o cluster.

Workload Identity

  1. Ative a API Pub/Sub no seu projeto:

    gcloud services enable cloudresourcemanager.googleapis.com pubsub.googleapis.com
    
  2. Crie um tópico e uma subscrição do Pub/Sub:

    gcloud pubsub topics create echo
    gcloud pubsub subscriptions create echo-read --topic=echo
    
  3. Implemente a aplicação no cluster:

    kubectl apply -f deployment/pubsub-with-workload-identity.yaml
    
  4. Esta aplicação define uma pubsub-sa conta de serviço do Kubernetes. Atribua-lhe a função de subscritor do Pub/Sub para que a aplicação possa publicar mensagens no tópico do Pub/Sub.

    gcloud projects add-iam-policy-binding projects/$PROJECT_ID \
      --role=roles/pubsub.subscriber \
      --member=principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/default/sa/pubsub-sa
    

    O comando anterior usa um identificador principal, que permite ao IAM referir-se diretamente a uma conta de serviço do Kubernetes.

    Prática recomendada:

    Use identificadores principais, mas considere a limitação na descrição de um método alternativo.

Autenticação antiga

  1. Ative a API Pub/Sub no seu projeto:

    gcloud services enable cloudresourcemanager.googleapis.com pubsub.googleapis.com
    
  2. Crie um tópico e uma subscrição do Pub/Sub:

    gcloud pubsub topics create echo
    gcloud pubsub subscriptions create echo-read --topic=echo
    
  3. Crie uma conta de serviço com acesso ao Pub/Sub:

    gcloud iam service-accounts create autoscaling-pubsub-sa
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member "serviceAccount:autoscaling-pubsub-sa@$PROJECT_ID.iam.gserviceaccount.com" \
      --role "roles/pubsub.subscriber"
    
  4. Transfira o ficheiro da chave da conta de serviço:

    gcloud iam service-accounts keys create key.json \
      --iam-account autoscaling-pubsub-sa@$PROJECT_ID.iam.gserviceaccount.com
    
  5. Importe a chave de conta de serviço para o cluster como um segredo:

    kubectl create secret generic pubsub-key --from-file=key.json=./key.json
    
  6. Implemente a aplicação no cluster:

    kubectl apply -f deployment/pubsub-with-secret.yaml
    

Métrica personalizada

kubectl apply -f custom-metrics-gmp.yaml

Depois de aguardar um momento para que a aplicação seja implementada, todos os pods atingem o estado Ready:

Pub/Sub

kubectl get pods

Saída:

NAME                     READY   STATUS    RESTARTS   AGE
pubsub-8cd995d7c-bdhqz   1/1     Running   0          58s

Métrica personalizada

kubectl get pods

Saída:

NAME                                  READY   STATUS    RESTARTS   AGE
custom-metrics-gmp-865dffdff9-x2cg9   1/1     Running   0          49s

Visualizar métricas no Cloud Monitoring

À medida que a aplicação é executada, escreve as suas métricas no Cloud Monitoring.

Para ver as métricas de um recurso monitorizado através do Metrics Explorer, faça o seguinte:

  1. Na Google Cloud consola, aceda à página  Explorador de métricas:

    Aceda ao Metrics Explorer

    Se usar a barra de pesquisa para encontrar esta página, selecione o resultado cujo subtítulo é Monitorização.

  2. No elemento Métrica, expanda o menu Selecionar uma métrica e, de seguida, selecione um tipo de recurso e um tipo de métrica. Por exemplo, para criar um gráfico da utilização da CPU de uma máquina virtual, faça o seguinte:
    1. (Opcional) Para reduzir as opções do menu, introduza parte do nome da métrica na barra de filtros. Para este exemplo, introduza utilization.
    2. No menu Recursos ativos, selecione Instância de VM.
    3. No menu Categorias de métricas ativas, selecione Instância.
    4. No menu Métricas ativas, selecione Utilização da CPU e, de seguida, clique em Aplicar.
  3. Para filtrar as séries cronológicas apresentadas, use o elemento Filtro.

  4. Para combinar séries cronológicas, use os menus no elemento Agregação. Por exemplo, para apresentar a utilização da CPU das suas VMs, com base na respetiva zona, defina o primeiro menu como Média e o segundo menu como zona.

    Todas as séries cronológicas são apresentadas quando o primeiro menu do elemento Agregação está definido como Não agregado. As predefinições do elemento Agregação são determinadas pelo tipo de métrica que selecionou.

O tipo de recurso e as métricas são os seguintes:

Pub/Sub

Explorador de métricas

Tipo de recurso: pubsub_subscription

Métrica: pubsub.googleapis.com/subscription/num_undelivered_messages

Métrica personalizada

Explorador de métricas

Tipo de recurso: prometheus_target

Métrica: prometheus.googleapis.com/custom_prometheus/gauge

Consoante a métrica, pode ainda não ver muita atividade no Explorador de métricas do Cloud Monitoring. Não se surpreenda se a sua métrica não estiver a ser atualizada.

Criar um objeto HorizontalPodAutoscaler

Quando vir a sua métrica no Cloud Monitoring, pode implementar um HorizontalPodAutoscaler para redimensionar a sua implementação com base na métrica.

Pub/Sub

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: pubsub
spec:
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - external:
      metric:
       name: pubsub.googleapis.com|subscription|num_undelivered_messages
       selector:
         matchLabels:
           resource.labels.subscription_id: echo-read
      target:
        type: AverageValue
        averageValue: 2
    type: External
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: pubsub

Métrica personalizada

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: custom-metrics-gmp-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: custom-metrics-gmp
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Pods
    pods:
      metric:
        name: prometheus.googleapis.com|custom_prometheus|gauge
      target:
        type: AverageValue
        averageValue: 20

Implemente o HorizontalPodAutoscaler no seu cluster:

Pub/Sub

kubectl apply -f deployment/pubsub-hpa.yaml

Métrica personalizada

kubectl apply -f custom-metrics-gmp-hpa.yaml

A gerar carga

Para algumas métricas, pode ter de gerar carga para observar o ajuste de escala automático:

Pub/Sub

Publicar 200 mensagens no tópico Pub/Sub:

for i in {1..200}; do gcloud pubsub topics publish echo --message="Autoscaling #${i}"; done

Métrica personalizada

Não aplicável: o código usado nesta amostra exporta um valor constante de 40 para a métrica personalizada. O HorizontalPodAutoscaler está definido com um valor de destino de 20, pelo que tenta aumentar a escala da implementação automaticamente.

Pode ter de aguardar alguns minutos para que o HorizontalPodAutoscaler responda às alterações das métricas.

Observar o aumento da escala do HorizontalPodAutoscaler

Pode verificar o número atual de réplicas da sua implementação executando o seguinte comando:

kubectl get deployments

Depois de dar algum tempo para a métrica se propagar, a implementação cria cinco pods para processar o backlog.

Também pode inspecionar o estado e a atividade recente do HorizontalPodAutoscaler executando o seguinte comando:

kubectl describe hpa

Limpar

Para evitar incorrer em custos na sua conta do Google Cloud pelos recursos usados neste tutorial, elimine o projeto que contém os recursos ou mantenha o projeto e elimine os recursos individuais.

Pub/Sub

  1. Limpe a subscrição e o tópico do Pub/Sub:

    gcloud pubsub subscriptions delete echo-read
    gcloud pubsub topics delete echo
    
  2. Elimine o cluster do GKE:

    gcloud container clusters delete metrics-autoscaling
    

Métrica personalizada

Elimine o cluster do GKE:

 gcloud container clusters delete metrics-autoscaling

O que se segue?