Membuat Domain pada Kubernetes menjadi HTTPS menggunakan cert-manager

Sep 27, 2022 min read

Certmanager Nahhh

Kali ini catatan yang menurut saya agak banyak langkah, tanpa basa basi please welcome Membuat Domain pada Kubernetes menjadi HTTPS menggunakan cert-manager. Ada 2 bagian yang perlu diperhatikan

  1. ingress
  2. cert-manager

Ingress

Pertama kita perlu menginstall ingress pada cluster k8s terlebih dahulu, untuk metode installnya bisa menggunakan helm atau jika kita menggunakan digitalocean bisa menggunakan fitur Install Kubernetes 1-Click Apps. Install ingress melalui helm:

helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace

Cert-Manager

Sama halnya dengan Ingress jika kita menggunakan DO bisa menginstall melalui Install Kubernetes 1-Click Apps. Jika menginstall melalui helm berikut perintahnya

helm repo add jetstack https://charts.jetstack.io
helm repo update
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.9.1 \
  # --set installCRDs=true

Oke, setelah ingress dan cert-manager telah terinstall. Coba untuk membuat ingress tanpa https sesuai dengan service yang sudah terdeploy. Contoh ingress yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: RELEASE-NAME-demo
  labels:
    helm.sh/chart: demo-0.1.0
    app.kubernetes.io/name: demo
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "0.28.0"
    app.kubernetes.io/managed-by: Helm
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: "k8s-backend.demo.id"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: RELEASE-NAME-demo
                port:
                  number: 80

Pastikan sudah bisa mengakses domain yang sudah dibuat melalui ingress, contoh hasil ingress sudah terbuat semacam ini:

NAMESPACE   NAME          CLASS    HOSTS                   ADDRESS        PORTS     AGE
default     demo          nginx    k8s-backend.demo.id    167.x.x.x       80        21h

Issuer

Berfungsi untuk request dan genarate TLS yang valid untuk ingress yang sedang digunakan, dalam hal ini yaitu ingress-nginx. Berikut contoh file yaml issuer untuk staging:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
 name: letsencrypt-staging
 namespace: cert-manager
spec:
 acme:
   # The ACME server URL
   server: https://acme-staging-v02.api.letsencrypt.org/directory
   # Email address used for ACME registration
   email: yudi@mail.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

Apply file yaml tersebut, untuk mengecek apakah sudah terpasang bisa menggunakan perintah kubectl get clusterissuers.cert-manager.io. Buat juga file yaml untuk production

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

Setelah kedua file yaml tersebut terpasang, tambahkan pada file ingress yang tadi sudah dibuat sehingga menjadi seperti ini ingress-https.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: RELEASE-NAME-demo
  labels:
    helm.sh/chart: demo-0.1.0
    app.kubernetes.io/name: demo
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "0.28.0"
    app.kubernetes.io/managed-by: Helm
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
  tls:
    - hosts:
        - "k8s-backend.demo.id"
      secretName: demo-tls
  rules:
    - host: "k8s-backend.demo.id"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: RELEASE-NAME-demo
                port:
                  number: 80

Agar generate ssl aman dan untuk menghindari limit request kita menggunakan cluster-issuer staging terlebih dahulu. Jika sudah dirasa aman dan log pada pod cert-manager tidak ada masalah, baru pindah ke letsencrypt yang prod.

Jika tidak nampak error harusnya sudah bisa berjalan dan https sudah terinstall pada domain kita. yuhuuuu

sumber dan referensi:

https://marketplace.digitalocean.com/apps/cert-manager https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nginx-ingress-with-cert-manager-on-digitalocean-kubernetes