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.com
compute.googleapis.com
trafficdirector.googleapis.com
networkservices.googleapis.com
meshconfig.googleapis.com
monitoring.googleapis.com
É possível ativar todas as APIs usando o seguinte comando da Google Cloud CLI:
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 projeto. - Substitua
ZONE
pela zona em que você pretende criar o cluster do GKE. - Substitua
CLUSTER
pelo nome do cluster. - Substitua
MESH_NAME
pelo 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-alias
Receba 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
MutatingWebhookConfiguration
ao 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 EOF
Ative 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: 1337
Aplique 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: 1337
Aplique 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
Mesh
e salve-a em um arquivo chamadomesh.yaml
:name: MESH_NAME interceptionPort: 15001
Crie o recurso
Mesh
usando a especificação mesh.yaml.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=global
Crie uma verificação de integridade:
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-port
Crie 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 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 integridade.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 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
HTTPRoute
usando 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.yaml
Em 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-policy
Crie 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_SERVICE
e 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
user
e o valordemo
se 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.yaml
Crie 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-policy
Use 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 verificar 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
contador
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