Istio Ingress Gateway는 단순히 외부 요청을 내부 서비스로 라우팅하는 기능을 넘어서, HTTPS를 통한 보안 통신(Transport Layer Security) 도 지원한다. 이번 실습에서는 self-signed 인증서를 생성하고 이를 Istio Ingress Gateway에 적용해, 외부 클라이언트가 HTTPS로 내부 서비스(httpbin)에 안전하게 접근할 수 있도록 설정한다.
[클라이언트 HTTPS 요청]
↓
[ Istio Ingress Gateway ]
↓ (이미 HTTP로 변환된 트래픽)
[ 내부 서비스 (httpbin) - 평문 HTTP ]
HTTPS 통신을 위해 TLS 인증서가 필요하다. 실제 운영 환경에서는 Let's Encrypt나 사설 CA를 사용할 수 있지만, 이번 실습에서는 개발 및 테스트 목적이므로 self-signed 인증서를 생성한다.
mkdir -p certs && cd certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=myhost.example.com/O=myorg"
cd ..
CN=myhost.example.com: 인증서가 유효한 호스트 이름 (이후 curl 요청 시 사용)O=myorg: 조직 이름-nodes: 개인키를 암호화하지 않도록 설정 (비밀번호 없이 사용)생성한 인증서와 키를 Kubernetes Secret으로 변환하여 Istio에서 참조할 수 있도록 만든다.
kubectl create -n istio-system secret tls my-credential \
--key=certs/tls.key \
--cert=certs/tls.crt
my-credential: 나중에 Gateway 리소스에서 참조할 이름istio-system 네임스페이스에 생성해야 Ingress Gateway에서 사용 가능TLS를 수신할 Gateway 리소스를 생성한다. 해당 Gateway는 443 포트에서 HTTPS 요청을 수신하고, 앞서 만든 Secret을 사용하여 TLS를 처리한다.
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: https-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: my-credential
hosts:
- "myhost.example.com"
EOF
credentialName: 앞서 만든 TLS Secret의 이름hosts: 이 Gateway가 수신할 호스트 이름 (CN과 일치해야 함)mode: SIMPLE: 단순 TLS (mTLS 아님)테스트용으로 많이 쓰는 httpbin 이미지를 배포하고, Service로 노출한다.
kubectl create deploy httpbin --image=docker.io/kennethreitz/httpbin
kubectl expose deploy httpbin --port 80
이제 httpbin 서비스는 클러스터 내에서 접근 가능한 상태다.
HTTPS 요청이 들어왔을 때 특정 경로(prefix)에 대해 httpbin 서비스로 라우팅하도록 설정한다.
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
namespace: default
spec:
hosts:
- "myhost.example.com"
gateways:
- https-gateway
http:
- match:
- uri:
prefix: /status
route:
- destination:
host: httpbin
port:
number: 80
EOF
/status로 시작하는 경로 요청을 httpbin 서비스로 포워딩한다.Istio Ingress Gateway의 외부 IP(또는 localhost)를 사용해 HTTPS 요청을 보낸다.
kubectl get svc istio-ingressgateway -n istio-system
curl -v -k --resolve myhost.example.com:443:127.0.0.1 https://myhost.example.com/status/200
--resolve는 DNS 없이 특정 호스트명과 IP를 수동으로 매핑-k는 self-signed 인증서 허용curl 결과에 SSL connection using TLSv1.3 등 TLS 설정이 명시되어야 한다.Server certificate: 항목에 CN=myhost.example.com이 확인되어야 한다.HTTP/2 200 응답 코드는 httpbin이 정상적으로 응답한 것