Part 1: Setting Up a Cost-Effective Kubernetes Cluster with HostHatch and Talos Linux

Deploying a Kubernetes cluster can often be expensive and complex, but it doesn’t have to be. In this series of blog posts, I will guide you through setting up a Kubernetes cluster using HostHatch as the hosting service and Talos Linux as the OS. Much of this can be replicated on other VPS providers but I’m going with HostHatch since they provide quality nodes at a good price. This setup is particularly cost-effective for developers looking to host websites for side projects without the high overhead of traditional cloud providers. This initial post focuses on the basic setup, while future entries will delve into advanced topics such as scaling, security enhancements, and implementing continuous deployment with ArgoCD.

Prerequisites

Before we start, ensure you have:

  • A HostHatch account
    • If you don’t have one already and would like to support us feel free to sign up with this link.
  • Access to Cloudflare for DNS management

Step 1: Download and Set Up Talos Linux

  1. Download the Latest Talos Image:

    • Obtain the latest Talos release from their GitHub releases page. As of this writing, the latest stable release is v1.7.1.
    • Download the metal-amd64.iso image suitable for bare metal environments as well as virtualized environments.

  2. Upload the Image to HostHatch:

    • Since direct uploading from GitHub to HostHatch didn’t seem to work for me, I’d recommend first upload the image to a web server if you have one.
    • From your web server, transfer the image to HostHatch with the “Upload Image” function under the images page on HostHatch.
    • If that doesn’t seem to work for you, I’d recommend opening a support ticket with HostHatch.

  3. Purchase VPS Instances:

    • I started by purchasing three VPS instances from HostHatch to ensure high availability for my Kubernetes cluster.
      • I went with 3x NVMe 16 GB, 4 core (2 dedicated, 2 fair-shared cores), 16 GB DDR4 RAM, 75 GB NVMe Storage ($15/month each). Although looking back I probably should have done 3 of theNVMe 4 GB nodes ($6/month each) for the control plane nodes and then added more powerful dedicated worker nodes.
      • Since you will be installing Talos Linux, you can choose any available image during the purchase process, such as Ubuntu, since the system will be wiped and replaced by Talos Linux anyway.

  4. DNS Configuration:

    • Set up A records within Cloudflare for each of the hosts, such as cp-001.ord.k8s.example.com for control plane nodes and worker-001.ord.k8s.example.com for worker nodes. I’m using ord within my hostnames since I chose the Chicago region for my nodes.
    • I also setup an A record for ord.k8s.example.com that contains the IPs for each of the control plan nodes. This doesn’t handle fail-overs like a load balancer would but it will get us most of the way there without having another monthly expense.

  5. Enable Private Networking:

    • Enable “Private Networking” for each VPS in the HostHatch management console to enhance performance.

Step 2: Configure Talos and Kubernetes

  1. Install Necessary Tools:

    • Install talosctl and kubectl on your local machine. I won’t cover this here since it will vary based on your operating system but both talos and kubernetes have great documentation around this.

  2. Generate Base Talos Configuration:

    • Generate the initial configuration files using:
      • talosctl gen config ORD-K8S https://ord.k8s.example.com:6443
      • The ORD-K8S section of the command is just what I’m naming my cluster, feel free to name yours how you’d like.

  3. Prepare Patch Files For Each Host:

    • Create a directory for host-specific configurations, e.g., hosts underneath where you’re keeping your talos configurations.
    • Create a patch file for each host, adjusting settings like disk, network interfaces, and Kubernetes scheduling options. Here’s an example patch file I created:
    cp-001.ord.k8s.example.com.patch
    machine:
      install:
        disk: /dev/vda
      network:
        # Be sure to update this line for each host
        hostname: cp-001.ord.k8s.example.com
        interfaces:
          - deviceSelector:
              hardwareAddr: "00:20:*"
            dhcp: true
          - deviceSelector:
              hardwareAddr: "00:22:*"
            dhcp: false
            # This address will need to be unique for each host
            addresses: [10.0.0.11/24]
      certSANs: 
        - ord.k8s.example.com
    
    # # Uncomment these lines if are only using control plane nodes
    # cluster:
    #     allowSchedulingOnControlPlanes: true
  4. Apply the Patch Files:

    Apply the patch to create specific host configurations:

    Bash
    cd hosts && talosctl machineconfig patch ../controlplane.yaml --patch @cp-001.ord.k8s.example.com.patch --output cp-001.ord.k8s.example.com.yaml

    Apply the configuration to the nodes:

    Bash
    cd ../ && talosctl apply-config --insecure --nodes cp-001.ord.k8s.example.com --file hosts/cp-001.ord.k8s.example.com.yaml
  5. Set the Endpoint Config:

    Set the endpoint configuration for the control plane nodes. This will simplify the future talosctl commands so you don’t have to continually specify the endpoint.

    Bash
    talosctl --talosconfig=./talosconfig config endpoint ord.k8s.example.com
    talosctl --talosconfig=./talosconfig config node ord.k8s.example.com
  6. Bootstrap the Kubernetes Cluster:

    Run the bootstrap script on one of the control plane nodes:

    Bash
    talosctl --talosconfig=./talosconfig bootstrap --nodes cp-001.ord.k8s.example.com --endpoints cp-001.ord.k8s.example.com
  7. Create the Kubeconfig File:

    After the cluster is bootstrapped, generate the kubeconfig file to allow kubectl to communicate with your Kubernetes cluster:

    Bash
    talosctl --talosconfig=./talosconfig kubeconfig
  8. Test the Kubernetes Cluster:

    Verify that kubectl is correctly configured and can communicate with your Kubernetes cluster:

    Bash
    kubectl get nodes

    This command should list all the nodes in your cluster along with their statuses. It ensures that each node is up and running and that kubectl can manage the cluster effectively.

Update: Adding More Hosts to the Cluster

Looking back on this post, I realized I didn’t mention how to add worker nodes. It’s a very similar process as to what’s described above. Create a patch file for each node such as worker-001.ord.k8s.example.com.patch. Then on the talosctl machineconfig patch command make sure to reference the worker.yaml file instead of controlplane.yaml. Then you need to apply the file to the node and it should join the cluster.

Looking Ahead

This post is the first in a series designed to take you from a basic Kubernetes setup to a fully operational, robust, and secure cluster. Future posts will cover:

  1. Implementing Longhorn for Persistent Storage: Explore how to use Longhorn for scalable and reliable block storage.
  2. Automating Deployments with ArgoCD: Learn to set up ArgoCD for continuous deployment through a GitOps approach.
  3. Securing with Cloudflare Tunnels: How to securely connect your Kubernetes cluster to the internet without exposing services directly.
  4. Enhancing Network Security with Firewalls: Best practices for securing your Kubernetes cluster with firewalls and network policies.

Conclusion

Setting up a Kubernetes cluster with HostHatch and Talos Linux involves several detailed steps, from preparing the OS image to configuring network settings and bootstrapping the cluster. This guide should help you get your Kubernetes environment up and running efficiently, with more in-depth and specialized discussions to follow in this series. Whether you’re hosting websites for side projects or looking for a robust solution for larger applications, this series aims to provide you with the knowledge and tools to succeed.

Leave a Comment