Configurar a limitação de taxa do Google Cloud Armor com o Envoy
Nesta página, mostramos como configurar a limitação de taxa global do lado do servidor para sua malha de serviço usando o Cloud Armor. Use esse recurso para aplicar a limitação de taxa de fairshare a todo o tráfego que chega ao seu serviço. Isso ajuda a compartilhar de maneira justa a capacidade disponível dos seus serviços e mitigar o risco de clientes maliciosos ou com comportamento inadequado sobrecarregarem seus serviços. Para mais informações sobre a limitação de taxa, leia a visão geral da limitação de taxa.
Configurar o Google Kubernetes Engine (GKE) para o Envoy
Antes de começar
Antes de começar, ative as seguintes APIs:
container.googleapis.comcompute.googleapis.comtrafficdirector.googleapis.comnetworkservices.googleapis.commeshconfig.googleapis.commonitoring.googleapis.com
É possível ativar todas as APIs usando o seguinte comando da CLI 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 projeto. - Substitua
ZONEpela zona em que você pretende criar o cluster do GKE. - Substitua
CLUSTERpelo nome do cluster. - Substitua
MESH_NAMEpelo nome da malha.
Criar um cluster do GKE
Use o comando a seguir para criar um cluster do GKE na zona especificada na seção anterior:
gcloud container clusters create "CLUSTER" \ --zone="ZONE" \ --scopes="cloud-platform" \ --tags="allow-envoy-health-checks" \ --enable-ip-aliasReceba as credenciais do novo cluster:
gcloud container clusters get-credentials "CLUSTER" \ --zone="ZONE"
Ativar a injeção automática
Use o comando a seguir para aplicar o recurso
MutatingWebhookConfigurationao cluster. Quando um pod é criado, o controlador de admissão no cluster é invocado e instrui o injetor de sidecar gerenciado a adicionar o contêiner 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 no namespace padrão. O injetor de sidecar injeta contêineres de sidecar para pods criados no namespace padrão.
kubectl label namespace default td-injection=enabled
Salve a seguinte configuração do GKE para 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 você criou na etapa anterior:
kubectl apply -f service_sample.yaml
Salve a seguinte configuração do GKE para 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 a amostra de cliente que você criou na etapa anterior:
kubectl apply -f client_sample.yaml
Configurar o Cloud Service Mesh para limitação de taxa
Siga as etapas nesta seção para preparar o Cloud Service Mesh para a limitação de taxa.
Crie a especificação do recurso
Meshe salve-a em um arquivo chamadomesh.yaml:name: MESH_NAME interceptionPort: 15001
Crie o recurso
Meshusando a especificação mesh.yaml.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=globalCrie uma verificação de integridade:
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-portCrie uma regra de firewall para permitir conexões de verificação de integridade de entrada com 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 integridade.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 salve-a em um arquivo chamadohttp_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
HTTPRouteusando a especificação no arquivohttp_route.yaml.gcloud network-services http-routes import rate-limit-demo-http-route \ --source=http_route.yaml \ --location=global
Configurar a limitação de taxa com o Envoy
As seções a seguir explicam como configurar a limitação de taxa do lado do servidor para sua malha de serviço. A primeira seção mostra como configurar um limite global de taxa do lado do servidor para todos os clientes, e a segunda seção mostra como aplicar limites de taxa diferentes para diferentes grupos de clientes.
Configurar a limitação de taxa global do lado do servidor
Neste exemplo, você cria uma regra de limitação de taxa do lado do servidor que aplica a limitação de taxa a todos os clientes.
Em um arquivo YAML chamado
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 chamada
rate-limit-policy:gcloud beta compute security-policies create rate-limit-policy \ --global \ --file-name=rate-limit-policy.yamlEm um arquivo YAML, crie uma política de endpoint que faça referência à política de segurança criada na etapa anterior. Nesses exemplos, o arquivo é chamado de
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 endpoint chamada
rate-limit-ep:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global
Configurar diferentes limites de taxa do lado do servidor para diferentes grupos de clientes
Neste exemplo, você cria diferentes regras de limitação de taxa do lado do servidor que impõem diferentes limites para grupos de clientes.
Crie uma política de segurança do Cloud Armor com o tipo
CLOUD_ARMOR_INTERNAL_SERVICEe várias regras de limitação de taxa, como a definida no arquivo a seguir. Nesses exemplos, o arquivo é chamadoper-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"Essa política aplica a limitação de taxa a solicitações que contêm um cabeçalho HTTP com o nome
usere o valordemose o Cloud Service Mesh receber mais de 1.000 solicitações desse tipo em um período de 60 segundos. As solicitações que não têm esse cabeçalho HTTP são limitadas por taxa se o Cloud Service Mesh receber mais de 10.000 solicitações desse tipo em um período de 60 segundos.Use o comando a seguir para criar a política, chamada
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 endpoint que faça referência à política de segurança criada na etapa anterior, como a definida no arquivo a seguir. Neste exemplo, o arquivo é chamado de
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 comando a seguir para criar uma política de endpoint chamada
rate-limit-ep:gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=per-client-endpoints-policies.yaml \ --location=global
Validar sua configuração
Use a ferramenta de teste de carga Nighthawk para gerar tráfego e testar se as regras de limitação de taxa estão funcionando como esperado. Use o comando a seguir 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 comando a seguir para ativar os registros 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 uso que o Envoy envia ao servidor de gerenciamento, consulte Como acessar seus registros.
Os resultados do teste podem mostrar o seguinte:
- Leva cerca de cinco minutos para que a limitação de taxa entre em vigor.
- Após o período inicial de aquecimento, você verá cerca de 15 a 21 QPS na saída do cliente Nighthawk
benchmark.http_2xx. Isso significa que o Cloud Armor permite cerca de 1.000 solicitações por minuto.
Para conferir a eficácia das regras da política de segurança do Cloud Armor, consulte Como acessar o painel de monitoramento.
Desativar a limitação de taxa
É possível desativar a limitação de taxa usando um dos seguintes métodos:
- É possível excluir as políticas de endpoint e de segurança que você configurou com suas regras de limitação de taxa.
- É possível separar a política de segurança da política de endpoint atualizando a
política de endpoint para remover o campo
securityPolicies.
As seções a seguir mostram como desativar a limitação de taxa usando cada método.
Excluir uma política de endpoint e uma política de segurança
Primeiro, use o seguinte comando gcloud para excluir a política de endpoint chamada
rate-limit-ep.
Se você usou o nome fornecido no primeiro ou segundo exemplo desta página, a política de endpoint será chamada de endpoints-policies ou per-client-endpoints-policies, respectivamente.
gcloud beta network-services endpoint-policies delete --location=global rate-limit-ep
Em seguida, use o comando gcloud a seguir para excluir uma política de segurança, substituindo
per-client-security-policy
pelo nome da sua política de segurança. Se você usou o nome fornecido no primeiro ou segundo exemplo desta página, sua política de segurança tem o mesmo nome da política de endpoint.
gcloud beta compute security-policies delete --global per-client-security-policy
Remover uma política de segurança da política de endpoint
Primeiro, atualize o arquivo 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 comando a seguir para atualizar a política de endpoint chamada
rate-limit-ep
com as mudanças no arquivo endpoint-policy.yaml:
gcloud beta network-services endpoint-policies import rate-limit-ep \
--source=endpoints-policies.yaml \
--location=global