Introduction
In this post we will configure cert-manager on Kubernetes in order to manage your traffic using HTTPS (SSL/TLS) certificates with cert-manager and Let’s Encrypt. At Octopus, we’ve seen firsthand how important security is in the world of cloud services. Our team’s deep expertise in Kubernetes and open-source technologies ensures that we’re adept at guiding clients through securing their traffic. Cert-manager is one of these tools that we recommend. Even in air-gapped disconnected environments.
In order to better understand the procedure let’s explain a few concepts related to the operator:
ClusterIssuer – A custom resource (extending k8s api) that assist in certificate issuance on a cluster-wide scope. Instead of dealing with individual issuers per namespace, a ClusterIssuer allows you to set a single point of certificate management that can serve certificates to applications across different namespaces
Issuer – Same as ClusterIssuer only limited to a namespace.
CA – represent a Certificate Authority (CA) that can issue certificates. By creating a CA object, we essentially allow cert-manager to act as its own Certificate Authority. This enables us to issue certificates based on a CA private key, which is useful for production air-gapped/disconnected, internal or testing purposes.
ACME – An issuer Automated Certificate Management Environment (ACME) Certificate Authority server. Can be configured using a specific email.
Procedure
cert-manager provides Helm charts as a first-class method of installation on both Kubernetes and OpenShift.
Be sure never to embed cert-manager as a sub-chart of other Helm charts
cert-manager manages non-namespaced resources in your cluster and care must be taken to ensure that it is installed exactly once.
Add the helm repo
Use the following to add the helm chart repo and update the helm repositories on the machine
$ helm repo add jetstack https://charts.jetstack.io
$ helm repo update
Install cert-manager
Use the following to install the cert-manager operator:
$ helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.11.0 \
--set installCRDs=true
Generate a local CA
In our example we don’t have a CA from our organization, we can use the following commands to create a CA:
# generate an rsa key
openssl genrsa -out k8stests-root-ca-key.pem 2048
# generate root certificate
openssl req -x509 -new -nodes -key k8stests-root-ca-key.pem \
-days 3650 -sha256 -out k8stests-root-ca.pem -subj "/CN=k8stests-ca"
Create the secret to hold that CA
The following command will load the CA key and cert to the kubernetes etcd into a secret.
kubectl create secret tls -n cert-manager root-ca \
--cert=k8stests-root-ca.pem \
--key=k8stests-root-ca-key.pem
Cluster-issuer
Let’s create the ClusterIssuer object. The ClusterIssuer will sign our required certificates using cert-manger automatically. This object is the base for our certificates.
kubectl apply -n cert-manager -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: ca-issuer
spec:
ca:
secretName: root-ca
EOF
Configuration wise, this is the main configuration we need to do. Now let’s see how we can configure a certificate based on this CA.
Issue a certificate
Using Ingress Operator you can now use the cluster-issuer in order to issue certificates.
For example, add to your ingress application the following lines:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: root-ca
.
.
.
NOTE: the name of our CA is root-ca it might be different on your cluster.
Configuring Let’s Encrypt
Assuming your cluster is connected to the internet, we can use Let’s Encrypt and their CA to have a allowed and known SSL/TLS certificate on every computer in the world.
Let’s Encrypt is a widely-used, free certificate authority that provides SSL/TLS certificates for securing web traffic. Its automated processes make obtaining and deploying certificates incredibly easy. With the cert-manager it’s even easier.
Let’s Encrypt uses the ACME protocol (Automatic Certificate Management Environment) to automate the process of obtaining and renewing SSL/TLS certificates. ACME is the communication protocol that enables a server to request certificates from Let’s Encrypt and prove its control over the domain
Staging Issuer
Let’s configure the staging issuer. The organization provides access to the staging signing server for us to do tests.
04_letsencrypt_staging.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: letsencrypt@k8s.co.il
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: letsencrypt-staging-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
Create it:
$ k create -f 04_letsencrypt_staging.yaml
Production Issuer
Now, let’s create the Let’s Encrypt signing production system
05_letsencrypt_production.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: letsencrypt@k8s.co.il
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: letsencrypt-production-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
Let’s create the LetsEncrypt Production ClusterIssuer:
$ k create -f 05_letsencrypt_staging.yaml
You should now have 3 cluster issuers:
# k get clusterissuer
NAME READY AGE
ca-issuer True 99d
letsencrypt-production True 32d
letsencrypt-staging True 32d
With these cluster issuers, you can add a secure connection with HTTPS configuration derived from Nginx Ingress Operator.
An example for such a usage can be seen in our post of How to deploy Harbor registry on Kubernetes :
Adding the following line to the values of the ingress of your application will create a certificate for you.
cert-manager.io/cluster-issuer: letsencrypt-production
Here’s the output of the above certificate generated with Let’s Encrypt’s ISRG Root X1 CA and R3 Intermediate CA.
Summary
Certificates are vital for securing data and building trust with users. Using cert-manager in Kubernetes for this, they ensure safe communication dynamically. I hope this will help you integrate and manage certificates with cert-manager in Kubernetes. Upgrading your security.
Enjoy!