15.2. SSL with Let’s Encrypt#
Let’s Encrypt is a service that automatically issues certificates if you can prove you control a website. Certificate Manager is a Kubernetes project that automates the process of getting a certificate from Let’s Encrypt when a new host name appears in your DNS records. Certificates are tied to particular DNS names and IP addresses, so you must have External DNS working. Certificates can only be applied to Ingress
resources so you must have an Ingress controller working too.
Before You Begin
There are prerequisites that must be complete for you to do this lab:
You must have an Ingress controller working
You must have External DNS working
Introduction#
Let’s Encrypt validates that you own a domain by asking you to create custom DNS records. So we will reuse the service accounts from the 14-03-automate-dns
lab. After that we can install Cert Manager.
Add Role Bindings#
Use the existing role account:
$ project=$(gcloud config get-value core/project)
$ sa_name="Kubernetes external-dns"
$ sa_email=$(gcloud iam service-accounts list --format='value(email)' \
--filter="displayName:$sa_name")
$ gcloud iam service-accounts add-iam-policy-binding "$sa_email" \
--member="serviceAccount:${project}.svc.id.goog[default/cert-manager]" \
--role=roles/iam.workloadIdentityUser
Create Values for the Cert Manager Chart#
Put this YAML fragment into a file in the root of your repo called values-cert-manager.yaml
:
Warning
Update the file to contain your project ID.
installCRDs: true
prometheus:
enabled: false
serviceAccount:
create: true
name: cert-manager
annotations:
iam.gke.io/gcp-service-account: sa-edns@YOUR-PROJECT-ID.iam.gserviceaccount.com
global:
leaderElection:
namespace: default
resources:
requests:
memory: "512Mi"
cpu: "250m"
ephemeral-storage: "10Mi"
limits:
memory: "512Mi"
cpu: "250m"
ephemeral-storage: "10Mi"
webhook:
resources:
requests:
memory: "512Mi"
cpu: "250m"
ephemeral-storage: "10Mi"
limits:
memory: "512Mi"
cpu: "250m"
ephemeral-storage: "10Mi"
cainjector:
resources:
requests:
memory: "512Mi"
cpu: "250m"
ephemeral-storage: "10Mi"
limits:
memory: "512Mi"
cpu: "250m"
ephemeral-storage: "10Mi"
startupapicheck:
resources:
requests:
memory: "512Mi"
cpu: "250m"
ephemeral-storage: "10Mi"
limits:
memory: "512Mi"
cpu: "250m"
ephemeral-storage: "10Mi"
Install Cert Manager#
Now use Helm to install Cert Manager:
$ helm repo add jetstack https://charts.jetstack.io
$ helm repo update
$ helm install cert-manager jetstack/cert-manager --values values-cert-manager.yaml
Create Let’s Encrypt Configuration#
Add the following contents to cluster-issuer.yaml
in your repo root:
Warning
Update the file to contain your project ID and email address.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
email: you@you.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- dns01:
cloudDNS:
project: YOUR-PROJECT-ID
Apply the issuer resource with:
$ kubectl apply -f cluster-issuer.yaml
Monitor the Issuer#
Use kubectl get all
to get the name of the cert-manager
pod. Use the name to watch the logs as you update the Ingress
resource:
$ kubectl logs -f pod/cert-manager-7b68dcc5d-96pr8
Update the Ingress Resource#
Update your Ingress
resource to have some annotations and a tls
section like this:
Warning
Update the file to contain your DNS name.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cis-92-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt
networking.gke.io/v1beta1.FrontendConfig: secure-redirect
spec:
tls:
- hosts:
- mysite.mydomain.com
secretName: apps-cert-secret
rules:
- host: "mysite.domain.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mysite
port:
number: 80
Apply the resource:
$ kubectl apply -f deployment/ingress.yaml
It can take several minutes for the ingress controller to settle. Check the logs of both Cert Manager and External DNS to make sure there’s no errors.