This guide demonstrates the usage of cert-manager as a certificate provider to manage and issue certificates in OSM.

Prerequisites

  • Kubernetes cluster running Kubernetes v1.20.0 or greater.
  • Have kubectl available to interact with the API server.
  • Have osm CLI available for installing and managing the service mesh.

Demo

The following demo uses cert-manager as the certificate provider to issue certificates to the curl and httpbin applications communicating over Mutual TLS (mTLS) in an OSM managed service mesh.

  1. Install cert-manager. This demo uses cert-manager v1.6.1.

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

    Confirm the pods are ready and running in the cert-manager namespace.

    1. kubectl get pod -n cert-manager
    2. NAME READY STATUS RESTARTS AGE
    3. cert-manager-55658cdf68-pdnzg 1/1 Running 0 2m33s
    4. cert-manager-cainjector-967788869-prtjq 1/1 Running 0 2m33s
    5. cert-manager-webhook-6668fbb57d-vzm4j 1/1 Running 0 2m33s
  2. Configure cert-manager Issuer and Certificate resources required by cert-manager to be able to issue certificates in OSM. These resources must be created in the namespace where OSM will be installed later.

    Note: cert-manager must first be installed, with an issuer ready, before OSM can be installed using cert-manager as the certificate provider.

    Create the namespace where OSM will be installed.

    1. export osm_namespace=osm-system # Replace osm-system with the namespace where OSM is installed
    2. kubectl create namespace "$osm_namespace"

    Next, we use a SelfSigned issuer to bootstrap a custom root certificate. This will create a SelfSigned issuer, issue a root certificate, and use that root as a CA issuer for certificates issued to workloads within the mesh.

    1. # Create Issuer and Certificate resources
    2. kubectl apply -f - <<EOF
    3. apiVersion: cert-manager.io/v1
    4. kind: Issuer
    5. metadata:
    6. name: selfsigned
    7. namespace: "$osm_namespace"
    8. spec:
    9. selfSigned: {}
    10. ---
    11. apiVersion: cert-manager.io/v1
    12. kind: Certificate
    13. metadata:
    14. name: osm-ca
    15. namespace: "$osm_namespace"
    16. spec:
    17. isCA: true
    18. duration: 87600h # 365 days
    19. secretName: osm-ca-bundle
    20. commonName: osm-system
    21. issuerRef:
    22. name: selfsigned
    23. kind: Issuer
    24. group: cert-manager.io
    25. ---
    26. apiVersion: cert-manager.io/v1
    27. kind: Issuer
    28. metadata:
    29. name: osm-ca
    30. namespace: "$osm_namespace"
    31. spec:
    32. ca:
    33. secretName: osm-ca-bundle
    34. EOF
  3. Confirm the osm-ca-bundle CA secret is created by cert-manager in OSM’s namespace.

    1. $ kubectl get secret osm-ca-bundle -n "$osm_namespace"
    2. NAME TYPE DATA AGE
    3. osm-ca-bundle kubernetes.io/tls 3 84s

    The CA certificate saved in this secret will be used by OSM upon install to bootstrap its ceritifcate provider utility.

  4. Install OSM with its certificate provider kind set to cert-manager.

    1. osm install --set osm.certificateProvider.kind="cert-manager"

    Confirm the OSM control plane pods are ready and running.

    1. $ kubectl get pod -n "$osm_namespace"
    2. NAME READY STATUS RESTARTS AGE
    3. osm-bootstrap-7ddc6f9b85-k8ptp 1/1 Running 0 2m52s
    4. osm-controller-79b777889b-mqk4g 1/1 Running 0 2m52s
    5. osm-injector-5f96468fb7-p77ps 1/1 Running 0 2m52s
  5. Enable permissive traffic policy mode to set up automatic application connectivity.

    Note: this is not a requirement to use cert-manager but simplifies the demo by not requiring explicit traffic policies for application connectivity.

    1. kubectl patch meshconfig osm-mesh-config -n "$osm_namespace" -p '{"spec":{"traffic":{"enablePermissiveTrafficPolicyMode":true}}}' --type=merge
  6. Deploy the httpbin service into the httpbin namespace after enrolling its namespace to the mesh. The httpbin service runs on port 14001.

    1. # Create the httpbin namespace
    2. kubectl create namespace httpbin
    3. # Add the namespace to the mesh
    4. osm namespace add httpbin
    5. # Deploy httpbin service in the httpbin namespace
    6. kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.1/manifests/samples/httpbin/httpbin.yaml -n httpbin

    Confirm the httpbin service and pods are up and running.

    1. $ kubectl get svc -n httpbin
    2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    3. httpbin ClusterIP 10.96.198.23 <none> 14001/TCP 20s
    1. $ kubectl get pods -n httpbin
    2. NAME READY STATUS RESTARTS AGE
    3. httpbin-5b8b94b9-lt2vs 2/2 Running 0 20s
  7. Deploy the curl client into the curl namespace after enrolling its namespace to the mesh.

    1. # Create the curl namespace
    2. kubectl create namespace curl
    3. # Add the namespace to the mesh
    4. osm namespace add curl
    5. # Deploy curl client in the curl namespace
    6. kubectl apply -f https://raw.githubusercontent.com/openservicemesh/osm-docs/release-v1.1/manifests/samples/curl/curl.yaml -n curl

    Confirm the curl client pod is up and running.

    1. $ kubectl get pods -n curl
    2. NAME READY STATUS RESTARTS AGE
    3. curl-54ccc6954c-9rlvp 2/2 Running 0 20s
  8. Confirm the curl client is able to access the httpbin service on port 14001.

    1. $ kubectl exec -n curl -ti "$(kubectl get pod -n curl -l app=curl -o jsonpath='{.items[0].metadata.name}')" -c curl -- curl -I http://httpbin.httpbin:14001
    2. HTTP/1.1 200 OK
    3. server: envoy
    4. date: Mon, 15 Mar 2021 22:45:23 GMT
    5. content-type: text/html; charset=utf-8
    6. content-length: 9593
    7. access-control-allow-origin: *
    8. access-control-allow-credentials: true
    9. x-envoy-upstream-service-time: 2

    A 200 OK response indicates the HTTP request from the curl client to the httpbin service was successful. The traffic between the application sidecar proxies is encrypted and authenticated using Mutual TLS (mTLS) by leverging the certificates issued by the cert-manager certificate provider.