Cấu hình Cert-Manager Kubernetes: Tự động gia hạn SSL miễn phí cho VPS (2025)

Tác giả: Trần Thảo 28 tháng 05, 2026

Trong kỷ nguyên của Cloud Native, việc bảo mật đường truyền dữ liệu bằng HTTPS không còn là một lựa chọn, mà là tiêu chuẩn bắt buộc. Nếu bạn đang vận hành website trên nền tảng VPS truyền thống với Nginx hay Apache thuần túy, việc cài đặt SSL Let’s Encrypt qua certbot là điều quá đỗi quen thuộc. Tuy nhiên, khi chuyển dịch hạ tầng sang Kubernetes (K8s) trên VPS, câu chuyện quản lý chứng chỉ số trở thành một thách thức hoàn toàn khác biệt.

Bạn không thể SSH vào từng Pod để chạy lệnh gia hạn thủ công. Pod sinh ra rồi mất đi, IP thay đổi liên tục. Nếu không có cơ chế tự động hóa, bạn sẽ đối mặt với rủi ro vận hành lớn: Sáng thức dậy và thấy hàng loạt dịch vụ báo lỗi “Kết nối không an toàn” vì chứng chỉ hết hạn, kéo theo sự sụt giảm nghiêm trọng về uy tín thương hiệu và thứ hạng SEO.

Đó là lúc Cert-Manager Kubernetes xuất hiện như một giải pháp tối ưu. Bài viết này sẽ là tài liệu hướng dẫn chuyên sâu (Technical Deep Dive), giúp bạn không chỉ cài đặt thành công phiên bản mới nhất (v1.19.2) mà còn hiểu rõ tận gốc rễ cơ chế hoạt động bên trong để làm chủ hệ thống của mình.

Mô hình hóa mã hóa dữ liệu SSL/TLS trong Kubernetes

Nội dung chính bài viết:

  • Cơ chế: Hiểu cách Cert-Manager tự động hóa ACME Challenge.
  • Cài đặt: Hướng dẫn cài đặt chuẩn OCI (v1.19.2) mới nhất 2025.
  • Cấu hình: Phân biệt Staging và Production để tránh bị khóa Rate Limit.
  • Xử lý lỗi: Cách debug lỗi Challenge bị treo hoặc lỗi 429.

Cert-Manager Kubernetes: Không chỉ là công cụ cấp SSL

Nhiều người lầm tưởng Cert-Manager chỉ đơn thuần là một công cụ xin cấp SSL. Thực tế, đây là một bộ điều khiển (Controller) mạnh mẽ hoạt động theo kiến trúc Native của Kubernetes. Nó biến chứng chỉ SSL thành một loại tài nguyên (Resource) có thể quản lý, theo dõi và gia hạn tự động ngay trong Cluster.

Cơ chế hoạt động “Under The Hood”

Khi bạn yêu cầu một chứng chỉ, Cert-Manager thực hiện một quy trình quy chuẩn gồm 4 giai đoạn, thông qua các Custom Resource Definitions (CRDs):

  1. Certificate Resource: Đây là “bản vẽ” mong muốn của bạn. Bạn khai báo: “Tôi muốn domain example.com có SSL, hết hạn sau 90 ngày”.
  2. CertificateRequest: Cert-Manager tạo ra yêu cầu ký chứng chỉ (CSR) chứa thông tin khóa công khai.
  3. Order: Hệ thống gửi đơn đặt hàng tới máy chủ ACME của Let’s Encrypt.
  4. Challenge: Đây là bước quan trọng nhất. Let’s Encrypt sẽ gửi yêu cầu xác thực: “Nếu anh thực sự là chủ của example.com, hãy chứng minh đi!”. Cert-Manager sẽ tự động giải quyết yêu cầu này (thông qua việc tạo file tạm hoặc sửa DNS Record) để hoàn tất xác thực.

