O Service Mesh (ASM) coleta dados de telemetria de clusters ACK e ACS de forma não intrusiva e gera métricas de serviço baseadas nos quatro sinais dourados: latência, tráfego, erros e saturação. Este tópico explica como configurar um Horizontal Pod Autoscaler (HPA) para dimensionar cargas de trabalho com base nessas métricas do ASM. Essa abordagem vai além do uso de CPU e memória, permitindo o dimensionamento conforme padrões reais de tráfego.
Como funciona
O ASM expõe métricas de serviço (como requisições por segundo) ao Prometheus. O adaptador de métricas personalizadas kube-metrics-adapter registra essas métricas na camada de agregação do Kubernetes e as disponibiliza para os HPAs por meio da API de métricas personalizadas.
Fluxo de ponta a ponta:
O ASM coleta métricas de requisição e as grava no Prometheus.
O kube-metrics-adapter consulta o Prometheus e registra as métricas como métricas externas no Kubernetes.
O HPA consulta a API de métricas externas a cada 30 segundos e ajusta o número de réplicas quando o valor da métrica ultrapassa o limiar.
Para obter a lista completa de métricas geradas pelo ASM, consulte Istio Standard Metrics.
Pré-requisitos
Antes de começar, verifique se você tem:
Um cluster ACK ou ACS. Consulte Criar um cluster gerenciado ACK ou Criar um cluster ACS.
Uma instância do ASM. Consulte Criar uma instância do ASM.
Instâncias do Prometheus e do Grafana implantadas nos clusters. Consulte Usar o Prometheus open source para monitorar um cluster ACK.
Uma instância do Prometheus configurada para monitorar a instância do ASM. Consulte Monitorar instâncias do ASM usando uma instância do Prometheus autogerenciada.
Etapa 1: Ativar o monitoramento do Prometheus para a instância do ASM
Siga as instruções em Coletar métricas para o Managed Service for Prometheus para ativar a coleta de métricas do Prometheus na sua instância do ASM.
Etapa 2: Implantar o adaptador de métricas personalizadas
O adaptador de métricas personalizadas (kube-metrics-adapter) conecta as métricas do Prometheus à API de métricas externas do Kubernetes, permitindo que os HPAs consultem métricas do ASM diretamente.
-
Instale o kube-metrics-adapter no namespace
kube-systemcom o Helm 3. Definaprometheus.urlcomo o endereço interno da instância do Prometheus no cluster. Para obter o código-fonte do chart, consulte kube-metrics-adapter.Parâmetro
Descrição
asm-custom-metricsNome da release do Helm
prometheus.urlEndereço interno da instância do Prometheus no cluster que coleta métricas do ASM
helm -n kube-system install asm-custom-metrics ./kube-metrics-adapter \ --set prometheus.url=http://prometheus.istio-system.svc:9090 -
Verifique se o adaptador está em execução:
-
Confira se o grupo de API
autoscaling/v2betaestá registrado:kubectl api-versions | grep "autoscaling/v2beta"Saída esperada:
autoscaling/v2beta -
Valide se o pod do adaptador está em execução:
kubectl get po -n kube-system | grep metrics-adapterSaída esperada:
asm-custom-metrics-kube-metrics-adapter-85c6d5d865-2**** 1/1 Running 0 19s -
Certifique-se de que a API de métricas externas está disponível (nenhuma métrica registrada ainda):
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .Saída esperada:
{ "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "external.metrics.k8s.io/v1beta1", "resources": [] }
-
Etapa 3: Implantar um aplicativo de exemplo
Esta etapa implanta um aplicativo podinfo e um serviço de teste de carga no namespace test para permitir o acionamento e a observação do dimensionamento automático posteriormente.
Crie o namespace
test. Consulte Gerenciar namespaces e cotas de recursos.Ative a injeção automática de proxy sidecar no namespace
test. Consulte Ativar injeção automática de proxy sidecar.-
Implante o aplicativo podinfo. Crie um arquivo chamado
podinfo.yamlcom o conteúdo a seguir e aplique-o.apiVersion: apps/v1 kind: Deployment metadata: name: podinfo namespace: test labels: app: podinfo spec: minReadySeconds: 5 strategy: rollingUpdate: maxUnavailable: 0 type: RollingUpdate selector: matchLabels: app: podinfo template: metadata: annotations: prometheus.io/scrape: "true" labels: app: podinfo spec: containers: - name: podinfod image: stefanprodan/podinfo:latest imagePullPolicy: IfNotPresent ports: - containerPort: 9898 name: http protocol: TCP command: - ./podinfo - --port=9898 - --level=info livenessProbe: exec: command: - podcli - check - http - localhost:9898/healthz initialDelaySeconds: 5 timeoutSeconds: 5 readinessProbe: exec: command: - podcli - check - http - localhost:9898/readyz initialDelaySeconds: 5 timeoutSeconds: 5 resources: limits: cpu: 2000m memory: 512Mi requests: cpu: 100m memory: 64Mi --- apiVersion: v1 kind: Service metadata: name: podinfo namespace: test labels: app: podinfo spec: type: ClusterIP ports: - name: http port: 9898 targetPort: 9898 protocol: TCP selector: app: podinfokubectl apply -n test -f podinfo.yaml -
Implante o serviço de teste de carga. Crie um arquivo chamado
loadtester.yamlcom o conteúdo a seguir e aplique-o.apiVersion: apps/v1 kind: Deployment metadata: name: loadtester namespace: test labels: app: loadtester spec: selector: matchLabels: app: loadtester template: metadata: labels: app: loadtester annotations: prometheus.io/scrape: "true" spec: containers: - name: loadtester image: weaveworks/flagger-loadtester:0.18.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 command: - ./loadtester - -port=8080 - -log-level=info - -timeout=1h livenessProbe: exec: command: - wget - --quiet - --tries=1 - --timeout=4 - --spider - http://localhost:8080/healthz timeoutSeconds: 5 readinessProbe: exec: command: - wget - --quiet - --tries=1 - --timeout=4 - --spider - http://localhost:8080/healthz timeoutSeconds: 5 resources: limits: memory: "512Mi" cpu: "1000m" requests: memory: "32Mi" cpu: "10m" securityContext: readOnlyRootFilesystem: true runAsUser: 10001 --- apiVersion: v1 kind: Service metadata: name: loadtester namespace: test labels: app: loadtester spec: type: ClusterIP selector: app: loadtester ports: - name: http port: 80 protocol: TCP targetPort: httpkubectl apply -n test -f loadtester.yaml -
Verifique se ambas as cargas de trabalho estão em execução:
kubectl get pod -n testSaída esperada (ambos os pods mostram
2/2 Running, indicando que o contêiner do aplicativo e o sidecar do Istio estão prontos):NAME READY STATUS RESTARTS AGE loadtester-64df4846b9-nxhvv 2/2 Running 0 2m8s podinfo-6d845cc8fc-26xbq 2/2 Running 0 11m -
Envie um pico curto de tráfego para confirmar o funcionamento completo da configuração:
export loadtester=$(kubectl -n test get pod -l "app=loadtester" -o jsonpath='{.items[0].metadata.name}') kubectl -n test exec -it ${loadtester} -c loadtester -- hey -z 5s -c 10 -q 2 http://podinfo.test:9898Uma resposta bem-sucedida do
heyconfirma que o serviço podinfo está acessível pela malha.
Etapa 4: Configurar um HPA usando métricas do ASM
Defina um HPA para dimensionar o deployment do podinfo com base no número de requisições recebidas por segundo, conforme medido pela métrica istio_requests_total no Prometheus.
O HPA utiliza dois constructos do Kubernetes em conjunto:
Uma anotação que incorpora a consulta PromQL e lhe atribui um nome (
processed-requests-per-second).Uma referência de métrica em
spec.metricsque aponta para a consulta nomeada e define o limiar de dimensionamento.
Crie um arquivo chamado hpa.yaml com o conteúdo a seguir e aplique-o:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: podinfo
namespace: test
annotations:
# The annotation key format is:
# metric-config.external.prometheus-query.prometheus/<query-name>
# The query-name must match the value of the matchLabels selector below.
metric-config.external.prometheus-query.prometheus/processed-requests-per-second: |
sum(
rate(
istio_requests_total{
destination_workload="podinfo",
destination_workload_namespace="test",
reporter="destination"
}[1m]
)
)
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
metrics:
- type: External
external:
metric:
name: prometheus-query
selector:
matchLabels:
query-name: processed-requests-per-second # matches the annotation key suffix above
target:
type: AverageValue
averageValue: "10" # scale out when average RPS per replica exceeds 10
kubectl apply -f hpa.yaml
Explicação dos campos principais:
|
Campo |
Valor |
Descrição |
|
Anotação |
Expressão PromQL |
Define a consulta que o kube-metrics-adapter executa no Prometheus. O sufixo |
|
Rótulo |
|
Vincula a anotação (consulta PromQL) à referência de métrica em |
|
|
|
O HPA escala horizontalmente quando a média de requisições por segundo por réplica excede 10. |
|
|
|
Limites inferior e superior para o número de réplicas. |
Após aplicar o HPA, verifique se a métrica externa foi registrada:
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .
Saída esperada:
{
"kind": "APIResourceList",
"apiVersion": "v1",
"groupVersion": "external.metrics.k8s.io/v1beta1",
"resources": [
{
"name": "prometheus-query",
"singularName": "",
"namespaced": true,
"kind": "ExternalMetricValueList",
"verbs": [
"get"
]
}
]
}
A entrada prometheus-query em resources confirma que o kube-metrics-adapter registrou a métrica e que o HPA está ativo.
Verificar o dimensionamento automático
-
Abra um terminal e inicie uma carga sustentada no podinfo (5 minutos, 10 usuários simultâneos, 5 requisições/segundo cada):
kubectl -n test exec -it ${loadtester} -c loadtester -- sh ~ $ hey -z 5m -c 10 -q 5 http://podinfo.test:9898 -
Em outro terminal, acompanhe o aumento de escala do HPA:
Por padrão, as métricas são sincronizadas a cada 30 segundos. O HPA também aplica um período de resfriamento de 3 a 5 minutos entre eventos de dimensionamento para evitar oscilações excessivas.
watch kubectl -n test get hpa/podinfoÀ medida que a carga aumenta acima do limiar, o HPA escala horizontalmente:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE podinfo Deployment/podinfo 8308m/10 (avg) 1 10 6 124mO valor
8308musa a notação de miliunidade do Kubernetes para representar 8,308 requisições por segundo. Como a média de RPS por réplica (8,3) está abaixo do limiar de 10, o HPA estabilizou em 6 réplicas. Se a carga fosse maior, o HPA continuaria escalando até o máximo de 10 réplicas. Ao término do teste de carga, a taxa de requisições cai para zero. O HPA inicia a redução de escala e, em alguns minutos, o número de réplicas retorna a 1.