catalog service의 v1 버전을 배포합니다! 이 서비스는 Kubernetes 클러스터 안에서 동작하며, 외부에서 접근할 수 있도록 설정합니다.
다음 명령어를 실행해 catalog service를 배포합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f services/catalog/kubernetes/catalog.yaml -n istioinaction
serviceaccount/catalog created
service/catalog created
deployment.apps/catalog created
다음과 같은 리소스를 생성합니다:
serviceaccount/catalog
service/catalog
deployment.extensions/catalog
다음 명령어로 pod의 상태를 실시간으로 확인합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get pod -n istioinaction -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
catalog-6cf4b97d-dpflk 2/2 Running 0 56s 10.10.0.12 myk8s-control-plane <none> <none>
도메인 질의를 위한 임시 설정 'catalog.istioinaction.io' 도메인 이름을 로컬 컴퓨터(127.0.0.1)로 연결
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ echo "127.0.0.1 catalog.istioinaction.io" | sudo tee -a /etc/hosts
[sudo] password for ssoon:
127.0.0.1 catalog.istioinaction.io
클러스터 내부에서 catalog service가 제대로 동작하는지 확인합니다. netshoot로 내부에서 catalog 접속 확인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f ch5/catalog-vs.yaml -n istioinaction
virtualservice.networking.istio.io/catalog-vs-from-gw created
확인합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get gw,vs -n istioinaction
NAME AGE
gateway.networking.istio.io/catalog-gateway 2m41s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/catalog-vs-from-gw ["catalog-gateway"] ["catalog.istioinaction.io"] 43s
istio-ingressgateway Service(NodePort)에 포트 정보를 확인합니다.
이제 모든 설정이 완료됐습니다! Istio ingress gateway를 통해 외부에서 catalog service에 접근해볼게요. 호스트에서 NodePort(Service)로 접속을 확인합니다. Gateway를 통해 catalog service의 /items 엔드포인트를 호출합니다.
C:\Users\ssoon>curl -v -H "Host: catalog.istioinaction.io" http://localhost:30000
* Host localhost:30000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:30000...
* Trying 127.0.0.1:30000...
* Connected to localhost (127.0.0.1) port 30000
* using HTTP/1.x
> GET / HTTP/1.1
> Host: catalog.istioinaction.io
> User-Agent: curl/8.11.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
...
* Connection #0 to host localhost left intact
VirtualService를 설정해 Gateway로 들어온 트래픽을 catalog service로 라우팅합니다. 외부에서 curl 명령어로 테스트하여 서비스가 잘 동작하는지 확인합니다.
📌핵심 요약
작업 환경 정리: istioinaction namespace로 전환하고 기존 리소스를 삭제해 깨끗한 환경을 준비
Catalog Service 배포: catalog service v1을 배포하고, pod 상태를 확인한 뒤 클러스터 내부에서 동작을 테스트
Gateway 설정: Istio Gateway를 만들어 외부 트래픽을 catalog.istioinaction.io 도메인으로 받을 수 있게 설정.
VirtualService 설정: VirtualService를 통해 Gateway로 들어온 트래픽을 catalog service로 라우팅
외부 접근 테스트: curl 명령어로 외부에서 서비스에 접근해 정상적으로 응답하는지 확인.
🚀Istio로 Catalog Service v2 배포하고 트래픽 확인하기
🛠️ Catalog Service v2 배포하기
Istio의 트래픽 제어 기능을 확인하기 위해, 먼저 catalog service의 v2 버전을 배포합니다. v2는 v1와 다른 응답을 반환해서 트래픽이 어떻게 분배되는지 확인할 수 있습니다.
다음 명령어를 실행해 catalog service v2를 배포합니다: catalog-v2라는 이름의 새로운 deployment를 생성해요. 배포가 완료되면 클러스터에 v1과 v2가 모두 존재하게 됩니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f services/catalog/kubernetes/catalog-deployment-v2.yaml -n istioinaction
deployment.apps/catalog-v2 created
클러스터에 어떤 pod이 있는지 확인합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get deploy -n istioinaction --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
catalog 1/1 1 1 20m app=catalog,version=v1
catalog-v2 1/1 1 1 65s app=catalog,version=v2
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get pod -n istioinaction -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
catalog-6cf4b97d-dpflk 2/2 Running 0 23m 10.10.0.12 myk8s-control-plane <none> <none>
catalog-v2-6df885b555-nw8w7 2/2 Running 0 3m16s 10.10.0.13 myk8s-control-plane <none> <none>
catalog service v2를 배포해 v1과 함께 클러스터에서 실행되도록 설정합니다.
🔍 Catalog Service v1과 v2의 응답 비교하기
이제 catalog service에 여러 번 요청을 보내서 v1과 v2의 응답이 어떻게 다른지 확인해볼게요. Istio는 기본적으로 트래픽을 pod 간에 분배하기 때문에, v1과 v2 응답이 섞여 출력됩니다.
다음 명령어를 실행해 catalog service의 /items 엔드포인트에 10번 요청을 보냅니다:
응답을 보면v2 응답에는 imageUrl 필드가 포함되어 있고,v1 응답에는 이 필드가 없습니다. 여러 번 요청을 보내면 v1과 v2 응답이 무작위로 섞여 나오는 걸 볼 수 있습니다. 이는 Istio가 트래픽을 두 pod에 자동으로 분배하기 때문이에요.
catalog service에 여러 번 요청을 보내 v1과 v2의 응답을 비교합니다. v2 응답에는 imageUrl 필드가 추가되어 있어 두 버전의 차이를 확인할 수 있습니다!
📌핵심 요약
Catalog Service v2 배포: catalog-deployment-v2.yaml 파일을 적용해 v2 버전을 배포하고, kubectl get pod로 v1과 v2 pod이 정상 실행 중인지 확인
응답 비교: Istio ingress gateway를 통해 여러 번 요청을 보내 v1과 v2의 응답 차이를 확인. v2는 imageUrl 필드가 추가된 점이 특징
트래픽 분배 관찰: Istio가 트래픽을 v1과 v2 pod에 자동으로 분배해 응답이 섞여 나오는 걸 확인
🚀 Istio로 Catalog Service v1으로 모든 트래픽 라우팅하기
🗂️ DestinationRule로 v1과 v2 구분하기
Istio가 catalog service의 v1과 v2를 구분할 수 있도록, 먼저 DestinationRule을 설정합니다. 이 리소스는 서비스의 서로 다른 버전을 subset으로 정의해서 Istio가 트래픽을 올바르게 라우팅할 수 있게 도와줍니다.
catalog service의 v1과 v2는 Kubernetes Deployment에서 각각 app: catalog, version: v1과 app: catalog, version: v2라는 레이블로 구분돼 있습니다.. 이를 기반으로 DestinationRule을 아래와 같이 정의합니다: 이 설정은 catalog 서비스의 두 버전을 version-v1과 version-v2라는 이름의 subset으로 나눠 정의해요.
DestinationRule을 적용합니다. 이로써 Istio는 v1과 v2를 명확히 구분할 준비가 되었습니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f ch5/catalog-dest-rule.yaml -n istioinaction
destinationrule.networking.istio.io/catalog created
Istio의 DestinationRule 리소스를 조회합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get destinationrule -n istioinaction
NAME HOST AGE
catalog catalog.istioinaction.svc.cluster.local 68s
istio-ingressgateway의 Envoy 프록시가 인식하고 있는 catalog.istioinaction.svc.cluster.local 서비스에 대한 클러스터 설정 정보를 확인합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ docker exec -it myk8s-control-plane istioctl proxy-config cluster deploy/istio-ingressgateway.istio-system --fqdn catalog.istioinaction.svc.cluster.local
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE
catalog.istioinaction.svc.cluster.local 80 - outbound EDS catalog.istioinaction
catalog.istioinaction.svc.cluster.local 80 version-v1 outbound EDS catalog.istioinaction
catalog.istioinaction.svc.cluster.local 80 version-v2 outbound EDS catalog.istioinaction
DestinationRule을 사용해 catalog service의 v1과 v2를 각각 version-v1과 version-v2 subset으로 정의합니다. 이렇게 하면 Istio가 버전을 구분해 트래픽을 라우팅할 수 있습니다!
🔄 VirtualService로 모든 트래픽을 v1으로 라우팅하기
이제 Istio가 v1과 v2를 구분할 수 있으니, 모든 트래픽을 catalog service의 v1으로 라우팅하도록 VirtualService를 업데이트합니다. 이를 통해 v2로 가는 트래픽을 차단하고 v1만 응답하도록 설정할 수 있습니다.
아래는 업데이트된 VirtualService 설정입니다: catalog.istioinaction.io로 들어오는 모든 HTTP 요청을 catalog 서비스의 version-v1 subset(즉, v1)으로 라우팅하도록 지정합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ cat ch5/catalog-vs-v1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog-vs-from-gw
spec:
hosts:
- "catalog.istioinaction.io" #VirtualService는 'catalog.istioinaction.io' 도메인으로 들어오는 트래픽에 적용
gateways:
- catalog-gateway
http:
- route: #라우팅 동작을 정의
- destination: #트래픽이 전달될 목적지를 지정
host: catalog #목적지 서비스의 이름이 'catalog'임
subset: version-v1 #해당 서비스의 특정 서브셋(subset)인 'version-v1'으로 트래픽을 보냅니다.
VirtualService를 업데이트해 모든 트래픽을 version-v1 subset으로 라우팅합니다. 이렇게 하면 catalog service의 v1만 응답하게 됩니다!
✅ v1 응답 확인하기
catalog service에 요청을 보내 실제로 v1 응답만 오는지 확인합니다. 다음 명령어를 실행해 10번 요청을 보냅니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ for i in {1..10}; do curl -s http://catalog.istioinaction.io:30000/items/ ; printf "\n\n"; done
[
{
"id": 1,
"color": "amber",
"department": "Eyewear",
"name": "Elinor Glasses",
"price": "282.00"
},
{
...
이제 모든 응답이 v1에서 오기 때문에, 이전에 v2 응답에서 보였던 imageUrl 필드가 없는 결과만 나타납니다. 이는 Istio가 트래픽을 version-v1 subset으로 정확히 라우팅하고 있다는 뜻입니다.
VirtualService 적용 후 요청을 보내 v1 응답만 오는지 확인합니다. 모든 트래픽이 v1으로 라우팅되면 imageUrl 필드가 없는 응답만 나타납니다!
📌핵심 요약
DestinationRule 설정: DestinationRule을 만들어 catalog service의 v1과 v2를 version-v1과 version-v2 subset으로 정의
VirtualService 업데이트: VirtualService를 수정해 catalog.istioinaction.io로 들어오는 모든 트래픽을 version-v1 subset으로 라우팅하도록 설정
응답 테스트: 여러 번 요청을 보내 모든 응답이 v1에서 오는지 확인 > imageUrl 필드가 없는 응답만 나타나 성공적으로 v1 라우팅 완료
🚀Istio로 특정 요청을 Catalog Service v2로 라우팅하기
🔧 VirtualService로 특정 요청 라우팅 설정하기
Istio를 사용하면 HTTP 헤더 같은 조건을 기반으로 트래픽을 원하는 서비스 버전으로 보낼 수 있습니다. x-istio-cohort: internal 헤더가 포함된 요청을 catalog service의 v2 버전으로 라우팅하도록 설정합니다. 나머지 요청은 v1으로 가도록 유지합니다. 아래는 이를 구현한 VirtualService설정입니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ cat ch5/catalog-vs-v2-request.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: catalog-vs-from-gw
spec:
hosts:
- "catalog.istioinaction.io"
gateways:
- catalog-gateway
http: #HTTP 트래픽에 대한 라우팅 규칙을 정의
- match: #첫 번째 라우팅 규칙이 적용될 조건을 정의
- headers: #HTTP 헤더에 기반한 매칭 조건을 지정
x-istio-cohort: #매칭할 HTTP 헤더의 이름이 'x-istio-cohort'임을 나타냄
exact: "internal" #'x-istio-cohort' 헤더의 값이 정확히 "internal"일 때 이 규칙이 적용됨
route:
- destination:
host: catalog
subset: version-v2
- route:
- destination:
host: catalog
subset: version-v1
이 설정을 살펴보면:
match 블록에서 x-istio-cohort 헤더 값이 정확히 internal인 요청을 찾습니다.
이제 2장에서 다뤘던 아키텍처를 복원합니. 이 아키텍처는 webapp 서비스가 catalog 서비스를 호출하는 구조로, Istio Gateway를 통해 외부 트래픽이 webapp으로 들어오게 설정할게요.
먼저 webapp 서비스와 관련 리소스를 배포합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -n istioinaction -f services/webapp/kubernetes/webapp.yaml
serviceaccount/webapp created
service/webapp created
deployment.apps/webapp created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get gw,vs -n istioinaction
NAME AGE
gateway.networking.istio.io/coolstore-gateway 39s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/webapp-virtualservice ["coolstore-gateway"] ["webapp.istioinaction.io"] 39s
도메인 질의를 위한 임시 설정
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ echo "127.0.0.1 webapp.istioinaction.io" | sudo tee -a /etc/hosts
cat /etc/hosts | tail -n 3
[sudo] password for ssoon:
127.0.0.1 webapp.istioinaction.io
ff02::2 ip6-allrouters
127.0.0.1 catalog.istioinaction.io
127.0.0.1 webapp.istioinaction.io
이제 webapp 서비스의 /api/catalog 엔드포인트를 호출해 catalog 서비스의 응답을 확인합니다.
이 요청은 webapp을 통해 catalog 서비스로 전달되며, catalog의 v1과 v2 응답이 섞여 나타납니다. 이는 Istio가 기본적으로 트래픽을 두 버전의 pod에 분배하기 때문입니다.
다음으로, VirtualService를 만들어 모든 트래픽을 catalog의 v1으로 라우팅하도록 설정합니다: virtualservice.networking.istio.io/catalog를 생성하며, catalog 서비스로 가는 모든 내부 요청을 version-v1 subset으로 보냅니다.