Cert-Manager + Let’s Encrypt 사용 K8s에서 SSL 적용 튜토리얼
이 포스트에서는 쿠버네티스 환경 내부에서 https 통신을 하기 위한 인증서를 생성하고 자동으로 갱신해주는 Cert-Manager 라는 모듈과 Let’s Encrypt 를 사용하여 인증서를 발급하는 방법에 대한 가이드를 소개합니다.
해당 포스트에서는 Ingress Controller는 NGINX Plus Ingress Controller를 사용하며, Cert-Manager의 설치 및 배포하는 과정은 다루지 않습니다. Cert-Manager 설치에 대한 가이드는 여기를 클릭하여 확인하세요.
이 포스트에서의 테스트 환경은 다음과 같습니다:
- Kubernetes Client Version: v1.28.2
- Kubernetes Server Version: v1.28.9
- NGINX Plus Ingress Controller v3.5.0
- Ubuntu 22.04.3 LTS
- Cert-Manager 1.14.4
목차
1. Service & Deploy 리소스 배포
2. Cert-Manager Issuer 리소스 생성
3. VirtualServer 리소스 생성
4. 발급된 인증서 확인
1. Service & Deploy 리소스 배포
SSL 인증서 발급을 하기 전, 테스트하기 위해 NGINX 이미지를 사용하여 간단한 Service와 Deployment 리소스를 배포합니다:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy1
namespace: nginx-ingress
spec:
selector:
matchLabels:
app: deploy1
template:
metadata:
labels:
app: deploy1
spec:
containers:
- name: containerd1
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc1
namespace: nginx-ingress
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: deploy1
위에 작성한 파일을 배포 및 확인합니다.
$ kubectl apply -f service.yaml
deployment.apps/deploy1 created
service/svc1 created
$ kubectl get pods -n nginx-ingress
NAME READY STATUS RESTARTS AGE
deploy1-xxxxxxx-yyyyyyy 1/1 Running 0 44s
2. Cert-Manager Issuer 리소스 생성
Issuer 리소스에 대해 간단히 설명하자면,
Issuer는 Cert-Manager가 TLS 인증서를 요청하는 방법을 정의합니다. Issuer 리소스는 쿠버네티스의 단일 Namespace에만 적용됩니다. 해당 포스트에서는 nginx-ingress라는 Namespace에 배포합니다. (TLS 인증서를 클러스터에 적용시키고 싶으시다면 ClusterIssuer 리소스를 사용하시면 됩니다.)
해당 테스트에서는 프로덕션용 인증서를 발급합니다. Issuer 리소스 내용은 다음과 같습니다:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-prod
namespace: nginx-ingress
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: admin@example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
ingressClassName: nginx
위에서 작성한 Issuer 리소스를 배포 및 확인합니다.
$ kubectl apply -f letsencrypt-prod.yaml
issuer.cert-manager.io "letsencrypt-prod" created
$ kubectl get issuer -n nginx-ingress
NAME READY AGE
letsencrypt-prod True 145m
스테이징용 Issuer 리소스는 아래와 같습니다:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
namespace: nginx-ingress
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: admin@example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
ingressClassName: nginx
3. VirtualServer 리소스 생성
해당 테스트에서는 Ingress 리소스가 아닌 NGINX Plus Ingress Controller의 커스텀 리소스인 VirtualServer 리소스를 사용합니다.
해당 테스트에서는 hodevops.nginxstore.kr이라는 DNS를 사용하며, VirtualServer 리소스의 내용은 다음과 같습니다:
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: hodevops
namespace: nginx-ingress
spec:
host: hodevops.nginxstore.kr
tls:
cert-manager:
issuer: letsencrypt-prod # 위에서 작성한 Issuer 리소스 이름
secret: quickstart-example-tls # 발급받을 Secret 이름
ingressClassName: nginx
upstreams:
- name: default
service: svc1
port: 80
routes:
- path: /
action:
pass: default
spec.tls.cert-manager 오브젝트는 기본적으로 NGINX Plus Ingress Controller에서 비활성화 되어있습니다. NGINX Plus Ingress Controller의 Deployment 리소스에서 아래와 같이 활성화합니다.
...
args:
- -nginx-plus
- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
- -enable-cert-manager
...
4. Cert-Manager 가 발급한 인증서 확인
위에서 생성한 Issuer 리소스와 VirtualServer 리소스를 배포하게 되면 Secret, Certificate, CertificateRequest, Order, Challenge 등 Let’s Encrypt 에서 인증서 발급을 위한 검증 리소스들이 생성이 됩니다.
위 Issuer 리소스를 작성할 때 이번 테스트에서는 ACME HTTP-01 유형을 사용했습니다. 이 유형으로 인증서를 발급받기 위해서는 Let’s Encrypt가 위에서 지정한 DNS의 80포트로 접근이 가능해야 합니다.
모든 검증이 끝나게 되면 아래 명령어를 통해서 인증서 발급이 됐는지 확인할 수 있습니다:
$ kubectl get certificate -n nginx-ingress
NAME READY SECRET AGE
quickstart-example-tls True quickstart-example-tls 163m
또한 위의 VirtualServer 리소스에서 정의한 Secret을 확인하려 tls.key와 tls.crt가 정상적으로 발급되었는지 아래 명령어를 통해 확인할 수 있습니다.
$ kubectl describe secret quickstart-example-tls -n nginx-ingress
...
Data
====
tls.crt: 3611 bytes
tls.key: 1679 bytes
정상적으로 발급이 완료되었다면, https로 접속하여 확인합니다.


인증서가 잘 적용된 것을 확인할 수 있습니다.
NGINX Plus를 직접 사용해 보시려면 30일 무료 평가판을 신청하거나 NGINX STORE에 연락하여 논의하십시오.
댓글을 달려면 로그인해야 합니다.