Let’s Encrypt for Kubernetes. An easy way to HTTPS!
Today, the whole internet uses HTTPS protocol to secure websites, if you want to follow this protocol on your cluster without headache, this guide is for you.
Prerequisites
Sure, you need to have a Kubernetes cluster where you want to configure Let’s Encrypt.
As a package manager, we will use Helm. Installation guide here.
Kubectl CLI for managing the Kubernetes cluster.
Preparation
As a primary tool which allows us to manage certificates is a cert-manager.
cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of obtaining, renewing and using those certificates.
Let’s create an allocated namespace in the Kubernetes cluster where we will install our tools.
kubectl create namespace cert-manager
Next, add Helm Repository:
helm repo add jetstack https://charts.jetstack.io
helm repo update
After, we are ready to install cert-manager.
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.8.2 \
--set installCRDs=true \
--set =issuer-letsencrypt \
--set ingressShim.defaultIssuerKind=ClusterIssuer
After, let’s check the result:
> helm list -n cert-manager
NAME NAMESPACE STATUS CHART APP VERSION
cert-manager cert-manager deployed cert-manager-v1.8.2 v1.8.2
Above, I provided three additional parameters using --set ...
:
installCRDs=true
- since cert-manager requires a number of CRD resources we have to allow Helm to create them.ingressShim.defaultIssuerName=issuer-letsencrypt
- defines the name automatically issuing certificates.ingressShim.defaultIssuerKind=ClusterIssuer
- defines the strategy of issuing certificates.
Exists two types of IssuerKind:
Issuer
- issues and manages certificates in the namespace where were created.ClusterIssuer
- issues and manages certificates in the cluster independent of the namespace.
Create an Issuer
First of all, we need to create an Issuer which will be used by the cert-manager to specify for whom and how to issue the certificate.
Above, when we installed a cert-manger we defined a name by default issuer-letsencrypt, that's the name will be used as a modifier for cert-manager which it will manage.
Let’s take a look at both types.
ClusterIssuer
To create an Issuer that will manage and issue certificates for the whole cluster, we need to create a Kubernetes object with a type ClusterIssuer.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: issuer-letsencrypt
namespace: cert-manager
spec:
acme:
email: [your email address here]
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: issuer-letsencrypt
solvers:
- http01:
ingress:
class: nginx
Here, we are using a unique email address based on that will be issuing new certificates.
Issuer
In case you want to sign the certificates in the scope of the particular namespace, you could use the kind Issuer
. Namespace, where it is located, defines where it will generate certificates.
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: issuer-letsencrypt
namespace: staging
spec:
acme:
email: [your email address here]
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: issuer-letsencrypt
solvers:
- http01:
ingress:
class: nginx
Also, both if above using the same configurations:
metadata.name=issuer-letsencrypt
- the name ofingressShim.defaultIssuerName
which we defined in the installation stage of cert-manager.spec.acme.email
- an email which will be used to sign the certificates;spec.acme.server
- exist two servers for signing certificates production and staging:-
https://acme-staging-v02.api.letsencrypt.org/directory
For testing purposes only recommended to use.
The detail doc is here.
How to use an Issuer?
Above I described the kinds of Issuers and how to create them, but to allow them to sign the certificates we have to define for ingress object the additional annotation.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: **issuer-letsencrypt**
name: [name of ingress]
namespace: [name of namespace]
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: [name of service]
servicePort: [port of service]
path: /
tls:
- hosts:
- example.com
secretName: [secret name]
Using the annotation cert-manager.io/cluster-issuer: issuer-letsencrypt
we are talking cert-manager about the new Ingress it should manage.
After, when an Ingress will be detected by the cert-manger, it sings the new certificates and allows using HTTPS.