Blog was originally published on medium (https://medium.com/goglides/ssl-certificates-using-google-managed-certificate-on-gke-c4bc43f5cbf2)
Note: Managed certificates require clusters with masters running Kubernetes 1.12.6-gke.7 or higher.
In goglides.com we started allowing users to map custom domain names to Tenants URL also. One of the challenges we were facing initially when we started implementing solutions is how to issue an SSL certificate for the custom domain name automatically so that we can establish a secure connection for Tenants.
Issuing and managing a certificate is not a trivial task, especially if you are trying to build the solutions from scratch. Luckily, Goglides is running on Kubernetes so it became trivial to implement a solution.
There are so many ways we can issue certificates, in this blog we are focusing on K8S cluster running on Google (GKE) using a custom resource called ManagedCertificate and ingress rules.
Before we jump into solutions, let’s start with explaining some of the technology we are using here,
As per the official definition,
Ingress is an, API object that manages external access to the services in a cluster, typically HTTP. Ingress can provide load balancing, SSL termination, and name-based virtual hosting.
One of the main use cases of ingress is, it allows users to access Kubernetes services from outside the Kubernetes cluster.
Ingress has 2 parts, ingress controller (there are many controllers) and ingress rules. We create ingress rules and we need a controller that satisfies and process those rules. Only applying ingress rules does not affect the cluster.
Managed Certificate is a Custom Resource object created by google. This CRD allows users to automatically acquire an SSL certificate from a Certificate Authority, configure certificate on the load balancer and auto-renew it on time when it’s expired.
The process is super simple and users only need to provide a domain for which they want to obtain a certificate.
- You must own the domain name and name must be no longer than 63 characters. In this example, we are going to use a subdomain (gke.goglides.com)
- Create a reserved (static) external IP address using the following command, or use google console. Here I am using
gke-goglides-static-ipas IP address identifier which we are going to use later. It can be anything.
gcloud compute addresses create gke-goglides-static-ip --global gcloud compute addresses \ describe gke-goglides-static-ip --global \ --format='value(address)'
Create DNS record ahead so that google certificate authority can validate ownership of the domain, issue certificates and attached it to load balancer using managed certificate features.
Now, let’s start with creating Kubernetes resources.
- Create Managed Certificate
cat <<EOF | kubectl apply -f - --- apiVersion: networking.gke.io/v1beta1 kind: ManagedCertificate metadata: name: gke-goglides-certificate spec: domains: - gke.goglides.com EOF
You can check the status of a certificate using the following command
kubectl describe managedcertificate gke-goglides-certificate
- Create Deployment
cat <<EOF | kubectl apply -f - --- apiVersion: apps/v1 kind: Deployment metadata: labels: run: gke-goglides name: hello-world spec: selector: matchLabels: run: gke-goglides replicas: 1 template: metadata: labels: run: gke-goglides spec: containers: - name: hello-world image: nginx:1.15.8 ports: - containerPort: 80 protocol: TCP EOF
Create a Service Object
cat<<EOF | kubectl apply -f - --- apiVersion: v1 kind: Service metadata: labels: run: gke-goglides name: hello-world-service spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: gke-goglides type: NodePort EOF
cat <<EOF | kubectl apply -f - --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: gke-goglides-ingress annotations: kubernetes.io/ingress.global-static-ip-name: gke-goglides-static-ip networking.gke.io/managed-certificates: gke-goglides-certificate spec: backend: serviceName: hello-world-service servicePort: 80 EOF
This took ~10–20min to become active. Verify that SSL is working by visiting your domain using the https:// prefix.
You should see the following outputs.
</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>