Thanks to Let’s encrypt we can create SSL certificates for our HTTPS or TLS services for.. FREE!
These certificates have a 99% of compatibility with browsers.
A running Kubernetes cluster.
For our example, we use a cluster managed with Rancher.
If you don’t have one, you can follow this post to setup yours in just 15 minutes!
How to create a Kubernetes cluster with Rancher on Hetzner
TL;DR: In 15 minutes you can have a lab cluster ready to test or to deploy your projects cheap and easily.
Let’s go, Let’s Encrypt
Let’s Encrypt is a certification authority (CA) created in 2016 by the Electronic Frontier Foundation and Mozilla Foundation. Its target is that every Internet communication be ciphered using TLS protocol.
Until that date, if you wanted a valid SSL/TLS certificate for your Internet service, you had to pay at least around $10 for a cheap SSL certificate such as Comodo or RapidSSL.
That purchased certificate has one year validation.
The free Let’s Encrypt certificate has a validity of 3 months. Its certificate management is a bit tedious.
Fortunately “certbot”, the CLI Let’s Encrypt tool, allows to renew the certificates automatically. Just put it in a CRON job.
The Kubernetes way to get “Let’s Encrypt” certicates is using “cert-manager”.
The great feature for “cert-manager” is: automate certificate management.
That means: forget about certificates renewal.
In addition to Let’s Encrypt certificates (a.k.a ACME certs), cert-manager can emit self-signed certificates and manages others certificates issued by 3th parties CA.
We use manifest install method. In case of our Rancher’s cluster, just apply the following manifest:
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.yaml
Note: the last stable version when we wrote this post was 0.15.0, please, check latest version available.
The installation process create several new custom resource definitions (CRD) required.
The main CRDs created are:
- Issuer: Let’s encrypt account setup to use for certificate request. The issuer is valid for a specific namespace.
- ClusterIssuer: It’s like an Issuer but it’s valid for all the cluster, not just for a specific namespace.
- Certificate: The Let’s Encrypt certificate emitted after the issuer made the request, and Let’s Encrypt generates and gives us the certificate.
The Let’s Encrypt certificate issuer process
In the certificate issuer process, the CA needs to verify that you are the owner/manager of the domain/subdomain to use in the certificate.
There are two methods:
- TXT DNS Record challenge, where we create a DNS entry for our domain with a specific token given by the CA.
- HTTP challenge, where the CA tool generate a specific token file under our domain and the CA server tries to request it. If success, the domain is verified and CA emits the new certificate. It’s the preferred method and the one that we’ll use too.
We need to create a Issuer for our namespace. In the example, we use “app” namespace.
Let’s encrypt has a sandbox environment. First we create a sandbox issuer due to the API usage limitation that the real environment has, and if our setup is not OK, Let’s Encrypt may ban us from using it for while.
We use the following YAML
As you can see in the YAML, the kind of object is issuer and the namespace is “app”. Also, the server is for the staging (sandbox) endpoint.
In the solvers section, we specify that we use http challenge and the ingress is nginx class. The nginx ingress is installed by default with Rancher.
You need to replace “email@example.com” with your real email. It’s important to receive alerts about SSL certs close to expire.
Now we apply it
kubectl apply -f sandbox-le-issuer.yaml
If all is ok, we obtain the following output
issuer.cert-manager.io "letsencrypt-staging" created
We create the production issuer now.
We can’t test our issuer without an app/service.
We use “kuard” as our “hello-world” app. You need a domain that points to the IP of your load balancer.
We create a deployment and service to use it.
We apply it
kubectl apply -f deployment-service-kuard.yaml
All that remains is to create the ingress.
To use Let’s Encrypt certificates with our ingress, we just have to add the annotation:
In first place we use the sandbox issuer, and if it goes well, we re-apply it with the production issuer.
Don’t forget to replace “yourdomain.com” with your real domain!
We apply it
kubectl apply -f ingress.yaml
After that, cert-manager creates a temporary pod to request the certificate. We can check the status with the following kubectl command
kubectl get certificate -n app
Once the certificate is ready, we obtain an output like as the following:
NAME READY SECRET AGE
quickstart-example-tls True quickstart-example-tls 2m
Sounds good! Now we can emit the real certificate.
Just replace in the issuer.yaml file, cert-manager.io/issuer: “letsencrypt-staging” by cert-manager.io/issuer: “letsencrypt-prod”, and re-apply it.
kubectl apply -f ingress.yaml
This time the real certificate can take up to several minutes to be ready.
We can get more details using the next describe command
kubectl describe certificate quickstart-example-tls -n app
In the last lines, you can see the status and all the events.
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CreateOrder 9m cert-manager Created new ACME order, attempting validation...
Normal DomainVerified 8m cert-manager Domain "yourdomain.com" verified with "http-01" validation
Normal IssueCert 8m cert-manager Issuing certificate...
Normal CertObtained 7m cert-manager Obtained certificate from ACME server
Normal CertIssued 7m cert-manager Certificate issued Successfully
But the real test is to go to “http://yourdomain.com” and check if you are redirected to “https://yourdomain.com” with a valid free Let’s Encrypt certificate.
Now you have no excuse to not use SSL in all your Kubernetes projects!
Are you interested in your own private Docker Registry?
Your own Docker registry with Kubernetes and Rancher
TL;DR: Deploy a private docker registry in just 5 minutes!
Please, if you liked it give me a round of applause. And if you want to know more about DevOps, Kubernetes, Docker, etc … follow me! KR