K8s Gateway API(NGF) & Istio: Pod 간 mTLS 적용 가이드
본 포스트에서는 NGINX Gateway Fabric(NGF)을 Gateway API의 구현체로 사용하여 외부 트래픽을 수신하고, 이를 Istio 사이드카와 연동하여 Pod 간 완벽한 mTLS 통신 환경을 구축하는 과정을 다룹니다. 특히 Istio의 PeerAuthentication을 STRICT 모드로 설정하여 평문 통신을 강제로 차단하고, Gateway API의 핵심 기능인 URLRewrite 필터를 활용해 서비스 메시 내부에서 올바른 인증서 로딩과 라우팅이 이루어지도록 구성하는 가이드를 제시합니다.
목차
1. 환경 구성
2. Istio Sidecar 적용
3. NGINX Gateway Fabric + App 구성
4. Istio Sidecar mTLS 구성
5. 결론
1. 환경 구성
- kubernetes: v1.32.2
- NGINX Gateway Fabric : 2.2.2
- Istio : 1.28.1
2. Istio Sidecar 적용
먼저 Istio Sidecar를 적용하여 Envoy Proxy를 통해 통신할 수 있도록 구성합니다.
kubectl label namespace application istio-injection=enabled
해당 Namespace 전체에 Sidecar를 Injection 할 수 있도록 구성하였습니다.

3. NGINX Gateway Fabric + App 구성
먼저 백엔드가 될 애플리케이션을 배포합니다.
NGINX Deployment를 구성하였습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
namespace: application
spec:
replicas: 2
selector:
matchLabels:
app: coffee
template:
metadata:
labels:
app: coffee
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: coffee-svc
namespace: application
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nginx
selector:
app: coffee
NGINX Gateway Fabric를 통하여 접속할 수 있도록 Gateway와 HTTPRoute를 구성합니다.
먼저 SSL 통신을 위한 서버 인증서를 추가합니다.
kubectl create secret tls server-tls-secret \
--cert=server.crt \
--key=server.key -n application
기본적으로 443 포트를 리스닝하는 Gateway 구성입니다.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: edge-gateway
namespace: application
spec:
gatewayClassName: nginx
listeners:
- name: https-listener
port: 443
protocol: HTTPS
hostname: "devopschan.com"
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: server-tls-secret
HTTPRoute를 구성합니다.
mTLS 환경에서 URLRewrite를 사용하는 이유는, Gateway가 트래픽을 백엔드로 보낼 때 ‘이 요청은 내부 메시(Mesh) 간 통신이므로 mTLS로 암호화해야 한다’는 것을 식별하기 위함입니다.
Envoy Proxy는 Host 헤더가 내부 KubeDNS(서비스명)와 일치할 때만 해당 서비스에 맞는 인증서와 SNI를 로드하여 mTLS 핸드쉐이크를 시도합니다. Host가 외부 도메인(devopschan.com)인 상태 그대로 전송되면, Gateway는 이를 내부 트래픽으로 인식하지 못해 평문(Plaintext)으로 전송하게 되고, 암호화된 트래픽만 허용하는 수신 측 Sidecar에 의해 연결이 거부됩니다.
따라서 URLRewrite를 통해 Host를 내부 서비스명으로 변경하거나, ServiceEntry로 외부 도메인을 메시에 등록하는 절차가 필수적입니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: coffee-route
namespace: application
spec:
parentRefs:
- name: edge-gateway
hostnames:
- "devopschan.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: URLRewrite
urlRewrite:
hostname: coffee-svc.application.svc.cluster.local # hostname을 coffe service의 kubeDNS 도메인으로 변경합니다.
backendRefs:
- name: coffee-svc # 해당 서비스로 Rewrite합니다.
port: 80
해당 구성을 추가한 뒤 구성을 저장합니다.

먼저 구성 전 Ingress Traffic이 잘 전달되는지 확인합니다.
정상적으로 devopschan.com 도메인으로 접속되는 것을 확인할 수 있습니다.

Kubernetes Pods안에서 coffee Service의 ClusterIP로 요청을 전송합니다.
curl용 Pods를 생성합니다.(sidecar는 제거한 후 요청을 전송합니다.)
kubectl run curl --image=curlimages/curl -n application --annotations="sidecar.istio.io/inject=false" -it --rm -- sh

요청이 되는 것을 확인할 수 있습니다.
4. Istio Sidecar mTLS 구성
Istio는 기본적으로 PERMISSIVE 모드로 동작합니다.
예를 들어 사이드카(Envoy)가 있는 A, B 파드 간 통신은 자동으로 mTLS 암호화가 적용되지만, 수신 측(B)은 암호화되지 않은 평문(Plain Text) 요청도 허용합니다.
해당 포스트에서는 STRICT 모드를 사용하여 정책을 변경하여 mTLS 통신만 허용하도록 강제합니다.
PeerAuthentication : Envoy Proxy의 mTLS 정책을 구성합니다.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: specific-app-mtls
namespace: application
spec:
selector:
matchLabels:
app: coffee # application Pods 만 해당 정책을 활성화합니다.
mtls:
mode: STRICT # mTLS를 강제합니다.
해당 구성을 추가한 후 curl을 통해 Pods에서 요청합니다.

Sidecar끼리 통신하는 것이 아니기 때문에 요청이 거절되는 것을 확인할 수 있습니다.
Istio Sidecar가 붙은 NGINX Gateway Fabric으로 접속 시 정상적인 응답을 하는 것을 확인할 수 있습니다.

Istio Monitoring 시스템인 Kiali에서도 mTLS가 구성된 것을 확인할 수 있습니다.

5. 결론
이번 실습을 통해 NGINX Gateway Fabric과 Istio를 연동함으로써 외부 요청부터 내부 애플리케이션에 도달하기까지의 전 구간에 강력한 보안 정책을 성공적으로 적용해 보았습니다. PeerAuthentication 정책을 STRICT 모드로 설정하여 사이드카를 통하지 않은 비인가 평문(Plaintext) 트래픽이 효과적으로 차단됨을 확인하였으며, Gateway 단에서의 적절한 Host 헤더 재작성(URLRewrite)을 통해 서비스 메시 내부의 mTLS 핸드쉐이크가 끊김 없이 수행됨을 검증할 수 있었습니다.
결과적으로 Gateway API의 표준화된 인터페이스와 Istio의 강력한 보안 기능을 결합하여, 운영의 복잡성을 최소화하면서도 엔터프라이즈급의 제로 트러스트 환경을 구축할 수 있었습니다.
F5 Distributed Cloud를 통해 JWT의 클레임 기반 접근 제어를 포함한 다양한 애플리케이션 보호 기능을 경험해 보고 싶으시다면 NGINX STORE를 통해 문의하세요.
댓글을 달려면 로그인해야 합니다.