istio는 기존 분산 애플리케이션에 투명하게 레이어링되는 오픈소스 서비스 메쉬이다. istio의 강력한 기능은 서비스를 보호하고 연결하고 모니터링하는 균일하고 효율적인 방법을 제공한다. istio를 사용하면 애플리케이션 코드를 거의 변경하지 않아도 아래 기능들을 사용할 수 있다.
- mTLS, 강력한 ID 기반 인증 및 권한 부여를 통해 클러스터에서 안전한 서비스간 통신을 제공한다.
- HTTP, gRPC, WebSocket, TCP 트래픽에 대한 로드밸런싱 기능 제공
- 풍부한 라우팅 규칙, retry, failover, fault injection 을 통한 트래픽 세부 제어
- 접근 제어, 속도 제한, rate limits을 지원하는 플러그형 정책을 구성할 수 있다.
- 클러스터를 오가는 모든 트래픽에 대한 자동 메트릭, 로그, 추적기능 제공
istio는 확장성을 염두에 두고 설계되었으며 다양한 배포 요구 사항을 처리할 수 있다. istio의 컨트롤 플레인은 쿠버네티스에서 구동되며 해당 클러스터에 배포된 애플리케이션을 메시에 추가하고 메시를 다른 클러스터로 확장하거나 쿠버네티스 외부에서 실행되는 엔드포인트를 연결할 수도 있다.
Architecture
Istio는 envoy proxy를 사용하여 모든 네트워크 트래픽을 가로채서 사용자가 설정한 구성에 따라 다양한 기능을 사용할 수 있도록 한다.
envoy proxy는 C++으로 개발된 고성능의 L7 프록시 서버이다. istio에서 제공하는 로드밸런싱, 라우팅, retry, failover 등의 기능은 실질적으로는 envoy proxy가 제공하며, envoy proxy를 쿠버네티스 환경에 맞게 사용하고 관리하기 위해 istio를 사용한다.
istio는 컨트롤 플레인과 데이터 플레인으로 구성된다.
데이터 플레인
데이터 플레인은 쿠버네티스 파드의 사이드카로서 베포된 envoy proxy들로 이루어져 있다. 이 프록시는 마이크로서비스간의 모든 네트워크 동신을 조정하고 제어하며 모든 트래픽에 대한 메트릭을 수집하고 보고한다.
istio의 기능인 트래픽 라우팅, 로드밸런싱, 암호화, 모니터링, 로깅 등이 envoy proxy를 사용하여 제공하기 때문에, 사이드카가 없는 파드들은 데이터 플레인이 아니다. (istio의 관리대상이 아님)
쿠버네티스 클러스터 관점에서 보면 데이터 플레인은 크게 세가지 형태로도 볼 수 있다.
- ingress gateway: envoy proxy 한대로만 구성이 된 파드들로, 클러스터 내부로 들어오는 트래픽을 받아서 제어한다. ingress gateway는 보통 LoadBalancer 타입 또는 NodePort 타입으로 노출시켜 외부에서 트래픽을 받는 형태로 사용한다. 외부로 노출시킬 필요가 없다면 배포하지 않아도 된다.
- mesh: 실제 애플리케이션과 함께 envoy proxy 형태의 사이드카로 배포되는 파드들이다.
- egress gateway: envoy proxy 한대로만 구성이 된 파드들로, mesh 밖으로 나가는 트래픽을 최종적으로 가로채서 제어하는 역할을 한다. mesh 밖으로 나가는 트래픽을 제어할 필요가 없다면 배포하지 않아도 된다.
컨트롤 플레인
컨트롤 플레인은 데이터 플레인인 envoy proxy를 관리하고 구성한다. 컨트롤 플레인은 istiod 단독으로 이루어져있다. istiod는 서비스 디스커버리, 구성 및 인증서 관리를 제공한다.
istio에서는 트래픽 동작을 제어하는 규칙들을 쿠버네티스 커스텀 리소스 (CR)의 형태로 관리한다. (대표적으로 VirtualService, Gateway 등) 이러한 커스텀 리소스가 클러스터 내에서 변경이 되면 istiod가 변경사항을 감지하여 커스텀 리소스를 envoy 전용 구성으로 변환하여 런타임 시점에 사이드카에 전파한다.
istiod 보안은 내장된 id 및 자격 증명 관리를 통해 강력한 서비스 간 인증과 최종 사용자 인증을 지원한다. istio를 사용하여 서비스 메시에서 암호화되지 않은 트래픽을 코드 변경 없이 암호화할 수 있으며, istio의 인증 기능을 사용하여 서비스에 접근할 수 있는 사용자를 제어할 수도 있다.
데이터 플레인 모드 (1.22+)
1.22버전 이후로 istio는 두 가지의 데이터플레인 모드를 제공한다. 1.22버전 이전에는 sidecar mode 뿐이었는데 sidecar mode의 단점을 해결하기 위해 amibent mode를 추가로 구축하게 되었다고 한다.
- sidecar mode: 쿠버네티스 클러스터에서 생성된 모든 파드에 envoy proxy를 추가로 배포하거나 vm에서 실행되는 서비스와 함께 실행한다.
- ambient mode: 노드별 레이어4 프록시를 사용하는 ambient mode와 선택적으로 레이어7 기능을 위한 네임스페이스별 envoy proxy를 사용할 수 있다.
설치(with helm)
istio를 설치하는 방식은 istioctl 방식과 helm 방식이 있다. 어느 방식이 더 낫다고는 할 수는 없지만 나는 helm으로 관리하는 것이 조금 더 편하다고 생각한다. 그래서 helm chart로 istio를 구성하는 방법에 대해 알아보자.
istio-base
먼저 istio-base를 설치해야 한다. istio-base를 설치하면 istio에서 사용하는 CRD (Custom Resource Definition)을 받을 수 있다. 따로 배포되는 파드 같은건 없지만 istio를 사용하려면 Custom Resource를 사용할 수 있어야 하기 때문에 필수이다.
먼저 다음과 같이 istio-base 차트의 값을 설정할 values.yaml 파일을 하나 생성하자. 여기서 생성하는 revision값은 현재 istio 버전 값으로 설정하였는데, 이렇게 미리 설정해두면 istio를 업그레이드 할 때 조금 편하다. (예시는 1.23.4 버전을 설치함)
base.yaml
defaults:
defaultRevision: "1-23-4"
파일 생성 후에 helm install 명령어로 base를 설치하자.
$ helm repo add istio https://istio-release.storage.googleapis.com/charts
$ helm install istio-base istio/base -n istio-system --create-namespace --version 1.23.4 -f base.yaml
- 최초로 istio를 설치할 때는 helm repo를 추가해야 한다.
istio-system
네임스페이스가 없으면--create-namespace
옵션을 통해 네임스페이스 추가까지 할 수 있다.
설치 완료되었으면 CRD가 추가되었는지 확인한다. (대충 이렇게 나오면 설치가 잘 된 것)
$ kubectl get crd | grep istio.io
authorizationpolicies.security.istio.io 2025-01-11T08:22:07Z
destinationrules.networking.istio.io 2025-01-11T08:22:07Z
envoyfilters.networking.istio.io 2025-01-11T08:22:07Z
gateways.networking.istio.io 2025-01-11T08:22:07Z
peerauthentications.security.istio.io 2025-01-11T08:22:07Z
proxyconfigs.networking.istio.io 2025-01-11T08:22:07Z
requestauthentications.security.istio.io 2025-01-11T08:22:07Z
serviceentries.networking.istio.io 2025-01-11T08:22:07Z
sidecars.networking.istio.io 2025-01-11T08:22:07Z
telemetries.telemetry.istio.io 2025-01-11T08:22:07Z
virtualservices.networking.istio.io 2025-01-11T08:22:07Z
wasmplugins.extensions.istio.io 2025-01-11T08:22:07Z
workloadentries.networking.istio.io 2025-01-11T08:22:07Z
workloadgroups.networking.istio.io 2025-01-11T08:22:07Z
istiod
그 다음에는 istio의 컨트롤플레인인 istiod를 설치하면 된다. 다음과 같이 파일 하나를 생성하자.
istiod.yaml
defaults:
revision: "1-23-4"
# istiod 리소스 설정
pilot:
autoscaleMin: 1
autoscaleMax: 2
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 256Mi
# istio-proxy sidecar 리소스 설정
proxy:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 128Mi
default.pilot
은 istiod에 대한 설정인데 여기서는 기본적으로 레플리카 수와 리소스를 상황에 맞게 설정하면 된다.default.proxy
는 애플리케이션에 붙을 사이드카 (envoy proxy)에 대한 컨테이너 리소스 설정을 하였다. 아무래도 애플리케이션 개수에 비례해서 사이드카가 생기기 마련이기 때문에 추가 리소스는 감당해야한다. 그래서 리소스 낭비를 줄이기 위해 적절하게 리소스를 설정해야 한다.
파일 생성 후에 helm install 명령어로 istiod를 설치하자.
$ helm install istiod istio/istiod -n istio-system --version 1.23.4 -f istiod.yaml
설치 후에 istiod가 잘 떴는지 확인한다.
$ kubectl get po
NAME READY STATUS RESTARTS AGE
istiod-1-23-4-567f9c879-vkrpk 1/1 Running 0 21s
gateway 설치 (Optional)
서비스를 목적으로 클러스터를 만들었다면 클러스터 외부에서 클러스터로 접근할 수 있도록 통로를 열어줘야 한다. istio에서는 ingressgateway를 사용할 수 있으며, 이 역할은 ingress-nginx와 비슷하다.
ingressgateway를 일단 설치하기 위해 파일을 하나 만들자.
ingressgateway.yaml
defaults:
revision: "1-23-4"
autoscaling:
minReplicas: 2
maxReplicas: 3
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 128Mi
파일 생성 후에 helm install 명령어로 ingressgateway를 설치하자.
$ helm install ingressgateway istio/gateway -n istio-system --version 1.23.4 -f ingressgateway.yaml
설치 후에 ingressgateway가 잘 떴는지 확인한다.
$ kubectl get po
NAME READY STATUS RESTARTS AGE
ingressgateway-64d96fccbb-mvvh2 1/1 Running 0 25s
ingressgateway-64d96fccbb-s5pxm 1/1 Running 0 25s
istiod-1-23-4-567f9c879-vkrpk 1/1 Running 0 2m33s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingressgateway LoadBalancer 10.106.60.41 192.168.35.240 15021:31213/TCP,80:31167/TCP,443:31368/TCP 25s
istiod-1-23-4 ClusterIP 10.101.184.215 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 2m33s
istioctl 설치 (Optional)
마지막으로 istioctl를 설치하자. istioctl으로 istio를 설치하지 않았다고 해서 istioctl을 사용하지 않는 것은 아니다. istioctl는 istio를 관리하고 디버깅 하기 위한 좋은 도구로써도 사용이 되기 때문이다.
Mac OS에서는 brew로 간단히 설치가 가능하다.
$ brew install istioctl
$ istioctl version
client version: 1.24.2
control plane version: 1.23.4
data plane version: 1.23.4 (2 proxies)
사이드카 붙여보기
istio 설치를 완료하였다면 애플리케이션에 istio-proxy 사이드카를 붙여볼 수 있다. 쿠버네티스에서는 사이드카를 붙이기 위해 Pod에 container를 하나 더 추가하면 된다. 하지만 Pod 각각에 대해 istio-proxy 사이드카를 일일히 붙이는건 노동에 가깝다. 다행히 Istio는 똑똑하게 Kubernetes에서 제공하는 Admission Control 기능을 활용하여 특정 레이블이 있는 네임스페이스에 추가되는 파드의 컨테이너 설정을 추가하여 istio-proxy 컨테이너를 자동으로 넣어준다.
아래 명령어를 입력하면 istio-proxy 컨테이너를 자동으로 넣어주는 설정을 확인해볼 수 있다.
$ kubectl get mutatingwebhookconfigurations
먼저 istio-proxy를 자동으로 넣을 네임스페이스에게 다음과 같이 레이블을 추가하자. 둘 중 하나의 레이블만 추가해도 된다. (istio 업그레이드 시점이 다가오는 것을 대비하여 istio.io/rev 레이블을 사용하는 것이 더 좋다.)
# helm에서 설정한 revision을 넣어주면 됨.
$ kubectl label ns todo istio.io/rev=1-23-4
# istio.io/rev 아니면 이거
$ kubectl label ns todo istio-injection=enabled
그 후 해당 네임스페이스에 있는 파드들을 모두 재시작하자. 새로운 파드가 뜨면 컨테이너가 두개 떠있는 것을 확인할 수 있다.
$ kubectl rollout restart deploy -n todo
deployment.apps/todo-api restarted
$ kubectl get po -n todo
NAME READY STATUS RESTARTS AGE
todo-api-5c6745bb7d-ts8rt 0/2 PodInitializing 0 1s
todo-api-74cdc8bb68-hhp4h 1/1 Running 0 9h
해당 명령어를 통해 istio-proxy의 로그 또한 확인할 수 있다.
$ kubectl logs todo-api-5c6745bb7d-ts8rt -c istio-proxy
마무리
istio에 대한 간략한 소개와 함께 helm으로 istio를 설치하고, 사이드카를 붙여보는 방법에 대해 알아보았다. 추후에는 트래픽 관리 및 보안과 istio를 활용한 Observability에 대한 실질적인 내용을 다뤄볼 예정이다.
📒 참고 자료
https://istio.io/latest/docs/overview/what-is-istio/
https://istio.io/latest/docs/ops/deployment/architecture/
https://istio.io/latest/docs/overview/dataplane-modes/
https://istio.io/latest/docs/setup/install/helm/
'DevOps > Istio' 카테고리의 다른 글
istio traffic 관리 (2) [Gateway] (0) | 2025.01.13 |
---|---|
istio traffic 관리 (1) [VirtualService & DestinationRule] (0) | 2025.01.12 |
댓글