Hiểu được luồng dữ liệu này sẽ giúp bạn rất nhiều trong quá trình debug (sẽ đề cập chi tiết ở phần cuối bài).

Chiến lược xác thực: HTTP-01 hay DNS-01?

Trước khi bắt tay vào cấu hình, bạn cần chọn chiến lược xác thực (Solver) phù hợp với hạ tầng VPS của mình. Hai phương thức phổ biến nhất là HTTP-01 và DNS-01.

HTTP-01 Challenge (Khuyên dùng cho Web Server cơ bản)

Đây là phương thức đơn giản và phổ biến nhất, được sử dụng trong bài hướng dẫn này.

  • Cách hoạt động: Let’s Encrypt gửi một token bí mật tới Cert-Manager. Cert-Manager đưa token này lên một đường dẫn web công khai (ví dụ: http://example.com/.well-known/acme-challenge/token). Let’s Encrypt truy cập đường dẫn đó, nếu thấy đúng token sẽ xác thực thành công.
  • Ưu điểm: Dễ cấu hình, không phụ thuộc vào nhà cung cấp DNS.
  • Nhược điểm: Bắt buộc VPS phải mở Port 80 và domain phải trỏ đúng về IP của VPS. Không hỗ trợ chứng chỉ Wildcard (*.example.com).

DNS-01 Challenge (Dành cho hệ thống nâng cao)

  • Cách hoạt động: Thay vì truy cập web, Let’s Encrypt yêu cầu bạn tạo một TXT Record trên DNS. Cert-Manager sẽ dùng API Key của nhà cung cấp DNS (như Cloudflare, AWS Route53) để tự động thêm Record này.
  • Ưu điểm: Hỗ trợ chứng chỉ Wildcard, hoạt động được ngay cả khi Web Server nằm trong mạng nội bộ (không public internet).
  • Nhược điểm: Cấu hình phức tạp hơn, cần quản lý API Key bảo mật.

Trong khuôn khổ bài viết này, chúng ta sẽ tập trung vào HTTP-01 vì tính ứng dụng rộng rãi cho các website thông thường trên VPS.

Chuẩn bị môi trường kỹ thuật (Prerequisites)

Để đảm bảo quá trình cài đặt diễn ra ổn định theo chuẩn 2025, hệ thống của bạn cần đáp ứng các yêu cầu sau:

  1. Hạ tầng Kubernetes:
    • Phiên bản Kubernetes khuyến nghị: v1.22+. Lý do là các phiên bản cũ hơn sử dụng API Ingress cũ (extensions/v1beta1) đã bị loại bỏ, gây lỗi khi tương tác với Cert-Manager mới.
    • VPS cần có tối thiểu 2GB RAM để vận hành ổn định các Controller của Cert-Manager.
  2. Công cụ quản trị:
    • Helm v3: Công cụ quản lý gói cài đặt. Chúng ta sẽ không dùng file YAML thô (manifests) vì khó quản lý phiên bản về sau.
    • Kubectl: Đã cấu hình kết nối tới Cluster.
  3. Hạ tầng mạng & tên miền:
    • Tên miền (ví dụ: example.com) BẮT BUỘC phải trỏ A Record về địa chỉ Public IP của Ingress Controller trên VPS.
    • Tường lửa (Firewall/Security Group): Phải mở (Allow) Port 80443. Lỗi phổ biến nhất là Admin chỉ mở Port 443 (HTTPS) mà chặn Port 80, khiến Let’s Encrypt không thể thực hiện HTTP-01 Challenge. Bạn có thể tham khảo hướng dẫn cấu hình UFW để mở port an toàn.

Quy trình triển khai Cert-Manager (Chuẩn OCI)

Quy trình DevOps triển khai Cert-Manager

Chúng ta sẽ đi qua 4 bước triển khai thực tế. Lưu ý rằng bài viết này sử dụng phương thức cài đặt qua OCI Registry – tiêu chuẩn mới thay thế cho Helm Repo truyền thống để đảm bảo tính bảo mật và cập nhật nhanh nhất.

Bước 1: Cài đặt Cert-Manager qua Helm OCI

Các phiên bản Cert-Manager cũ thường hướng dẫn dùng lệnh helm repo add jetstack.... Tuy nhiên, với phiên bản v1.19.2, Jetstack khuyến nghị cài đặt trực tiếp từ OCI Registry.

Hãy chạy lệnh sau trên Terminal. Đảm bảo bạn đã nắm vững các lệnh Linux cơ bản để thao tác:

helm install \
  cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.19.2 \
  --set crds.enabled=true \
  --set prometheus.enabled=false

Phân tích lệnh:

  • oci://quay.io/...: Giao thức OCI (Open Container Initiative) giúp kéo gói cài đặt từ nguồn chính thống (“source of truth”), tránh rủi ro man-in-the-middle từ các repo trung gian không cập nhật.
  • --namespace cert-manager --create-namespace: Gom toàn bộ tài nguyên vào một namespace riêng để dễ quản lý và dọn dẹp.
  • --set crds.enabled=true: Đây là cờ quan trọng nhất. Nó ra lệnh cho Helm tự động cài đặt các CRD (Custom Resource Definitions) như Certificate, Issuer. Nếu quên cờ này, Cert-Manager sẽ chạy nhưng không “hiểu” được các lệnh tạo chứng chỉ của bạn.
  • --set prometheus.enabled=false: Tạm tắt Prometheus để tiết kiệm tài nguyên cho VPS nhỏ. Nếu bạn có hệ thống giám sát, hãy đổi thành true.

Sau khi cài đặt, hãy kiểm tra trạng thái hoạt động của các Pods:

kubectl get pods -n cert-manager

Bạn cần thấy 3 thành phần cốt lõi ở trạng thái Running:

  1. cert-manager: Controller chính điều phối mọi hoạt động.
  2. cert-manager-cainjector: Tự động tiêm CA bundle vào các Webhook.
  3. cert-manager-webhook: Kiểm tra tính hợp lệ (Validate) của các tài nguyên bạn tạo ra.

Bước 2: Thiết lập ClusterIssuer – “Người cấp phát” chứng chỉ

ClusterIssuer là tài nguyên đại diện cho tài khoản của bạn tại Let’s Encrypt. Khác với Issuer (chỉ dùng trong 1 namespace), ClusterIssuer có thể cấp chứng chỉ cho toàn bộ các namespace trong VPS.

Chúng ta cần thiết lập 2 môi trường riêng biệt: StagingProduction.

Cảnh báo về Rate Limit: Let’s Encrypt Production giới hạn rất nghiêm ngặt. Bạn chỉ được phép tạo 50 chứng chỉ/tuần cho một tên miền đăng ký. Nếu cấu hình sai và để hệ thống retry liên tục, bạn sẽ bị chặn (Block) trong 1 tuần. Môi trường Staging không có giới hạn này, giúp bạn kiểm thử an toàn.

Cấu hình Staging (cluster-issuer-staging.yaml):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # Server Staging của Let's Encrypt
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: [email protected] # Thay bằng email thật của bạn
    privateKeySecretRef:
      name: letsencrypt-staging-key
    solvers:
    - http01:
        ingress:
          # CẬP NHẬT 2025: Dùng 'ingressClassName' thay vì 'class'
          ingressClassName: nginx

Cấu hình Production (cluster-issuer-prod.yaml):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # Server Production chính thức
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
    - http01:
        ingress:
          ingressClassName: nginx

Áp dụng cấu hình vào Cluster:

kubectl apply -f cluster-issuer-staging.yaml
kubectl apply -f cluster-issuer-prod.yaml

Lưu ý kỹ thuật: Trường ingressClassName: nginx là bắt buộc đối với Kubernetes v1.19+ trở lên. Nếu bạn dùng phiên bản cũ (dùng annotation kubernetes.io/ingress.class), Cert-Manager có thể không nhận diện được Ingress Controller.

Bước 3: Tích hợp vào Ingress (Ingress Shim)

Thay vì phải tạo thủ công một tài nguyên Certificate rồi link vào Ingress, chúng ta sử dụng tính năng thông minh tên là Ingress Shim. Chỉ cần thêm một dòng annotation vào file Ingress, Cert-Manager sẽ tự động xử lý phần còn lại.

Dưới đây là mẫu Ingress chuẩn v1:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-website-ingress
  annotations:
    # Kích hoạt Cert-Manager. BẮT ĐẦU với Staging trước!
    cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - example.com           # Domain của bạn
    secretName: example-tls # Tên Secret chứa chứng chỉ (tự động tạo)
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

Khi bạn apply file này, ingress-shim sẽ phát hiện annotation cert-manager.io/cluster-issuer, tự động tạo ra một Certificate resource, từ đó kích hoạt quy trình ACME mà chúng ta đã phân tích ở đầu bài.

Bước 4: Kiểm tra, xác thực và chuyển đổi Production

Đây là bước xác định thành quả của bạn. Đừng vội vàng chuyển sang Production ngay.

Kiểm tra chứng chỉ Staging: Chạy lệnh kubectl get certificate.

  • Nếu thấy trạng thái READY: True: Chúc mừng, cấu hình của bạn đã đúng.
  • Truy cập website: Bạn sẽ thấy cảnh báo đỏ “Kết nối không riêng tư”. Đừng lo, hãy xem chi tiết chứng chỉ (Certificate Details). Nếu phần Issuer Name hiện là “(STAGING) Artificial Apricot…”, nghĩa là hệ thống đã hoạt động hoàn hảo. Trình duyệt báo lỗi chỉ vì chứng chỉ Staging không được tin cậy mặc định.

Chuyển đổi sang Production:
Sau khi Staging đã thành công, hãy quay lại file Ingress ở Bước 3, sửa annotation thành:
cert-manager.io/cluster-issuer: letsencrypt-prod

Apply lại Ingress và đợi khoảng 1-2 phút. Xóa Secret cũ nếu cần thiết (kubectl delete secret example-tls) để ép hệ thống lấy chứng chỉ mới ngay lập tức. Lúc này, website của bạn sẽ hiện ổ khóa xanh an toàn.

Các vấn đề thường gặp và cách xử lý (Troubleshooting)

Khắc phục sự cố Cert-Manager Kubernetes

Hệ thống tự động hóa dù tốt đến đâu cũng có thể gặp lỗi. Dưới đây là quy trình debug chuẩn cho Cert-Manager trên VPS.

Challenge bị treo (Pending)

Triệu chứng: Lệnh kubectl get certificate hiện READY: False mãi mãi.

Debug: Kiểm tra trạng thái của Challenge.

kubectl get challenges
kubectl describe challenge <tên-challenge>

Nguyên nhân & khắc phục:

  • Lỗi DNS: Let’s Encrypt không tìm thấy domain. → Kiểm tra lại A Record đã trỏ đúng IP VPS chưa.
  • Lỗi Firewall: Thông báo lỗi thường là Timeout. → Kiểm tra xem Port 80 trên VPS có đang mở không.
  • Lỗi Ingress Class: Cert-Manager tạo Pod giải mã nhưng Ingress không định tuyến traffic vào đó được. → Kiểm tra lại trường ingressClassName trong ClusterIssuer có khớp với Ingress Controller đang chạy không.

Lỗi Rate Limit (429 Too Many Requests)

Triệu chứng: Trong describe order thấy thông báo lỗi 429.

Nguyên nhân: Bạn đã yêu cầu quá nhiều chứng chỉ Production trong thời gian ngắn (50 chứng chỉ/tuần hoặc 5 lần lỗi xác thực/giờ).

Khắc phục: Không có cách nào để reset giới hạn này. Bạn buộc phải chờ hết thời gian phạt (1 giờ hoặc 1 tuần tùy lỗi). Đây là bài học đắt giá cho việc không dùng môi trường Staging.

Vấn đề gia hạn (Renewal)

Cert-Manager mặc định sẽ gia hạn chứng chỉ 30 ngày trước khi hết hạn.

Kiểm tra:

kubectl get certificate -o wide

Bạn sẽ thấy cột RENEWAL TIME. Nếu thời gian này đã qua mà chứng chỉ chưa được gia hạn, hãy kiểm tra logs của controller:

kubectl logs -l app=cert-manager -n cert-manager

Câu hỏi thường gặp (FAQ)

1. Tại sao Pod Cert-Manager không chạy (Status Pending/CrashLoopBackOff)?

Thường do 2 nguyên nhân: VPS thiếu RAM (OOMKilled) hoặc Webhook không khởi động được do Firewall chặn giao tiếp nội bộ. Hãy kiểm tra bằng lệnh kubectl describe pod -n cert-manager <tên-pod>.

2. Tôi có thể dùng Cert-Manager để cấp chứng chỉ Wildcard (*.domain.com) không?

Được, nhưng phải dùng DNS-01. Phương thức HTTP-01 trong bài này không hỗ trợ Wildcard. Bạn cần chuyển sang DNS-01 và cung cấp API Key của nhà cung cấp DNS (như Cloudflare).

3. Cert-Manager có tiêu tốn nhiều tài nguyên VPS không?

Rất nhẹ, chỉ khoảng 100MB – 200MB RAM trên Cluster K3s. Tuy nhiên, để ổn định, VPS nên có tối thiểu 2GB RAM.

4. Làm sao để gia hạn chứng chỉ thủ công (Force Renew)?

Cách nhanh nhất là xóa Secret chứa chứng chỉ cũ: kubectl delete secret example-tls. Cert-Manager sẽ phát hiện mất Secret và lập tức yêu cầu cấp mới ngay lập tức.

5. Tại sao đã chuyển sang Production mà trình duyệt vẫn báo “Not Secure”?

Do trình duyệt lưu Cache chứng chỉ Staging cũ (thử mở Tab ẩn danh) hoặc Secret cũ chưa được cập nhật. Hãy xóa thủ công Secret cũ để hệ thống kéo chứng chỉ mới về.

6. Tôi lỡ tay xóa mất Cert-Manager Controller, chứng chỉ có bị mất không?

Không. Chứng chỉ lưu trong Kubernetes Secret, độc lập với Controller. Web vẫn chạy HTTPS bình thường cho đến khi hết hạn (90 ngày).

Kết luận

Triển khai Cert-Manager Kubernetes trên VPS không chỉ giải quyết bài toán SSL miễn phí mà còn giúp hệ thống của bạn vận hành chuyên nghiệp hơn, giảm thiểu rủi ro do sai sót thủ công. Với phiên bản v1.19.2 và cài đặt qua OCI, bạn đang sở hữu một hạ tầng bảo mật hiện đại, dễ dàng mở rộng và bảo trì.

Hãy nhớ quy tắc vàng: Luôn test với Staging trước khi chạy Production. Một chút cẩn trọng sẽ giúp bạn tiết kiệm hàng giờ đồng hồ xử lý sự cố sau này.

Sau khi triển khai SSL tự động, đừng quên thiết lập hệ thống giám sát VPS Linux để theo dõi thời hạn chứng chỉ và thực hiện các bước bảo mật VPS Linux toàn diện khác.

Nếu bạn đang tìm kiếm một giải pháp VPS hiệu năng cao, tối ưu hóa sẵn cho Kubernetes để vận hành những hệ thống tự động hóa phức tạp như thế này, hãy tham khảo ngay các gói Cloud VPS chuyên dụng của chúng tôi.

Tài liệu tham khảo