In this post we will review the steps to create a signed SSL certificate for our site, running in Google Kubernetes Engine (aka GKE) and using Ingress to handle the incoming traffic.
The SSL certificate is created by the Let's Encrypt service, which will automatically, and free of charge supplies the signing service, and renewal service, based on the ownership of the domain in the DNS. This works only if traffic the the related domain that we are signing is sent to the GKE ingress, hence assuring that the SSL certificate requester is indeed authentic.
In the following example, we wee present signing of 2 FQDNs:
www.my-domain.com, api.my-domain.com
After connecting to the GKE cluster, use helm to install cert manager, which will manage the SSL certificate creation and renewals.
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.2.0/cert-manager.crds.yaml
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.2.0
kubectl get pods --namespace cert-manager
The following steps include 2 parts. First we use a test/staging let's encrypt service to ensure that the integration with let's encrypt indeed works well. Only then we move to the production let's encrypt service. This is since the production let's encrypt service has some limits on the requests amounts, and the certificate singing is slower.
Using Staging Let's Encrypt
cat <<EOF > test-resources.yaml
apiVersion: v1
kind: Namespace
metadata:
name: cert-manager-test
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: test-selfsigned
namespace: cert-manager-test
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: selfsigned-cert
namespace: cert-manager-test
spec:
dnsNames:
- example.com
secretName: selfsigned-cert-tls
issuerRef:
name: test-selfsigned
EOF
kubectl apply -f test-resources.yaml
kubectl describe certificate -n cert-manager-test
kubectl delete -f test-resources.yaml
cat <<EOF > clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: john.doe@my-email.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: ingress-gce
EOF
kubectl apply -f clusterissuer.yaml
kubectl describe clusterissuer letsencrypt-staging
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
acme.cert-manager.io/http01-edit-in-place: "true"
tls:
- secretName: ingress-secret-letsencrypt
hosts:
- www.my-domain.com
- api.my-domain.com
kubectl get certificate
kubectl describe certificate ingress-secret-letsencrypt
kubectl describe secret ingress-secret-letsencrypt
Move to Production Let's Encrypt
As we've done before, we create a issuer, but this time for the production service.
cat <<EOF > clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: john.doe@my-email.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: ingress-gce
EOF
kubectl apply -f clusterissuer.yaml
kubectl delete secret ingress-secret-letsencrypt
And track the progress using the commands:
kubectl describe clusterissuer letsencrypt-prod
kubectl get order
Next, we should wait again for the ingress load balancer to update, for another ~15 minutes, and then check that the certificate is indeed valid.
No comments:
Post a Comment