istio를 설치하는 방법은 여러가지가 있다.
istioctl, Istio Operator, Istio helm chart로 설치하는 방법이 있다.
1. istioctl 설치
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.13.1
export PATH=$PWD/bin:$PATH
2. 설치가능한 프로필 확인
istioctl profile list
3. defalut profile 설치
istioctl install --set profile=default -y
4. envoy sidecar proxy auto 주입
kubectl label namespace <네임스페이스> istio-injection=enabled
## disabled 설정
kubectl label namespace innog-dev istio-injection=disabled --overwrite
## 특정 pod에만 주입하지 않는 경우
template
metadata:
annotations:
sidecar.istio.io/inject: "false" # Istio 사이드카 주입 비활성화
## 특정 pod에 주입할 경우
istioctl kube-inject -f <your-application.yaml> -o <output.yaml>
Istio manifest에 미리 변수를 설정하고자 할 때 아래 명령어 수행 하지만 istioctl 설치는 형상관리, GitOps가 되지 않기 때문에 설치 버전을 yaml 형식으로 버저닝한다면 helm이 좋은 거 같다.
|
|
|
1. helm 설치
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
2. helm chart 배포
kubectl create namespace istio-system
# base 리소스는 Istio의 동작에 필요한 CRDs(Custom Resource Definitions) 및 네임스페이스 등의 필수 구성 요소를 포함하고 있다.
helm install istio-base istio/base -n istio-system --set defaultRevision=default
# istiod 서비스 설치를 위한 배포
helm install istiod istio/istiod -n istio-system --set profile=default --wait
3. enovy sidecar 주입 (위와 동일)
kubectl label namespace <네임스페이스> istio-injection=enabled
## disabled 설정
kubectl label namespace innog-dev istio-injection=disabled --overwrite
## 특정 pod에만 주입하지 않는 경우
template
metadata:
annotations:
sidecar.istio.io/inject: "false" # Istio 사이드카 주입 비활성화
## 특정 pod에 주입할 경우
istioctl kube-inject -f <your-application.yaml> -o <output.yaml>
|
|
|
마지막으로 operator를 통한 방식이다.
운영할 때는 설정을 파일로 관리하는 편이 장점이 더 많다. 예를 들어서 kubectl create -f <yaml>처럼 말이다. istioctl도 istio 설정을 파일로 관리하는 기능을 제공해주는데 그게 바로 istio operator이다. istio operator을 이용하면 쿠버네티스 CRD로 istio를 설정할 수 있다.
1. istio operator 설치
istioctl operator init
istioctl명령어로 설치했던 과정을 이제 yaml파일로 설치할 수 있다.
https://istio.io/latest/docs/setup/install/operator/#install-istio-with-the-operator
2. istio operator을 이용하여 istio 설치
kubectl apply -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: example-istiocontrolplane
spec:
profile: default
EOF
|
|
|
설치가 완료됐다면 간단하게 적용하는 예제를 보자. 필자는 EKS 환경이기에 AWS ALB를 ingress로 활용하고 있다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-istio
namespace: istio-system
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: instance
alb.ingress.kubernetes.io/group.name: ingress-alb-g
alb.ingress.kubernetes.io/load-balancer-name: ingress-alb
alb.ingress.kubernetes.io/certificate-arn: "acm arn"
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/ssl-redirect: '443'
alb.ingress.kubernetes.io/healthcheck-path: "/actuator/health"
alb.ingress.kubernetes.io/security-groups: "sg-exam"
alb.ingress.kubernetes.io/manage-backend-security-group-rules: "true"
spec:
ingressClassName: alb
rules:
- host: xxx.xxx.co.kr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: istio-ingressgateway
port:
number: 80
ingress에서 xxx.xxx.co.kr 로 들어오는 경우 istio-ingressgateway svc로 트래픽을 보낸다.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway-istio
namespace: <NS>
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "xxx.xxx.co.kr"
Gateway는 Istio의 서비스 메시 외부에서 들어오는 트래픽을 수신하고, 이를 내부 서비스로 전달하는 역할을 한다. Kubernetes의 Ingress와 유사하지만, Istio Gateway는 더 세밀한 제어를 제공한다.
- 외부 트래픽 관리: Istio Gateway는 L4/L7 계층에서 외부에서 들어오는 HTTP, HTTPS, TCP 트래픽을 처리하며, 보안, 인증, 경로 제어 등을 설정할 수 있다.
- 예시: 특정 도메인으로 들어오는 요청을 클러스터 내 특정 서비스로 라우팅하거나, TLS 종료를 처리하는 등의 작업을 Gateway에서 정의한다.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtualservice-istio
namespace: <NS>
spec:
hosts:
- "xxx.xxx.co.kr"
gateways:
- gateway-istio
http:
- match:
- uri:
prefix: /x/
route:
- destination:
host: x-svc # 라우팅할 서비스
port:
number: 80
- match:
- uri:
prefix: /
route:
- destination:
host: default-svc # 라우팅할 서비스
port:
number: 80
VirtualService는 들어오는 트래픽을 어떤 서비스로 라우팅할지 결정하는 트래픽 라우팅 규칙을 정의한다. 여러 서비스로 분기하거나, 조건에 따라 특정 버전의 서비스로 트래픽을 보낼 수 있다.
- 트래픽 라우팅: VirtualService는 서비스 메시에 있는 트래픽을 라우팅할 수 있으며, URL 경로나 헤더에 따라 다르게 처리할 수 있다.
- Retry, 타임아웃, 페일오버와 같은 고급 네트워크 기능도 VirtualService에서 설정할 수 있다.
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: destinationrule-istio
namespace: <NS>
spec:
host: default-svc # 라우팅할 서비스 이름
trafficPolicy:
connectionPool:
http:
http1MaxPendingRequests: 100 # 최대 대기 요청 수
maxRequestsPerConnection: 100 # 한 연결당 최대 요청 수
outlierDetection:
consecutive5xxErrors: 3 # 연속 5번의 500 오류 발생 시 인스턴스 격리
interval: 10s # 상태를 평가하는 주기
baseEjectionTime: 10s # 인스턴스를 30초 동안 격리
maxEjectionPercent: 100 # 격리할 최대 인스턴스 비율
loadBalancer:
simple: ROUND_ROBIN # 라운드 로빈 방식의 로드 밸런싱
DestinationRule은 VirtualService에서 정의한 목적지(서비스)에 대한 정책을 설정한다. 예를 들어, 서비스의 **서브셋(subset)**을 정의하거나, 로드 밸런싱, 연결 풀 관리, mTLS 설정 등을 여기서 구성한다.
- 서브셋 관리: 특정 서비스의 여러 버전(v1, v2)에 대해 로드 밸런싱 규칙을 설정할 수 있으며, Canary 배포나 Blue/Green 배포 시에 유용하다.
- mTLS 설정: 서로 다른 서비스 간의 통신을 암호화하는 mTLS 설정도 DestinationRule에서 할 수 있다.
트래픽 흐름은 아마 다음과 같을 것이다. (틀린 부분이 있을 수도 있습니다.)
ingress로 부터 유입된 트래픽은 위 설정과 같이 istio-ingressgateway svc로 들어와 ingressgateway pod로 전달될 것이다.
이후 pod에 sidecar로 배포된 envoy proxy를 통해 실제 서비스에 트래픽이 유입될 것이다.
istio도 쿠버네티스와 비슷한 아키텍쳐로 Control Plane과 Data Plane으로 컴포넌트를 구분할 수 있다.
간단하게 각 Plane이 어떤 컴포넌트로 구성되어있고 어떤 역할을 하는지 아주 간단하게 살펴보자.
Control Plane은 Data Plane을 컨트롤하는 구성 요소를 가리키고 Pilot, Mixer, Citadel, Galley 등으로 구성되어 있다.
Pilot은 envoy에 대한 설정 관리를 하는 역할을 한다. Traffic Management 기능을 제공한다. Service Discovery (Envoy Endpoint 검색, Traffic Retry,Circuit Breaker,Timeout)
Mixer는 Serice Mesh 전체 영역에서 Access 제어 및 정책을 관리하고 모니터링 지표를 수집한다. 기존의 Mixer의 기능은 Pilot이 수행한다.
Citadel은 보통 보안과 관련된 기능을 담당하는 컴포넌트라고 생각하면 쉽다. 대표적으로 인증 기능을 관리한다.(TLS Certification 등)
Galley는 Istio configuration을 체크한다. Kubernetes Yaml 파일을 istio가 이해할 수 있는 형태로 변환한다.
현재 Control Plane은 istiod라는 하나의 프로세스로 합쳐졌다.(기존의 Mixer의 기능을 1.5 버전부터 Pilot이 수행함)
Data Plane은 실제로 트래픽을 받아 처리해주는 부분이라고 보면 될 거 같다. Sidecar 형태로 배포된 envoy proxy가 해당 영역에 속한다. 보통 사용자가 Gateway, VirtualService, DestinationRule 등을 정의하고 적용하면 Api-server는 해당 리소스를 etcd에 저장한다. 이후 istiod는 변경 사항을 감지하여 이를 읽고 xDS API를 통해 구성 정보를 Envoy Sidecar에게 전달한다. Envoy는 받은 설정을 기반으로 트래픽을 처리하게 된다. xDS API는 Envoy Proxy와 istiod간에 사용되는 API 모음으로 각종 설정을 전달하여 업데이트하는 데 사용된다.
필자가 해당 구성도를 그린 이유는 트래픽 흐름이 이해가 잘 가지 않았다. kube-proxy를 통해 iptables을 업데이트하고 Kubernetes SVC가 가리키는 Pod의 주소를 받아오는 것으로 이해하였는데 서비스메시, istio를 도입하고 나서는 Architecture가 아예 달랐다.
윗 그림은 앞선 구조 관점의 Istio의 정의를 나타냄과 동시에 Istio가 없는 traffic 흐름과의 차이를 보여준다.
Istio가 없는 상단 traffic은 kube-proxy에 의해 L4에서 routing되는 반면(L4 load balancing), Istio 기반의 하단 traffic은 kube-proxy 없이 L7에서 routing되어(L7 load balancing), kube-proxy 의 개입 없이 destination pod로 직접 전달된다.
Control plane인 istiod 는 앞선 routing에 필요한 pod IP를 포함한 cluster 정보를 각각의 Istio proxy에 동기화함과 동시에 각종 control message를 전달하여 가능한 구조이다.
최근에는 Sidecar없는 아키텍쳐의 Service Mesh가 부각되기도 했다고 한다.
istio를 활용하여 전반적인 트래픽 흐름을 흘리는데는 어떻게 큰 문제 없이 되었지만 세세한 설정에 관해서는 확인해보지 못했고 오버 엔지니어링이 되지 않을까 고민도 많이 해봤던 거 같다.
추가로 istio를 모니터링하기 위한 Kiali 설치와 기존 Prometheus와 통합하는 방법에 대해서는 따로 기록하였으니 관심있다면 참고해보도록 하자.
https://sh970901.tistory.com/157
https://www.anyflow.net/sw-engineer/istio-overview-1
'IT' 카테고리의 다른 글
AWS Opensearch(ElasticSearch) Data CSV 변환, S3 적재 (0) | 2024.10.26 |
---|---|
쿠버네티스[EKS] Kiali 설치 및 기존 Prometheus 활용 (2) | 2024.10.09 |
EKS worker node SSM 접속 (0) | 2024.10.09 |
쿠버네티스[EKS] argo rollout을 이용한 Blue/Green, Canary 배포 (3) | 2024.10.09 |
쿠버네티스[EKS] argocd 설치 및 AWS ALB 외부 노출, Slack 설정 (0) | 2024.10.09 |