[Egress Gateway] Ingress부터 Egress까지 E2E 트래픽 흐름 제어

y001·2025년 4월 19일

Istio 실전 스터디

목록 보기
6/26

Istio를 사용하면 단순히 트래픽을 라우팅하는 것을 넘어, 네트워크 흐름을 관찰하고 제어하는 구조를 만들 수 있다. 이 글에서는 Ingress Gateway와 Egress Gateway를 함께 구성하여, 외부에서 내부 앱을 호출하고 다시 외부로 나가는 요청까지 포함한 End-to-End 트래픽 흐름을 실습했다.


🧭 실습 목표

  • 외부 사용자가 Istio Ingress Gateway를 통해 내부 앱 external-app에 접근한다.
  • external-app은 외부 사이트(http://www.google.com)로 요청을 전송한다.
  • 외부로 나가는 요청은 반드시 Istio Egress Gateway를 경유하도록 구성한다.

📐 트래픽 흐름도

+---------------------------+
|     [외부 클라이언트]     |  ← curl http://127.0.0.1/external
+------------+--------------+
             |
             v
+---------------------------+
|   Istio Ingress Gateway   | (공개 엔드포인트)
+------------+--------------+
             |
             v
+---------------------------+       +-----------------------------+
|     [external-app]        |  -->  |     (http://www.google.com) |
|  (Node.js 기반 테스트 서버) |       |    실제 외부 웹사이트 호출   |
+---------------------------+       +-----------------------------+
             |
             v
     (Istio Egress Gateway)   ← ServiceEntry + VirtualService + DestinationRule
             |
             +-- DNS resolve: www.google.com
             |
             +-- 실제 HTTP 요청 전송

1️⃣ Minikube 및 Istio 설치

minikube start --driver=docker --cpus=4 --memory=6g

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.2 sh -
cd istio-1.17.2
export PATH=$PWD/bin:$PATH

istioctl install --set profile=demo -y

2️⃣ 네임스페이스 생성 및 사이드카 주입 활성화

kubectl create namespace egress-test
kubectl label namespace egress-test istio-injection=enabled

3️⃣ 외부 도메인 접근 허용 (ServiceEntry)

kubectl apply -n egress-test -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: allow-google
spec:
  hosts:
  - www.google.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: DNS
  location: MESH_EXTERNAL
EOF

이 리소스는 Istio가 도메인 www.google.com을 외부 서비스로 인식하도록 해준다.


4️⃣ Egress Gateway를 통한 라우팅 설정

(1) Egress Gateway 리소스

kubectl apply -n istio-system -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - www.google.com
EOF

(2) DestinationRule (TLS 비활성화)

kubectl apply -n egress-test -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: direct-google
spec:
  host: www.google.com
  trafficPolicy:
    tls:
      mode: DISABLE
EOF

(3) VirtualService (Egress 경유 설정)

kubectl apply -n egress-test -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: route-through-egress-gateway
spec:
  hosts:
  - www.google.com
  gateways:
  - mesh
  - istio-egressgateway
  http:
  - match:
    - gateways: [mesh]
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        port:
          number: 80
  - match:
    - gateways: [istio-egressgateway]
    route:
    - destination:
        host: www.google.com
        port:
          number: 80
EOF

5️⃣ external-app 배포 (Node.js 앱)

Dockerfile

FROM node:18
WORKDIR /app
RUN npm init -y && npm install express
COPY server.js .
CMD ["node", "server.js"]

server.js

const express = require('express');
const http = require('http');
const app = express();

app.get('/external', (req, res) => {
  http.get('http://www.google.com', (resp) => {
    let data = '';
    resp.on('data', chunk => data += chunk);
    resp.on('end', () => res.send(`Google says:\n${data.substring(0, 300)}...`));
  }).on('error', err => res.status(500).send('Error: ' + err.message));
});

app.listen(3000);

이미지 빌드 및 Minikube 로드

docker build -t external-app:local .
minikube image load external-app:local

앱 및 서비스 배포

kubectl apply -n egress-test -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: external-app
  template:
    metadata:
      labels:
        app: external-app
    spec:
      containers:
      - name: external-app
        image: external-app:local
        ports:
        - containerPort: 3000
EOF

kubectl apply -n egress-test -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: external-app
spec:
  selector:
    app: external-app
  ports:
  - port: 80
    targetPort: 3000
EOF

6️⃣ Ingress Gateway 경유 라우팅 설정

kubectl apply -n egress-test -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: external-app-vs
spec:
  hosts:
  - "*"
  gateways:
  - istio-system/istio-ingressgateway
  http:
  - match:
    - uri:
        exact: /external
    route:
    - destination:
        host: external-app.egress-test.svc.cluster.local
        port:
          number: 80
EOF

✅ 최종 확인

# 터미널 1: minikube tunnel
minikube tunnel

# 터미널 2: 외부에서 호출
curl http://127.0.0.1/external

✨ 왜 Istio Gateway를 쓰는가?

기존의 Kubernetes Ingress는 단순한 HTTP 라우팅에만 초점이 맞춰져 있다. 반면, Istio Gateway는 다음과 같은 고급 기능들을 지원한다.

  • 경로/호스트/헤더 기반 라우팅
  • TLS 처리, 미러링, 트래픽 분할
  • 인증/인가 처리 (mTLS, JWT)
  • 외부 트래픽 관찰 (Egress Gateway)
  • 시각화 도구(Kiali), 추적(Zipkin), 모니터링(Prometheus) 통합

0개의 댓글