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.comcompute.googleapis.comtrafficdirector.googleapis.comnetworkservices.googleapis.commeshconfig.googleapis.commonitoring.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_IDpelo ID do seu projeto - Substitua 
ZONEpela zona na qual quer criar o cluster do GKE - Substitua 
CLUSTERpelo nome do cluster - Substitua 
MESH_NAMEpelo 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-aliasObtenha 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
MutatingWebhookConfigurationao 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 EOFAtive 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: 1337Aplique 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: 1337Aplique 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
Meshe guarde-a num ficheiro denominadomesh.yaml:name: MESH_NAME interceptionPort: 15001
Crie o recurso
Meshcom a especificação mesh.yaml.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=globalCrie uma verificação de funcionamento:
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-portCrie 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 tcpCrie um serviço de back-end global com um esquema de balanceamento de carga de
INTERNAL_SELF_MANAGEDe 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_MANAGEDAdicione o NEG
rate-limit-demo-negao 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 5Crie a especificação
HTTPRoutee 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
HTTPRoutecom 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.yamlNum 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-policyCrie 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_SERVICEcom 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
usere o valordemose 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.yamlCrie 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-policyUse 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