I love me some Let’s Encrypt. This nonprofit certificate authority brought a no-nonsense set of tools and practices to managing certs, with a great price tag. The traditional route for managing certs was with certbot, which made the workflow for attestation of domain ownership very easy. However, the command line doesn’t scale and I was looking for a way to GitOps my certificate management.
Installing the Operator
The cert-manager project was originally created by Jetstack and was then donated to the CNCF Sandbox. The cert-manager operator installation is easy and they provide great docs on deploying using k8s manifests, helm, or the OLM. To get started, let’s get the operator installed. We are going to be using OpenShift for our target platform and will be doing everything using manifests. The first manifest is the subscription and we are going to make the operator available cluster wide by deploying into the openshift-operators
namespace .
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: cert-manager
namespace: openshift-operators
spec:
channel: stable
installPlanApproval: Automatic
name: cert-manager
source: community-operators
sourceNamespace: openshift-marketplace
startingCSV: cert-manager.v1.6.1
Creating the Cluster Issuer
Once the operator is installed, we need to create the issuer. Issuers come in two forms: the Issuer
, which is namespace scoped, and the ClusterIssuer
, which is cluster scoped. In this example, we are going to be creating a ClusterIssuer
since all the certs for the cluster will be coming from Let’s Encrypt.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging-cluster-issuer
spec:
acme:
email: youremail@yourcompany.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-staging-cluster-issuer-account-key
solvers:
- http01:
ingress:
serviceType: ClusterIP
Notes:
- We are going to be using HTTP solvers for validating the certificate requests. More detail on this below.
- The email address will be used to send updates on the certificates such as notices of expiration. More than likely, you’ll want to use a group address to make sure awareness is broad.
Creating the Certificate
Once the issuer is in place, we can then start creating certificates. Here’s the example for a certificate running on my OpenShift cluster.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: default-apps-ocp-mydomain-com
namespace: default
spec:
secretName: default-apps-ocp-mydomain-com-tls
issuerRef:
name: letsencrypt-staging-cluster-issuer
kind: ClusterIssuer
dnsNames:
- "default.apps.ocp.mydomain.com"
Notes:
- The
secretName
is where the cert will be issued. Your organization will be better off if a consistent canonical naming pattern is applied so that application deployments can infer quickly where exactly those certs will be stored. - If you are using a
ClusterIssuer
, then you must denote thekind
. Thekind
defaults toIssuer
.
Once this is done, the certificate is magically issued and available in the secret.