이전 포스팅에서는 외부 트래픽을 클러스터로 유입시키는 방법(Istio IngressGateway)과, 그 과정에서 고려해야 할 요소들을 살펴봤다. 이번 포스팅에는 클러스터 내부로 들어온 요청이 어떻게 적절한 서비스로 라우팅 되는지에 대해 알아본다.
클러스터 안에 있는 서비스들은 서로 어떻게 통신할까? 또, 클러스터 밖에 있는 다른 서비스와 통신하려면 어떤 경로를 거쳐야 할까?
Istio는 VirtualService를 통해 트래픽이 어떤 방식으로 라우팅 될지 애플리케이션 간 트래픽을 개별 요청 단위까지 세밀하게 제어할 수 있다.
Istio의 다양한 트래픽 관리 기법에 대해 알아보자.
요청 라우팅(Routing requests with Istio)
새로운 코드 배포 리스크 위험 줄이기
Blue/Green 배포는 기존 서비스의 v1(파란색)과 새로운 버전 v2(녹색)을 나란히 프로덕션 환경에 배포한 뒤, 원하는 시점에 트래픽을 v2로 전환하는 방법이다. 이 접근 방식 덕분에, 만약 새로운 버전(v2)에서 문제가 발생하더라도 기존 버전(v1)으로 신속하게 롤백할 수 있었고, 덕분에 배포 중 중단 리스크를 크게 줄일 수 있었다.
하지만 Blue/Green 배포에도 한계가 있다. v1에서 v2로 트래픽을 전환하는 순간, 여전히 모든 코드 변경이 한 번에 릴리스 되는 “빅뱅” 현상을 피할 수는 없기 때문이다.
Istio의 세밀한 트래픽 제어를 통해, 서비스를 변경하거나 새로운 버전을 배포할 때 사용자가 변화에 안전하게 노출될 수 있도록 방해를 최소화하는 방법을 알아보자.
이렇게 하면, 전체 사용자에게 영향을 주지 않고, 통제된 방식으로 특정 그룹에만 새로운 기능을 점진적으로 노출할 수 있다.
실습 코드는 다음과 같다. (자세한 애플리케이션 정보는 이전 차시 참고)
git clone https://github.com/AcornPublishing/istio-in-action
cd book-source-code-master
카탈로그 서비스 v1 배포
# Let’s deploy v1 of our catalog service. From the root of the book’s source code, run the following command
kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction
# 확인
kubectl get pod -n istioinaction -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
catalog-6cf4b97d-ftl77 2/2 Running 0 42s 10.10.0.14 myk8s-control-plane <none> <none>
# 도메인 질의를 위한 임시 설정 : 실습 완료 후에는 삭제 해둘 것
echo "127.0.0.1 catalog.istioinaction.io" | sudo tee -a /etc/hosts
cat /etc/hosts | tail -n 3
Gateway 및 VirtualService 설정
외부에서 접근할 수 있도록 Gateway와 VirtualService를 설정한다.
# 외부 노출을 위해 Gateway 설정
cat ch5/catalog-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: catalog-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "catalog.istioinaction.io"
kubectl apply -f ch5/catalog-gateway.yaml -n istioinaction
# 트래픽을 catalog 서비스로 라우팅하는 VirtualService 리소스 설정
cat ch5/catalog-vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog-vs-from-gw
spec:
hosts:
- "catalog.istioinaction.io"
gateways:
- catalog-gateway
http:
- route:
- destination:
host: catalog
kubectl apply -f ch5/catalog-vs.yaml -n istioinaction
# 확인
kubectl get gw,vs -n istioinaction
NAME AGE
gateway.networking.istio.io/catalog-gateway 95s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/catalog-vs-from-gw ["catalog-gateway"] ["catalog.istioinaction.io"] 3s
# 도메인 질의를 위한 임시 설정 : 실습 완료 후에는 삭제 해둘 것
echo "127.0.0.1 catalog.istioinaction.io" | sudo tee -a /etc/hosts
cat /etc/hosts | tail -n 3
카탈로그 서비스 v2 배포
릴리즈(배포) 과정을 연습하기 위해, 기존 카탈로그 서비스에 이어 v2 버전을 추가로 배포해 본다
kubectl apply -f services/catalog/kubernetes/catalog-deployment-v2.yaml -n istioinaction
v2 버전의 카탈로그 서비스는 기존 v1에 비해 ImageUrl 필드가 추가된 응답을 반환한다.
라우팅 설정을 하지 않았기 때문에, 기본적으로는 v1과 v2가 service에 의해 라운드로빈 방식으로 트래픽을 분산해서 모두 호출된다.
v1 서비스만 호출하도록 설정 v2를 배포했지만, 아직은 트래픽이 v1과 v2에 모두 분산되기 때문에, 특정 버전(v1)으로만 트래픽을 고정하도록 설정을 변경한다.
DestinationRule 생성
v1과 v2를 서브셋으로 등록하는 DestinationRule을 생성한다.
cat ch5/catalog-dest-rule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: catalog
spec:
host: catalog.istioinaction.svc.cluster.local
subsets:
- name: version-v1
labels:
version: v1
- name: version-v2
labels:
version: v2
# 배포
kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction
VirtualService 수정
VirtualService를 수정해, 라우팅 대상이 v1 서브셋만 가리키도록 설정한다.
cat ch5/catalog-vs-v1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog-vs-from-gw
spec:
hosts:
- "catalog.istioinaction.io"
gateways:
- catalog-gateway
http:
- route:
- destination:
host: catalog
subset: version-v1
kubectl apply -f ch5/catalog-vs-v1.yaml -n istioinaction
istio-proxy(envoy) 설정 확인
[ 특정 콘텐츠가 담긴 요청 라우팅 ]
HTTP 요청에 특정 헤더를 추가해서, 트래픽을 v2 서비스로만 보내는 방식을 살펴본다.
예를 들어, 요청 헤더에 x-istio-cohort: internal 값을 포함시키면,
이 요청은 catalog v2로 라우팅 되도록 설정할 수 있다.
VirtualService 수정
HTTP 요청 헤더 x-istio-cohort: internal 이 포함된 경우, 트래픽을 v2 서비스로 라우팅 하는 VirtualService를 수정한다.
# VirtualService 적용
kubectl apply -f ch5/catalog-vs-v2-request.yaml -n istioinaction
v2 서비스로 요청 보내기
아래처럼 curl 명령어를 사용해서, 헤더를 포함한 요청을 보낸다.
curl http://catalog.istioinaction.io:30000/items -H "x-istio-cohort: internal"
요청에 x-istio-cohort: internal 헤더가 포함되어 있기 때문에, 이 트래픽은 기존 v1 서비스가 아니라 v2 서비스로 전달된다.
설정 확인
Cluster와 Endpoint 관계를 보면, Cluster는 여러 엔드포인트(서비스 인스턴스)를 그룹화하는 역할을 한다.
istio-proxy 설정을 확인해 보면, 순서에 따라, 위에서부터 적용되는데, v2에 헤더 매치 설정이 들어갔음을 확인할 수 있다.
이제 트래픽은 오직 v1 서비스로만 라우팅 되며, v2는 호출되지 않는다. 이를 통해 점진적 배포(Dark Launch)**를 세밀하게 제어할 수 있게 된다.
호출 그래프 내 깊은 위치에서 라우팅(Mesh Gateway)
지금까지는 Istio를 사용해 요청을 라우팅 하는 방법을 살펴봤지만, 라우팅이 수행되는 위치는 주로 에지(Edge)나 게이트웨이(Gateway)에 한정되어 있었다.
하지만 트래픽 라우팅 규칙은 서비스 호출 그래프 내 깊은 곳에서도 적용할 수 있다.
Mesh Gateway를 사용함으로써, 외부 트래픽뿐만 아니라, 클러스터 내부 서비스 간 트래픽도 세밀하게 제어하고, A/B 테스트나 다크 런치 같은 고급 배포 전략을 내부 통신에도 적용할 수 있다.(내부 통신에도 VirtualService 규칙을 적용할 수 있게 만드는 게 목적!)
Mesh 내부에서의 라우팅
지금까지 다룬 라우팅 방식은 주로 Ingress Gateway를 통한 외부 트래픽을 다루는 정책이었다.
하지만 실제 서비스 내부에서는, 서비스 ➔ 서비스 간 호출 흐름에도 Mesh Gateway(Mesh 레벨) 라우팅을 적용할 수 있다.
Gateway와 VirtualService 설정
먼저 webapp 서비스에 대한 Gateway와 VirtualService를 생성한다.
webapp에서 catalog로 가는 요청은 기본적으로 Kubernetes ClusterIP 서비스 라우팅을 사용한다.
cat services/webapp/istio/webapp-catalog-gw-vs.yaml
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: coolstore-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "webapp.istioinaction.io"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: webapp-virtualservice
spec:
hosts:
- "webapp.istioinaction.io"
gateways:
- coolstore-gateway
http:
- route:
- destination:
host: webapp
port:
number: 80
# 배포
kubectl apply -f services/webapp/istio/webapp-catalog-gw-vs.yaml -n istioinactio
webapp 사이드카 프록시 로그 활성화
webapp의 istio-proxy 컨테이너에서 트래픽 흐름을 살펴보기 위해, 로그를 활성화한다.
# webapp 액세스 로그 활성화
cat << EOF | kubectl apply -f -
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: webapp
namespace: istioinaction
spec:
selector:
matchLabels:
app: webapp
accessLogging:
- providers:
- name: envoy
disabled: false
EOF
webapp의 istio-proxy 컨테이너에서 트래픽 흐름을 살펴보자.
# webapp istio-proxy 로그 활성화
# 신규 터미널
kubectl logs -n istioinaction -l app=webapp -c istio-proxy -f
Catalog 서비스 버전별 서브셋 설정
ch5/catalog-dest-rule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: catalog
spec:
host: catalog.istioinaction.svc.cluster.local
subsets:
- name: version-v1
labels:
version: v1
- name: version-v2
labels:
version: v2
kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction
VirtualService 생성
Mesh 내부에서 직접 라우팅이 적용될 수 있도록, VirtualService 리소스도 설정한다.
VirtualService 리소스를 조회하면, GATEWAYS 항목에 “mesh”가 명시되어 있는 걸 확인할 수 있다.
kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction
# VirtualService 확인 : GATEWAYS 에 mesh 확인
kubectl get vs -n istioinaction
NAME GATEWAYS HOSTS AGE
catalog ["mesh"] ["catalog"] 12s
webapp-virtualservice ["coolstore-gateway"] ["webapp.istioinaction.io"] 28s
호출 테스트(반복 호출)
while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog -I | head -n 1 ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
트래픽 전환하기(Traffic Shifting)
수동 가중치 기반 카나리 배포(Manual Carnary release)
이전 절에서는 헤더 비교를 기반으로 특정 사용자 그룹에 다크 런치를 수행하는 라우팅을 다뤘다면,
이번에는 가중치 기반 트래픽 분배를 활용해, 동일한 서비스를 여러 버전으로 배포한 뒤, 트래픽을 원하는 비율로 분산시키는 방법을 실습한다.
예를 들어, catalog 서비스의 v2 버전을 내부 직원에게 다크 런치했는데,
이제는 전체 트래픽 중 10%만 v2로 보내고, 나머지 90%는 v1으로 보내고 싶다고 가정해 보자.
이렇게 하면 v2 버전에 대한 부정적인 영향 범위를 제한할 수 있고, 문제가 발견되면 v2의 가중치를 0%로 줄여 빠르게 롤백할 수 있다.
이제 Istio를 활용해 가중치 기반 트래픽 전환을 수작업으로 수행해 보자.
서비스 상태 확인
- catalog v1과 v2가 각각 배포되어 있고,
- webapp도 최신 버전으로 배포된 상태여야 한다.
# 배포 상태를 확인
kubectl get deploy,rs,pod -n istioinaction --show-labels
모든 트래픽을 catalog v1으로 재설정
먼저 전체 트래픽을 v1으로 보내도록 VirtualService를 재설정한다
# 모든 트래픽을 catalog service v1 으로 재설정하자
cat ch5/catalog-vs-v1-mesh.yaml
...
http:
- route:
- destination:
host: catalog
subset: version-v1
kubectl apply -f ch5/catalog-vs-v1-mesh.yaml -n istioinaction
배포 완료 후, 호출 테스트를 진행한다.
curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
트래픽 10%를 v2로 전환
이번에는 전체 트래픽의 10%만 v2로, 나머지 90%는 v1으로 보내보자.
cat ch5/catalog-vs-v2-10-90-mesh.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
gateways:
- mesh
http:
- route:
- destination:
host: catalog
subset: version-v1
weight: 90
- destination:
host: catalog
subset: version-v2
weight: 10
# 적용
kubectl apply -f ch5/catalog-vs-v2-10-90-mesh.yaml -n istioinaction
# VirtualService 적용 확인
kubectl get vs -n istioinaction catalog
NAME GATEWAYS HOSTS AGE
catalog ["mesh"] ["catalog"] 1h
호출 테스트: v2 호출 비중 확인
• imageUrl 필드가 존재하는 응답은 v2 서비스의 결과
• 호출 결과를 통해 v2 비율을 대략적으로 검증
# 100번 반복 시도.
for i in {1..100}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
10
100번 시도 중, v2의 호출은 10번이므로, 트래픽 가중치 설정이 잘 적용되었음을 확인할 수 있다.
라우팅 설정 내부 확인 (proxy-config)
webapp의 envoy proxy 설정을 확인해 보면 설정한 가중치를 확인할 수 있다.
트래픽을 50:50으로 분할
이번에는 트래픽을 v1과 v2 각각 50%로 나누어보자.
cat ch5/catalog-vs-v2-50-50-mesh.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
gateways:
- mesh
http:
- route:
- destination:
host: catalog
subset: version-v1
weight: 50
- destination:
host: catalog
subset: version-v2
weight: 50
# 적용
kubectl apply -f ch5/catalog-vs-v2-50-50-mesh.yaml -n istioinaction
# 호출 테스트 : v2 호출 비중 확인
for i in {1..100}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
50
이번 절에서는 여러 버전 사이에서 트래픽을 수작업으로 점진 전환하는 실습을 진행했다.
하지만 실제 운영 환경에서는 이런 작업을 수작업으로 반복하는 건 번거롭고, 실수할 위험도 크다.
이를 해결하기 위해 자동화된 배포 도구를 사용하는 게 훨씬 안전하고 효율적이다.
특히, Flagger를 사용하면 Istio의 VirtualService 리소스를 기반으로 Canary, A/B 테스트, Blue-Green 배포를 자동으로 관리할 수 있다. (이 내용은 다음 포스팅에서 더 자세히 다룰 예정이다.)
트래픽 미러링(Traffic Mirroring)
트래픽 미러링으로 리스크 줄이기
앞서 살펴본 요청 수준 라우팅과 트래픽 전환 같은 기술들은 릴리스 위험성을 낮추는 데 도움을 준다.
하지만 이 두 방법 모두 라이브 트래픽을 직접 사용하기 때문에, 아무리 파급 범위를 제어한다고 해도 사용자에게 실제 영향을 줄 가능성은 완전히 사라지지 않는다.
트래픽 미러링을 사용하면, 운영 환경의 실제 트래픽을 새로운 배포 대상에 복사(mirror) 해서 보내지만, 응답은 원래 서비스로만 돌아가게 된다.
즉, 사용자에게 전혀 영향을 주지 않고, 새로운 버전의 코드가 실제 트래픽을 어떻게 처리하는지 리얼한 피드백을 얻을 수 있다.
Istio는 이런 트래픽 미러링 기능을 기본 지원하기 때문에, 이를 활용하면, 배포나 릴리스 과정에서의 위험성을 앞서 다룬 방법들보다 훨씬 더 줄일 수 있다.
미러링을 적용할 VirtualService 설정
- 현재 VirtualService는 라이브 트래픽을 전부 catalog v1으로 보내면서, 동시에 catalog v2로 트래픽을 미러링 한다.
- 미러링은 요청의 복사본을 만들어 catalog-v2로 전송하는, 일명 “보내고 잊는(send and forget)” 방식으로 작동한다.
- 미러링 된 요청은 Istio 프록시가 응답을 모두 무시(drop) 하기 때문에, 성공하든 실패하든 실제 사용자 요청에는 전혀 영향을 주지 않는다
# 미러링 VS 설정 적용
kubectl apply -f ch5/catalog-vs-v2-mirror.yaml -n istioinaction
로그 활성화 (Telemetry 추가)
catalog 서비스에 대해 액세스 로그를 활성화해서, v1과 v2로 트래픽이 어떻게 전달되는지 살펴본다.
cat << EOF | kubectl apply -f -
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: catalog
namespace: istioinaction
spec:
accessLogging:
- disabled: false
providers:
- name: envoy
selector:
matchLabels:
app: catalog
EOF
트래픽 호출 테스트
v1 서비스로만 호출을 시도한다
# v1 호출 테스트
#
for i in {1..100}; do curl -s http://webapp.istioinaction.io:30000/api/catalog | grep -i imageUrl ; done | wc -l
0 # 실제 사용자 요청은 모두 v1 서비스로만 전달된다.
v1, v2 서비스 로그 확인
v1 서비스 로그를 보면 정상적으로 요청을 처리하는 걸 확인할 수 있다.
kubectl logs -n istioinaction -l app=catalog -l version=v1 -c catalog -f
v2 서비스 로그를 보면, 요청 헤더의 Host 값이 다르게 설정된 걸 확인할 수 있다.
• Host 값에 -shadow 접미사가 붙는다.
• 미러링 된 요청임을 서비스가 식별할 수 있다.
Host에 -shadow가 붙는 이유는 미러링된 요청이 catalog v2로 복제될 때, Host 헤더가 수정되어 catalog-shadow로 변경된다.
이를 통해서 서비스는 미러링된 요청임을 인식하고, 트랜잭션을 커밋하지 않거나, 리소스를 많이 소모하는 작업을 생략할 수 있다.
즉, 미러링된 요청은 실제 서비스 로직에 영향을 주지 않도록 설계된다.
Envoy 트래픽 설정 확인
트래픽 미러링은 요청 라우팅, 트래픽 전환과 함께 릴리즈 시, 리스크를 줄이는 매우 강력한 기술 중 하나이다.
메쉬에서 관리하는 네트워크 외부망 통제하기
외부 트래픽 통제의 필요성
기본적으로, Istio는 클러스터 외부로 나가는 트래픽을 허용한다. 애플리케이션이 서비스 메시가 관리하지 않는 외부 웹사이트나 서비스를 호출하려고 해도, Istio는 이를 막지 않고 그냥 트래픽을 나가게 한다.
하지만 모든 트래픽은 기본적으로 사이드카 프록시(istio-proxy) 를 거치기 때문에, Istio 설정만 조정하면 트래픽 라우팅을 통제하거나, 심지어 외부로 나가는 모든 트래픽을 차단할 수도 있다.
서비스나 애플리케이션이 손상됐을 때 악성 코드가 외부와 통신하는 걸 방지할 때 유용한 전략이 될 수 있다.
Istio 외부 트래픽 통제하기(outboundTrafficPolicy)
Istio는 outboundTrafficPolicy
라는 설정으로 외부로 나가는 트래픽을 어떻게 처리할지 제어할 수 있다
outboundTrafficPolicy3가지 모드
모드 | 설명 |
---|---|
ALLOW_ANY (기본값) | 모든 외부 트래픽 허용 |
REGISTRY_ONLY | Istio에 등록된 서비스만 허용 (나머지 차단) |
ALLOW_LIST | 특정 도메인만 허용하는 리스트 관리 방식 |
[ 실습: 외부망 차단 설정 ]
외부 다운로드 시도 (차단 전 상태)
다운로드가 정상 작동한다. (외부 통신 허용 상태)
# 현재 istiooperators meshConfig 설정 확인(적용 전)
kubectl get istiooperators -n istio-system -o json
...
"meshConfig": {
"defaultConfig": {
"proxyMetadata": {}
},
"enablePrometheusMerge": true
},
...
# webapp 파드에서 외부 다운로드
kubectl exec -it deploy/webapp -n istioinaction -c webapp -- wget https://raw.githubusercontent.com/gasida/KANS/refs/heads/main/msa/sock-shop-demo.yaml
Istio outboundTrafficPolicy를 REGISTRY_ONLY로 변경
이제 등록된 서비스(Mesh) 외에는 모두 차단된다.
# 설정 변경
istioctl install --set profile=default --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
meshConfig 설정 확인
차단 확인
다시 외부 다운로드 시도를 하면 외부 트래픽이 차단됨을 확인할 수 있다.
# webapp 파드에서 외부 다운로드 시도 시, 차단
kubectl exec -it deploy/webapp -n istioinaction -c webapp -- wget https://raw.githubusercontent.com/gasida/KANS/refs/heads/main/msa/sock-shop-demo.yaml
Connecting to raw.githubusercontent.com (185.199.108.133:443)
wget: error getting response: Connection reset by peer
command terminated with exit code 1
webapp 사이드카 로그 확인
BlackHoleCluster로 연결되면서 트래픽이 차단된 것을 볼 수 있다
[2025-04-25T05:23:52.211Z] "- - -" 0 UH - - "-" 0 0 0 - "-" "-" "-" "-" "-" BlackHoleCluster - 185.199.111.133:443 10.10.0.14:33848 - -
메쉬 외부 서비스와 통신 제어하기(ServiceEntry)
모든 서비스가 항상 서비스 메시 내부에만 있는 건 아니다.
때로는 메시 내부 서비스가 메시 외부의 서비스(예: 외부 API, 데이터베이스, 캐시 등)와 통신해야 할 상황이 생긴다.
이럴 때 ServiceEntry를 활용하면, 외부 서비스와도 메쉬 수준에서 통제된 방식으로 통신할 수 있다.
ServiceEntry란?
ServiceEntry는 외부 서비스를 Istio의 내부 서비스 디스커버리 저장소에 등록하는 역할을 한다.
• Istio는 자체적으로 서비스 저장소(Registry)를 관리하는데, 여기에 등록된 서비스만 메쉬 내에서 탐색되고 통신이 가능하다.
기본적으로는 쿠버네티스 API를 기반으로 저장소를 구성하지만, ServiceEntry를 추가하면 외부 서비스도 메쉬 내부처럼 인식할 수 있다.
실습 시나리오
- webapp의 Forum 서비스가 외부의 jsonplaceholder.typicode.com API를 호출해 데이터를 가져온다.
- 현재 OutboundTrafficPolicy를 REGISTRY_ONLY로 설정했기 때문에, 외부로 나가는 모든 트래픽은 차단되어 있다.
- 따라서 ServiceEntry를 등록해서 이 외부 호출을 허용하는 흐름을 실습해 본다.
Forum 서비스 배포
# forum 설치
cat services/forum/kubernetes/forum-all.yaml
kubectl apply -f services/forum/kubernetes/forum-all.yaml -n istioinaction
# 확인
kubectl get deploy,svc -n istioinaction -l app=webapp
docker exec -it myk8s-control-plane istioctl proxy-status
# webapp 웹 접속
open http://webapp.istioinaction.io:30000/
Forum 서비스가 webapp에 데이터를 전달해야 하지만, 현재는 외부 API(jsonplaceholder.typicode.com)에 접근할 수 없기 때문에 webapp 화면에 Forum 데이터가 보이지 않는다.
ServiceEntry 생성 및 적용
외부 트래픽을 허용하기 위해 jsonplaceholder.typicode.com에 대한 ServiceEntry를 작성한다.
# 적용
kubectl apply -f ch5/forum-serviceentry.yaml -n istioinaction
적용 결과 확인
외부 API 도메인에 대한 IP 목록이 HEALTHY 상태로 등록된 걸 확인할 수 있다
# 라우트(Route) 등록 확인
docker exec -it myk8s-control-plane istioctl proxy-config routes deploy/forum.istioinaction | grep json
80 jsonplaceholder.typicode.com /*
# **엔드포인트(Endpoint) 등록 확인**
docker exec -it myk8s-control-plane istioctl proxy-config endpoint deploy/forum.istioinaction --cluster 'outbound|80||jsonplaceholder.typicode.com'
ENDPOINT STATUS OUTLIER CHECK CLUSTER
104.21.112.1:80 HEALTHY OK outbound|80||jsonplaceholder.typicode.com
104.21.16.1:80 HEALTHY OK outbound|80||jsonplaceholder.typicode.com
104.21.32.1:80 HEALTHY OK outbound|80||jsonplaceholder.typicode.com
104.21.48.1:80 HEALTHY OK outbound|80||jsonplaceholder.typicode.com
104.21.64.1:80 HEALTHY OK outbound|80||jsonplaceholder.typicode.com
104.21.80.1:80 HEALTHY OK outbound|80||jsonplaceholder.typicode.com
104.21.96.1:80 HEALTHY OK outbound|80||jsonplaceholder.typicode.com
결과
이제 webapp의 Forum 서비스는 jsonplaceholder.typicode.com API를 정상적으로 호출할 수 있고, webapp 화면에도 Forum 데이터가 표시된다.
OutboundTrafficPolicy를 REGISTRY_ONLY로 설정했더라도, ServiceEntry를 활용하여, 명시적으로 등록된 외부 서비스만 허용하는 보안성 높은 구조를 만들 수 있다. = 화이트리스트(Whitelist) 방식
'Infrastructure' 카테고리의 다른 글
Istio 시리즈 # 5 – 네트워크 복원력 강화하기(Resilience) (0) | 2025.04.27 |
---|---|
Istio 시리즈 # 3 – 외부 트래픽 진입점, Ingress Gateway 알아보기 (0) | 2025.04.20 |
Istio 시리즈 # 2 - Istio의 핵심, Envoy Proxy를 이해하자 (0) | 2025.04.20 |
Istio 시리즈 # 1 - 설치부터 기본 트레픽 제어까지 (0) | 2025.04.13 |
개발자(엔지니어)에게 꼭 필요한 기초 암호학(X.509) (0) | 2025.03.15 |