Ratenbegrenzung in Google Cloud Armor mit Envoy konfigurieren
Auf dieser Seite wird beschrieben, wie Sie mit Cloud Armor die globale serverseitige Ratenbegrenzung für Ihr Service Mesh konfigurieren. Mit dieser Funktion können Sie für den gesamten Traffic, der bei Ihrem Dienst eingeht, eine Ratenbegrenzung für die faire Nutzung anwenden. So können Sie die verfügbare Kapazität Ihrer Dienste fair aufteilen und das Risiko minimieren, dass böswillige oder fehlerhafte Clients Ihre Dienste überlasten. Weitere Informationen zur Ratenbegrenzung finden Sie in der Übersicht zur Ratenbegrenzung.
Google Kubernetes Engine (GKE) für Envoy konfigurieren
Hinweise
Bevor Sie beginnen, müssen Sie die folgenden APIs aktivieren:
container.googleapis.com
compute.googleapis.com
trafficdirector.googleapis.com
networkservices.googleapis.com
meshconfig.googleapis.com
monitoring.googleapis.com
Sie können alle APIs mit dem folgenden Google Cloud CLI-Befehl aktivieren:
gcloud services enable \ container.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ meshconfig.googleapis.com \ monitoring.googleapis.com
Erstellen Sie dann die Umgebungsvariablen, die in diesem Dokument verwendet werden:
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}
Ersetzen Sie die folgenden Variablen durch Informationen aus Ihrem Projekt:
- Ersetzen Sie
PROJECT_ID
durch Ihre Projekt-ID. - Ersetzen Sie
ZONE
durch die Zone, in der Sie den GKE-Cluster erstellen möchten. - Ersetzen Sie
CLUSTER
durch den Namen des Clusters. - Ersetzen Sie
MESH_NAME
durch den Namen des Mesh.
GKE-Cluster erstellen
Verwenden Sie den folgenden Befehl, um einen GKE-Cluster in der Zone zu erstellen, die Sie im vorherigen Abschnitt angegeben haben:
gcloud container clusters create "CLUSTER" \ --zone="ZONE" \ --scopes="cloud-platform" \ --tags="allow-envoy-health-checks" \ --enable-ip-alias
Rufen Sie die Anmeldedaten für den neuen Cluster ab:
gcloud container clusters get-credentials "CLUSTER" \ --zone="ZONE"
Automatisches Einfügen aktivieren
Wenden Sie die
MutatingWebhookConfiguration
-Ressource mit dem folgenden Befehl auf Ihren Cluster an. Wenn ein Pod erstellt wird, wird der clusterinterne Admission-Controller aufgerufen und weist den verwalteten Sidecar-Injector an, dem Pod den Envoy-Container hinzuzufügen.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
Aktivieren Sie die Sidecar-Injektion für den Standard-Namespace. Der Sidecar-Injektor fügt Sidecar-Container in Pods ein, die unter dem Standard-Namespace erstellt werden.
kubectl label namespace default td-injection=enabled
Speichern Sie die folgende GKE-Konfiguration für Ihren Dienst als
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
Wenden Sie das Dienstbeispiel an, das Sie im vorherigen Schritt erstellt haben:
kubectl apply -f service_sample.yaml
Speichern Sie die folgende GKE-Konfiguration für Ihren Client als
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
Wenden Sie das Clientbeispiel an, das Sie im vorherigen Schritt erstellt haben:
kubectl apply -f client_sample.yaml
Cloud Service Mesh für die Ratenbegrenzung einrichten
Mit den Schritten in diesem Abschnitt bereiten Sie Cloud Service Mesh für die Ratenbegrenzung vor.
Erstellen Sie die Spezifikation der
Mesh
-Ressource und speichern Sie sie in einer Datei mit dem Namenmesh.yaml
:name: MESH_NAME interceptionPort: 15001
Erstellen Sie die
Mesh
-Ressource mit der Spezifikation mesh.yaml.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=global
Erstellen Sie eine Systemdiagnose.
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-port
Erstellen Sie eine Firewallregel, um eingehende Systemdiagnoseverbindungen zu Instanzen in Ihrem Netzwerk zuzulassen.
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
Erstellen Sie einen globalen Backend-Dienst mit dem Load-Balancing-Schema
INTERNAL_SELF_MANAGED
und fügen Sie die Systemdiagnose hinzu.gcloud compute backend-services create rate-limit-demo-service \ --global \ --health-checks rate-limit-demo-hc \ --load-balancing-scheme INTERNAL_SELF_MANAGED
Fügen Sie dem Backend-Dienst die NEG
rate-limit-demo-neg
hinzu.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
Erstellen Sie die Spezifikation
HTTPRoute
und speichern Sie sie in einer Datei mit dem Namenhttp_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"
Erstellen Sie die
HTTPRoute
-Ressource mit der Spezifikation in der Dateihttp_route.yaml
.gcloud network-services http-routes import rate-limit-demo-http-route \ --source=http_route.yaml \ --location=global
Ratenbegrenzung mit Envoy konfigurieren
In den folgenden Abschnitten wird beschrieben, wie Sie die serverseitige Ratenbegrenzung für Ihr Service Mesh konfigurieren. Im ersten Abschnitt wird beschrieben, wie Sie ein globales serverseitiges Ratenlimit für alle Clients festlegen. Im zweiten Abschnitt erfahren Sie, wie Sie unterschiedliche Ratenlimits für verschiedene Clientgruppen erzwingen.
Serverseitige globale Ratenbegrenzung konfigurieren
In diesem Beispiel erstellen Sie eine serverseitige Ratenbegrenzungsregel, die die Ratenbegrenzung für alle Clients erzwingt.
Erstellen Sie in einer YAML-Datei mit dem Namen
rate-limit-policy.yaml
eine Cloud Armor-Sicherheitsrichtlinie mit dem TypCLOUD_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"
Erstellen Sie die Sicherheitsrichtlinie mit dem Namen
rate-limit-policy
:gcloud beta compute security-policies create rate-limit-policy \ --global \ --file-name=rate-limit-policy.yaml
Erstellen Sie in einer YAML-Datei eine Endpunktrichtlinie, die auf die Sicherheitsrichtlinie verweist, die Sie im vorherigen Schritt erstellt haben. In diesen Beispielen heißt die Datei
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
Erstellen Sie eine Endpunktrichtlinie mit dem Namen
rate-limit-ep
:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global
Unterschiedliche serverseitige Ratenbegrenzungen für verschiedene Clientgruppen konfigurieren
In diesem Beispiel erstellen Sie verschiedene serverseitige Ratenbegrenzungsregeln, mit denen unterschiedliche Ratenbegrenzungsschwellen für Gruppen von Clients erzwungen werden.
Erstellen Sie eine Cloud Armor-Sicherheitsrichtlinie vom Typ
CLOUD_ARMOR_INTERNAL_SERVICE
mit mehreren Ratenbegrenzungsregeln, wie in der folgenden Datei definiert. In diesen Beispielen heißt die Dateiper-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"
Diese Richtlinie wendet die Ratenbegrenzung auf Anfragen an, die einen HTTP-Header mit dem Namen
user
und dem Wertdemo
enthalten, wenn Cloud Service Mesh innerhalb von 60 Sekunden mehr als 1.000 solcher Anfragen empfängt. Anfragen ohne diesen HTTP-Header werden stattdessen ratenbeschränkt,wenn Cloud Service Mesh innerhalb von 60 Sekunden mehr als 10.000 solcher Anfragen empfängt.Verwenden Sie den folgenden Befehl, um die Richtlinie mit dem Namen
per-client-security-policy
zu erstellen:gcloud beta compute security-policies create per-client-security-policy \ --global \ --file-name=per-client-security-policy.yaml
Erstellen Sie eine Endpunktrichtlinie, die auf die Sicherheitsrichtlinie verweist, die Sie im vorherigen Schritt erstellt haben, z. B. die in der folgenden Datei definierte. In diesem Beispiel heißt die Datei
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
Verwenden Sie den folgenden Befehl, um eine Endpunktrichtlinie mit dem Namen
rate-limit-ep
zu erstellen:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=per-client-endpoints-policies.yaml \ --location=global
Einrichtung validieren
Mit dem Nighthawk-Tool für Lasttests können Sie Traffic generieren, um zu prüfen, ob Ihre Ratenbegrenzungsregeln wie erwartet funktionieren. Verwenden Sie den folgenden Befehl, um mit Nighthawk Traffic zu generieren:
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
Aktivieren Sie als Nächstes mit dem folgenden Befehl die Envoy-Debug-Logs:
kubectl exec -it deploy/app1 -c app1 -- wget -q -O - \ --post-data="" 'http://localhost:15000/logging?level=debug'
Informationen zum Aufrufen der Nutzungsberichte, die Envoy an den Verwaltungsserver sendet, finden Sie unter Auf Logs zugreifen.
Die Testergebnisse liefern folgende Informationen:
- Es dauert etwa fünf Minuten, bis die Ratenbegrenzung wirksam wird.
- Nach der anfänglichen Aufwärmphase sehen Sie etwa 15–21 QPS in der Nighthawk-Clientausgabe
benchmark.http_2xx
. Das bedeutet,dass Cloud Armor etwa 1.000 Anfragen pro Minute zulässt.
Informationen dazu, wie Sie die Effektivität Ihrer Cloud Armor-Sicherheitsrichtlinienregeln ansehen, finden Sie unter Monitoring-Dashboard ansehen.
Ratenbegrenzung deaktivieren
Sie können die Ratenbegrenzung mit einer der folgenden Methoden deaktivieren:
- Sie können die Endpunktrichtlinien und Sicherheitsrichtlinien löschen, die Sie mit Ihren Ratenbegrenzungsregeln konfiguriert haben.
- Sie können die Sicherheitsrichtlinie von Ihrer Endpunktrichtlinie trennen, indem Sie die Endpunktrichtlinie aktualisieren und das Feld
securityPolicies
entfernen.
In den folgenden Abschnitten wird beschrieben, wie Sie die Ratenbegrenzung mit den einzelnen Methoden deaktivieren.
Endpunktrichtlinie und Sicherheitsrichtlinie löschen
Verwenden Sie zuerst den folgenden gcloud
-Befehl, um die Endpunktrichtlinie mit dem Namen rate-limit-ep
zu löschen.
Wenn Sie den Namen aus dem ersten oder zweiten Beispiel auf dieser Seite verwendet haben, heißt die Endpunktrichtlinie endpoints-policies
bzw. per-client-endpoints-policies
.
gcloud beta network-services endpoint-policies delete --location=global rate-limit-ep
Verwenden Sie dann den folgenden gcloud
-Befehl, um eine Sicherheitsrichtlinie zu löschen. Ersetzen Sie dabei per-client-security-policy
durch den Namen Ihrer Sicherheitsrichtlinie. Wenn Sie den Namen aus dem ersten oder zweiten Beispiel auf dieser Seite verwendet haben, hat Ihre Sicherheitsrichtlinie denselben Namen wie Ihre Endpunktrichtlinie.
gcloud beta compute security-policies delete --global per-client-security-policy
Sicherheitsrichtlinie von Ihrer Endpunktrichtlinie trennen
Aktualisieren Sie zuerst die Datei endpoint-policy.yaml
, um das Feld securityPolcies
zu entfernen:
name: "rate-limit-ep" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: rate-limit-demo type: SIDECAR_PROXY
Verwenden Sie dann den folgenden Befehl, um die Endpunktrichtlinie mit dem Namen rate-limit-ep
mit den Änderungen an der Datei endpoint-policy.yaml
zu aktualisieren:
gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global