Envoy로 Google Cloud Armor 비율 제한 구성
이 페이지에서는 Cloud Armor를 사용하여 서비스 메시의 전역 서버 측 비율 제한을 구성하는 방법을 보여줍니다. 이 기능을 사용하면 서비스에 도착하는 모든 트래픽에 공평한 공유 비율 제한을 적용하여 서비스의 사용 가능한 용량을 공정하게 공유하고 악성 또는 잘못된 클라이언트가 서비스를 과부하하는 위험을 완화할 수 있습니다. 비율 제한에 대한 자세한 내용은 비율 제한 개요를 참고하세요.
Envoy용 Google Kubernetes Engine (GKE) 구성
시작하기 전에
시작하기 전에 다음 API를 사용 설정해야 합니다.
container.googleapis.com
compute.googleapis.com
trafficdirector.googleapis.com
networkservices.googleapis.com
meshconfig.googleapis.com
monitoring.googleapis.com
다음 Google Cloud CLI 명령어를 사용하여 모든 API를 사용 설정할 수 있습니다.
gcloud services enable \ container.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ meshconfig.googleapis.com \ monitoring.googleapis.com
그런 다음 이 문서에서 사용되는 환경 변수를 만듭니다.
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}
다음 변수를 프로젝트 정보로 바꿉니다.
PROJECT_ID
를 프로젝트 ID로 바꿉니다.ZONE
을 GKE 클러스터를 만들 영역으로 바꿉니다.CLUSTER
을 클러스터 이름으로 바꿉니다.MESH_NAME
을 메시 이름으로 바꿉니다.
GKE 클러스터 만들기
다음 명령어를 사용하여 이전 섹션에서 지정한 영역에 GKE 클러스터를 만듭니다.
gcloud container clusters create "CLUSTER" \ --zone="ZONE" \ --scopes="cloud-platform" \ --tags="allow-envoy-health-checks" \ --enable-ip-alias
새 클러스터의 사용자 인증 정보를 가져옵니다.
gcloud container clusters get-credentials "CLUSTER" \ --zone="ZONE"
자동 삽입 사용 설정
다음 명령어를 사용하여
MutatingWebhookConfiguration
리소스를 클러스터에 적용합니다. 포드가 생성되면 클러스터 내 허용 컨트롤러가 호출되고 관리형 사이드카 인젝터에 Envoy 컨테이너를 포드에 추가하도록 지시합니다.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
기본 네임스페이스에 대해 사이드카 삽입을 사용 설정합니다. 사이드카 인젝터는 기본 네임스페이스로 만든 포드에 사이드카 컨테이너를 삽입합니다.
kubectl label namespace default td-injection=enabled
서비스의 다음 GKE 구성을
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
이전 단계에서 만든 서비스 샘플을 적용합니다.
kubectl apply -f service_sample.yaml
클라이언트의 다음 GKE 구성을
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
이전 단계에서 만든 클라이언트 샘플을 적용합니다.
kubectl apply -f client_sample.yaml
속도 제한을 위한 Cloud Service Mesh 설정
이 섹션의 단계에 따라 Cloud Service Mesh가 비율 제한을 준비하도록 합니다.
Mesh
리소스 사양을 만들고mesh.yaml
파일에 저장합니다.name: MESH_NAME interceptionPort: 15001
mesh.yaml 사양을 사용하여
Mesh
리소스를 만듭니다.gcloud network-services meshes import "MESH_NAME" \ --source=mesh.yaml \ --location=global
상태 확인을 만듭니다.
gcloud compute health-checks create http rate-limit-demo-hc \ --use-serving-port
네트워크 인스턴스에 들어오는 상태 점검 연결을 허용하는 방화벽 규칙을 만듭니다.
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
부하 분산 스키마가
INTERNAL_SELF_MANAGED
인 전역 백엔드 서비스를 만들고 상태 점검을 추가합니다.gcloud compute backend-services create rate-limit-demo-service \ --global \ --health-checks rate-limit-demo-hc \ --load-balancing-scheme INTERNAL_SELF_MANAGED
백엔드 서비스에 NEG
rate-limit-demo-neg
를 추가합니다.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
HTTPRoute
사양을 만들고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"
http_route.yaml
파일의 사양을 사용하여HTTPRoute
리소스를 만듭니다.gcloud network-services http-routes import rate-limit-demo-http-route \ --source=http_route.yaml \ --location=global
Envoy로 비율 제한 구성
다음 섹션에서는 서비스 메시의 서버 측 비율 제한을 구성하는 방법을 설명합니다. 첫 번째 섹션에서는 모든 클라이언트에 대해 하나의 서버 측 전역 비율 제한을 설정하는 방법을 보여주고, 두 번째 섹션에서는 클라이언트 그룹별로 다른 비율 제한을 적용하는 방법을 보여줍니다.
서버 측 전역 비율 제한 구성
이 예에서는 모든 클라이언트에 비율 제한을 적용하는 서버 측 비율 제한 규칙을 하나 만듭니다.
rate-limit-policy.yaml
이라는 YAML 파일에서CLOUD_ARMOR_INTERNAL_SERVICE
유형의 Cloud Armor 보안 정책을 만듭니다.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"
rate-limit-policy
이라는 보안 정책을 만듭니다.gcloud beta compute security-policies create rate-limit-policy \ --global \ --file-name=rate-limit-policy.yaml
YAML 파일에서 이전 단계에서 만든 보안 정책을 참조하는 엔드포인트 정책을 만듭니다. 이 예시에서 이 파일은
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
rate-limit-ep
라는 엔드포인트 정책을 만듭니다.gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global
클라이언트 그룹별로 다른 서버 측 비율 제한 구성
이 예에서는 클라이언트 그룹에 서로 다른 비율 제한 기준을 적용하는 다양한 서버 측 비율 제한 규칙을 만듭니다.
다음 파일에 정의된 것과 같이 여러 비율 제한 규칙이 있는
CLOUD_ARMOR_INTERNAL_SERVICE
유형의 Cloud Armor 보안 정책을 만듭니다. 이 예시에서 이 파일은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"
이 정책은 Cloud Service Mesh가 60초 내에 이름이
user
이고 값이demo
인 HTTP 헤더가 포함된 요청을 1,000개 이상 수신하는 경우 해당 요청에 비율 제한을 적용합니다. 이 HTTP 헤더가 없는 요청은 Cloud Service Mesh가 60초 내에 이러한 요청을 10,000개 이상 수신하는 경우 대신 비율 제한됩니다.다음 명령어를 사용하여
per-client-security-policy
이라는 정책을 만듭니다.gcloud beta compute security-policies create per-client-security-policy \ --global \ --file-name=per-client-security-policy.yaml
다음 파일에 정의된 것과 같이 이전 단계에서 만든 보안 정책을 참조하는 엔드포인트 정책을 만듭니다. 이 예시에서는 이 파일의 이름을
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
다음 명령어를 사용하여
rate-limit-ep
이라는 엔드포인트 정책을 만듭니다.gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=per-client-endpoints-policies.yaml \ --location=global
설정 확인
Nighthawk 부하 테스트 도구를 사용하여 트래픽을 생성하여 속도 제한 규칙이 예상대로 작동하는지 테스트할 수 있습니다. 다음 명령어를 사용하여 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
그런 다음 다음 명령어를 사용하여 Envoy 디버그 로그를 사용 설정합니다.
kubectl exec -it deploy/app1 -c app1 -- wget -q -O - \ --post-data="" 'http://localhost:15000/logging?level=debug'
Envoy가 관리 서버에 전송하는 사용량 보고서를 보려면 로그 액세스를 참고하세요.
테스트 결과에서 다음을 확인할 수 있습니다.
- 속도 제한이 적용되기까지 약 5분이 걸립니다.
- 초기 워밍업 기간이 지나면 Nighthawk 클라이언트 출력
benchmark.http_2xx
카운터에서 약 15~21 QPS가 표시됩니다. 즉, Cloud Armor는 분당 약 1,000개의 요청을 허용합니다.
Cloud Armor 보안 정책 규칙의 효과를 확인하려면 모니터링 대시보드 보기를 참고하세요.
비율 제한 사용 중지
다음 방법 중 하나를 사용하여 비율 제한을 사용 중지할 수 있습니다.
- 비율 제한 규칙으로 구성한 엔드포인트 정책과 보안 정책을 삭제할 수 있습니다.
- 엔드포인트 정책을 업데이트하여
securityPolicies
필드를 삭제하면 엔드포인트 정책에서 보안 정책을 분리할 수 있습니다.
다음 섹션에서는 각 방법을 사용하여 비율 제한을 사용 중지하는 방법을 설명합니다.
엔드포인트 정책 및 보안 정책 삭제
먼저 다음 gcloud
명령어를 사용하여 rate-limit-ep
이라는 엔드포인트 정책을 삭제합니다.
이 페이지의 첫 번째 또는 두 번째 예에 제공된 이름을 사용한 경우 엔드포인트 정책의 이름은 각각 endpoints-policies
또는 per-client-endpoints-policies
입니다.
gcloud beta network-services endpoint-policies delete --location=global rate-limit-ep
그런 다음 다음 gcloud
명령어를 사용하여 보안 정책을 삭제합니다. 이때 per-client-security-policy
을 보안 정책 이름으로 바꿉니다. 이 페이지의 첫 번째 또는 두 번째 예에 제공된 이름을 사용한 경우 보안 정책의 이름이 엔드포인트 정책의 이름과 동일합니다.
gcloud beta compute security-policies delete --global per-client-security-policy
엔드포인트 정책에서 보안 정책 분리
먼저 endpoint-policy.yaml
파일을 업데이트하여 securityPolcies
필드를 삭제합니다.
name: "rate-limit-ep" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: rate-limit-demo type: SIDECAR_PROXY
그런 다음 다음 명령어를 사용하여 endpoint-policy.yaml
파일의 변경사항으로 rate-limit-ep
라는 엔드포인트 정책을 업데이트합니다.
gcloud beta network-services endpoint-policies import rate-limit-ep \ --source=endpoints-policies.yaml \ --location=global