Prerequisites
Before getting started, here are some prerequisites.
- Kubernetes Cluster
- Cert-Manager Installed (follow Part 1)
- Domain name
- IP Pointing to Domain name (Assigned to the Contour Ingress Controller)
Introduction
Secure Sockets Layer (SSL) is an effective way to secure our sites from malicious actors. Having an SSL cert means that attackers cannot snoop into the communication between the server and the client rendering traditional Man in the Middle (MiTM) attacks useless.
Lets Encrypt
Nowadays, many SSL vendors in the wild provide SSL certs at different prices. One particular vendor is Lets Encrypt, managed by the Electronic Frontier Foundation. They provide free SSL certificates to anyone with a domain name and a public IP address that can actually be verified.
Once you verify the details, you can acquire an SSL Certificate for free. The maximum duration of an SSL cert is 90 days (3 months), after which you need to renew it to keep it active.
They also provide automated mechanisms to help you renew your certificate without worrying about it. Let's start configuring our certificate.
For Certificate Provisioning, we'll use cert-manager by Jetstack. It's a CNCF project specifically developed to be used in Kubernetes Environments. It can provision certificates from Let's Encrypt (free) and other paid certificate issuers like Sectigo, Digicert, etc.
Installing & Configuring Cert Manager
To install cert-manager, we'll use Helm Charts. Run the commands below to add the Helm repo for cert-manager and install it.
1. Add Helm Repository
helm repo add jetstack https://charts.jetstack.io
2. Update the Helm Repository
helm repo update
3. Install Cert-Manager
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.9.1 \
--set installCRDs=true
Once it's installed, wait for the pods to transition to a running state.
k get po -n cert-manager
Provisioning Certificate
We'll use a wildcard certificate for our domain. There are two options to set the issuer. They are:
a. ClusterIssuer (Available All Over the Cluster)
ClusterIssuer can be accessed from anywhere within the Cluster. It's namespace agnostic, meaning Certificates can be generated in any namespace using the Cluster Issuer.
b. Issuer (Available Only in the Deployed Namespace)
An issuer can only be accessed from the namespace it is deployed in, issuer for namespace A cannot be accessed from namespace B, C, etc.
I'll go with the ClusterIssuer as I'll deploy different applications over different namespaces using a Wild Card SSL Certificate, so having a single Issuer satisfies my requirements.
To get a wildcard certificate, we need to perform DNS validation for the domain we choose to issue a certificate for. Each cloud provider provides a specific way of verifying the domain, the steps provided below are generic and may work for most of them.
Setting up the Certificate
Step 1: Create an API Token and Put It in a Variable
export token="some_token_123.abc"
Step 2: Base64 Encode the Token
echo $token | base64
Step 3: Create a Secret Object in the Cert-Manager Namespace
Now let's create a ClusterIssuer.
Now create the Certificate.
Routing Traffic to the httpd Deployment
We created the httpd deployment in the last article. We'll now make it available through https as well.
To turn the HTTP deployment to https, simply add the tls secret entry into the ingress manifest like this:
Let's check the status of the ingress. We should see the https port show up as well.
NAME CLASS HOSTS ADDRESS PORTS AGE
httpds <none> httpds.example.com 192.168.22.9 80, 443 1d
Now let's run a curl command to check.
curl https://httpds.example.com
Troubleshooting
Rate Limit
If the certificate keeps getting requested for a similar domain name more than 5 times a week, then we won't be able to request a certificate for a whole week. Please use the staging server to generate the certificate first, and once successful, use the production server.
(This is applicable for the production Let's Encrypt certificate)
There's no way to bypass this, but a workaround exists where you can add another DNS name during certificate generation. But make sure that the DNS name is a derivative of the domain you are issuing the certificate for.
Wrapping Up
We learned to provision certificates for our applications deployed in Kubernetes using cert-manager. We also learned about a recurring problem during certificate generation and its workaround.
Hope you learned from this article. Stay tuned for more on Ingress Controllers.