Configurar la limitación de frecuencia de Google Cloud Armor con Envoy
En esta página se explica cómo configurar la limitación de frecuencia global del lado del servidor para tu malla de servicios mediante Cloud Armor. Puedes usar esta función para aplicar límites de velocidad de uso compartido equitativo a todo el tráfico que llegue a tu servicio, lo que te ayudará a compartir de forma equitativa la capacidad disponible de tus servicios y a mitigar el riesgo de que los clientes maliciosos o con un comportamiento inadecuado sobrecarguen tus servicios. Para obtener más información sobre la limitación de la frecuencia, consulta la introducción a la limitación de la frecuencia.
Configurar Google Kubernetes Engine (GKE) para Envoy
Antes de empezar
Antes de empezar, debes habilitar las siguientes APIs:
container.googleapis.comcompute.googleapis.comtrafficdirector.googleapis.comnetworkservices.googleapis.commeshconfig.googleapis.commonitoring.googleapis.com
Puedes habilitar todas las APIs con el siguiente comando de la CLI de Google Cloud:
gcloud services enable \
container.googleapis.com \
compute.googleapis.com \
trafficdirector.googleapis.com \
networkservices.googleapis.com \
meshconfig.googleapis.com \
monitoring.googleapis.com
A continuación, 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}
Sustituye las siguientes variables por la información de tu proyecto:
- Sustituye
PROJECT_IDpor el ID de tu proyecto. - Sustituye
ZONEpor la zona en la que quieras crear el clúster de GKE. - Sustituye
CLUSTERpor el nombre del clúster. - Sustituye
MESH_NAMEpor el nombre de la malla.
Crear un clúster de GKE
Usa el siguiente comando para crear un clúster de GKE en la zona que has especificado en la sección anterior:
gcloud container clusters create "CLUSTER" \ --zone="ZONE" \ --scopes="cloud-platform" \ --tags="allow-envoy-health-checks" \ --enable-ip-aliasObtén las credenciales de tu nuevo clúster:
gcloud container clusters get-credentials "CLUSTER" \ --zone="ZONE"
Habilitar la inyección automática
Usa el siguiente comando para aplicar el recurso
MutatingWebhookConfigurationa tu clúster. Cuando se crea un pod, se invoca el controlador de admisión del clúster, que indica al inyector de sidecar gestionado que añada el contenedor 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 EOFHabilita la inyección de sidecar para el espacio de nombres predeterminado. El inyector de sidecar inserta contenedores sidecar en 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: 1337Aplica el ejemplo de servicio que has creado 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: 1337Aplica el ejemplo de cliente que has creado en el paso anterior:
kubectl apply -f client_sample.yaml
Configurar Cloud Service Mesh para limitar la frecuencia
Sigue los pasos de esta sección para preparar Cloud Service Mesh para la limitación de velocidad.
Crea la especificación de recursos
Meshy guárdala en un archivo llamadomesh.yaml:name: MESH_NAME interceptionPort: 15001
Crea el recurso
Meshcon la especificación mesh.yaml.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=globalCrea una comprobación del estado:
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-portCrea una regla de cortafuegos para permitir las conexiones de comprobación del 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 tcpCrea un servicio de backend global con un esquema de balanceo de carga
INTERNAL_SELF_MANAGEDy añade la comprobación del estado.gcloud compute backend-services create rate-limit-demo-service \ --global \ --health-checks rate-limit-demo-hc \ --load-balancing-scheme INTERNAL_SELF_MANAGEDAñade el NEG
rate-limit-demo-negal 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 5Crea la especificación
HTTPRoutey 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
HTTPRoutecon la especificación del archivohttp_route.yaml.gcloud network-services http-routes import rate-limit-demo-http-route \ --source=http_route.yaml \ --location=global
Configurar la limitación de frecuencia con Envoy
En las siguientes secciones se explica cómo configurar la limitación de frecuencia por parte del servidor para tu malla de servicios. En la primera sección se explica cómo configurar un límite de frecuencia global del lado del servidor para todos los clientes, y en la segunda, cómo aplicar límites de frecuencia diferentes a distintos grupos de clientes.
Configurar la limitación de frecuencia global del lado del servidor
En este ejemplo, se crea una regla de limitación de frecuencia del lado del servidor que aplica la limitación de frecuencia a todos los clientes.
En un archivo YAML llamado
rate-limit-policy.yaml, crea una política de seguridad de Cloud Armor de 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.yamlEn un archivo YAML, cree una política de endpoint que haga referencia a la política de seguridad que ha creado en el paso anterior. En estos ejemplos, el 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-policyCrea una política de endpoint llamada
rate-limit-ep:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global
Configurar diferentes límites de frecuencia del lado del servidor para distintos grupos de clientes
En este ejemplo, se crean diferentes reglas de limitación de frecuencia del lado del servidor que aplican umbrales de limitación de frecuencia distintos a grupos de clientes.
Crea una política de seguridad de Cloud Armor con el tipo
CLOUD_ARMOR_INTERNAL_SERVICEcon varias reglas de limitación 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 la limitación de frecuencia a las solicitudes que contienen un encabezado HTTP con el nombre
usery el valordemosi Cloud Service Mesh recibe más de 1000 solicitudes de este tipo en un periodo de 60 segundos. 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 periodo 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.yamlCrea una política de endpoint que haga referencia a la política de seguridad que has creado en el paso anterior, como la que se define en el siguiente archivo. En este ejemplo, el 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-policyUsa el siguiente comando para crear una política de endpoint llamada
rate-limit-ep:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=per-client-endpoints-policies.yaml \ --location=global
Validar la configuración
Puedes usar la herramienta de prueba de carga Nighthawk para generar tráfico y comprobar si tus reglas de limitación 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 gestión, consulta Acceder a los registros.
En los resultados de la prueba, verás lo siguiente:
- Se tarda unos cinco minutos en aplicar la limitación de frecuencia.
- Después del periodo de calentamiento inicial, verás entre 15 y 21 QPS en el contador
benchmark.http_2xxde la salida del cliente de Nighthawk. Esto significa que Cloud Armor permite unas 1000 solicitudes por minuto.
Para ver la eficacia de las reglas de tu política de seguridad de Cloud Armor, consulta Ver el panel de monitorización.
Inhabilitar el límite de frecuencia
Puedes inhabilitar la limitación de la frecuencia mediante uno de los siguientes métodos:
- Puedes eliminar las políticas de endpoint y las políticas de seguridad que hayas configurado con tus reglas de limitación de frecuencia.
- Para desvincular la política de seguridad de tu política de endpoints, actualiza esta última para eliminar el campo
securityPolicies.
En las siguientes secciones se explica cómo inhabilitar la limitación de la frecuencia con cada método.
Eliminar una política de endpoint y una política de seguridad
Primero, usa el siguiente comando gcloud para eliminar la política de endpoint llamada rate-limit-ep.
Si has usado el nombre proporcionado en el primer o segundo ejemplo de esta página, la política de endpoint se llamará endpoints-policies o per-client-endpoints-policies, respectivamente.
gcloud beta network-services endpoint-policies delete --location=global rate-limit-ep
A continuación, usa el siguiente comando gcloud para eliminar una política de seguridad. Sustituye per-client-security-policy por el nombre de tu política de seguridad. Si has usado 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 endpoint.
gcloud beta compute security-policies delete --global per-client-security-policy
Desvincular una política de seguridad de tu política de endpoint
Primero, actualiza el 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
A continuación, usa el siguiente comando para actualizar la política de endpoint llamada rate-limit-ep con los cambios del archivo endpoint-policy.yaml:
gcloud beta network-services endpoint-policies import rate-limit-ep \
--source=endpoints-policies.yaml \
--location=global