TLS 종료가 포함된 Ingress 예제
TLS 종료가 포함된 Ingress 예제 (Ingress Example with TLS Termination)
이 예제는 HTTP 및 gRPC Ingress 예제를 기반으로 TLS 종료(termination)를 추가한 내용이에요. 같은 라우팅 규칙을 사용하면서도 HTTPS 요청을 받아 처리하는 방법을 다룹니다.
본문
아래 두 애플리케이션을 사용하는 TLS Ingress 예제입니다.
# TLS ingress example, requires the below two applications
# https://raw.githubusercontent.com/istio/istio/release-1.11/samples/bookinfo/platform/kube/bookinfo.yaml
# https://github.com/GoogleCloudPlatform/microservices-demo
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
namespace: default
spec:
ingressClassName: cilium
rules:
- host: hipstershop.cilium.rocks
http:
paths:
- backend:
service:
name: productcatalogservice
port:
number: 3550
path: /hipstershop.ProductCatalogService
pathType: Prefix
- backend:
service:
name: currencyservice
port:
number: 7000
path: /hipstershop.CurrencyService
pathType: Prefix
- host: bookinfo.cilium.rocks
http:
paths:
- backend:
service:
name: details
port:
number: 9080
path: /details
pathType: Prefix
- backend:
service:
name: productpage
port:
number: 9080
path: /
pathType: Prefix
tls:
- hosts:
- bookinfo.cilium.rocks
- hipstershop.cilium.rocks
secretName: demo-cert
TLS 인증서와 개인 키 만들기
Self-signed Certificate
시연 목적으로 가상의 자가 서명 인증 기관(CA)이 서명한 TLS 인증서를 사용할 거예요. 이를 위한 가장 쉬운 방법 중 하나는 mkcert를 사용하는 것입니다. 이 예제에서 사용하는 호스트 이름인 bookinfo.cilium.rocks와 hipstershop.cilium.rocks를 검증할 수 있는 인증서가 필요해요.
$ mkcert bookinfo.cilium.rocks hipstershop.cilium.rocks
Note: the local CA is not installed in the system trust store.
Run "mkcert -install" for certificates to be trusted automatically ⚠️
Created a new certificate valid for the following names 📜
- "bookinfo.cilium.rocks"
- "hipstershop.cilium.rocks"
The certificate is at "./bookinfo.cilium.rocks+1.pem" and the key at "./bookinfo.cilium.rocks+1-key.pem" ✅
It will expire on 29 November 2026 🗓
이 데모 키와 인증서로 Kubernetes secret을 만드세요.
$ kubectl create secret tls demo-cert --key=bookinfo.cilium.rocks+1-key.pem --cert=bookinfo.cilium.rocks+1.pem
cert-manager
cert-manager를 설치해 봅시다.
$ helm repo add jetstack https://charts.jetstack.io
$ helm install cert-manager jetstack/cert-manager --version v1.16.2 \
--namespace cert-manager \
--set crds.enabled=true \
--create-namespace \
--set config.apiVersion="controller.config.cert-manager.io/v1alpha1" \
--set config.kind="ControllerConfiguration" \
--set config.enableGatewayAPI=true
이제 CA Issuer를 만드세요.
$ kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/servicemesh/ca-issuer.yaml
Ingress 배포
이 데모의 Ingress 구성은 기존 데모들과 동일한 라우팅을 제공하면서 TLS 종료가 추가된 형태예요.
Self-signed Certificate
$ kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/servicemesh/tls-ingress.yaml
cert-manager
$ kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/servicemesh/tls-ingress.yaml
이 Ingress가 인증서를 필요로 한다는 것을 cert-manager에 알리려면, 앞서 만든 CA issuer 이름으로 Ingress에 어노테이션을 추가하세요.
$ kubectl annotate ingress tls-ingress cert-manager.io/issuer=ca-issuer
그러면 TLS 인증서를 담은 Secret과 함께 Certificate 오브젝트가 만들어져요.
$ kubectl get certificate,secret demo-cert
NAME READY SECRET AGE
certificate.cert-manager.io/demo-cert True demo-cert 33m
NAME TYPE DATA AGE
secret/demo-cert kubernetes.io/tls 3 33m
External IP 주소는 Ingress에 표시돼요.
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
tls-ingress cilium hipstershop.cilium.rocks,bookinfo.cilium.rocks 35.195.24.75 80, 443 6m5s
이 Ingress 구성에서 hipstershop.cilium.rocks와 bookinfo.cilium.rocks 호스트 이름은 경로 라우팅 규칙에 명시돼 있어요. 클라이언트는 접근하려는 호스트를 지정해야 합니다. 이는 로컬의 /etc/hosts 파일을 편집해서 달성할 수 있어요. (이 파일을 편집하려면 거의 확실히 superuser 권한이 필요합니다.) Ingress 서비스에 할당된 IP 주소로 항목을 추가해서, 파일이 다음과 비슷하게 보이게 만드세요:
$ sudo perl -ni -e 'print if !/\.cilium\.rocks$/d' /etc/hosts; sudo tee -a /etc/hosts \
<<<"$(kubectl get ing tls-ingress -o=jsonpath='{.status.loadBalancer.ingress[0].ip}') bookinfo.cilium.rocks hipstershop.cilium.rocks"
HTTPS 요청 보내기
Self-signed Certificate
curl 요청에 CA의 인증서를 지정하면, 그 CA가 서명한 인증서를 신뢰한다는 뜻이 돼요.
$ curl --cacert minica.pem -v https://bookinfo.cilium.rocks/details/1
원한다면 CA를 지정하는 대신 -k를 사용해서 curl 클라이언트가 서버의 인증서를 검증하지 않게 할 수도 있어요. 둘 다 지정하지 않으면 "알 수 없는 기관(unknown authority)이 서명한 인증서"라는 오류가 발생합니다.
curl 요청에 -v를 지정하면 TLS 핸드셰이크가 성공적으로 일어난 것을 확인할 수 있어요.
gRPC 요청에도 비슷하게 CA를 지정할 수 있어요:
# Download demo.proto file if you have not done before
$ curl -o demo.proto https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/protos/demo.proto
$ grpcurl -proto ./demo.proto -cacert minica.pem hipstershop.cilium.rocks:443 hipstershop.ProductCatalogService/ListProducts
cert-manager
$ curl https://bookinfo.cilium.rocks/details/1
gRPC 요청에도 비슷하게 CA를 지정할 수 있어요:
grpcurl -proto ./demo.proto -cacert minica.pem hipstershop.cilium.rocks:443 hipstershop.ProductCatalogService/ListProducts
Note
아직
demo.proto파일을 내려받지 않았다면 gRPC Ingress 예제를 참고하세요.
브라우저에서 https://bookinfo.cilium.rocks를 방문할 수도 있어요. 브라우저가 인증 기관을 알 수 없다고 경고할 수 있지만, 이 경고를 넘어서면 bookstore 애플리케이션 홈페이지가 보일 거예요.
https://를 지정하지 않으면 요청이 타임아웃된다는 점을 기억하세요.