Skip to content

Instantly share code, notes, and snippets.

@timroster
Last active May 25, 2022 14:33
Show Gist options
  • Save timroster/732acbc2c75a544bb0ab133da7e78f6f to your computer and use it in GitHub Desktop.
Save timroster/732acbc2c75a544bb0ab133da7e78f6f to your computer and use it in GitHub Desktop.
Configure LE certificates with Cert Manager

Requesting TLS certificates on Red Hat OpenShift using the cert-manager operator

OpenShift Container Platform typically supports edge-terminated TLS applications in a simple way for application developers through the route resource. This is accomplished through a wildcard certificate which will usually take a form like *.apps.cluster.domain.example.com. By default when exposing a service in OpenShift, a hostname is created by combining the service name (such as console) with a project (like openshift-console) to create a FQDN for a host, resulting in a host name like console-openshift-console.apps.cluster.domain.example.com. This just "works" due to the cluster wildcard certificate.

However, it is possible to manage custom certificates for use with OpenShift routes or Kubernetes ingress resources. The Cert-Manager CNCF project provides a handy tool to request custom TLS certificates for OpenShift, or any other Kubernetes platform. This gist will walk through setting up cert-manager on OpenShift, setting it up with a confguration to request free TLS certificates from Let's Encrypt and requesting a certificate. You will need an OpenShift cluster (technically even CRC could work) and the ability to resolve the DNS names for your desired TLS certificates to your OpenShift router LoadBalancer service.

Installing the cert-manager operator

Begin by installing the Cert-Manager operator on your cluster. On OpenShift 4.x as a cluster-admin user, select the Administrator perspective and open the Operators->Operator Hub menu. Search with the string cert-manager, then click on the tile that is not tagged Marketplace

Click on the Install button to bring up the operator configuration form:

Cert-Manager Operator Install

It's ok to keep all default values and keep the openshift-operators namespace as shown. Click on Install to install the operator to your cluster.

Creating a Certificate Manager instance

After a few minutes, the operator will be confirmed as installed. Switch over to an OpenShift CLI session or use the Web UI to apply the resources as follows:

  1. Create a project for the cert-manager: oc new-project cert-manager

  2. Create a cert-manager resource in this project. Apply this yaml to the cert-manager project:

    apiVersion: operator.cert-manager.io/v1alpha1
    kind: CertManager
    metadata:
      name: cert-manager
      namespace: cert-manager
    spec: {}
  3. Create a ClusterIssuer for Let's Encrypt using the acme protocol. This cluster issuer you will specify in the certificate requests. It's best to create both a staging and production issuer so that you can experiment as desired before making a request for a full production certificate. The issuer needs your email address, and this address will get automated notifications before the certificates expire.

    staging issuer (update with your email address before applying):

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-staging
      labels:
        name: letsencrypt-staging
    spec:
      acme:
        # update the following with your email address
        email: youremail@example.com
        privateKeySecretRef:
          name: letsencrypt-staging
        server: https://acme-staging-v02.api.letsencrypt.org/directory
        solvers:
        - http01:
            ingress:
              class: nginx

    production issuer (update with your email address before applying):

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-prod
      labels:
        name: letsencrypt-prod
    spec:
      acme:
        # update the following with your email address
        email: youremail@example.com
        privateKeySecretRef:
          name: letsencrypt-prod
        server: https://acme-v02.api.letsencrypt.org/directory
        solvers:
        - http01:
            ingress:
              class: nginx
  4. At this point, you can change to another project, say myproject, where you have an application of interest where you want to have a secret created with the private key and associated TLS certificate. Within this project, create a Certificate Resource for your desired certificate. In this hypothetical example, we will request a nested subdomain certificate off the wildcard certificate of a Red Hat OpenShift on IBM Cloud cluster. Note that the Red Hat OpenShift on IBM Cloud cluster default wildcard certificate is very long so this example also includes an additional dnsName and commonName corresponding to the standard cluster CN (which you can get from the regular wildcard certificate).

    For this example, the CN is: timrovpc-roks-demo-clus.us-east.containers.appdomain.cloud, the Wildcard domain is timrovpc-roks-demo-clus-c0b572361ba41c9eef42d4d51297b04b-0000.us-east.containers.appdomain.cloud and the nested subdomain host will be: mywebapp.myservice-myproject . It's a good idea to test the process by setting the cluster issuer to letsencrypt-staging and confirmed the certificate in the secret once:

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: mywebapp-crt
    spec:
      commonName: timrovpc-roks-demo-clus.us-east.containers.appdomain.cloud
      dnsNames:
        - >-
          mywebapp.myservice-myproject.timrovpc-roks-demo-clus-c0b572361ba41c9eef42d4d51297b04b-0000.us-east.containers.appdomain.cloud
        - timrovpc-roks-demo-clus.us-east.containers.appdomain.cloud
      issuerRef:
        group: cert-manager.io
        kind: ClusterIssuer
        name: letsencrypt-prod
      secretName: mywebapp-tls-secret
  5. If there are no typos in the request, after a few minutes, this request will show a Ready status and the named secret will contain values for the private key and certificate. You can verify the certificate from the CLI with a command like:

    oc get secret mywebapp-tls-secret -o jsonpath='{ .data.tls\.crt }' | base64 -d | openssl x509 -text

Next steps

The secret is ready for use with a Kubernetes ingress resource, or you can extract the private key and certificate to use in other ways for example with the route command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment