istio란

현대의 대규모 애플리케이션들(아마존, 넷플릭스 등)은 최소 수백 개에서 수천 개에 달하는 마이크로서비스(microservice)의 조합으로 구동된다. 각 마이크로서비스들은 단일 역할을 수행하고, 독립적으로 배포되며, 서로 느슨하게 연결되어 있다. 이런 구조에서 발생할 수 있는 문제점은, 각 서비스의 상태를 모니터링하기 어려우며, 단일 서비스 장애가 전체로 전파될 수 있는 가능성이 존재한다는 점이다. 이런 문제점의 해결책으로 제시된 것이 서비스 메시(service mesh)다.
서비스 메시란, 수백 수천 개의 마이크로서비스로 설계된 애플리케이션에서 각 마이크로 서비스의 상태를 추적하고, 마이크로서비스 간 트래픽의 제어 및 암호화 기능을 제공하는 확장 기반 구조(infrastructure)로 정의할 수 있다.
이스티오(Istio)는 쿠버네티스에 적합한 서비스 메시의 구현체다. 이스티오 아키텍처는 각 서비스의 정보를 수집하는 데이터 평면(data plane)과 각 서비스 간 통신 흐름을 제어하고 관측하는 제어 평면(control plane)으로 구성된다. 데이터 평면에 존재하는 각 서비스들에는 모두 sidecar 프록시가 주입되며, 해당 서비스로 전달되는 모든 트래픽들은 이 사이드카 프록시를 통해 전달된다.

사이드카 프록시는 각종 metric들을 제어 평면에 존재하는 istiod(istio demon)으로 전송하며, istiod는 각 프록시 간 트래픽 전달 규칙을 결정한다. 이 때 프록시는 7계층 정보를 기반으로 트래픽을 라우팅한다(대표적으로 host 헤더 기반으로 라우팅할 수 있다).
본 포스트에선 이전 포스트에서 소개한 kind(https://securitygeek.tistory.com/2) 환경에서, istio를 설치하는 법을 소개한다. kind, kubectl, helm 이 설치되어있다는 가정하에 소개하기 때문에, 만약 설치되어 있지 않다면 위 링크를 참조하면 된다.
개요
- 목표:
- Bookinfo라는 sample application을 배포하고, host 웹에서 http://localhost:8080/productpage 에 접속했을 때, 관리 페이지가 표시되게 한다.
- 과정
- 포트포워딩 규칙을 포함하는 클러스터를 생성한다.
- 클러스터에 Istio 를 설치한다.
- Istio ingress gateway를 생성한다.
- demo 네임스페이스를 생성한다.
- 해당 네임스페이스에 Sidecar를 주입하고, Bookinfo application을 배포한다.
- 네임스페이스에 Virtual service와 gateway를 생성한다.
- 개념

Istio 상에 Bookinfo 예제 프로그램 설치 예제
- virtual service: Envoy ingress gateway가 수신한 http 요청 중에서
- host header
- URI 경로
- gateway port
- 위 정보를 기반으로 어떤 서비스(pod)로 라우팅할지 결정한다.
1. 클러스터 생성
먼저 도커 컨테이너 형태로 클러스터(kluster)를 생성한다. 일반적인 쿠버네티스 클러스터는 단일 제어 평면(istio 제어 평면과는 구분된다)과 여러 개의 노드(node)로 구성되지만, kind는 일반적으로 로컬 개발 및 테스트가 목적이므로 단일 노드로 구성된다. 또한, 컨테이너 형태로 도커 상에 배포되기 때문에, 클러스터 내부와 외부 간 통신을 위해선 배포 시점에 컨테이너 포트포워딩 설정이 필요하다.
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 8080
protocol: TCP
- containerPort: 30443
hostPort: 8443
protocol: TCP
- 호스트 OS의 포트 8080과, 컨테이너 포트 30080을 연결한다.
- 해당 파일을 기반으로 클러스터를 생성하는 명령어는 다음과 같다.
kind create cluster --name istio-cluster --config kind-config.yaml
2. istio 설치
istio는 마이크로서비스 간의 트래픽 제어, 보안, 관측(Observability) 등의 기능을 제공한다.
2.1 네임스페이스/리포지터리/애플리케이션 추가
kubectl create namespace istio-system
먼저, istio 의 모든 기본 리소스(istiod, ingress gateway, metrics) 등이 설치될 네임스페이스를 생성한다. 이 때 네임스페이스(namespace)란, 쿠버네티스 클러스터 내에서의 논리적인 분리 단위, 또는 가상 공간이다. istio의 사이드카 프록시 역시 네임스페이스 단위로 주입(injection)된다.
helm repo add istio <https://istio-release.storage.googleapis.com/charts>
helm repo update
새로운 애플리케이션을 추가할 땐, 패키지 관리자 helm을 통해 istio repository를 추가한다.
- Helm repository:
- Helm chart들을 저장해 놓은 원격 저장소.
- 여러 서비스들의 배포 템플릿이 모여있다.
helm install istio-base istio/base -n istio-system
helm install istiod istio/istiod -n istio-system --wait
istio repository로부터, istio-base와 istiod 를 설치한다.
- istio-base: istio 구성 요소들의 공통 CRD 및, RBAC, 네임스페이스 등을 정의
- 사용자 정의 리소스 (Custom Resource Definition, CRD)란, 쿠버네티스에서 기본으로 제공하지 않는 리소스 타입을 사용자가 직접 정의할 수 있도록 하는 기능이다.
- istiod: Istio의 두뇌 역할로 메시 내부 서비스들을 제어하고 관측하는 역할을 한다. Control plane에 해당한다.
helm ls -n istio-system
- 설치가 완료되면, 네임스페이스 istio-system 내에서 구동되는 서비스들을 확인한다.
2.2 Ingress gate way 설치
ingress gateway란, 외부 트래픽이 서비스 메시 내로 들어올 수 있는 진입점이다. 외부 트래픽을 받아, VirtualService 규칙에 따라 메시 내 서비스로 라우팅한다.
- gateway-values.yaml
- helm 으로 리포지터리에 존재하는 기본 ingress gateway를 배포할 때 사용하는 설정 파일이다.

node port architecture
- helm 으로 리포지터리에 존재하는 기본 ingress gateway를 배포할 때 사용하는 설정 파일이다.
name: istio-ingress
type: NodePort
ports:
- name: http2
port: 80 #쿠버네티스 내부에서 Gateway 서비스가 수신하는 포트.
targetPort: 80 #요청이 내부적으로 전달될 대상 Pod의 컨테이너 포트
nodePort: 30080 #NodePort 서비스일 때, 클러스터 외부에서 접근 가능한 포트
- name: https
port: 443
targetPort: 443
nodePort: 30443
- name: status-port
port: 15021
targetPort: 15021
nodePort: 32021
kind 환경에서는 로드밸런서가 아닌 Nodeport 로 ingress gateway를 배포해야 한다. 이론적으로는 해당 yaml 파일을 통해 ingress gateway를 설치할 수 있어야 하나, yaml 파일로는 정상적으로 적용이 안되는 버그가 존재했다. 따라서, 다음 방식으로 강제로 구성한다.
helm install ingressgateway istio/gateway -n istio-system
먼저 기본 ingress gateway를 배포한다.
kubectl patch svc ingressgateway -n istio-system \\
-p '{
"spec": {
"type": "NodePort",
"ports": [
{
"name": "http2",
"port": 80,
"targetPort": 80,
"nodePort": 30080,
"protocol": "TCP"
},
{
"name": "https",
"port": 443,
"targetPort": 443,
"nodePort": 30443,
"protocol": "TCP"
},
{
"name": "status-port",
"port": 15021,
"targetPort": 15021,
"nodePort": 32021,
"protocol": "TCP"
}
]
}
}'
kubectl의 patch 기능을 사용해, 현재 구동 중인 ingress 서비스를 강제로 패치한다.
kubectl get svc -n istio-system ingressgateway
구동 중인 Ingress의 정보를 확인한다. Nodeport로 적용됐다면, 정상적으로 적용된 것이다.
3. sample application 설치 (Bookinfo)
istio는 bookinfo라는 예제 애플리케이션을 제공한다. 간단한 책 리뷰 페이지를 제공하는 웹 애플리케이션이다. 본 단락에서는 bookinfo를 istio 상에 설치하는 방법을 다룬다.
kubectl create namespace demo
kubectl label namespace demo istio-injection=enabled
먼저 애플리케이션을 배포하는데 사용할 demo 네임스페이스를 생성하고, 사이드카 주입을 활성화한다.
kubectl apply -f <https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/platform/kube/bookinfo.yaml> -n demo
demo 네임스페이스 상에 bookinfo application을 배포한다.
kubectl get pods -n demo
demo 상에 배포된 파드의 목록을 확인한다.

