Cài đặt TLS Let's Encrypt tự động trên Kubernetes

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:

[1] -  https://cert-manager.io/docs/