Configura el límite de frecuencia de Google Cloud Armor con Envoy
En esta página, se muestra cómo configurar un límite de frecuencia global del servidor para tu malla de servicios con Cloud Armor. Puedes usar esta función para aplicar la límite de frecuencia de uso compartido equitativo a todo el tráfico que llega a tu servicio, lo que te ayudará a compartir de manera equitativa la capacidad disponible de tus servicios y mitigar el riesgo de que los clientes maliciosos o con comportamiento inadecuado sobrecarguen tus servicios. Para obtener más información sobre el límite de frecuencia, consulta la descripción general del límite de frecuencia.
Configura Google Kubernetes Engine (GKE) para Envoy
Antes de comenzar
Antes de comenzar, debes habilitar las siguientes APIs:
container.googleapis.com
compute.googleapis.com
trafficdirector.googleapis.com
networkservices.googleapis.com
meshconfig.googleapis.com
monitoring.googleapis.com
Puedes habilitar todas las APIs con el siguiente comando de Google Cloud CLI:
gcloud services enable \ container.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ meshconfig.googleapis.com \ monitoring.googleapis.com
Luego, crea las variables de entorno que se usan en este documento:
export PROJECT_ID=PROJECT_ID export PROJECT_NUMBER="$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")" export CLUSTER=CLUSTER export ZONE=ZONE export MESH_NAME=MESH_NAME export MESH_URI=projects/${PROJECT_NUMBER}/locations/global/meshes/${MESH_NAME}
Reemplaza las siguientes variables por la información de tu proyecto:
- Reemplaza
PROJECT_ID
por el ID de tu proyecto. - Reemplaza
ZONE
por la zona en la que deseas crear tu clúster de GKE. - Reemplaza
CLUSTER
por el nombre del clúster. - Reemplaza
MESH_NAME
por el nombre de la malla.
Crea un clúster de GKE
Usa el siguiente comando para crear un clúster de GKE en la zona que especificaste en la sección anterior:
gcloud container clusters create "CLUSTER" \ --zone="ZONE" \ --scopes="cloud-platform" \ --tags="allow-envoy-health-checks" \ --enable-ip-alias
Obtén las credenciales de tu clúster nuevo:
gcloud container clusters get-credentials "CLUSTER" \ --zone="ZONE"
Habilita la inserción automática
Usa el siguiente comando para aplicar el recurso
MutatingWebhookConfiguration
a tu clúster. Cuando se crea un Pod, se invoca el controlador de admisión en el clúster, que le indica al inyector de sidecar administrado que agregue el contenedor de Envoy al Pod.cat <<EOF | kubectl apply -f - apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: labels: app: sidecar-injector name: td-mutating-webhook webhooks: - admissionReviewVersions: - v1beta1 - v1 clientConfig: url: https://meshconfig.googleapis.com/v1internal/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER/channels/rapid/targets/${MESH_URI}:tdInject failurePolicy: Fail matchPolicy: Exact name: namespace.sidecar-injector.csm.io namespaceSelector: matchExpressions: - key: td-injection operator: Exists reinvocationPolicy: Never rules: - apiGroups: - "" apiVersions: - v1 operations: - CREATE resources: - pods scope: '*' sideEffects: None timeoutSeconds: 30 EOF
Habilita la inserción de sidecar para el espacio de nombres predeterminado. El inyector de sidecar inserta contenedores de sidecar para los Pods creados en el espacio de nombres predeterminado.
kubectl label namespace default td-injection=enabled
Guarda la siguiente configuración de GKE para tu servicio como
service_sample.yaml
.apiVersion: v1 kind: Service metadata: name: service-test annotations: cloud.google.com/neg: '{"exposed_ports":{"80":{"name": "rate-limit-demo-neg"}}}' spec: ports: - port: 80 name: service-test targetPort: 8000 selector: run: app1 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: app1 labels: run: app1 spec: replicas: 1 selector: matchLabels: run: app1 template: metadata: labels: run: app1 annotations: cloud.google.com/proxyMetadata: '{"app": "rate-limit-demo"}' cloud.google.com/includeInboundPorts: "8000" cloud.google.com/sidecarProxyVersion: "1.34.1-gke.1" spec: containers: - image: mendhak/http-https-echo:37 name: app1 ports: - containerPort: 8000 env: - name: VALIDATION_NONCE value: "http" - name: HTTP_PORT value: "8000" securityContext: fsGroup: 1337
Aplica la muestra de servicio que creaste en el paso anterior:
kubectl apply -f service_sample.yaml
Guarda la siguiente configuración de GKE para tu cliente como
client_sample.yaml
:apiVersion: apps/v1 kind: Deployment metadata: labels: run: client name: load-generator spec: replicas: 1 selector: matchLabels: run: client template: metadata: labels: run: client spec: containers: - name: load-generator image: envoyproxy/nighthawk-dev command: ["/bin/sh", "-c"] args: ["echo 'Nighthawk client pod is running' && sleep infinity"] resources: requests: cpu: 200m memory: 256Mi limits: cpu: 1 memory: 512Mi securityContext: fsGroup: 1337
Aplica la muestra del cliente que creaste en el paso anterior:
kubectl apply -f client_sample.yaml
Configura Cloud Service Mesh para el límite de frecuencia
Sigue los pasos de esta sección para preparar Cloud Service Mesh para la limitación de frecuencia.
Crea la especificación de recursos
Mesh
y guárdala en un archivo llamadomesh.yaml
:name: MESH_NAME interceptionPort: 15001
Crea el recurso
Mesh
con la especificación mesh.yaml.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=global
Crea una verificación de estado de la siguiente forma:
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-port
Crea una regla de firewall que permita las conexiones de verificación de estado entrantes a las instancias de tu red.
gcloud compute firewall-rules create rate-limit-demo-fw-allow-hc \ --action ALLOW \ --direction INGRESS \ --source-ranges 35.191.0.0/16,130.211.0.0/22 \ --target-tags allow-envoy-health-checks \ --rules tcp
Crea un servicio de backend global con un esquema de balanceo de cargas de
INTERNAL_SELF_MANAGED
y agrega la verificación de estado.gcloud compute backend-services create rate-limit-demo-service \ --global \ --health-checks rate-limit-demo-hc \ --load-balancing-scheme INTERNAL_SELF_MANAGED
Agrega el NEG
rate-limit-demo-neg
al servicio de backend.gcloud compute backend-services add-backend rate-limit-demo-service \ --global \ --network-endpoint-group rate-limit-demo-neg \ --network-endpoint-group-zone "ZONE" \ --balancing-mode RATE \ --max-rate-per-endpoint 5
Crea la especificación
HTTPRoute
y guárdala en un archivo llamadohttp_route.yaml
:name: rate-limit-demo-http-route hostnames: - service-test - service-test:80 meshes: - projects/PROJECT_ID/locations/global/meshes/MESH_NAME rules: - action: destinations: - serviceName: "projects/PROJECT_ID/locations/global/backendServices/rate-limit-demo-service"
Crea el recurso
HTTPRoute
con la especificación del archivohttp_route.yaml
.gcloud network-services http-routes import rate-limit-demo-http-route \ --source=http_route.yaml \ --location=global
Configura el límite de frecuencia con Envoy
En las siguientes secciones, se explica cómo configurar la limitación de frecuencia del servidor para tu malla de servicios. En la primera sección, se muestra cómo configurar un límite de frecuencia global del servidor para todos los clientes, y en la segunda, se explica cómo aplicar diferentes límites de frecuencia para diferentes grupos de clientes.
Configura la limitación global de frecuencia del servidor
En este ejemplo, crearás una regla de límite de frecuencia del servidor que aplique la límite de frecuencia a todos los clientes.
En un archivo YAML llamado
rate-limit-policy.yaml
, crea una política de seguridad de Cloud Armor con el tipoCLOUD_ARMOR_INTERNAL_SERVICE
.name: "rate-limit-policy" type: CLOUD_ARMOR_INTERNAL_SERVICE rules: - priority: 2147483647 match: config: srcIpRanges: ["*"] versionedExpr: SRC_IPS_V1 action: "fairshare" rateLimitOptions: rateLimitThreshold: count: 10000 intervalSec: 60 exceedAction: "deny(429)" conformAction: "allow" enforceOnKey: "ALL"
Crea la política de seguridad llamada
rate-limit-policy
:gcloud beta compute security-policies create rate-limit-policy \ --global \ --file-name=rate-limit-policy.yaml
En un archivo YAML, crea una política de extremos que haga referencia a la política de seguridad que creaste en el paso anterior. En estos ejemplos, este archivo se llama
endpoints-policies.yaml
.name: "rate-limit-ep" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: rate-limit-demo type: SIDECAR_PROXY securityPolicy: projects/PROJECT_ID/locations/global/securityPolicies/rate-limit-policy
Crea una política para el extremo llamada
rate-limit-ep
:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global
Configura diferentes límites de frecuencia del servidor para diferentes grupos de clientes
En este ejemplo, crearás diferentes reglas de límite de frecuencia del servidor que apliquen diferentes umbrales de límite de frecuencia para grupos de clientes.
Crea una política de seguridad de Cloud Armor con el tipo
CLOUD_ARMOR_INTERNAL_SERVICE
y varias reglas de límite de frecuencia, como la que se define en el siguiente archivo. En estos ejemplos, este archivo se llamaper-client-security-policy.yaml
.name: "per-client-security-policy" type: CLOUD_ARMOR_INTERNAL_SERVICE rules: - priority: 0 match: expr: expression: "request.headers['user'] == 'demo'" action: "fairshare" rateLimitOptions: rateLimitThreshold: count: 1000 intervalSec: 60 exceedAction: "deny(429)" conformAction: "allow" enforceOnKey: "ALL" - priority: 2147483647 match: config: srcIpRanges: ["*"] versionedExpr: SRC_IPS_V1 action: "fairshare" rateLimitOptions: rateLimitThreshold: count: 10000 intervalSec: 60 exceedAction: "deny(429)" conformAction: "allow" enforceOnKey: "ALL"
Esta política aplica un límite de frecuencia a las solicitudes que contienen un encabezado HTTP con el nombre
user
y el valordemo
si Cloud Service Mesh recibe más de 1,000 solicitudes de este tipo en un período de 60 segundos. En cambio, las solicitudes que no tienen este encabezado HTTP se limitan si Cloud Service Mesh recibe más de 10,000 solicitudes de este tipo en un período de 60 segundos.Usa el siguiente comando para crear la política, que se llama
per-client-security-policy
:gcloud beta compute security-policies create per-client-security-policy \ --global \ --file-name=per-client-security-policy.yaml
Crea una política de extremos que haga referencia a la política de seguridad que creaste en el paso anterior, como la que se define en el siguiente archivo. En este ejemplo, este archivo se llama
per-client-endpoints-policies.yaml
.name: "rate-limit-ep" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: rate-limit-demo type: SIDECAR_PROXY securityPolicy: projects/PROJECT_ID/locations/global/securityPolicies/per-client-security-policy
Usa el siguiente comando para crear una política de extremos llamada
rate-limit-ep
:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=per-client-endpoints-policies.yaml \ --location=global
Valida tu configuración
Puedes usar la herramienta de prueba de carga Nighthawk para generar tráfico y probar si tus reglas de límite de frecuencia funcionan como esperas. Usa el siguiente comando para generar tráfico con Nighthawk:
kubectl exec -it deploy/load-generator -c load-generator -- \ nighthawk_client http://service-test \ --open-loop --no-default-failure-predicates \ --rps 60 \ --duration 360 \ --connections 10 \ --protocol http1 \ --request-header user:demo
A continuación, usa el siguiente comando para habilitar los registros de depuración de Envoy:
kubectl exec -it deploy/app1 -c app1 -- wget -q -O - \ --post-data="" 'http://localhost:15000/logging?level=debug'
Para ver los informes de uso que Envoy envía al servidor de administración, consulta Cómo acceder a tus registros.
En los resultados de la prueba, verás lo siguiente:
- El límite de frecuencia tarda aproximadamente cinco minutos en surtir efecto.
- Después del período de calentamiento inicial, verás entre 15 y 21 QPS en el contador
benchmark.http_2xx
del cliente de Nighthawk. Esto significa que Cloud Armor permite alrededor de 1,000 solicitudes por minuto.
Para ver la eficacia de las reglas de tu política de seguridad de Cloud Armor, consulta Cómo ver el panel de supervisión.
Inhabilita el límite de frecuencia
Puedes inhabilitar el límite de frecuencia con cualquiera de los siguientes métodos:
- Puedes borrar las políticas de endpoint y las políticas de seguridad que configuraste con tus reglas de límite de frecuencia.
- Puedes separar la política de seguridad de tu política de extremos actualizando esta última para quitar el campo
securityPolicies
.
En las siguientes secciones, se explica cómo inhabilitar la límite de frecuencia con cada método.
Borra una política de extremos y una política de seguridad
Primero, usa el siguiente comando gcloud
para borrar tu política de extremo llamada rate-limit-ep
.
Si usaste el nombre proporcionado en el primer o segundo ejemplo de esta página, la política de extremo se llama endpoints-policies
o per-client-endpoints-policies
, respectivamente.
gcloud beta network-services endpoint-policies delete --location=global rate-limit-ep
Luego, usa el siguiente comando gcloud
para borrar una política de seguridad y reemplaza per-client-security-policy
por el nombre de tu política de seguridad. Si usaste el nombre proporcionado en el primer o segundo ejemplo de esta página, tu política de seguridad tendrá el mismo nombre que tu política de extremos.
gcloud beta compute security-policies delete --global per-client-security-policy
Desconecta una política de seguridad de tu política de extremo
Primero, actualiza tu archivo endpoint-policy.yaml
para quitar el campo securityPolcies
:
name: "rate-limit-ep" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: rate-limit-demo type: SIDECAR_PROXY
Luego, usa el siguiente comando para actualizar la política de extremos llamada rate-limit-ep
con los cambios en el archivo endpoint-policy.yaml
:
gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global