Published

- 2 min read

วิธีการสร้าง SSL Certificate โดยใช้ Cert Manager

img of วิธีการสร้าง SSL Certificate โดยใช้ Cert Manager

ต่อจากบทความที่แล้ว ก็จะมาต่อกับการสร้าง SSL Certificate โดยใช้ Cert Manager และใช้วิธี HTTP-01 challenge กันครับ
ซึ่งในบทความนี้จะทำแสดงวิธีการทำ SSL ที่ได้มาจาก Let’s Encrypt นะครับ

ปล. มีอีกท่าที่สามารถทำได้คือ เราสามารถ map DNS record โดยชี้ไปที่ IPv4 Address ที่เรา static IP Address ไว้ได้เลย แต่ต้อง Enable CloudFlare Proxy ครับ😁

โดยขั้นตอนการทำจะมีวิธีการเพิ่มขึ้นมาจากของเดิมดังนี้ครับ

Install Cert Manager

   # Cert Manager installation guide: https://cert-manager.io/docs/installation/helm/#1-add-the-helm-repository
# Add the Helm repository
helm repo add jetstack https://charts.jetstack.io

# Update your local Helm chart repository cache
helm repo update

# installing CRDs with kubectl
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.crds.yaml

# Install cert-manager
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.13.3

Apply ClusterIssuer โดย manifest จะเป็นตามตัวอย่างด้านล่างครับ

   apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: cert-manager
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ${EMAIL}
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx

ทำการเช็ค ClusterIssuer ซักนิดนึงว่าถูกสร้างแล้ว

   $ kubectl get clusterissuer
NAME               READY   AGE
letsencrypt-prod   True    93m
   $ kubectl get secret/letsencrypt-prod -n cert-manager
NAME               TYPE     DATA   AGE
letsencrypt-prod   Opaque   1      102m

ต่อไปจะเป็นการเพิ่ม reference ClusterIssuer ที่ชื่อ “letsencrypt-prod” มาที่ Ingress Object ครับ

โดยเรานั้นสามารถกำหนด secretName ที่เป็นเก็บค่า TLS Certificate ใน Secret Object ได้เลยครับ และตามด้วยกำหนด host ของเราที่ map DNS record ไว้

   apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/ssl-passthrough: 'true'
    nginx.ingress.kubernetes.io/proxy-connect-timeout: '300'
    nginx.ingress.kubernetes.io/proxy-read-timeout: '300'
    nginx.ingress.kubernetes.io/proxy-send-timeout: '300'
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - secretName: tls-secret
      hosts:
        - argocd.${YOURDOMAIN_COM}
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: argocd-server
                port:
                  number: 80

หลังจาก Apply ไปเสร็จเรียบร้อยก็มาตรวจ Certificate และ Secret ที่ถูกสร้างขึ้นครับ ซึ่งใน version ใหม่ๆ ของ Cert Manager
ได้มีการทำ default configuration ไว้ ซึ่งช่วยให้เราไม่ต้องกังวลเรื่อง Renewal (Rotation Policy) หรือการ explicit describe Certificate manifest ด้วยตัวเอง แต่จะเป็น pattern ที่ทาง Cert Manager เป็นคนสร้างให้เราเองเลย แค่เราประกาศชื่อ secretName ที่เราตั้งเท่านั้นครับ

   $ kubectl get secret/tls-secret -n argocd
NAME         TYPE                DATA   AGE
tls-secret   kubernetes.io/tls   2      93m
   $ kubectl describe certificate -n argocd
Name:         tls-secret
Namespace:    argocd
Labels:       <none>
Annotations:  <none>
API Version:  cert-manager.io/v1
Kind:         Certificate
Metadata:
  Creation Timestamp:  2023-12-14T21:34:43Z
  Generation:          1
  Owner References:
    API Version:           networking.k8s.io/v1
    Block Owner Deletion:  true
    Controller:            true
    Kind:                  Ingress
    Name:                  argocd-ingress
    UID:                   896ccf5e-09fb-48b2-aa7f-ae4d010786bc
  Resource Version:        11167058
  UID:                     aa56c1d2-1ead-403d-93ff-c66db2c8353c
Spec:
  Dns Names:
    argocd.${YOURDOMAIN_COM}
  Issuer Ref:
    Group:      cert-manager.io
    Kind:       ClusterIssuer
    Name:       letsencrypt-prod
  Secret Name:  tls-secret
  Usages:
    digital signature
    key encipherment
Status:
  Conditions:
    Last Transition Time:  2023-12-14T21:34:46Z
    Message:               Certificate is up to date and has not expired
    Observed Generation:   1
    Reason:                Ready
    Status:                True
    Type:                  Ready
  Not After:               2024-03-13T20:34:44Z
  Not Before:              2023-12-14T20:34:45Z
  Renewal Time:            2024-02-12T20:34:44Z
  Revision:                1
Events:                    <none>

หลังจากนั้นก็อย่าลืมมา map DNS record ครับ

แล้วเราก็ไปเข้าเว็ป argocd ผ่าน subdomain “argocd” ที่เรา map แล้ว expose ออกมาจะได้ผลลัพธ์ดังรูปด้านล่างครับ

References

https://cert-manager.io/docs/
https://cert-manager.io/docs/configuration/acme/
https://youtu.be/pcADx8JFUIA?si=YhDUvfxVx2ekc5MJ
https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address