Trong bài trước, tôi đã hướng dẫn để cài đặt Nginx Ingress Controller cho cụm Kubernetes. Trong bài này tôi sẽ thiết lập cấu hình TLS Let's Encrypt cho Nginx Ingress. Các TLS Certificate được tự động renew trong cluster.
Tôi sử dụng cert-manager để thực hiện quản lý các TLS Certificate. Ngoài việc hỗ trợ Let's Encryption, cert-manager còn hỗ trợ các tính năng như Self-Signed Certificate, CA, Vault. Để tìm hiểu thêm về cert-manager và các tính năng nâng cao bạn có thể truy cập vào document chính thức của cert-manager tại [1].
Cert-Manager quản lý các resource: Issuer (ClusterIssuer) , Certificates, CertificateRequest.
Hình sau đây mô tả mối quan hệ giữa Issuer, Certificate, Secret và cert-manager:

Yêu cầu:
- helm
- Nginx Ingress Controller
Thực hiện add helm repo cho cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update

Cài đặt cert-manager bằng helm, sử dụng lệnh sau để install cert-manager:
helm install \
--name cert-manager \
--namespace cert-manager \
--version v1.0.2 \
jetstack/cert-manager \
--set installCRDs=true

Kiểm tra các pod của cert-manager trên namespace cert-manager

Tạo ClusterIssuer phục vụ cho việc request tới ACME server để generate TLS Certificate
Bạn có thể sử dụng mẫu ClusterIssuer sau, ngoài ra ta cũng có thể sử dụng Issuer thay cho ClusterIssuer. Điểm khác nhau là với ClusterIssuer thì Issuer Cluster Wide tức là có thể sử dụng ở bất cứ namespace nào. Còn với Issuer chỉ tồn tại trong 1 namespace duy nhất.
Manifest tạo Cluster Issuer có tên sapd-issuer như sau
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: sapd-issuer
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: sapd@vccloud.vn
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: sapd-ssl
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
Lưu ý:
- Điền thông tin email
- Tên Secret lưu private key với ACME server
- Server URL. Lưu ý sử dụng acme staging cho test và production khi triển khai thật
Lưu lại manifest với tên file cluster-issuer.yml
Thực hiện tạo cluster-issuer bằng lệnh sau
kubectl apply -f cluster-issuer.yml
Kiểm tra ClusterIssuer đã được tạo

Khởi tạo 1 deployment Nginx để kiểm tra và expose qua service
kubectl create deploy --image nginx nginx
kubectl expose deploy nginx --port 80
Kiểm tra các resource vừa tạo

Ta sẽ cần sử dụng 1 domain cho service nginx vừa tạo ra. Tôi sẽ sử dụng domain ingress-1.k8slab.sapham.net và trỏ tới IP của Load Balancer là 45.124.94.24
Tip: Các bạn có thể trỏ wildcard domain vào địa chỉ IP của Load Balancer (Ingress)

Tạo ingress cho service nginx với domain trên. Sử dụng ingress manifest như sau
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-2
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "sapd-issuer"
spec:
tls:
- hosts:
- ingress-1.k8slab.sapham.net
secretName: ingress-1-ssl
rules:
- host: ingress-1.k8slab.sapham.net
http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 80
Lưu ý:
- Sử dụng annotation để chỉ định cluster-issuer đã được tạo ở trên
- Khai báo host cho tls và rule: domain dùng để truy cập vào service
- Cert-manager sẽ lưu TLS Certificate cấp bởi Let's Encrypt vào Secret
Sau khi khởi tạo Ingress, ta sẽ thấy cert-manager khởi tạo Certificate, Secret để lưu trữ TLS Cert vừa được Generate.

Ta có thể kiểm tra thông tin Certificate vừa được khởi tạo bằng lệnh
kubectl describe cert ingress-1-ssl

Truy cập thử vào domain thông qua trình duyệt web

References: