EnvoyFilter를 사용한 데이터 영역 확장성
EnvoyFilter API를 사용하여 다른 Istio API를 사용하는 것으로는 달성할 수 없는 Cloud Service Mesh의 데이터 영역 기능을 확장할 수 있습니다. EnvoyFilter API를 사용하면 워크로드에 적용된 다른 정책에서 생성된 Envoy 구성을 맞춤설정할 수 있습니다(예: HTTP 필터 체인에 필터 추가).
중요 고려사항
- API 노출 영역은 내부 구현 세부정보와 연결되어 있으므로 잘못된 구성으로 인해 메시가 불안정해질 수 있으므로 이 기능을 사용할 때는 특별히 주의해야 합니다. 다른 Istio API가 요구사항에 맞지 않는 경우에만
EnvoyFilterAPI를 사용하세요. EnvoyFilterAPI는 안정성과 지원 가능성을 위해 사용할 수 있는 필드와 확장 프로그램에 관한 특정 제한사항과 함께 지원됩니다.EnvoyFilterAPI에서 지원되는 기능의 전체 목록은 Istio API를 사용하는 지원 기능 (관리형 컨트롤 플레인)을 참고하세요.- Google에서 제공하는 지원 범위는 Envoy 사이드카가 있는 워크로드에 사용자가 제공한 구성을 전파하는 데 국한되며 확장 프로그램별 API를 사용하여 지정된 구성의 정확성에는 적용되지 않습니다.
지원되는 API 필드
EnvoyFilter API는 TRAFFIC_DIRECTOR 컨트롤 플레인 구현에서만 지원되며 다음과 같이 제한된 지원만 제공됩니다.
targetRefs: 지원되지 않음configPatches[].applyTo:HTTP_FILTER만 지원됩니다.configPatches[].patch.operation: 경로 필터와 함께 사용되는 경우INSERT_FIRST및INSERT_BEFORE만 지원됩니다.configPatches[].patch.value.type_url: 지원되는 확장 프로그램 참고configPatches[].patch.filterClass: 지원되지 않음configPatches[].match.proxy: 지원되지 않음configPatches[].match.routeConfiguration: 지원되지 않음configPatches[].match.cluster: 지원되지 않음- 다음 필드는
INSERT_BEFORE작업에만 지원됩니다.configPatches[].match.listener:filter만 지원됩니다.configPatches[].match.listener.filter.name:envoy.filters.network.http_connection_manager만 지원됩니다.configPatches[].match.listener.filter.subFilter.name:envoy.filters.http.router만 지원됩니다.
지원되는 확장 프로그램
다음은 다양한 출시 채널에서 지원되는 API 필드와 함께 지원되는 확장 프로그램 목록입니다. API 정의와 의미 체계는 공식 Envoy 문서에서 확인할 수 있습니다.
type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
| 필드 | 신속 | 일반 | 정식 |
|---|---|---|---|
stat_prefix |
|||
status |
|||
token_bucket |
|||
filter_enabled |
|||
filter_enforced |
|||
response_headers_to_add |
|||
request_headers_to_add_when_not_enforced |
|||
local_rate_limit_per_downstream_connection |
|||
enable_x_ratelimit_headers |
type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
| 필드 | 신속 | 일반 | 정식 |
|---|---|---|---|
| (필드 없음) |
사용 예시
이 튜토리얼에서는 Envoy의 기본 제공 로컬 비율 제한을 사용하여 EnvoyFilter API를 통해 서비스 트래픽을 동적으로 제한하는 방법을 알아봅니다.
비용
이 튜토리얼에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud구성요소를 사용합니다.
이 튜토리얼을 마치면 만든 리소스를 삭제하여 비용이 계속 청구되지 않도록 할 수 있습니다. 자세한 내용은 삭제를 참조하세요.
시작하기 전에
- 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.
- GKE 클러스터에 Cloud Service Mesh 프로비저닝
저장소를 클론합니다.
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples cd anthos-service-mesh-samples
인그레스 게이트웨이 배포
kubectl의 현재 컨텍스트를 클러스터로 설정합니다.gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION인그레스 게이트웨이에 대해 네임스페이스를 만듭니다.
kubectl create namespace asm-ingress네임스페이스의 삽입을 사용 설정합니다. 이 단계는 컨트롤 플레인 구현에 따라 다릅니다.
기본 삽입 라벨을 네임스페이스에 적용합니다.
kubectl label namespace asm-ingress \ istio.io/rev- istio-injection=enabled --overwriteanthos-service-mesh-samples저장소에 게이트웨이 예시를 배포합니다.kubectl apply -n asm-ingress \ -f docs/shared/asm-ingress-gateway예상 출력:
serviceaccount/asm-ingressgateway configured service/asm-ingressgateway configured deployment.apps/asm-ingressgateway configured gateway.networking.istio.io/asm-ingressgateway configured
Online Boutique 샘플 애플리케이션 배포
아직 설정하지 않은 경우
kubectl의 현재 컨텍스트를 클러스터로 설정합니다.gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION샘플 애플리케이션의 네임스페이스를 만듭니다.
kubectl create namespace onlineboutiqueEnvoy 프록시를 자동으로 주입하도록
onlineboutique네임스페이스에 라벨을 지정합니다.kubectl label namespace onlineboutique \ istio.io/rev- istio-injection=enabled --overwrite샘플 앱, 프런트엔드용
VirtualService, 워크로드의 서비스 계정을 배포합니다. 이 튜토리얼에서는 마이크로서비스 데모 앱인 Online Boutique를 배포합니다.kubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/virtual-service.yamlkubectl apply \ -n onlineboutique \ -f docs/shared/online-boutique/service-accounts
서비스 보기
onlineboutique네임스페이스의 포드를 확인합니다.kubectl get pods -n onlineboutique예상 출력:
NAME READY STATUS RESTARTS AGE adservice-85598d856b-m84m6 2/2 Running 0 2m7s cartservice-c77f6b866-m67vd 2/2 Running 0 2m8s checkoutservice-654c47f4b6-hqtqr 2/2 Running 0 2m10s currencyservice-59bc889674-jhk8z 2/2 Running 0 2m8s emailservice-5b9fff7cb8-8nqwz 2/2 Running 0 2m10s frontend-77b88cc7cb-mr4rp 2/2 Running 0 2m9s loadgenerator-6958f5bc8b-55q7w 2/2 Running 0 2m8s paymentservice-68dd9755bb-2jmb7 2/2 Running 0 2m9s productcatalogservice-84f95c95ff-c5kl6 2/2 Running 0 114s recommendationservice-64dc9dfbc8-xfs2t 2/2 Running 0 2m9s redis-cart-5b569cd47-cc2qd 2/2 Running 0 2m7s shippingservice-5488d5b6cb-lfhtt 2/2 Running 0 2m7s애플리케이션의 모든 포드가 작동되고
READY열의2/2를 사용해서 실행됩니다. 이것은 포드에 Envoy 사이드카 프록시가 성공적으로 주입된 것을 나타냅니다. 몇 분 후에도2/2가 표시되지 않는다면 문제 해결 가이드를 방문하세요.외부 IP를 가져오고 이를 변수로 설정합니다.
kubectl get services -n asm-ingress export FRONTEND_IP=$(kubectl --namespace asm-ingress \ get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \ )다음과 비슷한 출력이 표시됩니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE asm-ingressgateway LoadBalancer 10.19.247.233 35.239.7.64 80:31380/TCP,443:31390/TCP,31400:31400/TCP 27m웹브라우저에서
EXTERNAL-IP주소를 방문합니다. 브라우저에 Online Boutique 매장이 표시될 것으로 예상됩니다.
비율 제한 구성 적용
이 섹션에서는 EnvoyFilter 리소스를 적용하여 frontend 서비스에 대한 모든 트래픽을 5req/min으로 제한합니다.
frontend서비스에 CR을 적용합니다.kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: frontend-local-ratelimit namespace: onlineboutique spec: workloadSelector: labels: app: frontend configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.router" patch: operation: INSERT_BEFORE value: name: envoy.filters.http.local_ratelimit typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit value: stat_prefix: http_local_rate_limiter token_bucket: max_tokens: 5 tokens_per_fill: 5 fill_interval: 60s filter_enabled: runtime_key: local_rate_limit_enabled default_value: numerator: 100 denominator: HUNDRED filter_enforced: runtime_key: local_rate_limit_enforced default_value: numerator: 100 denominator: HUNDRED EOF예상 출력:
envoyfilter.networking.istio.io/frontend-local-ratelimit createdCR 상태에 오류가 보고되지 않는지 확인합니다.
kubectl get envoyfilter -n onlineboutique frontend-local-ratelimit -o yaml예상 출력:
... status: conditions: - lastTransitionTime: "2025-06-30T14:29:25.467017594Z" message: This resource has been accepted. This does not mean it has been propagated to all proxies yet reason: Accepted status: "True" type: Accepted토큰을 소비하는 서비스를 여러 번 호출하므로
loadgenerator배포를 삭제합니다.kubectl delete -n onlineboutique deployment loadgenerator예상 출력:
deployment.apps/loadgenerator deletedcurl를 사용하여 60초 동안 5개 이하의 요청이 허용되는지 확인합니다.429코드는 비율 제한이 적용되고 있음을 나타냅니다.for i in {1..10}; do curl -s http://${FRONTEND_IP} -o /dev/null -w "%{http_code}\n"; sleep 1; done예상 출력:
200 200 200 200 200 429 429 429 429 429
삭제
이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 프로젝트를 삭제하거나 개별 리소스를 삭제하면 됩니다.
프로젝트 삭제
Cloud Shell에서 프로젝트를 삭제합니다.
gcloud projects delete PROJECT_ID
리소스 삭제
클러스터를 유지하고 Online Boutique를 삭제하려면 다음 안내를 따르세요.
애플리케이션 네임스페이스를 삭제합니다.
kubectl delete namespace onlineboutique예상 출력:
namespace "onlineboutique" deleted인그레스 게이트웨이 네임스페이스를 삭제합니다.
kubectl delete namespace asm-ingress예상 출력:
namespace "asm-ingress" deleted
추가 요금이 청구되지 않도록 하려면 클러스터를 삭제하세요.
gcloud container clusters delete CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
문제 해결
데이터 영역 확장성 문제 해결을 참고하세요.