Configure a limitação de taxa do Google Cloud Armor com o Envoy
Esta página mostra como configurar a limitação de taxa global do lado do servidor para a sua malha de serviços através do Cloud Armor. Pode usar esta funcionalidade para aplicar a limitação de taxa de partilha equitativa a todo o tráfego que chega ao seu serviço, o que ajuda a partilhar equitativamente a capacidade disponível dos seus serviços e a mitigar o risco de clientes maliciosos ou com comportamento inadequado sobrecarregarem os seus serviços. Para mais informações sobre a limitação de taxa, leia a vista geral da limitação de taxa.
Configure o Google Kubernetes Engine (GKE) para o Envoy
Antes de começar
Antes de começar, tem de ativar as seguintes APIs:
container.googleapis.com
compute.googleapis.com
trafficdirector.googleapis.com
networkservices.googleapis.com
meshconfig.googleapis.com
monitoring.googleapis.com
Pode ativar todas as APIs através do seguinte comando da CLI gcloud do Google Cloud:
gcloud services enable \ container.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ meshconfig.googleapis.com \ monitoring.googleapis.com
Em seguida, crie as variáveis de ambiente usadas neste 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}
Substitua as seguintes variáveis por informações do seu projeto:
- Substitua
PROJECT_ID
pelo ID do seu projeto - Substitua
ZONE
pela zona na qual quer criar o cluster do GKE - Substitua
CLUSTER
pelo nome do cluster - Substitua
MESH_NAME
pelo nome da malha
Crie um cluster do GKE
Use o comando seguinte para criar um cluster do GKE na zona que especificou na secção anterior:
gcloud container clusters create "CLUSTER" \ --zone="ZONE" \ --scopes="cloud-platform" \ --tags="allow-envoy-health-checks" \ --enable-ip-alias
Obtenha as credenciais do novo cluster:
gcloud container clusters get-credentials "CLUSTER" \ --zone="ZONE"
Ative a injeção automática
Use o seguinte comando para aplicar o recurso
MutatingWebhookConfiguration
ao seu cluster. Quando um Pod é criado, o controlador de admissão no cluster é invocado e indica ao injetor de sidecar gerido que adicione o contentor Envoy ao 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
Ative a injeção de sidecar para o espaço de nomes predefinido. O injetor de sidecar injeta contentores sidecar para pods criados no espaço de nomes predefinido.
kubectl label namespace default td-injection=enabled
Guarde a seguinte configuração do GKE para o seu serviço 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
Aplique o exemplo de serviço que criou no passo anterior:
kubectl apply -f service_sample.yaml
Guarde a seguinte configuração do GKE para o seu 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
Aplique o exemplo de cliente que criou no passo anterior:
kubectl apply -f client_sample.yaml
Configure o Cloud Service Mesh para a limitação de taxa
Use os passos nesta secção para preparar a Cloud Service Mesh para a limitação de taxas.
Crie a especificação do recurso
Mesh
e guarde-a num ficheiro denominadomesh.yaml
:name: MESH_NAME interceptionPort: 15001
Crie o recurso
Mesh
com a especificação mesh.yaml.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=global
Crie uma verificação de funcionamento:
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-port
Crie uma regra de firewall para permitir ligações de verificações de estado de funcionamento de entrada a instâncias na sua rede.
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
Crie um serviço de back-end global com um esquema de balanceamento de carga de
INTERNAL_SELF_MANAGED
e adicione a verificação de funcionamento.gcloud compute backend-services create rate-limit-demo-service \ --global \ --health-checks rate-limit-demo-hc \ --load-balancing-scheme INTERNAL_SELF_MANAGED
Adicione o NEG
rate-limit-demo-neg
ao serviço de back-end.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
Crie a especificação
HTTPRoute
e guarde-a num ficheiro denominadohttp_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"
Crie o recurso
HTTPRoute
com base na especificação no ficheirohttp_route.yaml
.gcloud network-services http-routes import rate-limit-demo-http-route \ --source=http_route.yaml \ --location=global
Configure a limitação de taxa com o Envoy
As secções seguintes explicam como configurar a limitação de taxa do lado do servidor para a sua malha de serviços. A primeira secção mostra como configurar um limite de taxa global do lado do servidor para todos os clientes e a segunda secção mostra como aplicar limites de taxa diferentes para diferentes grupos de clientes.
Configure a limitação de taxa global do lado do servidor
Neste exemplo, cria uma regra de limitação de velocidade do lado do servidor que aplica a limitação de velocidade a todos os clientes.
Num ficheiro YAML denominado
rate-limit-policy.yaml
, crie uma política de segurança do Cloud Armor com o 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"
Crie a política de segurança denominada
rate-limit-policy
:gcloud beta compute security-policies create rate-limit-policy \ --global \ --file-name=rate-limit-policy.yaml
Num ficheiro YAML, crie uma política de ponto final que faça referência à política de segurança que criou no passo anterior. Nestes exemplos, este ficheiro chama-se
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
Crie uma política de ponto final com o nome
rate-limit-ep
:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global
Configure diferentes limites de taxa do lado do servidor para diferentes grupos de clientes
Neste exemplo, cria diferentes regras de limitação de taxa do lado do servidor que aplicam diferentes limites de limitação de taxa para grupos de clientes.
Crie uma política de segurança do Cloud Armor com o tipo
CLOUD_ARMOR_INTERNAL_SERVICE
com várias regras de limitação de taxa, como a definida no ficheiro seguinte. Nestes exemplos, este ficheiro chama-seper-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 a limitação de taxa a pedidos que contenham um cabeçalho HTTP com o nome
user
e o valordemo
se o Cloud Service Mesh receber mais de 1000 desses pedidos num período de 60 segundos. Os pedidos que não têm este cabeçalho HTTP são, em alternativa, limitados por taxa se o Cloud Service Mesh receber mais de 10 000 desses pedidos num período de 60 segundos.Use o seguinte comando para criar a política, que se chama
per-client-security-policy
:gcloud beta compute security-policies create per-client-security-policy \ --global \ --file-name=per-client-security-policy.yaml
Crie uma política de ponto final que faça referência à política de segurança que criou no passo anterior, como a definida no ficheiro seguinte. Neste exemplo, este ficheiro chama-se
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
Use o seguinte comando para criar uma política de pontos finais com o nome
rate-limit-ep
:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=per-client-endpoints-policies.yaml \ --location=global
Valide a configuração
Pode usar a ferramenta de teste de carga Nighthawk para gerar tráfego e testar se as regras de limitação de taxa estão a ter o desempenho esperado. Use o seguinte comando para gerar tráfego com o 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
Em seguida, use o seguinte comando para ativar os registos de depuração do Envoy:
kubectl exec -it deploy/app1 -c app1 -- wget -q -O - \ --post-data="" 'http://localhost:15000/logging?level=debug'
Para ver os relatórios de utilização que o Envoy envia para o servidor de gestão, consulte o artigo Aceder aos seus registos.
Pode esperar ver o seguinte nos resultados dos testes:
- Demora cerca de cinco minutos até que a limitação de taxa entre em vigor.
- Após o período de aquecimento inicial, vê cerca de 15 a 21 QPS na saída do cliente do Nighthawk, no contador
benchmark.http_2xx
. Isto significa que o Cloud Armor permite cerca de 1000 pedidos por minuto.
Para ver a eficácia das regras da política de segurança do Cloud Armor, consulte Ver o painel de controlo de monitorização.
Desative a limitação de velocidade
Pode desativar a limitação de taxa através de um dos seguintes métodos:
- Pode eliminar as políticas de pontos finais e as políticas de segurança que configurou com as suas regras de limitação de taxa.
- Pode desanexar a política de segurança da política de pontos finais atualizando a política de pontos finais para remover o campo
securityPolicies
.
As secções seguintes explicam como desativar a limitação de taxa através de cada método.
Elimine uma política de ponto final e uma política de segurança
Primeiro, use o seguinte comando gcloud
para eliminar a sua política de ponto final com o nome
rate-limit-ep
.
Se usou o nome fornecido no primeiro ou segundo exemplo nesta página, a política de
endpoint tem o nome endpoints-policies
ou per-client-endpoints-policies
respetivamente.
gcloud beta network-services endpoint-policies delete --location=global rate-limit-ep
Em seguida, use o seguinte comando gcloud
para eliminar uma política de segurança, substituindo
per-client-security-policy
pelo nome da sua política de segurança. Se usou o nome indicado no primeiro ou segundo exemplo desta página, a sua política de segurança tem o mesmo nome que a sua política de ponto final.
gcloud beta compute security-policies delete --global per-client-security-policy
Desanexe uma política de segurança da sua política de pontos finais
Primeiro, atualize o ficheiro endpoint-policy.yaml
para remover o campo securityPolcies
:
name: "rate-limit-ep" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: rate-limit-demo type: SIDECAR_PROXY
Em seguida, use o seguinte comando para atualizar a política de ponto final com o nome
rate-limit-ep
com as alterações ao ficheiro endpoint-policy.yaml
:
gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global