Securing your ingress with cert-manager & let's encrypt
In line with my previous article regarding external-dns
component in a kubernetes cluster : https://yodamad.hashnode.dev/set-up-external-dns-on-a-kubernetes-cluster, here is a quick one explaining how to secure your nginx ingresses
with a certificate to enable security in your environment.
This article is covering how to set up & configure the different elements to automatically generate a certificate provided by let's encrypt organism when deploying a new ingress in our cluster. Once it's done, every time an ingress will be deployed, with the right annotations, automatically a certificate will be generated to secure with TLS the HTTP endpoint.
Prerequisites for this article are :
A Kubernetes cluster running with an
nginx ingress controller
(and, optionally,external-dns
) installedkubectl
installed on your laptophelm
installed, optionally
First, we have to install cert-manager
component. This component is in charge to manage certificates in a cluster. A complete description is available here
# Install it with helm
$ helm repo add jetstack https://charts.jetstack.io
$ helm repo update
$ helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.11.0 \
--set installCRDs=true
# or install it kubectl
$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml
We can control that everything goes well by checking that the new components related to cert-manager
are known by the cluster
$ kubectl get crd | grep cert-manager
certificaterequests.cert-manager.io
certificates.cert-manager.io
challenges.acme.cert-manager.io
clusterissuers.cert-manager.io
issuers.cert-manager.io
orders.acme.cert-manager.io
$ kubectl explain Certificate
$ kubectl explain CertificateRequest
$ kubectl explain Challenge
Now, we need to create the component that will do the process to claim and generate a certificate regarding a certificate provider such as let's encrypt. This is done by creating a ClusterIssuer
component. This will cover the whole cluster. NB: If you want to restrict this feature to a dedicated namespace, you can use an Issuer
instead.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: <your_email_to_receive_notifications>
privateKeySecretRef:
name: letsencrypt-production
solvers:
- http01:
ingress:
class: nginx
Here, each ingress will be detected and a certificate will be generated to secure them if TLS
is configured. You can fine-grain the ingresses to handle using ingressTemplate
solver approach describes in the official documentation. Now, let's modify the Ingress
defined in the previous article:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hashnode
annotations:
kubernetes.io/ingress.class: nginx
# Add this for detection
# Replace cluster-issuer by issuer if you define an Issuer rather than a ClusterIssuer
cert-manager.io/cluster-issuer: letsencrypt-production
spec:
rules:
- host: demo.hashnode.mydns.fr
http:
paths:
- backend:
service:
name: hashnode
port:
number: 80
pathType: Prefix
path: /
# Add this part to enable TLS
tls:
- hosts:
- demo.hashnode.mydns.fr
secretName: nginx-demo-tls
kubectl apply -f hashnode-demo.yaml -n hashnode
Once applied, we can see that
ingress controller is exposing
443
porta certificate has been generated
$ kubectl get svc --all-namespaces | grep ingress-nginx-controller
ingress-nginx ingress-nginx-controller LoadBalancer 10.3.106.101 57.128.40.102 80:30542/TCP,443:30552/TCP 2d11h
$ kubectl get certificates -A
NAMESPACE NAME READY SECRET AGE
hashnode nginx-demo-tls True nginx-demo-tls 81m
Now we can check that our website is secured with a valid certificate
And we can have a quick look at the certificate
So, in conclusion, with a few steps, we are now able to secure our endpoints for valid certificates generated by an official organism.
All sources are still available in my GitLab repository.
Subscribe to my newsletter
Read articles from Matthieu Vincent directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Matthieu Vincent
Matthieu Vincent
TechAdvocate DevSecOps / Cloud platform Lead Architect @ Sopra Steria Speaker @ Devoxx, Snowcamp, Breizhcamp, GitLab Connect and internally Co-Founder of Volcamp IT Conference @ Clermont-Fd (https://volcamp.io) GitLab Hero