Istio는 현대적인 마이크로서비스 아키텍처를 위한 강력한 오픈소스 서비스 메시 플랫폼입니다. 특히 쿠버네티스 환경에서 복잡한 서비스 간 통신을 효율적으로 관리하고 제어할 수 있게 해주는 핵심 인프라스트럭처 솔루션입니다.
서비스 메시로서 Istio가 공식문서에서 말하는 세 가지 핵심 가치는 다음과 같습니다:
가시성 (Increase observability)
트래픽 관리 (Manage traffic)
보안 (Secure by default)
가장 주목할 만한 점은 애플리케이션 코드를 전혀 수정하지 않고도 이 모든 기능을 적용할 수 있다는 것입니다. Istio는 사이드카 프록시 패턴을 통해 기존 애플리케이션에 투명하게 통합되며, 개발자들은 비즈니스 로직에만 집중할 수 있습니다.
특히 마이크로서비스 환경에서 발생하는 서비스 디스커버리, 로드밸런싱, 장애 처리, 메트릭 수집 등의 복잡한 문제들을 Istio가 인프라 수준에서 해결해주므로, 쿠버네티스 기반의 시스템을 더욱 안정적이고 관리하기 쉽게 만들어줍니다.
istio의 구조를 이해하기 위해서는 먼저 핵심 구성요소인 Envoy에 대해 알아볼 필요가 있습니다.
Envoy 프록시 소개
Envoy는 애플리케이션 레이어(L7)에서 작동하는 오픈소스 로드밸런서입니다. 기본적으로 nginx와 같은 리버스 프록시 역할을 수행하며, 트래픽 경로를 제어할 수 있습니다. 하지만 Envoy는 여기서 한 걸음 더 나아가 다음과 같은 강력한 기능들을 제공합니다:
이러한 Envoy의 강력한 기능들을 활용하기 위해 쿠버네티스의 각 파드에 배포하면 시스템 전반에 대한 상세한 지표를 얻을 수 있습니다. 하지만 여기서 한 가지 문제가 발생합니다. Envoy를 개별적으로 배포하는 것은 좋지만, 수천 개의 파드에 일일이 접속하여 Traffic Retry, Circuit Breaker, Timeout 등의 설정을 관리하는 것은 현실적으로 불가능합니다. 바로 이 지점에서 Istio의 필요성이 대두됩니다.
Istio의 구조
Istio는 이러한 Envoy 프록시들을 효율적으로 관리할 수 있는 시스템을 제공합니다. 구조는 크게 두 가지 계층으로 나뉩니다:
Data Plane: 각 파드에 sidecar 형식으로 배포된 Envoy 프록시들의 집합
Control Plane: 이러한 Envoy 프록시들을 중앙에서 관리하고 제어하는 시스템
아래 사진은 이러한 Istio의 전체적인 아키텍처를 보여줍니다:
이제 이어지는 내용에서는 실제로 쿠버네티스 클러스터에 Istio를 설치하고, 마이크로서비스를 배포한 뒤, 가시성과 트래픽 관리를 어떻게 구현하는지 실습을 통해 자세히 알아보도록 하겠습니다.
참조사항
kubectl version
을 사용하여, 버전을 확인 후, istioctl을 설치합니다. 1.30.6 버전이므로, ISTIO_VERSION 1.24.1 을 설치하겠습니다.curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.24.1 TARGET_ARCH=x86_64 sh -
cd istio-1.24.1
export PATH=$PWD/bin:$PATH
istioctl install -f samples/bookinfo/demo-profile-no-gateways.yaml -y
kubectl label namespace default istio-injection=enabled
kubectl get crd [gateways.gateway.networking.k8s.io](http://gateways.gateway.networking.k8s.io/) &> /dev/null || \ { kubectl kustomize "[github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.0](http://github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.0)" | kubectl apply -f -; }
를 통하여 이후 사용할 Kubernetes Gateway API를 위해 CRD를 설치하도록 하겠습니다.
https://istio.io/latest/docs/examples/bookinfo/
위 링크에서 제공하는 istio 예시 application을 배포하겠습니다. 아키텍처는 아래와 같습니다.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/bookinfo/platform/kube/bookinfo.yaml
명령어를 통하여 애플리케이션을 설치합니다.
아래와 같이 결과가 나오면 정상입니다. kubectl get pods를 했을때 2개의 컨테이너가 ready 상태가 되어야합니다.
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.0.0.212 <none> 9080/TCP 29s
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 25m
productpage ClusterIP 10.0.0.57 <none> 9080/TCP 28s
ratings ClusterIP 10.0.0.33 <none> 9080/TCP 29s
reviews ClusterIP 10.0.0.28 <none> 9080/TCP 29s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-558b8b4b76-2llld 2/2 Running 0 2m41s
productpage-v1-6987489c74-lpkgl 2/2 Running 0 2m40s
ratings-v1-7dc98c7588-vzftc 2/2 Running 0 2m41s
reviews-v1-7f99cc4496-gdxfn 2/2 Running 0 2m41s
reviews-v2-7d79d5bd5d-8zzqd 2/2 Running 0 2m41s
reviews-v3-7dbcdcbc56-m8dph 2/2 Running 0 2m41s
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>"
kubectl annotate gateway bookinfo-gateway networking.istio.io/service-type=ClusterIP --namespace=default
kubectl annotate gateway bookinfo-gateway networking.istio.io/service-type=ClusterIP --namespace=default
kubectl get gateway
명령어 입력시 아래와 같이 값이 떠야합니다.$ kubectl get gateway
NAME CLASS ADDRESS PROGRAMMED AGE
bookinfo-gateway istio bookinfo-gateway-istio.default.svc.cluster.local True 42s
kubectl port-forward svc/bookinfo-gateway-istio 8080:80
kubectl apply -f samples/addons
명령어를 통해 Prometheus , Grafana , Jaeger 와 함께 Kiali 대시보드를 배포합니다.istioctl dashboard kiali
명령어를 치면 아래와 같은 결과가 나오게 됩니다. Failed to open browser; open http://localhost:20001/kiali in your browser.
for i in $(seq 1 1000); do curl -s -o /dev/null "http://127.0.0.1:8080/productpage"; done
와 같이 부하를 주게 되면, 요청이 증가한 Dashboard를 통해 확인할 수 있습니다.apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews-v1-circuit-breaker
spec:
host: reviews # 적용할 서비스
subsets: # 서비스의 하위 집합 정의
- name: v1
labels: # 어떤 pod에 적용할지
version: v1
trafficPolicy: # 트래픽 정책 설정
outlierDetection: # 서킷브레이커 설정
consecutive5xxErrors: 10 # 연속 에러 횟수
interval: 5s # 체크 주기
baseEjectionTime: 3m # 차단 시간
maxEjectionPercent: 100 # 최대 차단 비율
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews # 어떤 서비스에 대한 규칙인지
http:
- route: # 라우팅 규칙
- destination:
host: reviews # 목적지 서비스
subset: v1 # DestinationRule에서 정의한 subset
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1-fail
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1
spec:
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.20.2
command: ["/bin/sh"]
args: ["-c", "sleep 50000; exit 1"]
ports:
- containerPort: 9080
Istio는 이 외에도 트래픽 분할, 카나리 배포, 보안 정책 적용 등 더 많은 기능을 제공합니다.
이 포스트는 Istio의 방대한 기능 중 극히 일부분만을 다루었습니다. Istio는 깊이 있게 공부할 내용이 많은 서비스 메시 솔루션입니다. 트래픽 관리, 보안 정책, 관찰가능성(Observability) 등 각 영역별로 수많은 설정과 기능들이 있으며, 이를 실제 프로덕션 환경에 적용하기 위해서는 더 많은 학습과 경험이 필요합니다.