Ssoon
1주차 : Istio 첫걸음 (7) - Traffic Routing 본문
CloudNet@ 가시다님이 진행하는 Istio Hands-on Study [1기]
✅ Istio Traffic Routing
Istio를 사용하면 서비스 간 요청을 세밀하게 제어할 수 있어요.
즉, "어떤 요청이 어떤 서비스 버전으로 갈지"를 정밀하게 조절할 수 있는 기능입니다.
💡 Istio로 가능한 것
- 배포(Deploy)와 릴리스(Release)를 분리해서 안정적으로 운영 가능
- 트래픽을 사용자 그룹별로 분리해서 라우팅 가능
- 예: 내부 직원만 v2 사용, 일반 사용자는 계속 v1 사용
- 트래픽 점진 릴리스, 카나리 배포 등 다양한 전략 지원
🧰 사용하는 Istio 리소스
- DestinationRule: 서비스의 버전을 구분 (v1, v2 등)
- VirtualService: 요청 조건에 따라 어떤 버전으로 라우팅할지 설정
Istio는 서비스 버전별로 트래픽을 정밀하게 나누어 안정적으로 새로운 기능을 배포할 수 있게 도와줍니다.
✅ 실습
💠 catalog 애플리케이션의 새 버전(v2)을 배포
- catalog-v2라는 이름으로, catalog 앱의 버전 2를 1개의 파드로 실행합니다.
- 파드는 istioinaction/catalog:latest 이미지를 사용하고, 3000번 포트에서 HTTP 요청을 받습니다.
- 환경 변수로 네임스페이스(KUBERNETES_NAMESPACE)와 이미지 표시 설정(SHOW_IMAGE=true)을 전달합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat <<EOF | kubectl -n istioinaction apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: catalog
version: v2
name: catalog-v2
spec:
replicas: 1
selector:
matchLabels:
app: catalog
version: v2
template:
metadata:
labels:
app: catalog
version: v2
spec:
containers:
- env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: SHOW_IMAGE
value: "true"
image: istioinaction/catalog:latest
imagePullPolicy: IfNotPresent
name: catalog
ports:
- containerPort: 3000
name: http
protocol: TCP
securityContext:
privileged: false
EOF
💠 istioinaction 네임스페이스의 쿠버네티스 리소스(Deployment, Pod, Service, Endpoints)
- Deployment: catalog(v1), catalog-v2, webapp이 각각 1개 파드로 실행 중.
- Pod: catalog, catalog-v2, webapp 파드가 정상 실행 중(각각 2개 컨테이너).
- Service: catalog와 webapp이 내부 IP로 요청을 받음(80번 포트).
- Endpoints: catalog은 두 개의 IP:포트, webapp은 한 개의 IP:포트로 연결됨.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get deploy,pod,svc,ep -n istioinaction
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/catalog 1/1 1 1 3h13m
deployment.apps/catalog-v2 1/1 1 1 8s
deployment.apps/webapp 1/1 1 1 3h13m
NAME READY STATUS RESTARTS AGE
pod/catalog-6cf4b97d-5p442 2/2 Running 0 3h13m
pod/catalog-v2-6df885b555-tpkq2 2/2 Running 0 8s
pod/webapp-7685bcb84-mcmxv 2/2 Running 0 3h13m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/catalog ClusterIP 10.200.1.172 <none> 80/TCP 3h13m
service/webapp ClusterIP 10.200.1.145 <none> 80/TCP 3h13m
NAME ENDPOINTS AGE
endpoints/catalog 10.10.0.11:3000,10.10.0.14:3000 3h13m
endpoints/webapp 10.10.0.12:8080 3h13m
💠 istioinaction 네임스페이스의 Istio Gateway와 VirtualService 리소스
- Gateway: outfitters-gateway가 외부 트래픽을 처리
- VirtualService:
- catalog: catalog 서비스 트래픽 관리
- webapp-virtualservice: 모든 호스트(*)를 outfitters-gateway로 처리
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get gw,vs -n istioinaction
NAME AGE
gateway.networking.istio.io/outfitters-gateway 160m
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/catalog ["catalog"] 52m
virtualservice.networking.istio.io/webapp-virtualservice ["outfitters-gateway"] ["*"] 160m


