Istio를 사용하면 단순히 트래픽을 라우팅하는 것을 넘어, 네트워크 흐름을 관찰하고 제어하는 구조를 만들 수 있다. 이 글에서는 Ingress Gateway와 Egress Gateway를 함께 구성하여, 외부에서 내부 앱을 호출하고 다시 외부로 나가는 요청까지 포함한 End-to-End 트래픽 흐름을 실습했다.
external-app에 접근한다.external-app은 외부 사이트(http://www.google.com)로 요청을 전송한다.+---------------------------+
| [외부 클라이언트] | ← 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 요청 전송
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
kubectl create namespace egress-test
kubectl label namespace egress-test istio-injection=enabled
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을 외부 서비스로 인식하도록 해준다.
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
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
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
FROM node:18
WORKDIR /app
RUN npm init -y && npm install express
COPY server.js .
CMD ["node", "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);
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
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
기존의 Kubernetes Ingress는 단순한 HTTP 라우팅에만 초점이 맞춰져 있다. 반면, Istio Gateway는 다음과 같은 고급 기능들을 지원한다.