No menu items!
No menu items!
More

    Cert Manager trong Kubernetes

    Cert-manager là một controller trong Kubernetes được sử dụng để tạo và quản lý chứng chỉ SSL/TLS cho các ứng dụng chạy trên Kubernetes. Nó cho phép tự động hóa việc cài đặt, phát hành và quản lý chứng chỉ SSL/TLS miễn phí, đặc biệt là Let’s Encrypt. Cert-manager có thể tích hợp với nhiều trình cung cấp DNS, cho phép bạn sử dụng các tên miền do bên thứ ba quản lý và vẫn có thể sử dụng Let’s Encrypt để phát hành chứng chỉ. Nó giúp cho việc quản lý chứng chỉ SSL/TLS trở nên đơn giản và tiện lợi hơn khi triển khai ứng dụng trên Kubernetes.

    Cert-manager không chỉ hỗ trợ cho Let’s Encrypt mà còn hỗ trợ cho nhiều loại chứng chỉ SSL/TLS khác nhau. Nó được thiết kế để làm việc với các CAs khác nhau bằng cách sử dụng một phương thức gọi là “ACME challenge” (một giao thức chung giữa các CA khác nhau để xác thực các yêu cầu cấp chứng chỉ). Điều này cho phép Cert-manager làm việc với bất kỳ CA nào hỗ trợ ACME challenge, và không chỉ giới hạn cho Let’s Encrypt. Tuy nhiên, Let’s Encrypt là một trong những CA phổ biến nhất được hỗ trợ bởi Cert-manager.

    Cert-Manager hỗ trợ các loại chứng chỉ SSL/TLS sau:

    • ACME (Let’s Encrypt và bất kỳ ACME CA nào khác)
    • Vault
    • Venafi
    • HashiCorp Consul
    • Jetstack Certificate Manager (bao gồm cả self-signed certificate)
    • Self-signed certificates

    Ngoài ra, bạn cũng có thể sử dụng Cert-Manager để tạo ra CertificateSigningRequest và yêu cầu ký bởi các CA tự lập.

    Lưu, Cert-manager không hỗ trợ trực tiếp OpenSSL để phát hành các chứng chỉ SSL/TLS. Tuy nhiên, Cert-manager có thể được sử dụng để yêu cầu chứng chỉ từ một số ứng dụng như Let’s Encrypt, HashiCorp Vault, Venafi, Jetstack Certificate Manager, Vault PKI, ACME-based CAs, và Cloudflare Origin CA. Nếu bạn muốn sử dụng OpenSSL, bạn có thể sử dụng nó để tạo và tự ký một chứng chỉ SSL/TLS và sau đó sử dụng Cert-manager để sử dụng chứng chỉ đó trong Kubernetes.

    Đây là link manifest của Cert-manage, trong kho Github của Cert-manager bạn sẽ thấy 2 file YAML cert-manager.yamlcert-manager.crds.yaml

    https://github.com/cert-manager/cert-manager/releases

    Cả hai file YAML cert-manager.yamlcert-manager.crds.yaml đều liên quan đến triển khai Cert-manager trên Kubernetes, tuy nhiên chúng có mục đích khác nhau:

    • cert-manager.crds.yaml: chứa các Custom Resource Definition (CRD) cho Cert-manager, định nghĩa các kiểu tài nguyên tùy chỉnh để quản lý các yêu cầu và chứng chỉ SSL/TLS. File này cần được triển khai trước khi triển khai Cert-manager.
    • cert-manager.yaml: chứa tất cả các phiên bản của Cert-manager, bao gồm các Pod, Service và các thành phần khác của Cert-manager. File này sử dụng các CRD đã được định nghĩa trước đó trong cert-manager.crds.yaml để quản lý các yêu cầu và chứng chỉ SSL/TLS.

    Vì vậy, khi triển khai Cert-manager lần đầu tiên trên một cụm Kubernetes, bạn cần triển khai cert-manager.crds.yaml trước và sau đó triển khai cert-manager.yaml. Tuy nhiên, nếu bạn đã triển khai cert-manager.crds.yaml trước đó và chỉ muốn cập nhật Cert-manager, bạn có thể chỉ triển khai cert-manager.yaml.

    Để triển khai Cert-manager trên cụm Kubernetes, bạn có thể làm theo các bước sau:

    Đầu tiên tạo namespace cho Cert-manager bằng lệnh:

    kubectl create namespace cert-manager

    Đầu tiên mình sẽ tạo thư mục chứa cert-manager và di chuyển vào thư mục này.

    mkdir cert-manager
    cd cert-manager

    Mình sẽ tải file manifest này về local bằng lệnh wget <link file manifest>.

    wget https://github.com/cert-manager/cert-manager/releases/download/v1.12.0-beta.2/cert-manager.yaml
    $ ll
    total 432
    drwxr-xr-x 2 root root   4096 May 15 02:41 ./
    drwxr-xr-x 6 root root   4096 May 15 02:41 ../
    -rw-r--r-- 1 root root 430229 May 12 16:27 cert-manager.yaml
    $ kubectl apply --validate=false -f /home/cert-manager/cert-manager.yaml 
    namespace/cert-manager created
    customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
    customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
    customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
    customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
    customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created
    customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io created
    serviceaccount/cert-manager-cainjector created
    serviceaccount/cert-manager created
    serviceaccount/cert-manager-webhook created
    configmap/cert-manager-webhook created
    clusterrole.rbac.authorization.k8s.io/cert-manager-cainjector created
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-issuers created
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers created
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificates created
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-orders created
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-challenges created
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim created
    clusterrole.rbac.authorization.k8s.io/cert-manager-view created
    clusterrole.rbac.authorization.k8s.io/cert-manager-edit created
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-approve:cert-manager-io created
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificatesigningrequests created
    clusterrole.rbac.authorization.k8s.io/cert-manager-webhook:subjectaccessreviews created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-cainjector created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-issuers created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificates created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-orders created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-challenges created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-approve:cert-manager-io created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificatesigningrequests created
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-webhook:subjectaccessreviews created
    role.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection created
    role.rbac.authorization.k8s.io/cert-manager:leaderelection created
    role.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving created
    rolebinding.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection created
    rolebinding.rbac.authorization.k8s.io/cert-manager:leaderelection created
    rolebinding.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving created
    service/cert-manager created
    service/cert-manager-webhook created
    deployment.apps/cert-manager-cainjector created
    deployment.apps/cert-manager created
    deployment.apps/cert-manager-webhook created
    mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
    validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

    Hoặc bạn cũng có thể triển khai trực tiếp bằng cách chèn url của file manifest kubectl apply --validate=false -f <link file manifest> cũng được.

    $ kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0-beta.2/cert-manager.yaml
    namespace/cert-manager unchanged
    customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io unchanged
    customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io unchanged
    customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io unchanged
    customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io unchanged
    customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io unchanged
    customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io unchanged
    serviceaccount/cert-manager-cainjector unchanged
    serviceaccount/cert-manager unchanged
    serviceaccount/cert-manager-webhook unchanged
    configmap/cert-manager-webhook configured
    clusterrole.rbac.authorization.k8s.io/cert-manager-cainjector unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-issuers unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificates unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-orders unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-challenges unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-view unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-edit unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-approve:cert-manager-io unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificatesigningrequests unchanged
    clusterrole.rbac.authorization.k8s.io/cert-manager-webhook:subjectaccessreviews unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-cainjector unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-issuers unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificates unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-orders unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-challenges unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-approve:cert-manager-io unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificatesigningrequests unchanged
    clusterrolebinding.rbac.authorization.k8s.io/cert-manager-webhook:subjectaccessreviews configured
    role.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection unchanged
    role.rbac.authorization.k8s.io/cert-manager:leaderelection unchanged
    role.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving unchanged
    rolebinding.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection unchanged
    rolebinding.rbac.authorization.k8s.io/cert-manager:leaderelection configured
    rolebinding.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving configured
    service/cert-manager unchanged
    service/cert-manager-webhook unchanged
    deployment.apps/cert-manager-cainjector unchanged
    deployment.apps/cert-manager unchanged
    deployment.apps/cert-manager-webhook unchanged
    mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook configured
    validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook configured

    Bạn có thể verify lại xem cert-manager đã triển khai thành công chưa bằng lệnh kubectl -n cert-manager get all.

    $ kubectl -n cert-manager get all
    NAME                                           READY   STATUS    RESTARTS   AGE
    pod/cert-manager-757cfdccc6-q58nq              1/1     Running   0          37m
    pod/cert-manager-cainjector-54559f9d67-29tqm   1/1     Running   0          37m
    pod/cert-manager-webhook-547ddf5647-s44jp      1/1     Running   0          37m
    
    NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    service/cert-manager           ClusterIP   10.105.104.252   <none>        9402/TCP   37m
    service/cert-manager-webhook   ClusterIP   10.104.9.220     <none>        443/TCP    37m
    
    NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/cert-manager              1/1     1            1           37m
    deployment.apps/cert-manager-cainjector   1/1     1            1           37m
    deployment.apps/cert-manager-webhook      1/1     1            1           37m
    
    NAME                                                 DESIRED   CURRENT   READY   AGE
    replicaset.apps/cert-manager-757cfdccc6              1         1         1       37m
    replicaset.apps/cert-manager-cainjector-54559f9d67   1         1         1       37m
    replicaset.apps/cert-manager-webhook-547ddf5647      1         1         1       37m

    Như vậy Cert-manager đã cài đặt thành công. Phần tiếp theo sẽ hướng dẫn bạn sử dụng nó với Letsencrypt, nhưng trước hết bạn nên xem qua bài viết Chuyển đổi WordPress từ Virtual Machine hoặc Docker sang Kubernetes trước khi đọc tiếp phần dưới nhé. Vì bài này mình sẽ sử dụng project của bài trước để hướng dẫn.

    Sau khi xem qua bài viết mình nhắc ở trên, bạn cần cài đặt Cert Manager và thực hiện các bước sau:

    1. Tạo một Issuer để kết nối với Let’s Encrypt.

    Trong ví dụ này, chúng ta sử dụng Let’s Encrypt bằng cách tạo một ClusterIssuer. Hãy tạo một tệp YAML có nội dung như sau:

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-prod
      namespace: wiki-hoanghd
    spec:
      acme:
        email: hoanghd164@gmail.com
        server: https://acme-staging-v02.api.letsencrypt.org/directory
        privateKeySecretRef:
          name: letsencrypt-prod
        solvers:
          - http01:
              ingress:
                class: nginx

    Lưu ý rằng trong phần email, bạn cần thay thế your-email@example.com bằng địa chỉ email của bạn.

    1. Tạo một Certificate

    Sau khi tạo Issuer, bạn có thể tạo một Certificate để yêu cầu chứng chỉ SSL từ Let’s Encrypt. Tạo một tệp YAML có nội dung như sau:

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: website-tls
      namespace: wiki-hoanghd
    spec:
      secretName: website-tls
      duration: 2160h # 90 days
      renewBefore: 360h # 15 days
      commonName: wordpress.hoanghd.com
      dnsNames:
        - wordpress.hoanghd.com
      issuerRef:
        name: letsencrypt-prod
        kind: ClusterIssuer

    Trong phần commonNamednsNames, hãy thay thế wordpress.hoanghd.com bằng tên miền của bạn.

    1. Thêm TLS vào Ingress

    Cuối cùng, bạn cần thêm TLS vào Ingress của bạn bằng cách chỉ định tlshosts trong phần spec. Tạo một tệp YAML có nội dung như sau:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: website
      namespace: wordpress
      labels:
        app: website-wp
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "true"
        cert-manager.io/issuer: "letsencrypt-prod"
        cert-manager.io/cluster-issuer: "letsencrypt-prod"
    spec:
      tls:
        - secretName: website-tls
          hosts:
            - wordpress.hoanghd.com
      rules:
        - host: wordpress.hoanghd.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: website-wp
                    port:
                      number: 80

    Lưu ý rằng trong phần annotations, chúng ta thêm hai thông tin, cert-manager.io/issuercert-manager.io/cluster-issuer, để cho Cert Manager biết rằng Issuer nào được sử dụng cho Certificate này.

    Sau khi triển khai các tệp YAML này, Cert Manager sẽ tự động yêu cầu chứng chỉ SSL từ Let’s Encrypt thông qua ACME server của nó. Khi yêu cầu được chấp nhận và xác thực thành công, Cert Manager sẽ tạo ra một secret chứa chứng chỉ SSL và sử dụng nó để cấu hình Ingress Controller. Sau đó, bạn sẽ có thể truy cập trang web của mình bằng HTTPS và trình duyệt của bạn sẽ xác thực chứng chỉ SSL từ Let’s Encrypt.

    Lưu ý là để sử dụng Let’s Encrypt cho domain wordpress.hoanghd.com, bạn cần phải public domain này ra internet để các service của Let’s Encrypt có thể truy cập và xác thực. Vì vậy, để sử dụng Let’s Encrypt, bạn cần phải public domain wordpress.hoanghd.com ra internet.

    Tuy nhiên, nếu bạn chỉ muốn sử dụng SSL certificate để test ở môi trường local, bạn có thể tạo một self-signed certificate. Self-signed certificate sẽ không được xác thực bởi một tổ chức nào đó như Let’s Encrypt, và sẽ bị các trình duyệt hiển thị thông báo cảnh báo về tính bảo mật. Tuy nhiên, self-signed certificate vẫn cho phép bạn sử dụng HTTPS để kết nối với website của mình.

    Bạn có thể sử dụng OpenSSL để tạo self-signed certificate. Sau khi tạo xong, bạn có thể tạo một Kubernetes secret để lưu trữ certificate và key, và sử dụng nó trong Ingress object của mình.

    Sau khi chỉnh sửa xong, tôi đã update manifest lên Gitlab và ArgoCD đã update lại manifest cho tôi. Phần tô đỏ là phần deploy của Cert Manager.

    Bạn có thể verify lại thông tin Certificate đã tạo.

    $ kubectl get Certificate -n wiki-hoanghd
    NAME          READY   SECRET        AGE
    website-tls   False   website-tls   48m

    Hoặc thông tin ClusterIssuer đã tạo.

    $ kubectl get ClusterIssuer -n wiki-hoanghd
    NAME               READY   AGE
    letsencrypt-prod   True    49m

    Để xem chi tiết thông tin bạn có thể sử dụng lệnh kubectl describe ClusterIssuer -n wiki-hoanghd hoặc kubectl describe Certificate -n wiki-hoanghd .

    Và đây là kết quả khi truy cập website.

    Bài viết gần đây

    spot_img

    Related Stories

    Leave A Reply

    Please enter your comment!
    Please enter your name here

    Đăng ký nhận thông tin bài viết qua email