Kubernetes에 Istio Sidecar 와 NGINX Plus Ingress Controller 통합
Istio Sidecar 란, 마이크로서비스 간의 모든 네트워크 통신을 담당할 수 있는 프록시인 Envoy를 Sidecar 패턴으로 마이크로서비스에 배포한 다음, 프록시들의 설정값 저장 및 관리/감독을 수행하고 프록시들에 설정값을 전달하는 Controller 역할을 합니다.
NGINX Plus Ingress Controller는 Istio Sidecar Proxy와 통합하여 Service Mesh 형태로 배포할 수 있습니다.
해당 블로그 포스트는 NGINX Plus Ingress Controller를 Istio Service Mesh 형태로 배포하는 과정 중, Istio Sidecar를 설치하고 NGINX Plus Ingress Controller에 주입하여 통합하는 과정을 가이드합니다.
본 가이드에서는 Kubernetes 클러스터가 하나 이상의 Master Node와 Worker Node로 구성되어 있고 NGINX Plus Ingress Controller가 설치되어 있다는 전제조건 하에 진행됩니다.
목차
1. Istioctl 설치
2. Istio Sidecar 배포 및 Injection
3. Istio Sidecar 와 NGINX Plus Ingress Controller 통합
4. Istio Sidecar 를 통한 Service Mesh 배포
4-1. Virtual Server Resource 배포
4-2. Istio Service Mesh 형태로 NGINX Plus Ingress Controller 배포 확인
1. Istioctl 설치
Istio 공식 Documentation을 참고해 Istio를 설치합니다.

아래 명령어는 Istio의 최신버전을 아키텍처와 OS 정보에 맞게 다운로드 하는 명령어입니다.
curl -L https://istio.io/downloadIstio | sh -
Istio 패키지 디렉토리를 확인합니다.
# pwd
/root
# ls
istio-1.21.0
패키지의 bin 디렉토리 하위에, istioctl 명령어가 존재하는지 확인합니다.
# pwd
/root/istio-1.21.0/bin
# ls
istioctl
istio 패키지 디렉토리에서 istioctl의 환경변수를 등록한 후, istioctl 명령이 동작하는지 확인합니다.
export PATH=$PWD/bin:$PATH
Istio Sidecar를 설정하기 위해 Kubernetes 클러스터에 Istio 를 설치합니다. 최소설치를 위해 설치 프로필은 minimal로 설정합니다.
# istioctl install --set profile=minimal
This will install the Istio 1.21.0 "minimal" profile (with components: Istio core and Istiod) into the cluster. Proceed? (y/N) y
✔ Istio core installed
✔ Istiod installed
✔ Installation complete Made this installation the default for injection and validation.
kubectl 명령어를 통해 Kubernetes 클러스터 내에 Istio Daemon 파드가 생성되었는지 확인합니다.
# kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istiod-5c586775f7-r7xf9 1/1 Running 0 4m59s
2. Istio Sidecar 배포 및 Injection
NGINX Plus Ingress Controller 파드가 배포될 때 Istio Sidecar를 주입하기 위해 labeling을 진행합니다.
label을 지정할 시, Webhook을 통해 Istiod 파드의 /inject API를 호출합니다.
# kubectl label namespace nginx-ingress istio-injection=enabled
namespace/nginx-ingress labeled
# kubectl get namespaces nginx-ingress --show-labels
NAME STATUS AGE LABELS
nginx-ingress Active 25d istio-injection=enabled,kubernetes.io/metadata.name=nginx-ingress
Istio를 설정하고 구성한 후에는 NGINX Plus Ingress Controller와 Service Mesh의 일부가 될 애플리케이션을 배포할 수 있습니다. 이제 Istio는 Istio 구성 방식에 따라 Istio Sidecar를 주입합니다.
아래 이미지는 NGINX Plus Ingress Controller 및 Istio 배포의 흐름을 설명합니다.

