Published on

Tạo chứng chỉ Let’s Encrypt trên Kubernetes

Bài viết này mình sẽ hướng dẫn cách tạo chứng chỉ SSL Let’s Encrypt trên Kubernetes dùng Cert-manager.io

cert-manager

Đầu tiên chúng ta deploy cert-manager.io lên K8s cluster

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml

Sau khi deploy xong, chúng ta kiểm tra lại bằng lệnh kubectl get all -n cert-manager thì kết quả trả về

kubectl get all -n cert-manager
NAME                                          READY   STATUS    RESTARTS   AGE
pod/cert-manager-6ffb79dfdb-8g7zk             1/1     Running   0          7h51m
pod/cert-manager-cainjector-5fcd49c96-hh4sr   1/1     Running   0          7h51m
pod/cert-manager-webhook-796ff7697b-mrx9n     1/1     Running   0          7h51m
NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/cert-manager           ClusterIP   10.96.2.60       <none>        9402/TCP   7h51m
service/cert-manager-webhook   ClusterIP   10.101.101.199   <none>        443/TCP    7h51m
NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cert-manager              1/1     1            1           7h51m
deployment.apps/cert-manager-cainjector   1/1     1            1           7h51m
deployment.apps/cert-manager-webhook      1/1     1            1           7h51m
NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/cert-manager-6ffb79dfdb             1         1         1       7h51m
replicaset.apps/cert-manager-cainjector-5fcd49c96   1         1         1       7h51m
replicaset.apps/cert-manager-webhook-796ff7697b     1         1         1       7h51m

Cluster Issuer

Tiếp theo chúng ta tạo file cluster-issuer.yaml

# Dev ClusterIssue
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-dev
spec:
  selfSigned: {}
---
# Staging ClusterIssue
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # The ACME server URL
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: your-emai@email.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:
            class: nginx

# Production ClusterIssue
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: your-emai@email.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:
            class: nginx

Sau đó chúng ta apply

kubectl apply -f cluster-issuer.yaml

Ví dụ

Dưới đây là ví dụ đơn giản cách sử dụng Cluster issuer với Ingress Nginx, sau khi deploy thành công thì chứng chỉ Lest’s Encrypt sẽ được tự động tạo cho host. Tạo file example.yaml với nội dung như sau:

kind: Pod
apiVersion: v1
metadata:
  name: apple-app
  labels:
    app: apple
  namespace: fruit
spec:
  containers:
    - name: apple-app
      image: hashicorp/http-echo
      args:
        - '-text=apple'
---
kind: Service
apiVersion: v1
metadata:
  name: apple-service
  namespace: fruit
spec:
  selector:
    app: apple
  ports:
    - port: 5678 # Default port for image
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: apple
  namespace: fruit
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  rules:
    - host: your-domain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: apple-service
                port:
                  number: 5678
  tls:
    - hosts:
        - your-domain.com
      secretName: ssl-your-domain.com

Deploy resource

kubectl create namespace fruit
kubectl apply -f example.yaml