Kubernetes: Google-managed SSL Certificates using ManagedCertificate on GKE


I previously went over how to create SSL Certificates using cert-manager, but Google also has a GKE specific way of somewhat doing the same thing by using a custom resource called ManagedCertificate.

https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs

Create Deployment

kubectl run nginx --image=nginx --labels=app=nginx --port=80 --replicas=2

Create Service

kubectl expose deployment nginx --port=80 --target-port=80 --name=nginx-svc --type=NodePort

Create Static IP

gcloud compute addresses create managedcert-itsmetommy-io --global

Describe.

gcloud compute addresses \
  describe managedcert-itsmetommy-io --global \
  --format='value(address)'

Create DNS Zone

If you haven’t already, create a zone.

https://cloud.google.com/dns/docs/

Add dns record

https://cloud.google.com/sdk/gcloud/reference/dns/record-sets/transaction/

export STATIC_IP=$(gcloud compute addresses \
  describe managedcert-itsmetommy-io --global \
  --format='value(address)')
gcloud dns record-sets transaction start --zone itsmetommy-io-external
gcloud dns record-sets transaction add "$STATIC_IP" \
--name managedcert.itsmetommy.io. --ttl 300 \
--type A --zone itsmetommy-io-external
gcloud dns record-sets transaction execute --zone itsmetommy-io-external

Create Managed Certificate

This took ~20-30min to become active.

cat <<EOF > managedcert.yaml
apiVersion: networking.gke.io/v1beta1
kind: ManagedCertificate
metadata:
  name: managedcert-itsmetommy-io
spec:
  domains:
    - managedcert.itsmetommy.io
EOF

Create.

kubectl apply -f managedcert.yaml

Describe.

kubectl describe managedcertificate managedcert-itsmetommy-io

Create Ingress

cat <<EOF > managedcert-ing.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: managedcert-itsmetommy-io
    networking.gke.io/managed-certificates: managedcert-itsmetommy-io
spec:
  rules:
    - host: managedcert.itsmetommy.io
      http:
        paths:
          - path: /
            backend:
              serviceName: nginx-svc
              servicePort: 80
EOF

Create.

kubectl apply -f managedcert-ing.yaml

Describe.

kubectl describe ing nginx-ingress

Verify

Once I created the Ingress, it took ~15min for https to resolve.

curl https://managedcert.itsmetommy.io
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Clean up

{
  kubectl delete deploy nginx
  kubectl delete svc nginx-svc
  kubectl delete ing nginx-ingress
  kubectl delete managedcertificate managedcert-itsmetommy-io
  gcloud compute addresses delete managedcert-itsmetommy-io --global
  gcloud dns record-sets transaction start -z itsmetommy-io-external
  gcloud dns record-sets transaction remove --zone itsmetommy-io-external \
    --name managedcert.itsmetommy.io. --ttl 300 \
    --type A "$STATIC_IP"
  gcloud dns record-sets transaction execute --zone itsmetommy-io-external
}