Ssoon
2주차 : Istio gateways > 클러스터로 트래픽 유입 : TCP 트래픽 본문
CloudNet@ 가시다님이 진행하는 Istio Hands-on Study [1기]
🚀 Istio로 TCP 트래픽을 다뤄보자!
- Istio는 보통 HTTP/HTTPS 트래픽 관리로 유명하지만, TCP 기반의 모든 트래픽도 처리할 수 있는 강력한 도구입니다. 이를 통해 데이터베이스나 메시지 큐 같은 서비스를 외부 클라이언트가 클러스터 내부의 서비스와 소통할 수 있도록 노출할 수 있습니다..
🌐 Istio Gateway로 TCP 트래픽 열기
- Istio의 gateway는 HTTP뿐 아니라 TCP 기반의 다양한 트래픽을 처리할 수 있습니다. 예를 들어, MongoDB 같은 데이터베이스나 Kafka 같은 메시지 큐를 외부에서 접근 가능하도록 설정할 수 있습니다. 이는 Istio가 단순히 웹 트래픽뿐 아니라 클러스터 내부의 다양한 서비스를 외부로 연결하는 다리 역할을 합니다.
- Istio가 트래픽을 이해하고 라우팅하는 방식에 따라 설정이 달라집니다. HTTP 트래픽에서는 URL 경로나 헤더를 기반으로 세밀한 라우팅이 가능하지만, TCP 트래픽은 단순히 포트와 IP를 기준으로 동작하므로 설정이 더 직관적입니다.
Istio gateway를 사용하면 TCP 트래픽을 통해 MongoDB, Kafka 같은 서비스를 외부에 안전하게 노출할 수 있습니다.
🔌 TCP 트래픽의 한계와 특징
- TCP 트래픽을 Istio로 처리할 때는 몇 가지 제약이 있습니다. Istio가 HTTP처럼 트래픽의 세부 내용을 이해하지 못하기 때문에, retries, request-level circuit breaking, 복잡한 라우팅 같은 고급 기능은 사용할 수 없습니다. 이는 Istio가 TCP 트래픽을 '일반적인' 데이터 스트림으로 간주하기 때문입니다.
- 하지만 MongoDB처럼 Istio가 지원하는 특정 프로토콜을 사용할 경우, 약간의 추가 기능이 활성화될 수 있습니다. 그렇지 않다면 Istio는 트래픽을 단순히 전달하는 역할만 수행합니다.
TCP 트래픽은 HTTP와 달리 Istio가 프로토콜을 깊게 분석하지 않아 고급 기능이 제한됩니다.
🛠️ TCP 트래픽을 외부로 노출하는 방법
- Istio를 사용해 TCP 트래픽을 처리하려면 ingress gateway를 설정해 외부 클라이언트가 클러스터 내부 서비스에 접근할 수 있도록 해야 합니다. 이는 마치 집의 대문을 열어 특정 손님만 들어오게 하는 것과 비슷합니다. 외부에서 들어오는 TCP 트래픽이 클러스터 내부의 올바른 서비스로 전달되도록 라우팅 규칙을 정의하는 과정이 필요합니다.
- 이 과정에서 VirtualService와 DestinationRule 같은 Istio 리소스를 활용해 트래픽의 흐름을 제어합니다. 예를 들어, 특정 포트로 들어오는 트래픽을 MongoDB 서비스로 보내거나 Kafka 토픽으로 연결할 수 있죠.
ingress gateway를 설정해 TCP 트래픽을 클러스터 내부로 안전하게 라우팅할 수 있습니다.
🎉 마무리하며
Istio의 TCP 트래픽 처리 기능은 HTTP뿐 아니라 다양한 프로토콜을 사용하는 서비스를 외부로 노출할 때 매우 유용합니다. 비록 HTTP 트래픽만큼 세밀한 제어가 어렵지만, ingress gateway를 통해 데이터베이스나 메시지 큐 같은 서비스를 안전하게 외부와 연결할 수 있다는 점에서 큰 장점이 있습니다.
🌐 1. Istio Gateway로 TCP 트래픽 처리하기
지금까지 Istio Gateway를 사용해 HTTP와 HTTPS 트래픽을 처리하는 방법을 배웠습니다. 하지만 서비스 메시에서 HTTP가 아닌 TCP 기반 트래픽을 다루고 싶다면 어떻게 해야 할까요? 이번 가이드에서는 Istio Gateway를 활용해 TCP 포트를 노출하고, TCP 기반 서비스로 트래픽을 라우팅하는 방법을 설명합니다.
🛠️ TCP 기반 서비스 배포하기
- 먼저 서비스 메시 내부에 TCP 기반 서비스를 배포해야 합니다. 이번 예제에서는 go-echo(https://github.com/cjimti/go-echo)라는 TCP 서비스를 사용합니다. 이 서비스는 telnet 같은 TCP 클라이언트를 통해 접속해 명령을 입력하면 입력한 내용을 다시 출력해주는 간단한 에코 서버입니다.
- Deployment:
- tcp-echo 애플리케이션을 하나의 파드로 실행합니다.
- 해당 파드는 2701번 포트에서 TCP 요청을 수신합니다.
- Service:
- tcp-echo 애플리케이션에 접근하기 위한 TCP 서비스를 생성합니다.
- 외부에서 2701번 포트로 요청을 보내면, 이 서비스가 해당 요청을 내부의 tcp-echo 파드로 전달합니다.
- Deployment:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat ch4/echo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tcp-echo-deployment
labels:
app: tcp-echo
system: example
spec:
replicas: 1
selector:
matchLabels:
app: tcp-echo
template:
metadata:
labels:
app: tcp-echo
system: example
spec:
containers:
- name: tcp-echo-container
image: cjimti/go-echo:latest
imagePullPolicy: IfNotPresent
env:
- name: TCP_PORT
value: "2701"
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
ports:
- name: tcp-echo-port
containerPort: 2701
---
apiVersion: v1
kind: Service
metadata:
name: "tcp-echo-service"
labels:
app: tcp-echo
system: example
spec:
selector:
app: "tcp-echo"
ports:
- protocol: "TCP"
port: 2701
targetPort: 2701
- tcp-echo-deployment와 tcp-echo-service를 생성합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/echo.yaml -n istioinaction
deployment.apps/tcp-echo-deployment created
service/tcp-echo-service created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get pod -n istioinaction
NAME READY STATUS RESTARTS AGE
catalog-6cf4b97d-9h7db 2/2 Running 0 108m
tcp-echo-deployment-584f6d6d6b-dbzgq 2/2 Running 0 12s
webapp-7685bcb84-4kmr7 2/2 Running 0 108m
tcp-echo 서비스는 TCP 기반으로 동작하며,
Istio 사이드카 프록시가 함께 배포되어 서비스 메시 내에서 트래픽을 관리할 준비를 합니다.
🔌 Gateway로 TCP 포트 노출하기
- tcp 서빙 포트 추가
- port: 31400: 클러스터 내에서 31400번 포트에서 TCP 요청을 수신합니다.
- nodePort: 30006: 외부에서 Kubernetes 클러스터 외부에 접근하려면 30006번 포트를 사용하여 요청을 보냅니다.
- targetPort: 31400: 내부에서는 31400번 포트로 요청이 전달됩니다.
ports:
...
- name: tcp
nodePort: 30006
port: 31400
protocol: TCP
targetPort: 31400
...
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ KUBE_EDITOR="nano" kubectl edit svc istio-ingressgateway -n istio-system
service/istio-ingressgateway edited
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="tcp")]}'
{"name":"tcp","nodePort":30006,"port":31400,"protocol":"TCP","targetPort":31400}
- TCP 트래픽을 외부에서 수신하려면 Gateway 리소스를 설정해 특정 TCP 포트를 노출해야 합니다.
아래는 포트 31400을 열어 TCP 트래픽을 수신하는 Gateway 설정 예제입니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat ch4/gateway-tcp.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: echo-tcp-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 31400
name: tcp-echo
protocol: TCP
hosts:
- "*"
- 이 설정은 다음과 같은 작업을 수행합니다:
- istio-ingressgateway에서 포트 31400을 열어 TCP 트래픽을 수신합니다.
- protocol: TCP는 HTTP가 아닌 TCP 프로토콜을 사용함을 나타냅니다.
- hosts: "*"는 모든 호스트로 들어오는 TCP 트래픽을 허용합니다.
- 이 Gateway를 적용합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/gateway-tcp.yaml -n istioinaction
gateway.networking.istio.io/echo-tcp-gateway created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get gateway -n istioinaction
NAME AGE
coolstore-gateway 151m
echo-tcp-gateway 24s
Gateway는 TCP 포트(31400)를 노출해 외부 TCP 트래픽을 수신할 준비를 합니다.
포트는 NodePort 또는 LoadBalancer를 통해 외부로 노출되어야 합니다.
🛤️ VirtualService로 TCP 트래픽 라우팅하기
- Gateway에서 TCP 포트를 열었으니, 들어온 트래픽을 tcp-echo 서비스로 라우팅해야 합니다.
이를 위해 VirtualService 리소스를 사용하며, TCP 트래픽은 특정 포트(31400)에 매칭되도록 설정합니다. - 아래는 VirtualService 설정 예제입니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat ch4/echo-vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: tcp-echo-vs-from-gw
spec:
hosts:
- "*"
gateways:
- echo-tcp-gateway
tcp:
- match:
- port: 31400
route:
- destination:
host: tcp-echo-service
port:
number: 2701
- 이 설정은 다음과 같은 작업을 수행합니다:
- 포트 31400으로 들어오는 TCP 트래픽을 매칭합니다.
- 매칭된 트래픽을 tcp-echo-service의 포트 2701로 라우팅합니다.
- 이 VirtualService를 적용합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/echo-vs.yaml -n istioinaction
virtualservice.networking.istio.io/tcp-echo-vs-from-gw created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get vs -n istioinaction
NAME GATEWAYS HOSTS AGE
catalog-vs-from-gw ["coolstore-gateway"] ["catalog.istioinaction.io"] 25m
tcp-echo-vs-from-gw ["echo-tcp-gateway"] ["*"] 4s
webapp-vs-from-gw ["coolstore-gateway"] ["webapp.istioinaction.io"] 126m
VirtualService는 TCP 트래픽을 특정 포트(31400)에서
tcp-echo-service의 포트 2701로 라우팅하도록 설정합니다.
🔍 TCP 트래픽 테스트하기
- 이제 모든 설정이 완료되었으니, telnet을 사용해 TCP 서비스에 연결합니다.
콘솔에 텍스트를 입력하고 Enter를 누르면 입력한 내용이 그대로 출력됩니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ sudo apt install inetutils-telnet
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ telnet localhost 30006
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome, you are connected to node myk8s-control-plane.
Running on Pod tcp-echo-deployment-584f6d6d6b-dbzgq.
In namespace istioinaction.
With IP address 10.10.0.14.
Service default.
hello istio!
hello istio!
^]
telnet> quit
Connection closed.
telnet으로 포트 31400에 접속해 tcp-echo 서비스와 상호작용할 수 있습니다.
Gateway와 VirtualService가 TCP 트래픽을 올바르게 라우팅했음을 확인했습니다!
🎯 TCP 트래픽 관리 성공!
이제 Istio Gateway를 사용해 TCP 포트를 노출하고, TCP 기반 서비스로 트래픽을 라우팅하는 방법을 배웠습니다. tcp-echo 서비스를 배포하고, Gateway로 포트 31400을 열어 외부 트래픽을 수신하며, VirtualService로 트래픽을 서비스로 연결했습니다.
🚀2. Istio Gateway로 SNI Passthrough를 활용한 TCP 트래픽 라우팅
지금까지 Istio Gateway를 사용해 HTTP, HTTPS, 그리고 TCP 트래픽을 처리하는 방법을 배웠습니다. 이번에는 한 단계 더 나아가, SNI(Server Name Indication) Passthrough를 활용해 TLS로 보호된 TCP 트래픽을 Gateway에서 종료하지 않고 백엔드 서비스로 전달하는 방법을 알아봅니다. 이를 통해 데이터베이스, 메시지 큐, 캐시 같은 다양한 TCP 기반 애플리케이션을 서비스 메시에서 쉽게 다룰 수 있습니다.
🔒 SNI Passthrough로 TLS 트래픽 전달하기
- SNI Passthrough는 Istio Gateway가 TLS 연결을 종료하지 않고, 들어오는 TCP 트래픽을 SNI 헤더를 기반으로 적절한 백엔드 서비스로 라우팅하는 방식입니다. Gateway는 SNI를 검사해 트래픽을 전달할 서비스를 결정하며, TLS 연결은 백엔드 서비스에서 종료됩니다. 이를 통해 Gateway는 인증서 관리 부담 없이 다양한 TLS 기반 애플리케이션을 지원할 수 있습니다.
클라이언트 → Gateway (SNI 검사, TLS 종료 없이 전달) → 백엔드 서비스 (TLS 종료)
SNI Passthrough는 Gateway가 TLS를 종료하지 않고,
SNI 헤더를 기반으로 트래픽을 백엔드 서비스로 전달해 유연한 TCP 트래픽 처리를 가능하게 합니다.
🛠️ TLS를 종료하는 샘플 서비스 배포하기
- SNI Passthrough를 테스트하기 위해 TLS를 종료하는 샘플 애플리케이션(simple-tls-service-1)을 배포합니다.
이 서비스는 자체적으로 TLS 연결을 처리하며, Gateway는 트래픽을 전달만 합니다. - 다음 명령어를 실행해 서비스를 배포합니다: istioinaction 네임스페이스에 simple-tls-service-1을 배포합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/sni/simple-tls-service-1.yaml -n istioinaction
service/simple-tls-service-1 created
deployment.apps/simple-tls-service-1 created
secret/simple-sni-1.istioinaction.io created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get pod -n istioinaction
NAME READY STATUS RESTARTS AGE
catalog-6cf4b97d-9h7db 2/2 Running 0 136m
simple-tls-service-1-ffcc5bfd-f7hxc 2/2 Running 0 9s
tcp-echo-deployment-584f6d6d6b-dbzgq 2/2 Running 0 27m
webapp-7685bcb84-4kmr7 2/2 Running 0 136m
백엔드 서비스가 TLS를 종료하므로, Gateway는 인증서나 비밀 키를 설정할 필요가 없습니다.
트래픽은 단순히 전달됩니다.
🔌 Gateway로 SNI Passthrough 설정하기
- 이제 Gateway 리소스를 설정해 포트 31400에서 TLS 트래픽을 수신하고, SNI Passthrough를 활성화합니다.
- 이전 섹션에서 동일한 포트(31400)를 사용했으므로, 기존 Gateway를 먼저 삭제합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl delete gateway echo-tcp-gateway -n istioinaction
gateway.networking.istio.io "echo-tcp-gateway" deleted
- 다음은 SNI Passthrough를 위한 Gateway 설정 예제입니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat ch4/sni/passthrough-sni-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: sni-passthrough-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 31400
name: tcp-sni
protocol: TLS
hosts:
- "simple-sni-1.istioinaction.io"
tls:
mode: PASSTHROUGH
- 이 설정은 다음과 같은 작업을 수행합니다:
- 포트 31400에서 TLS 프로토콜로 트래픽을 수신합니다.
- tls.mode: PASSTHROUGH 는 Gateway가 TLS를 종료하지 않고 트래픽을 백엔드로 전달함을 나타냅니다.
- hosts는 SNI 헤더로 매칭할 호스트(simple-sni-1.istioinaction.io)를 지정합니다.
- 이 Gateway를 적용합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/sni/passthrough-sni-gateway.yaml -n istioinaction
gateway.networking.istio.io/sni-passthrough-gateway created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get gw -n istioinaction
NAME AGE
coolstore-gateway 169m
sni-passthrough-gateway 3s
tls.mode: PASSTHROUGH를 사용해 Gateway는 TLS 연결을 처리하지 않고,
SNI를 기반으로 트래픽을 라우팅합니다.
🛤️ VirtualService로 SNI 기반 라우팅 설정하기
- Gateway에서 트래픽을 수신했으니, 이를 simple-tls-service-1 서비스로 라우팅하려면 VirtualService 리소스를 설정해야 합니다.
- 아래는 SNI를 기반으로 트래픽을 라우팅하는 VirtualService 설정 예제입니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat ch4/sni/passthrough-sni-vs-1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: simple-sni-1-vs
spec:
hosts:
- "simple-sni-1.istioinaction.io"
gateways:
- sni-passthrough-gateway
tls:
- match:
- port: 31400
sniHosts:
- simple-sni-1.istioinaction.io
route:
- destination:
host: simple-tls-service-1
port:
number: 80
- 이 설정은 다음과 같은 작업을 수행합니다:
- 포트 31400에서 SNI 헤더가 simple-sni-1.istioinaction.io인 트래픽을 매칭합니다.
- 매칭된 트래픽을 simple-tls-service-1 서비스의 포트 80으로 라우팅합니다.
- 이 VirtualService를 적용합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/sni/passthrough-sni-vs-1.yaml -n istioinaction
virtualservice.networking.istio.io/simple-sni-1-vs created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl get vs -n istioinaction
NAME GATEWAYS HOSTS AGE
catalog-vs-from-gw ["coolstore-gateway"] ["catalog.istioinaction.io"] 45m
simple-sni-1-vs ["sni-passthrough-gateway"] ["simple-sni-1.istioinaction.io"] 4s
tcp-echo-vs-from-gw ["echo-tcp-gateway"] ["*"] 19m
webapp-vs-from-gw ["coolstore-gateway"] ["webapp.istioinaction.io"] 145m
VirtualService는 SNI 헤더를 기반으로 TLS 트래픽을 특정 서비스로 라우팅하며,
Gateway와 협력해 Passthrough를 구현합니다.
🔍 SNI Passthrough 테스트하기
- 설정이 완료되었으니, 포트 31400으로 HTTPS 요청을 보내 테스트해봅시다. 다음 명령어를 실행합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ curl https://simple-sni-1.istioinaction.io:30006/ \
--cacert ch4/sni/simple-sni-1/2_intermediate/certs/ca-chain.cert.pem
{
"name": "simple-tls-service-1",
"uri": "/",
"type": "HTTP",
"ip_addresses": [
"10.10.0.15"
],
"start_time": "2025-04-19T08:17:48.952375",
"end_time": "2025-04-19T08:17:48.952708",
"duration": "333.637µs",
"body": "Hello from simple-tls-service-1!!!",
"code": 200
}
- 이 요청은 Istio Gateway를 거쳐 TLS 종료 없이 simple-tls-service-1로 전달되었습니다.
Gateway는 SNI를 검사해 트래픽을 simple-tls-service-1로 라우팅했으며,
TLS는 백엔드 서비스에서 종료되었습니다.
🌐 두 번째 서비스로 SNI 라우팅 확장하기
- SNI Passthrough의 강력함을 더 확인하기 위해, 두 번째 서비스(simple-tls-service-2)를 배포하고 다른 SNI 호스트(simple-sni-2.istioinaction.io)로 라우팅해보겠습니다. 먼저 두 번째 서비스를 배포합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/sni/simple-tls-service-2.yaml -n istioinaction
service/simple-tls-service-2 created
deployment.apps/simple-tls-service-2 created
secret/simple-sni-2.istioinaction.io created
- 이제 Gateway를 업데이트해 두 SNI 호스트를 모두 처리하도록 설정합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat ch4/sni/passthrough-sni-gateway-both.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: sni-passthrough-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 31400
name: tcp-sni-1
protocol: TLS
hosts:
- "simple-sni-1.istioinaction.io"
tls:
mode: PASSTHROUGH
- port:
number: 31400
name: tcp-sni-2
protocol: TLS
hosts:
- "simple-sni-2.istioinaction.io"
tls:
mode: PASSTHROUGH
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/sni/passthrough-sni-gateway-both.yaml -n istioinaction
gateway.networking.istio.io/sni-passthrough-gateway configured
- 그리고 두 번째 VirtualService를 추가합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ cat ch4/sni/passthrough-sni-vs-2.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: simple-sni-2-vs
spec:
hosts:
- "simple-sni-2.istioinaction.io"
gateways:
- sni-passthrough-gateway
tls:
- match:
- port: 31400
sniHosts:
- simple-sni-2.istioinaction.io
route:
- destination:
host: simple-tls-service-2
port:
number: 80
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ kubectl apply -f ch4/sni/passthrough-sni-vs-2.yaml -n istioinaction
virtualservice.networking.istio.io/simple-sni-2-vs created
- 이제 두 번째 서비스를 테스트합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ echo "127.0.0.1 simple-sni-2.istioinaction.io" | sudo tee -a /etc/hosts
127.0.0.1 simple-sni-2.istioinaction.io
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-UQRJB87:~/istio-in-action/book-source-code-master$ curl https://simple-sni-2.istioinaction.io:30006 \
--cacert ch4/sni/simple-sni-2/2_intermediate/certs/ca-chain.cert.pem
{
"name": "simple-tls-service-2",
"uri": "/",
"type": "HTTP",
"ip_addresses": [
"10.10.0.16"
],
"start_time": "2025-04-19T08:22:00.782662",
"end_time": "2025-04-19T08:22:00.782902",
"duration": "239.598µs",
"body": "Hello from simple-tls-service-2!!!",
"code": 200
}
- 응답의 body 필드에서 simple-tls-service-2가 처리했음을 확인할 수 있습니다.
동일한 포트(31400)에서 SNI를 기반으로 두 서비스(simple-tls-service-1, simple-tls-service-2)로 트래픽을 라우팅했습니다. SNI Passthrough는 호스트별로 정확한 라우팅을 보장합니다.
🎯 SNI Passthrough로 다양한 애플리케이션 지원!
이제 Istio Gateway에서 SNI Passthrough를 사용해 TLS로 보호된 TCP 트래픽을 백엔드 서비스로 전달하는 방법을 배웠습니다. Gateway는 SNI 헤더를 검사해 트래픽을 올바른 서비스로 라우팅하며, TLS는 백엔드에서 종료됩니다. 이를 통해 데이터베이스, 메시지 큐, 캐시 같은 TCP 기반 애플리케이션은 물론, 레거시 HTTPS 서비스도 서비스 메시에 쉽게 통합할 수 있습니다.