Configurer la limitation du débit Google Cloud Armor avec Envoy
Cette page vous explique comment configurer une limitation du débit côté serveur globale pour votre service mesh à l'aide de Cloud Armor. Vous pouvez utiliser cette fonctionnalité pour appliquer une limitation du débit de partage équitable à tout le trafic arrivant à votre service. Cela vous permet de partager équitablement la capacité disponible de vos services et d'atténuer le risque de surcharge de vos services par des clients malveillants ou au comportement inapproprié. Pour en savoir plus sur la limitation du débit, consultez la présentation de la limitation du débit.
Configurer Google Kubernetes Engine (GKE) pour Envoy
Avant de commencer
Avant de commencer, vous devez activer les API suivantes :
container.googleapis.com
compute.googleapis.com
trafficdirector.googleapis.com
networkservices.googleapis.com
meshconfig.googleapis.com
monitoring.googleapis.com
Vous pouvez activer toutes les API à l'aide de la commande Google Cloud CLI suivante :
gcloud services enable \ container.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ meshconfig.googleapis.com \ monitoring.googleapis.com
Créez ensuite les variables d'environnement utilisées dans ce document :
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}
Remplacez les variables suivantes par les informations de votre projet :
- Remplacez
PROJECT_ID
par l'ID de votre projet. - Remplacez
ZONE
par la zone dans laquelle vous souhaitez créer votre cluster GKE. - Remplacez
CLUSTER
par le nom du cluster. - Remplacez
MESH_NAME
par le nom du maillage.
Créer un cluster GKE
Utilisez la commande suivante pour créer un cluster GKE dans la zone que vous avez spécifiée dans la section précédente :
gcloud container clusters create "CLUSTER" \ --zone="ZONE" \ --scopes="cloud-platform" \ --tags="allow-envoy-health-checks" \ --enable-ip-alias
Obtenez les identifiants de votre nouveau cluster :
gcloud container clusters get-credentials "CLUSTER" \ --zone="ZONE"
Activer l'injection automatique
Exécutez la commande suivante pour appliquer la ressource
MutatingWebhookConfiguration
à votre cluster. Lorsqu'un pod est créé, le contrôleur d'admission du cluster est appelé et indique à l'injecteur de side-car géré d'ajouter le conteneur Envoy au 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
Activez l'injection side-car pour l'espace de noms par défaut. L'injecteur de side-car injecte des conteneurs side-car pour les pods créés sous l'espace de noms par défaut.
kubectl label namespace default td-injection=enabled
Enregistrez la configuration GKE suivante pour votre service sous le nom
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
Appliquez l'exemple de service que vous avez créé à l'étape précédente :
kubectl apply -f service_sample.yaml
Enregistrez la configuration GKE suivante pour votre client sous le nom
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
Appliquez l'exemple de client que vous avez créé à l'étape précédente :
kubectl apply -f client_sample.yaml
Configurer Cloud Service Mesh pour la limitation du débit
Suivez les étapes de cette section pour préparer Cloud Service Mesh à la limitation du débit.
Créez la spécification de ressource
Mesh
et enregistrez-la dans un fichier nommémesh.yaml
:name: MESH_NAME interceptionPort: 15001
Créez la ressource
Mesh
à l'aide de la spécification mesh.yaml.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=global
Créez une vérification d'état :
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-port
Créez une règle de pare-feu pour autoriser les connexions de vérification d'état entrantes aux instances de votre réseau.
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
Créez un service de backend global avec un schéma d'équilibrage de charge
INTERNAL_SELF_MANAGED
et ajoutez la vérification de l'état.gcloud compute backend-services create rate-limit-demo-service \ --global \ --health-checks rate-limit-demo-hc \ --load-balancing-scheme INTERNAL_SELF_MANAGED
Ajoutez le NEG
rate-limit-demo-neg
au service 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
Créez la spécification
HTTPRoute
et enregistrez-la dans un fichier nomméhttp_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"
Créez la ressource
HTTPRoute
à l'aide de la spécification du fichierhttp_route.yaml
.gcloud network-services http-routes import rate-limit-demo-http-route \ --source=http_route.yaml \ --location=global
Configurer la limitation du débit avec Envoy
Les sections suivantes expliquent comment configurer la limitation du débit côté serveur pour votre maillage de services. La première section vous explique comment configurer une limite de fréquence globale côté serveur pour tous les clients, et la deuxième section vous explique comment appliquer différentes limites de fréquence pour différents groupes de clients.
Configurer la limitation globale du débit côté serveur
Dans cet exemple, vous allez créer une règle de limitation du débit côté serveur qui s'applique à tous les clients.
Dans un fichier YAML nommé
rate-limit-policy.yaml
, créez une règle de sécurité Cloud Armor avec le typeCLOUD_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"
Créez la stratégie de sécurité appelée
rate-limit-policy
:gcloud beta compute security-policies create rate-limit-policy \ --global \ --file-name=rate-limit-policy.yaml
Dans un fichier YAML, créez une règle de point de terminaison qui fait référence à la règle de sécurité que vous avez créée à l'étape précédente. Dans ces exemples, ce fichier est appelé
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
Créez une règle de point de terminaison nommée
rate-limit-ep
:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global
Configurer différentes limites de fréquence côté serveur pour différents groupes de clients
Dans cet exemple, vous allez créer différentes règles de limitation du débit côté serveur qui appliquent différents seuils de limitation du débit pour des groupes de clients.
Créez une stratégie de sécurité Cloud Armor avec le type
CLOUD_ARMOR_INTERNAL_SERVICE
et plusieurs règles de limitation du débit, comme celle définie dans le fichier suivant. Dans ces exemples, ce fichier est appeléper-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"
Cette règle applique une limitation du débit aux requêtes contenant un en-tête HTTP avec le nom
user
et la valeurdemo
si Cloud Service Mesh reçoit plus de 1 000 requêtes de ce type dans un intervalle de 60 secondes. Les requêtes qui ne comportent pas cet en-tête HTTP sont en revanche limitées en débit si Cloud Service Mesh reçoit plus de 10 000 requêtes de ce type au cours d'une période de 60 secondes.Exécutez la commande suivante pour créer la règle, qui est appelée
per-client-security-policy
:gcloud beta compute security-policies create per-client-security-policy \ --global \ --file-name=per-client-security-policy.yaml
Créez une règle de point de terminaison qui fait référence à la règle de sécurité que vous avez créée à l'étape précédente, comme celle définie dans le fichier suivant. Dans cet exemple, ce fichier s'appelle
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
Exécutez la commande suivante pour créer une stratégie de point de terminaison nommée
rate-limit-ep
:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=per-client-endpoints-policies.yaml \ --location=global
Valider votre configuration
Vous pouvez utiliser l'outil de test de charge Nighthawk pour générer du trafic et vérifier si vos règles de limitation du débit fonctionnent comme prévu. Utilisez la commande suivante pour générer du trafic avec 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
Ensuite, utilisez la commande suivante pour activer les journaux de débogage Envoy :
kubectl exec -it deploy/app1 -c app1 -- wget -q -O - \ --post-data="" 'http://localhost:15000/logging?level=debug'
Pour afficher les rapports d'utilisation qu'Envoy envoie au serveur de gestion, consultez Accéder à vos journaux.
Voici ce que vous pouvez attendre des résultats de votre test :
- Il faut environ cinq minutes pour que la limitation du débit prenne effet.
- Après la période de préchauffage initiale, vous devriez voir environ 15 à 21 requêtes par seconde dans le compteur de sortie du client Nighthawk
benchmark.http_2xx
. Cela signifie que Cloud Armor autorise environ 1 000 requêtes par minute.
Pour afficher l'efficacité de vos règles de stratégie de sécurité Cloud Armor, consultez Afficher le tableau de bord de surveillance.
Désactiver la limitation du débit
Vous pouvez désactiver la limitation du débit en utilisant l'une des méthodes suivantes :
- Vous pouvez supprimer les règles de sécurité et les règles pour les points de terminaison que vous avez configurées avec vos règles de limitation du débit.
- Vous pouvez dissocier la stratégie de sécurité de votre règle de point de terminaison en mettant à jour cette dernière pour supprimer le champ
securityPolicies
.
Les sections suivantes vous expliquent comment désactiver la limitation du débit à l'aide de chaque méthode.
Supprimer une règle de point de terminaison et une règle de sécurité
Tout d'abord, utilisez la commande gcloud
suivante pour supprimer votre stratégie de point de terminaison nommée rate-limit-ep
.
Si vous avez utilisé le nom fourni dans le premier ou le deuxième exemple de cette page, la règle de point de terminaison est nommée endpoints-policies
ou per-client-endpoints-policies
, respectivement.
gcloud beta network-services endpoint-policies delete --location=global rate-limit-ep
Ensuite, exécutez la commande gcloud
suivante pour supprimer une stratégie de sécurité, en remplaçant per-client-security-policy
par le nom de votre stratégie de sécurité. Si vous avez utilisé le nom fourni dans le premier ou le deuxième exemple de cette page, votre stratégie de sécurité porte le même nom que votre stratégie de point de terminaison.
gcloud beta compute security-policies delete --global per-client-security-policy
Dissocier une stratégie de sécurité de votre stratégie de point de terminaison
Commencez par mettre à jour votre fichier endpoint-policy.yaml
pour supprimer le champ securityPolcies
:
name: "rate-limit-ep" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: rate-limit-demo type: SIDECAR_PROXY
Ensuite, exécutez la commande suivante pour mettre à jour la stratégie de point de terminaison nommée rate-limit-ep
avec les modifications apportées au fichier endpoint-policy.yaml
:
gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global