Service Mesh (ASM) recopila datos de telemetría de los clústeres ACK y ACS de forma no intrusiva. A partir de estos datos genera métricas de servicio basadas en las cuatro señales doradas: latencia, tráfico, errores y saturación. Este tema explica cómo configurar un Horizontal Pod Autoscaler (HPA) que escala las cargas de trabajo según estas métricas de ASM. De este modo, el escalado responde a patrones de tráfico reales y no solo al uso de CPU o memoria.
Funcionamiento
ASM expone las métricas de servicio (como las solicitudes por segundo) a Prometheus. Un adaptador de métricas personalizadas, kube-metrics-adapter, registra estas métricas de Prometheus en la capa de agregación de Kubernetes. Gracias a esto, los HPA pueden consultarlas mediante la API de métricas personalizadas.
El flujo completo es el siguiente:
ASM recopila las métricas de solicitud y las escribe en Prometheus.
kube-metrics-adapter consulta Prometheus y registra las métricas como métricas externas en Kubernetes.
El HPA sondea la API de métricas externas cada 30 segundos y ajusta la cantidad de réplicas cuando el valor de la métrica cruza el umbral.
Para consultar la lista completa de métricas que genera ASM, consulte Istio Standard Metrics.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Un clúster ACK o un clúster ACS. Consulte Create an ACK managed cluster o Create an ACS cluster.
Una instancia de ASM. Consulte Create an ASM instance.
Una instancia de Prometheus y una instancia de Grafana desplegadas en los clústeres. Consulte Use open source Prometheus to monitor an ACK cluster.
Una instancia de Prometheus configurada para monitorear la instancia de ASM. Consulte Monitor ASM instances by using a self-managed Prometheus instance.
Paso 1: Habilitar el monitoreo de Prometheus para la instancia de ASM
Siga las instrucciones de Collect metrics to Managed Service for Prometheus para habilitar la recolección de métricas de Prometheus en su instancia de ASM.
Paso 2: Desplegar el adaptador de métricas personalizadas
El adaptador de métricas personalizadas (kube-metrics-adapter) conecta las métricas de Prometheus con la API de métricas externas de Kubernetes. Así, los HPA consultan las métricas de ASM directamente.
-
Instale kube-metrics-adapter en el namespace
kube-systemmediante Helm 3. Establezcaprometheus.urlcon la dirección interna del clúster de su instancia de Prometheus. Para obtener el origen del chart, consulte kube-metrics-adapter.Parámetro
Descripción
asm-custom-metricsNombre de la versión de Helm
prometheus.urlDirección interna del clúster de la instancia de Prometheus que recopila las métricas de ASM
helm -n kube-system install asm-custom-metrics ./kube-metrics-adapter \ --set prometheus.url=http://prometheus.istio-system.svc:9090 -
Compruebe que el adaptador se está ejecutando:
-
Verifique que el grupo de API
autoscaling/v2betaesté registrado:kubectl api-versions | grep "autoscaling/v2beta"Resultado esperado:
autoscaling/v2beta -
Compruebe que el pod del adaptador se está ejecutando:
kubectl get po -n kube-system | grep metrics-adapterResultado esperado:
asm-custom-metrics-kube-metrics-adapter-85c6d5d865-2**** 1/1 Running 0 19s -
Verifique que la API de métricas externas esté disponible (aún no hay métricas registradas):
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .Resultado esperado:
{ "kind": "APIResourceList", "apiVersion": "v1", "groupVersion": "external.metrics.k8s.io/v1beta1", "resources": [] }
-
Paso 3: Desplegar una aplicación de ejemplo
En este paso se despliega una aplicación podinfo y un servicio de pruebas de carga en el namespace test. Esto le permitirá activar y observar el escalado automático más adelante.
Cree el namespace
test. Consulte Manage namespaces and resource quotas.Habilite la inyección automática del proxy sidecar en el namespace
test. Consulte Enable automatic sidecar proxy injection.-
Despliegue la aplicación podinfo. Cree un archivo llamado
podinfo.yamlcon el contenido a continuación y aplíquelo.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 -
Despliegue el servicio de pruebas de carga. Cree un archivo llamado
loadtester.yamlcon el contenido a continuación y aplíquelo.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 -
Compruebe que ambas cargas de trabajo se estén ejecutando:
kubectl get pod -n testResultado esperado (ambos pods muestran
2/2 Running, lo cual indica que el contenedor de la aplicación y el sidecar de Istio están listos):NAME READY STATUS RESTARTS AGE loadtester-64df4846b9-nxhvv 2/2 Running 0 2m8s podinfo-6d845cc8fc-26xbq 2/2 Running 0 11m -
Envíe una ráfaga breve de tráfico para confirmar que la configuración funciona de extremo a extremo:
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:9898Si
heydevuelve una respuesta exitosa, significa que el servicio podinfo es accesible a través de la malla.
Paso 4: Configurar un HPA con las métricas de ASM
Defina un HPA que escale el despliegue de podinfo según la cantidad de solicitudes entrantes por segundo. Esta medición se obtiene de la métrica istio_requests_total en Prometheus.
El HPA utiliza dos elementos de Kubernetes de manera conjunta:
Una anotación que integra la consulta PromQL y le asigna un nombre (
processed-requests-per-second).Una referencia de métrica en
spec.metricsque apunta a la consulta nombrada y establece el umbral de escalado.
Cree un archivo llamado hpa.yaml con el contenido a continuación y aplíquelo:
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
Explicación de los campos principales:
|
Campo |
Valor |
Descripción |
|
Anotación |
Expresión PromQL |
Define la consulta que kube-metrics-adapter ejecuta contra Prometheus. El sufijo |
|
Etiqueta |
|
Vincula la anotación (la consulta PromQL) con la referencia de métrica en |
|
|
|
El HPA escala horizontalmente cuando el promedio de solicitudes por segundo por réplica supera 10. |
|
|
|
Límites de la cantidad de réplicas. |
Después de aplicar el HPA, compruebe que la métrica externa ya esté registrada:
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq .
Resultado esperado:
{
"kind": "APIResourceList",
"apiVersion": "v1",
"groupVersion": "external.metrics.k8s.io/v1beta1",
"resources": [
{
"name": "prometheus-query",
"singularName": "",
"namespaced": true,
"kind": "ExternalMetricValueList",
"verbs": [
"get"
]
}
]
}
La entrada prometheus-query en resources confirma que kube-metrics-adapter registró la métrica y que el HPA está activo.
Comprobación del escalado automático
-
Abra una terminal e inicie una carga sostenida contra podinfo (5 minutos, 10 usuarios simultáneos y 5 solicitudes por segundo cada uno):
kubectl -n test exec -it ${loadtester} -c loadtester -- sh ~ $ hey -z 5m -c 10 -q 5 http://podinfo.test:9898 -
En otra terminal, observe cómo el HPA escala verticalmente:
De forma predeterminada, las métricas se sincronizan cada 30 segundos. Además, el HPA aplica un periodo de enfriamiento de 3 a 5 minutos entre eventos de escalado para evitar oscilaciones.
watch kubectl -n test get hpa/podinfoCuando la carga supera el umbral, el HPA escala horizontalmente:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE podinfo Deployment/podinfo 8308m/10 (avg) 1 10 6 124mEl valor
8308mcorresponde a la notación de milésimas de Kubernetes y equivale a 8.308 solicitudes por segundo. Como el promedio de solicitudes por segundo por réplica (8.3) está por debajo del umbral de 10, el HPA se estabilizó en 6 réplicas. Si la carga fuera mayor, el HPA seguiría escalando hasta alcanzar el máximo de 10 réplicas. Al terminar la prueba de carga, la tasa de solicitudes cae a cero. El HPA comienza a reducir la escala y, en unos minutos, la cantidad de réplicas vuelve a 1.