배포된 각 서비스들의 READY 열에 2/2 문자를 확인할 수 있는데, 이는 각 파드에 두 개의 컨테이너(애플리케이션, 사이드카 프록시)가 존재함을 나타내는 것이다.
4. demo namespace의 virtualservice, gateway 설정
kubectl apply -f <https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/networking/bookinfo-gateway.yaml> -n demo
- bookinfo 애플리케이션에 기존 설정된 bookinfo-gateway.yaml을 사용한다.
- bookinfo-gateway.yaml 파일은, virtual service 리소스를 생성한다.
- ingress gateway는 이 virtual service 리소스를 참조해 라우팅한다.
kubectl get gateway -n demo
kubectl get virtualservice -n demo
- 게이트웨이와 virtual service가 구동되는지 확인한다.
- 다음 명령어를 사용해 bookinfo-gateway.yaml 을 수정한다.
kubectl edit gateway bookinfo-gateway -n demo
- bookinfo-gateway. yaml의 내용은 다음과 같다.
spec:
selector:
istio: ingressgateway #어떤 ingress gateway pod가 이 Gateway 설정을 사용할지 결정한다.
servers:
- hosts:
- '*'
port:
name: http
number: 80 #target port 80을 listen 하던 중 HTTP 요청이 들어오면 virtual service를 통해 Bookinfo pod로 라우팅.
protocol: HTTP
- Bookinfo
kubectl get gateway bookinfo-gateway -n demo -o yaml
kubectl get svc -n istio-system ingressgateway -o jsonpath="{.spec.selector}"
- 게이트웨이 리소스의 selector와 현재 ingress gateway의 라벨이 일치하는지 확인한다.
여기까지 마치면, localhost 에서 기존에 설정한 클러스터의 포트번호로 접속해 정상적으로 웹페이지가 구동되는지 확인한다.
마치며
istio 상에 간단한 예제 애플리케이션을 배포하는 방법을 알아보았다. 그러나, 이 방식은 개발자가 virtual 서비스부터 시작해 많은 부분을 공부하고 설정해줘야한다는 단점이 있다. 다음 포스트에선 이 과정을 간소화 시킬 수 있는 Knative에 대해 다룰 것이다.
'개발 > 쿠버네티스' 카테고리의 다른 글
| Docker 환경에서 kind 설치하기 (2) | 2025.06.09 |
|---|