3. Istio Sidecar 와 NGINX Plus Ingress Controller 통합
Istio와 함께 NGINX Plus Ingress Controller를 배포할 때, 특정 Annotation을 포함하도록 배포 yaml 파일을 수정합니다.
특정 Annotation은 다음과 같습니다.
traffic.sidecar.istio.io/includeInboundPorts: ""
traffic.sidecar.istio.io/excludeInboundPorts: "80,443"
traffic.sidecar.istio.io/excludeOutboundIPRanges: "10.244.0.0/16"
sidecar.istio.io/inject: 'true'
수정한 NGINX Plus Ingress Controller 배포 yaml 파일은 다음과 같아야 합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
app.kubernetes.io/name: nginx-ingress
annotations:
traffic.sidecar.istio.io/includeInboundPorts: ""
traffic.sidecar.istio.io/excludeInboundPorts: "80,443"
traffic.sidecar.istio.io/excludeOutboundIPRanges: "10.244.0.0/16"
sidecar.istio.io/inject: 'true'
spec:
serviceAccountName: nginx-ingress
NGINX Plus Ingress Controller를 배포한 후, Istio Sidecar가 주입되었는지 확인합니다.
기존에는 하나의 NGINX Plus Ingress Controller 파드에 NGINX Plus Ingress Controller 컨테이너만 있던 반면, 현재는 Sidecar Proxy 컨테이너가 통합되어 NPIC 파드에 컨테이너가 2/2인것을 확인할 수 있습니다.
# kubectl get pods -n nginx-ingress
NAME READY STATUS RESTARTS AGE
nginx-ingress-5885676f7d-294lz 2/2 Running 2 3m
4. Istio Sidecar 를 통한 Service Mesh 배포
4-1. Virtual Server Resource 배포
nginx-ingress 네임스페이스에 배포된 NGINX Plus Ingress Controller 파드를 확인합니다.
# kubectl get pods -n nginx-ingress
NAME READY STATUS RESTARTS AGE
nginx-ingress-5885676f7d-294lz 2/2 Running 2 5m
해당 Ingress Controller는 Istio Sidecar Injection이 완료된 상태이며 nginx-ingress Namespace에 대해 Injection이 labeling 되어 있는 상태입니다.
간단한 웹 애플리케이션 테스트용 Virtual Server를 nginx-ingress 네임스페이스에 배포합니다.
virtualserver.yaml
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: cafe
namespace: nginx-ingress
spec:
host: cafe.example.com
upstreams:
- name: tea
service: tea-svc
port: 80
use-cluster-ip: true
- name: coffee
service: coffee-svc
port: 80
use-cluster-ip: true
routes:
- path: /tea
action:
proxy:
upstream: tea
requestHeaders:
set:
- name: Host
value: tea-svc.nginx-ingress.svc.cluster.local
- path: /coffee
action:
proxy:
upstream: coffee
requestHeaders:
set:
- name: Host
value: coffee-svc.nginx-ingress.svc.cluster.local
tea-coffee-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tea
spec:
replicas: 1
selector:
matchLabels:
app: tea
template:
metadata:
labels:
app: tea
spec:
containers:
- name: tea
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: tea-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: tea
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
spec:
replicas: 3
selector:
matchLabels:
app: coffee
template:
metadata:
labels:
app: coffee
spec:
containers:
- name: coffee
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: coffee-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee
4-2. Istio Service Mesh 형태로 NGINX Plus Ingress Controller 배포 확인
Pod의 Ready된 컨테이너들을 보면, 2/2로 하나의 파드에 두 개의 컨테이너가 동작 중인 것을 확인할 수 있습니다.
# kubectl get pods -n nginx-ingress
NAME READY STATUS RESTARTS AGE
tea-9d8868bb4-fkzdr 2/2 Running 0 22d
coffee-6b8b6d6486-6z7fz 2/2 Running 0 22d
# kubectl describe pods coffee-6b8b6d6486-6z7fz -n nginx-ingress
...
Containers:
coffee:
Container ID: containerd://c07179415a044bd532c2679f78c44cc513e48a079650c751b8a487427a2a0780
Image: nginxdemos/nginx-hello:plain-text
...
istio-proxy:
Container ID: containerd://0bf5303f94c650d6e231e18b255ca46af11a50ba2865dfc795cffc8499367564
Image: docker.io/istio/proxyv2:1.20.3
curl 테스트로 NGINX Plus Ingress Controller의 Istio Sidecar 패턴의 Service Mesh 배포를 확인할 수 있습니다.
# curl -kI cafe.example.com:31886/tea
HTTP/1.1 200 OK
Server: nginx/1.25.3
Date: Tue, 19 Mar 2024 05:03:28 GMT
Content-Type: text/plain
Content-Length: 154
Connection: keep-alive
expires: Tue, 19 Mar 2024 05:03:27 GMT
cache-control: no-cache
x-envoy-upstream-service-time: 2
# curl -kI cafe.example.com:31886/coffee
HTTP/1.1 200 OK
Server: nginx/1.25.3
Date: Tue, 19 Mar 2024 05:03:30 GMT
Content-Type: text/plain
Content-Length: 161
Connection: keep-alive
expires: Tue, 19 Mar 2024 05:03:29 GMT
cache-control: no-cache
x-envoy-upstream-service-time: 2
Istio Sidecar를 사용하여 Ingress Controller를 Service Mesh 형태로 배포하고 싶으신가요? NGINX Plus Ingress Controller를 통해 시작해보세요.
댓글을 달려면 로그인해야 합니다.