This Ghost Blog is now running with Let's Encrypt in a cheap bare-metal Kubernetes Cluster (on Hetzner Cloud) — Part 3/3
Blog Deployment Descriptors
This will now describe the different sections of the YAML files deployed.
Storage
|
|
As discussed previously, we leverage the specific Container Storage Interface (CSI) Implementation for Hetzner, which we installed previously. This will then make Hetzner create a volume and bind it to a single node in Hetzner Cloud.
Note that the CSI driver does not support at the time of writing ReadWriteMany strategy. As a consequence, only one node at a given point in time can access the volume created. We will see below that unfortunately we cannot have more than 1 replicas, and this may imply some downtime when creating the Replica.
Pods Deployment
|
|
Note that the container image is pulled from my own private GitLab Docker registry, but the exact steps involved for this will be covered in a separate blog post.
Also, for dynamic resource management, I configured an AutoScaler, to ensure new pods are created once the CPU utilization is above 70% on average:
|
|
Services
|
|
Here I want to expose the Service onto an external IP address, that’s outside of the cluster. The ClusterIP service type exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.
Remember that NGINX is configured as our Ingress Resource, and as such, will serve as the main reverse-proxy entry-point to the application.
Ingress
|
|
This simply creates an Ingress resource in the cluster which does host-based routing and TLS/SSL termination. This means that the requested host allows the Ingress to determine the right backend service to route the request to. And this is what will actually trigger the Cert-Manager to:
- place orders for a certificate for rm3l.org host
- manage challenges requested by Let’s Encrypt for domain validation
- manage certificate auto-renewal
Once this is done, the blog should be reachable via the NGINX Ingress External IP address, which I set as an A resource in my DNS provider settings for this domain. This allows “rm3l.org” to be resolved by the NGINX Ingress External IP Address.
Wrapping up
This was a pretty fun and exciting journey to playing and learning a lot more about Kubernetes (on both the provision-and-manage and the deploy-in-the-cluster perspectives).
Change being the only constant, my next step is now to attempt a different deployment strategy for this blog, now that Ghost 3.0 has been released with support for a true headless CMS.
I now look forward to deploying this blog using the JAMStack (as in JavaScript, APIs, Markup), using Gatsby.js (front-end) + Netlify (PaaS) + Ghost (headless CMS back-end).
Please stay tuned — this other journey will be the topic of another blog post.