Overview
이번 글에서는 Istio를 Kubernetes 클러스터에 설치하고, Bookinfo 샘플 애플리케이션을 통해 실습하는 과정을 정리했다.
Istio는 서비스 메쉬 프레임워크로, 트래픽 제어, 보안, 관측(Observability) 기능을 제공하여 마이크로서비스 아키텍처를 효과적으로 운영할 수 있도록 도와준다.
설치 과정에서는 istioctl을 사용하여 Istio를 demo 프로파일로 설치하였고, 이후 Envoy 사이드카 자동 주입을 위한 네임스페이스 라벨 설정, Bookinfo 애플리케이션 배포, Istio Gateway 및 VirtualService 구성 등을 단계별로 실습했다.
또한, GCP 환경에서 Istio Ingress Gateway를 NodePort 방식으로 노출하고, Kiali, Grafana, Prometheus, Jaeger 등의 애드온을 설치하여 서비스 메쉬의 상태와 트래픽 흐름을 시각화하였다.
📅 관련 글
2023.04.15 - [IaC/Service Mesh] - Istio란?
2023.03.08 - [IaC/Service Mesh] - Service Mesh vs Api Gateway
Istio 설치 및 다운로드
Istio 다운로드
# 최신버전 다운로드
curl -L <https://istio.io/downloadIstio> | sh -
# 특정버전 다운로드
curl -L <https://istio.io/downloadIstio> | ISTIO_VERSION=1.20.2 TARGET_ARCH=x86_64 sh -
# 디렉토리 접속
cd istio-1.20.2
# path추가
export PATH=$PWD/bin:$PATH
Istio 설치
demo로 설치하여 공부해본다.
istioctl install --set profile=demo -y
kubectl label namespace default istio-injection=enabled
# label 확인
kubectl get ns --show-labels
NAME STATUS AGE LABELS
default Active 140m istio-injection=enabled,kubernetes.io/metadata.name=default
istio-system Active 52s kubernetes.io/metadata.name=istio-system
kube-node-lease Active 140m kubernetes.io/metadata.name=kube-node-lease
kube-public Active 140m kubernetes.io/metadata.name=kube-public
kube-system Active 140m kubernetes.io/metadata.name=kube-system
network-policy-test Active 132m kubernetes.io/metadata.name=network-policy-test
- 나중에 애플리케이션을 배포할 때 Envoy 사이드카 프록시를 자동으로 삽입하도록 Istio에 지시하려면 네임스페이스 라벨을 추가해야 한다.
Istio 설치 시 고려사항
항목 | 설명 |
버전 관리 | Istio는 자주 업데이트되며, 버전마다 설정 방법이 다소 달라질 수 있음. 특히 1.5 이후 istiod 단일 컨트롤러로 변경된 점을 유의. 최신 버전 기준으로 학습하는 것을 추천. |
프로파일 선택 | demo, default, minimal, external 등 다양한 프로파일 제공됨. 성능 테스트나 실제 운영 환경에서는 default 또는 external 프로파일 권장. |
리소스 사용량 | Istio는 강력하지만, Sidecar 프록시가 추가되면서 서비스당 약 50~100MB 정도 메모리 사용 증가. 클러스터 리소스 계획에 반영 필요. |
설치 후 체크리스트
체크 포인트 | 명령어 | 예시설명 |
컨트롤 플레인 상태 확인 | `k get po -n istio-system` | `Istiod, ingress, egress, addon` 정상 기동 확인 |
네임스페이스 라벨 확인 | `k get ns --show-labels` | `istio-injection=enabled` 라벨 확인 |
Sidecar 주입 확인 | `k describe po <pod명>` | pod 설명에서 Envoy sidecar 포함 여부 확인 |
Helm으로 설치하는 방법도 추천
현재 설명은 istioctl을 활용한 설치지만, Helm을 선호하는 환경에서는 아래처럼 Helm Chart를 활용할 수도 있다.
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
helm install istio-base istio/base -n istio-system --create-namespace
helm install istiod istio/istiod -n istio-system --set profile=demo
샘플 어플리케이션 배포
# 배포
k apply -f samples/bookinfo/platform/kube/bookinfo.yaml
# 서비스 확인
k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.233.25.129 <none> 9080/TCP 13s
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 143m
productpage ClusterIP 10.233.13.24 <none> 9080/TCP 12s
ratings ClusterIP 10.233.18.41 <none> 9080/TCP 13s
reviews ClusterIP 10.233.3.236 <none> 9080/TCP 13s
# pod 확인
k get po
NAME READY STATUS RESTARTS AGE
details-v1-698d88b-sfrpw 2/2 Running 0 2m16s
productpage-v1-675fc69cf-hsnlf 2/2 Running 0 2m15s
ratings-v1-6484c4d9bb-9jdhx 2/2 Running 0 2m16s
reviews-v1-5b5d6494f4-gqfnl 2/2 Running 0 2m15s
reviews-v2-5b667bcbf8-zjgm7 2/2 Running 0 2m15s
reviews-v3-5b9bd44f4-rr6s9 2/2 Running 0 2m15s
# 앱 확인
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
`bookinfo-gateway.yaml` 확인
cat samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
# The selector matches the ingress gateway pod labels.
# If you installed Istio using Helm following the standard documentation, this would be "istio=ingress"
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 8080
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
해당 어플리케이션을 lstio Ingress Gateway와 연결한다.
k apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
# 구성 확인
istioctl analyze
✔ No validation issues found when analyzing namespace: default.
현재 LB가 없기 때문에 NodePort를 확인해준다.
# 현재 구성 확인 한다.
k get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.233.19.220 <pending> 15021:30820/TCP,80:32233/TCP,443:30564/TCP,31400:30670/TCP,15443:32168/TCP 10m
kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'
32233
GCE를 사용중이기 때문에 terraform으로 방화벽을 열어준다.
## Firewall ##
resource "google_compute_firewall" "test_server_ssh" {
name = "allow-ssh-test-server"
network = var.shared_vpc
allow {
protocol = "tcp"
ports = ["22", "32233"]
}
source_ranges = ["${var.public_ip}/32""]
target_tags = [var.test_server]
depends_on = [module.vpc]
}
접속이 잘된다.
아래와 같이 로그도 확인할 수 있다.
k logs -n istio-system -l app=istio-ingressgateway
[2024-01-23T05:37:24.511Z] "GET /static/bootstrap/css/bootstrap-theme.min.css HTTP/1.1" 200 - via_upstream - "-" 0 23409 12 11 "10.233.64.194" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "a7e9fa4e-6091-94c5-b8fd-7b3eda3874d7" "34.64.45.131:32233" "10.233.64.118:9080" outbound|9080||productpage.default.svc.cluster.local 10.233.64.203:39806 10.233.64.203:8080 10.233.64.194:51114 - -
[2024-01-23T05:37:24.513Z] "GET /static/jquery.min.js HTTP/1.1" 200 - via_upstream - "-" 0 89493 16 13 "10.233.64.194" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "bab1b698-cc35-9361-b326-f3080674d89e" "34.64.45.131:32233" "10.233.64.118:9080" outbound|9080||productpage.default.svc.cluster.local 10.233.64.203:39820 10.233.64.203:8080 10.233.64.194:26863 - -
[2024-01-23T05:37:24.514Z] "GET /static/bootstrap/js/bootstrap.min.js HTTP/1.1" 200 - via_upstream - "-" 0 37045 15 15 "10.233.64.194" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "8d0e8404-a8c9-9cf8-a904-37c61bc7f4d3" "34.64.45.131:32233" "10.233.64.118:9080" outbound|9080||productpage.default.svc.cluster.local 10.233.64.203:39832 10.233.64.203:8080 10.233.64.194:31483 - -
[2024-01-23T05:37:24.567Z] "GET /favicon.ico HTTP/1.1" 404 NR route_not_found - "-" 0 0 0 - "10.233.64.194" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "66f15798-f936-9c9d-b73e-677808a3b67f" "34.64.45.131:32233" "-" - - 10.233.64.203:8080 10.233.64.194:26863 - -
[2024-01-23T05:37:46.329Z] "GET /productpage HTTP/1.1" 200 - via_upstream - "-" 0 4294 27 27 "10.233.65.132" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "cec1d906-c3cc-9d25-a512-a6f1af5f77c0" "34.64.176.165:32233" "10.233.64.118:9080" outbound|9080||productpage.default.svc.cluster.local 10.233.64.203:39802 10.233.64.203:8080 10.233.65.132:49237 - -
[2024-01-23T05:37:46.386Z] "GET /static/bootstrap/css/bootstrap.min.css HTTP/1.1" 200 - via_upstream - "-" 0 121200 6 5 "10.233.65.132" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "1daf5183-97be-9df8-9186-5361e08b8ef8" "34.64.176.165:32233" "10.233.64.118:9080" outbound|9080||productpage.default.svc.cluster.local 10.233.64.203:39802 10.233.64.203:8080 10.233.65.132:49237 - -
[2024-01-23T05:37:46.387Z] "GET /static/bootstrap/css/bootstrap-theme.min.css HTTP/1.1" 200 - via_upstream - "-" 0 23409 7 7 "10.233.65.132" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "3ffd067f-747f-99e7-bfb6-19fe6df6b33f" "34.64.176.165:32233" "10.233.64.118:9080" outbound|9080||productpage.default.svc.cluster.local 10.233.64.203:39832 10.233.64.203:8080 10.233.65.132:49303 - -
[2024-01-23T05:37:46.392Z] "GET /static/bootstrap/js/bootstrap.min.js HTTP/1.1" 200 - via_upstream - "-" 0 37045 12 12 "10.233.65.132" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "6a4e3113-0026-905c-be66-1fdcd4314bbd" "34.64.176.165:32233" "10.233.64.118:9080" outbound|9080||productpage.default.svc.cluster.local 10.233.64.203:40894 10.233.64.203:8080 10.233.65.132:49305 - -
[2024-01-23T05:37:46.389Z] "GET /static/jquery.min.js HTTP/1.1" 200 - via_upstream - "-" 0 89493 14 10 "10.233.65.132" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "cb9acf87-411d-960d-b65b-0432c9879910" "34.64.176.165:32233" "10.233.64.118:9080" outbound|9080||productpage.default.svc.cluster.local 10.233.64.203:39802 10.233.64.203:8080 10.233.65.132:49304 - -
[2024-01-23T05:37:46.446Z] "GET /favicon.ico HTTP/1.1" 404 NR route_not_found - "-" 0 0 0 - "10.233.65.132" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "8d960b9a-ed38-9600-b00c-83e7719c2aad" "34.64.176.165:32233" "-" - - 10.233.64.203:8080 10.233.65.132:49304 - -
대시보드 확인
Istio는 여러 가지 원격 측정 애플리케이션과 통합된다. 이는 서비스 Mesh의 구조를 이해하고, Mesh의 토폴로지를 표시하고, Mesh의 상태를 분석하는 데 도움이 될 수 있다.
Kiali 및 기타 애드온을 설치 하고 배포될 때까지 기다린다.
kubectl apply -f samples/addons
kubectl rollout status deployment/kiali -n istio-system
Waiting for deployment "kiali" rollout to finish: 0 of 1 updated replicas are available...
deployment "kiali" successfully rolled out
Kiali를 NodePort로 열어준다.
kubectl patch -n istio-system svc kiali -p '{"spec": {"type": "NodePort"}}'
service/kiali patched
k get svc -n istio-system |grep kiali
kiali NodePort 10.233.15.141 <none> 20001:32634/TCP,9090:30542/TCP 3m12s
동일하게 방화벽을 열어준다.
## Firewall ##
resource "google_compute_firewall" "test_server_ssh" {
name = "allow-ssh-test-server"
network = var.shared_vpc
allow {
protocol = "tcp"
ports = ["22", "32233", "32767"]
}
source_ranges = ["${var.public_ip}/32""]
target_tags = [var.test_server]
depends_on = [module.vpc]
}
접속이 잘된다.
추적 데이터를 보려면 서비스에 요청을 보내야 한다. 본 샘플링 비율이 1%인 경우 첫 번째 추적이 표시되기 전에 최소 100개의 요청을 보내야 한다. 서비스에 100개의 요청을 보낸다.
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
for i in $(seq 1 100); do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done
Kiali 대시보드 활용 예시
- 서비스 메쉬 내 트래픽 흐름 시각화
- 각 서비스 간 요청 수, 에러율, 응답시간 확인
- VirtualService, DestinationRule 등 설정된 리소스 UI로 확인 가능
- 버전별 트래픽 비율 확인 가능 (Canary 배포 모니터링)
Istio의 주요 리소스 (CRD)
리소스 | 설명 | 주요 필드 |
Gateway | Ingress 트래픽 수신 설정 | hosts, servers, selector |
VirtualService | 서비스 간 트래픽 라우팅 정책 | hosts, gateways, http (match/route) |
DestinationRule | 백엔드 서비스 연결 정책 | host, trafficPolicy, subsets |
ServiceEntry | 외부 서비스 연결 등록 | hosts, addresses, ports |
Bookinfo 구성도 이해
bookinfo는 Istio 학습용 대표 샘플로, 서비스 간 호출 관계는 아래와 같다.
- 각 서비스에 Envoy 사이드카가 붙어서 트래픽을 관리하는 구조
실전 운영 팁
상황 | 팁 |
Canary 배포 | VirtualService에서 weight 비율 조정 |
A/B 테스트 | 쿠키나 헤더 기반 라우팅 설정 |
장애 테스트 | Fault Injection 기능 활용 (지연, 에러 응답 주입) |
인증 및 보안 | PeerAuthentication, AuthorizationPolicy 설정으로 mTLS 강제 및 RBAC 구성 |
외부 서비스 호출 | ServiceEntry로 DNS 등록 (ex: 외부 DB, 외부 API 호출) |
관측 | Kiali, Prometheus, Grafana 연동은 필수 구성 |
Istio Canary 배포 예시 (VirtualService)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage.default.svc.cluster.local
http:
- route:
- destination:
host: productpage
subset: v1
weight: 80
- destination:
host: productpage
subset: v2
weight: 20
마무리
- 이번 포스팅에서는 Istio 설치 및 Bookinfo 예제까지 따라해보면서 Istio의 기본 개념과 구성 방법을 학습해봤다.
- Istio는 강력한 기능을 제공하는 만큼, 설치 및 운영 난이도도 높은 편이지만, 서비스 메쉬 표준 솔루션으로 자리 잡은 만큼 실제 운영 환경에서도 점차 도입이 늘어나고 있다.
- 다음 시간에는 Canary 배포, Fault Injection, mTLS 구성 같은 고급 활용법과, Istio + Prometheus + Grafana + Loki를 통한 모니터링/로깅 통합 환경 구성법도 이어서 다뤄보겠다!
Reference
https://istio.io/latest/docs/setup/getting-started/
https://musclebear.tistory.com/157
https://github.com/istio/istio/tree/master/samples/bookinfo
https://istio.io/latest/about/service-mesh/
- 공식 문서: https://istio.io/latest/docs/
- Istio Bookinfo 예제: https://github.com/istio/istio/tree/master/samples/bookinfo
- Istio 설치 가이드: https://istio.io/latest/docs/setup/getting-started/
'IaC > Service Mesh' 카테고리의 다른 글
Istio란? (0) | 2023.04.15 |
---|---|
Service Mesh vs Api Gateway (0) | 2023.03.08 |