💠 DestinationRule을 istioinaction 네임스페이스에 적용해 catalog 서비스의 트래픽을 버전별로 관리하도록 설정
- catalog 서비스를 대상으로, 두 개의 서브셋을 정의:
- version-v1: version: v1 레이블이 붙은 파드.
- version-v2: version: v2 레이블이 붙은 파드.
- 이 설정은 Istio가 catalog 서비스의 v1과 v2 버전을 구분해 트래픽을 분배
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat <<EOF | kubectl -n istioinaction apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: catalog
spec:
host: catalog
subsets:
- name: version-v1
labels:
version: v1
- name: version-v2
labels:
version: v2
EOF
destinationrule.networking.istio.io/catalog created
💠 Istio의 Gateway, VirtualService, DestinationRule 리소스를 확인
- Gateway: outfitters-gateway가 외부 트래픽을 처리
- VirtualService:
- catalog: catalog 서비스 트래픽 관리
- webapp-virtualservice: 모든 호스트(*)를 outfitters-gateway로 처리
- DestinationRule: catalog 서비스의 트래픽을 버전별로 구분
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get gw,vs,dr -n istioinaction
NAME AGE
gateway.networking.istio.io/outfitters-gateway 166m
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/catalog ["catalog"] 58m
virtualservice.networking.istio.io/webapp-virtualservice ["outfitters-gateway"] ["*"] 166m
NAME HOST AGE
destinationrule.networking.istio.io/catalog catalog 13s
💠 VirtualService를 istioinaction 네임스페이스에 적용해 catalog 서비스의 HTTP 트래픽을 version-v1 서브셋으로만 라우팅하도록 설정
- catalog 서비스로 오는 모든 요청을 version: v1 레이블이 붙은 파드(v1 버전)로 보냅니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat <<EOF | kubectl -n istioinaction apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
http:
- route:
- destination:
host: catalog
subset: version-v1
EOF
virtualservice.networking.istio.io/catalog configured
- 1초마다 http://127.0.0.1:30000/api/catalog에 요청을 보내 상품 목록을 JSON으로 출력하고, 현재 시간을 표시
while true; do curl -s http://127.0.0.1:30000/api/catalog | jq; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
- v1 접속 확인

💠 VirtualService를 istioinaction 네임스페이스에 적용해 catalog 서비스의 HTTP 트래픽을 조건에 따라 라우팅
- 요청에 x-dark-launch: v2 헤더가 있으면 version-v2 서브셋(v2 파드)으로 보냅니다.
- 그 외의 경우는 version-v1 서브셋(v1 파드)으로 보냅니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat <<EOF | kubectl -n istioinaction apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog
spec:
hosts:
- catalog
http:
- match:
- headers:
x-dark-launch:
exact: "v2"
route:
- destination:
host: catalog
subset: version-v2
- route:
- destination:
host: catalog
subset: version-v1
EOF
virtualservice.networking.istio.io/catalog configured
💠 Istio의 Gateway, VirtualService, DestinationRule 리소스를 확인
- Gateway: outfitters-gateway가 외부 트래픽을 받음
- VirtualService:
- catalog: catalog 서비스로 트래픽을 관리
- webapp-virtualservice: 모든 호스트(*)를 outfitters-gateway로 처리
- DestinationRule: catalog 서비스의 트래픽을 버전별로 구분
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get gw,vs,dr -n istioinaction
NAME AGE
gateway.networking.istio.io/outfitters-gateway 172m
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/catalog ["catalog"] 64m
virtualservice.networking.istio.io/webapp-virtualservice ["outfitters-gateway"] ["*"] 172m
NAME HOST AGE
destinationrule.networking.istio.io/catalog catalog 6m42s
- v1 접속 확인
while true; do curl -s http://127.0.0.1:30000/api/catalog | jq; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done

- v2 접속 확인
while true; do curl -s http://127.0.0.1:30000/api/catalog -H "x-dark-launch: v2" | jq; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done

💠 실습 완료 후 삭제
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl delete deploy,svc,gw,vs,dr --all -n istioinaction && kind delete cluster --name myk8s
deployment.apps "catalog" deleted
deployment.apps "catalog-v2" deleted
deployment.apps "webapp" deleted
service "catalog" deleted
service "webapp" deleted
gateway.networking.istio.io "outfitters-gateway" deleted
virtualservice.networking.istio.io "catalog" deleted
virtualservice.networking.istio.io "webapp-virtualservice" deleted
destinationrule.networking.istio.io "catalog" deleted
Deleting cluster "myk8s" ...
Deleted nodes: ["myk8s-control-plane"]
'Istio Hands-on Study [1기]' 카테고리의 다른 글
2주차 : Istio 데이터 플레인 > The Envoy proxy : Envoy 구성 (0) | 2025.04.15 |
---|---|
2주차 : Istio 데이터 플레인 > The Envoy proxy : Envoy 프록시란 무엇인가요? (0) | 2025.04.15 |
1주차 : Istio 첫걸음 (6) - Resiliency (0) | 2025.04.12 |
1주차 : Istio 첫걸음 (5) - Observability (0) | 2025.04.12 |
1주차 : Istio 첫걸음 (4) - 서비스 메시에 첫 번째 애플리케이션 배포 (0) | 2025.04.12 |
Comments