Ssoon
[7주차] 요청 경로에서 Istio 확장 : EnvoyFilter 리소스로 Envoy 필터 구성 본문
Istio Hands-on Study [1기]
[7주차] 요청 경로에서 Istio 확장 : EnvoyFilter 리소스로 Envoy 필터 구성
구구달스 2025. 4. 23. 16:47🚀 Istio의 EnvoyFilter로 데이터 플레인 확장하기
🛠️ EnvoyFilter 리소스란?
EnvoyFilter의 역할
- Istio는 VirtualService, DestinationRule, AuthorizationPolicy 같은 고수준 API를 통해 네트워킹과 보안 설정을 추상화합니다. 하지만 이러한 API로는 Envoy 프록시의 모든 기능을 다룰 수 없으며, 특정 필터나 설정을 직접 조정해야 하는 경우가 있습니다. 이때 EnvoyFilter 리소스를 사용하면 Envoy의 listeners, routes, clusters, filters 등을 직접 설정할 수 있습니다.
- EnvoyFilter는 고급 사용자를 위한 break glass 솔루션으로, 강력하지만 주의가 필요합니다. Envoy의 API는 Istio 릴리스 간에 변경될 수 있으므로, 설정이 잘못되면 데이터 플레인 전체가 중단될 수 있습니다.
EnvoyFilter는 Envoy의 세부 설정을 직접 조정할 수 있는 고급 도구로,
주의 깊게 사용해야 합니다.
🔧 Tap 필터를 활용한 디버깅
예제 설정: Tap 필터 적용
- Tap 필터는 HTTP 요청과 응답을 수정하지 않고 스트리밍해 디버깅하거나 네트워크 요청을 분석하는 데 유용합니다. Istio의 기본 API로는 Tap 필터를 설정할 수 없지만, EnvoyFilter를 사용하면 이를 쉽게 구성할 수 있습니다.
- 다음은 webapp 서비스에 Tap 필터를 적용하는 EnvoyFilter 설정 예제입니다:
- webapp이라는 레이블을 가진 Pod으로 들어오는 8080 포트의 HTTP 트래픽에 대해 envoy.filters.http.tap 필터를 활성화하는 EnvoyFilter입니다. 이를 통해 해당 트래픽을 복사해서 분석하거나 디버깅하는 등의 작업을 수행할 수 있게 됩니다.
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: tap-filter
namespace: istioinaction
spec:
workloadSelector:
labels:
app: webapp
configPatches:
- applyTo: HTTP_FILTER #Envoy 프록시 내의 HTTP 필터에 설정을 변경
match:
context: SIDECAR_INBOUND #사이드카 프록시의 인바운드(들어오는) 트래픽에 적용
listener:
portNumber: 8080 #특정 포트 번호(8080)로 들어오는 트래픽에 필터를 적용
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager" # Envoy 내에서 HTTP 연결을 관리하는 필터
subFilter:
name: "envoy.filters.http.router" #라우팅 기능을 담당하는 필터
patch:
operation: INSERT_BEFORE #찾은 라우터 필터 앞에 새로운 필터를 삽입
value:
name: envoy.filters.http.tap
typed_config: #tap 필터의 구체적인 설정을 정의
"@type": "type.googleapis.com/envoy.extensions.filters.http.tap.v3.Tap"
commonConfig:
adminConfig:
configId: tap_config #tap 필터의 설정을 관리하기 위한 고유한 ID를 tap_config라고 지정
설정 분석
- Namespace와 WorkloadSelector: EnvoyFilter는 기본적으로 네임스페이스의 모든 워크로드에 적용됩니다. workloadSelector를 사용해 app: webapp 레이블이 있는 워크로드로 대상을 제한합니다.
- ConfigPatches: HTTP 필터를 설정하며, SIDECAR_INBOUND 컨텍스트의 8080 포트 리스너에 적용됩니다. envoy.filters.network.http_connection_manager(HCM) 내의 envoy.filters.http.router 앞에 Tap 필터를 삽입합니다.
- Patch: INSERT_BEFORE 작업으로 Tap 필터를 추가하며, tap_config라는 ID로 설정을 정의합니다.
Tap 필터는 EnvoyFilter를 통해 설정할 수 있으며,
요청 디버깅을 위해 유용합니다.
🛠️ Tap 필터 적용 및 검증
환경 설정
- 필요한 서비스를 배포합니다:
$ kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction
kubectl apply -f services/webapp/kubernetes/webapp.yaml -n istioinaction
kubectl apply -f services/webapp/istio/webapp-catalog-gw-vs.yaml -n istioinaction
kubectl apply -f ch9/sleep.yaml -n istioinaction
serviceaccount/catalog created
service/catalog created
deployment.apps/catalog created
serviceaccount/webapp created
service/webapp created
deployment.apps/webapp created
gateway.networking.istio.io/coolstore-gateway created
virtualservice.networking.istio.io/webapp-virtualservice created
error: the path "ch9/sleep.yaml" does not exist
- 호출 확인 : mypc
$ EXT_IP=$(kubectl -n istio-system get svc istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ docker exec -it mypc curl -s -H "Host: webapp.istioinaction.io" http://$EXT_IP/api/catalogcatalog
[{"id":1,"color":"amber","department":"Eyewear","name":"Elinor Glasses","price":"282.00"},{"id":2,"color":"cyan","department":"Clothing","name":"Atlas Shirt","price":"127.00"},{"id":3,"color":"teal","department":"Clothing","name":"Small Metal Shoes","price":"232.00"},{"id":4,"color":"red","department":"Watches","name":"Red Dragon Watch","price":"232.00"}]
EnvoyFilter 적용
- 위의 Tap 필터 설정을 파일(tap-envoy-filter.yaml)로 저장한 뒤 적용합니다:
$ kubectl apply -f ch14/tap-envoy-filter.yaml
envoyfilter.networking.istio.io/tap-filter created
$ kubectl get envoyfilter -n istioinaction
NAME AGE
tap-filter 5s
설정 검증
- webapp 사이드카 프록시의 Envoy 설정을 확인해 Tap 필터가 추가되었는지 검증합니다:
$ docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/webapp.istioinaction --port 15006 -o json | grep envoy.filters.http.tap -A10
"name": "envoy.filters.http.tap",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.tap.v3.Tap",
"commonConfig": {
"adminConfig": {
"configId": "tap_config"
}
}
}
},
$ docker exec -it myk8s-control-plane istioctl proxy-config listener deploy/webapp.istioinaction --port 15006 -o json | grep envoy.filters.http.router -A10
"name": "envoy.filters.http.router",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
}
}
],
- 출력에서 다음과 같은 Tap 필터 설정을 확인할 수 있습니다:
EnvoyFilter를 적용한 후 istioctl 명령어로 설정을 검증할 수 있습니다.
🔍 Tap 필터 동작 확인
Tap 설정 및 실행
- 터미널 1 : 포트 포워딩 설정 후 tap 시작
- 먼저 webapp Pod의 Envoy 프록시 관리 인터페이스에 접근할 수 있는 통로를 만들고, 그 통로를 통해 tap 기능의 설정 정보를 Envoy에게 전달하여 원하는 트래픽을 감시하거나 기록할 수 있게 됩니다.
kubectl port-forward -n istioinaction deploy/webapp 15000 &
curl -X POST -d @./ch14/tap-config.json localhost:15000/tap
- 터미널 2 : 반복 접속
$ EXT_IP=$(kubectl -n istio-system get svc istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ while true; do docker exec -it mypc curl -s -H "x-app-tap: true" -H "Host: webapp.istioinaction.io" http://$EXT_IP/api/catalog ; echo ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
[{"id":1,"color":"amber","department":"Eyewear","name":"Elinor Glasses","price":"282.00"},{"id":2,"color":"cyan","department":"Clothing","name":"Atlas Shirt","price":"127.00"},{"id":3,"color":"teal","department":"Clothing","name":"Small Metal Shoes","price":"232.00"},{"id":4,"color":"red","department":"Watches","name":"Red Dragon Watch","price":"232.00"}]
2025-05-20 09:49:48
...
- 터미널 3 : 로그 확인
$ kubectl logs -n istioinaction -l app=webapp -c istio-proxy -f
...
[2025-05-20T00:50:48.161Z] "GET /items HTTP/1.1" 200 - via_upstream - "-" 0 502 4 3 "172.18.0.100" "beegoServer" "2182ded3-f18d-98ff-a0a4-a04d3ecbb246" "catalog.istioinaction:80" "10.10.0.14:3000" outbound|80||catalog.istioinaction.svc.cluster.local 10.10.0.15:37960 10.200.3.118:80 172.18.0.100:0 - default
[2025-05-20T00:50:48.158Z] "GET /api/catalog HTTP/1.1" 200 - via_upstream - "-" 0 357 8 8 "172.18.0.100" "curl/8.7.1" "2182ded3-f18d-98ff-a0a4-a04d3ecbb246" "webapp.istioinaction.io" "10.10.0.15:8080" inbound|8080|| 127.0.0.6:33855 10.10.0.15:8080 172.18.0.100:0 outbound_.80_._.webapp.istioinaction.svc.cluster.local default
2025-05-20T00:50:49.337713Z debug envoy http external/envoy/source/common/http/conn_manager_impl.cc:329 [C367] new stream thread=33
2025-05-20T00:50:49.337851Z debug envoy http external/envoy/source/common/http/conn_manager_impl.cc:1049 [C367][S15717155453701150003] request headers complete (end_stream=true):
':authority', 'webapp.istioinaction.io'
':path', '/api/catalog'
':method', 'GET'
'user-agent', 'curl/8.7.1'
'accept', '*/*'
'x-app-tap', 'true'
'x-forwarded-for', '172.18.0.100'
'x-forwarded-proto', 'http'
'x-envoy-internal', 'true'
'x-request-id', 'c97ea269-2edc-994a-96f3-170e4abab9c8'
'x-envoy-decorator-operation', 'webapp.istioinaction.svc.cluster.local:80/*'
'x-envoy-peer-metadata', 'ChQKDkFQUF9DT05UQUlORVJTEgIaAAoaCgpDTFVTVEVSX0lEEgw
...
📌 핵심 요약
- EnvoyFilter의 역할: Istio의 고수준 API로 다룰 수 없는 Envoy 설정을 직접 조정하며, listeners, routes, filters 등을 커스터마이징할 수 있습니다.
- Tap 필터: HTTP 요청/응답을 스트리밍해 디버깅에 유용하며, EnvoyFilter로 설정 가능합니다.
- WorkloadSelector와 ConfigPatches: EnvoyFilter는 특정 워크로드와 필터 체인에 설정을 적용하며, 정확한 위치 지정을 위해 세심한 설정이 필요합니다.
- 주의사항: EnvoyFilter는 강력하지만 잘못된 설정은 데이터 플레인을 중단시킬 수 있으므로 주의가 필요합니다.
'Istio Hands-on Study [1기]' 카테고리의 다른 글
[7주차] 요청 경로에서 Istio 확장 : Lua로 Istio의 Data Plane 확장 (0) | 2025.04.23 |
---|---|
[7주차] 요청 경로에서 Istio 확장 : 외부 콜아웃으로 요청 속도 제한 (0) | 2025.04.23 |
[7주차] 요청 경로에서 Istio 확장 : Envoy의 확장 기능 (0) | 2025.04.23 |
[7주차] 조직에서 Istio 확장 : 멀티 클러스터, 멀티 네트워크, 멀티 Control Plane 의 Service Mesh 개요 (0) | 2025.04.23 |
[7주차] 조직에서 Istio 확장 : 멀티 클러스터 Service Mesh 개요 (0) | 2025.04.23 |
Comments