setting up Let's Encrypt on my private kuberntes cluster
I’ve been using self signed certificates for a while, but safari started complaining about them with no simple option to simply trust the certificated as I had before. So, I decided to work on something I’ve been postponing for a while: using let’s encrypt to generate trusted certificates.
With an instance of cert-manager running, things were pretty straight-forward. With some annotations on the ingress definition, and some configurations about how cert-manager should generate the certificate, everything - generating, renewing ans using certificates - is done automatically.
For my cluster, I’m using an Nginx Ingress Controller, but I found no restriction about the chosen controller, so others should work too.
Cert-Manager resources
Cert manager supports a bunch of different strategies to issue certificates. Before, I was using the self signed, my goal now was to implement ACME.
ACME is a protocol provides a way to automate certificate generation, given a challenge can be fulfilled. There are currently two kinds of challenge:
- HTTP01 - Where to prove that you own the subdomain you should be able to serve a certain file from your server
- DNS01 - Here a TXT record is created in your DNS server
Let’s Encrypt and Cart-Manager both have good documentation on ACME and its challenges, so let’s focus on the implementation.
The HTTP challenge would not be possible, since my servers are not exposed and thus Let’s Encrypt servers would not be able to reach them to verify the file, so we needed to use the DNS one. There is a page with supported DNS providers, anything outside that list does not mean it would be impossible, but it would require more work, for example, using a webhook.
I choose to migrate my DNS to cloudflare since it is free and supported (note, I have no association with them), so I just needed to create two resources:
- A
Secret
to hold my API-TOKEN - A
ClusterIssuer
to listen to requests and generate certificates to my ingresses
Since I want every namespace to be able to issue a certificate, I used a ClusterIssuer
, not just an Issuer
.
The resources above needs Cert Manager to be configured already, and once applied we can move to the next step, that is telling our ingress to use this new ClusterIssuer
.
Ingress Resource
I’ll give here the example of how my grafana ingress came out, commenting above the important lines.
Basically, using the cert-manager.io/cluster-issuer
annotation we tell Cert Manager that we want it to use the given ClusterIssuer
to issue a certificate, and it uses the tls
section of the yaml to know which domain to issue to certificate to, and where to store it after it’s generated.
Conclusion
I was expecting the configuration of the DNS01 challenge to give me much more trouble, I’m really impressed of how smooth that went, given Cert Manager and an Ingress Controller already configured.
It is a challenge to administrate a kubernetes cluster, and there is a long way before I can say comfortably that I know how to do that, but this kind of integration makes the effort seems kinda worth it!