Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

Kubernetes on Hetzner with Claudie!

profile picture
Author
Cloudziu
Published
2026-03-23
Time to read
7 minutes reading time

About the author- ☸️ Kubernetes focused DevOps Engineer

Introduction

This tutorial explains the process of setting up a Kubernetes cluster across multiple regions on Hetzner Cloud using a tool called Claudie. Claudie is a platform for managing multi-cloud and hybrid-cloud Kubernetes clusters with support for nodepools across different cloud providers and on-premise data centers, including Hetzner Cloud.

This type of setup is resilient to regional cloud disruptions and also helps address resource shortages within a single or even multiple regions.

Prerequisites

Step 1 - Install Claudie

Claudie needs to be installed on an existing Kubernetes cluster, referred to as the Management Cluster, which is used to manage the clusters it provisions. For this tutorial, an ephemeral cluster like kind can be used for simplicity. This step assumes that you have kind installed locally.

For testing, you can use ephemeral clusters like Minikube or kind. However, for production environments, it is recommended to use a more resilient solution since Claudie maintains the state of the infrastructure it creates.

  1. Create a kind cluster and export the kubeconfig

    holu@<your_host>:~# kind create cluster --name claudie-mgmt
    Creating cluster "claudie-mgmt" ...
     ✓ Ensuring node image (kindest/node:v1.35.0) :frame_with_picture:
     ✓ Preparing nodes :package:
     ✓ Writing configuration :scroll:
     ✓ Starting control-plane :joystick:
     ✓ Installing CNI :electric_plug:
     ✓ Installing StorageClass :floppy_disk:
    Set kubectl context to "kind-claudie-mgmt"
    You can now use your cluster with:
    
    kubectl cluster-info --context kind-claudie-mgmt
    holu@<your_host>:~# kind get kubeconfig -n claudie-mgmt > ~/.kube/claudie
    holu@<your_host>:~# export KUBECONFIG=~/.kube/claudie
    holu@<your_host>:~# kubectl get nodes
    NAME                         STATUS   ROLES           AGE    VERSION
    claudie-mgmt-control-plane   Ready    control-plane   3m8s   v1.35.0
  2. Install cert-manager as it is a requirement for the Claudie Management cluster.

    holu@<your_host>:~# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.20.0/cert-manager.yaml

    Wait until cert-manager is ready before you continue with the next step:

    kubectl get pods -n cert-manager
  3. Deploy Claudie

    holu@<your_host>:~# kubectl apply -f https://github.com/berops/claudie/releases/download/v0.10.0/claudie.yaml
  4. Wait for all Pods to get into Ready state

    holu@<your_host>:~# kubectl get pods -n claudie
    NAME                                READY   STATUS    RESTARTS     AGE
    ansibler-594c67f799-p6rtp           1/1     Running   0            60s
    claudie-operator-56f4b6767f-smr2x   1/1     Running   0            60s
    kube-eleven-547645865f-4tls2        1/1     Running   0            60s
    kuber-7764ffb5df-d826z              1/1     Running   0            60s
    manager-59fc97fd48-n8cvj            1/1     Running   0            60s
    minio-0                             1/1     Running   0            60s
    minio-1                             1/1     Running   0            60s
    minio-2                             1/1     Running   0            60s
    minio-3                             1/1     Running   0            60s
    mongodb-6d59c69c99-gjrv2            1/1     Running   0            60s
    nack-5bbb756857-rhxx2               1/1     Running   0            60s
    nats-0                              2/2     Running   0            60s
    nats-1                              2/2     Running   0            60s
    nats-2                              2/2     Running   0            60s
    terraformer-6c88c87f8c-b9gtn        1/1     Running   0            60s

Step 2 - Create Hetzner API Key

  1. Login to your Hetzner Console to generate a new API token with Read & Write permissions. For more information you can follow this guide on creating an API Token.

  2. Create a Kubernetes Secret that will contain the Hetzner API Token.

    holu@<your_host>:~# kubectl create secret generic hetzner-secret --from-literal=credentials='YOUR_API_TOKEN' -n claudie

Step 3 - Create a Claudie manifest file

Now, let's create a Claudie manifest file that describes the Kubernetes cluster you want to create across multiple Hetzner regions. You can use the example manifest below as a starting point.

  • Create the file:

    holu@<your_host>:~# nano inputmanifest.yml
  • Add your content:

    apiVersion: claudie.io/v1beta1
    kind: InputManifest
    metadata:
      name: multi-cloud-k8s
    spec:
      providers:
        - name: hetzner-secret
          providerType: hetzner
          secretRef:
            name: hetzner-secret
            namespace: claudie
      nodePools:
        dynamic:
          - name: ctrl-hel
            providerSpec:
              name: hetzner-secret
              region: hel1
              zone: hel1-dc14
            count: 3
            serverType: cx23
            image: ubuntu-24.04
    
          - name: cmpt-hel
            providerSpec:
              name: hetzner-secret
              region: hel1
              zone: hel1-dc14
            count: 2
            serverType: cx23
            image: ubuntu-24.04
            storageDiskSize: 50
    
          - name: cmpt-nbg
            providerSpec:
              name: hetzner-secret
              region: nbg1
              zone: nbg1-dc3
            autoscaler:
              min: 1
              max: 2
            serverType: cx23
            image: ubuntu-24.04
            storageDiskSize: 50
      kubernetes:
        clusters:
          - name: hetzner-cluster
            version: v1.34.0
            network: 192.168.2.0/24
            pools:
              control:
                - ctrl-hel
              compute:
                - cmpt-hel
                - cmpt-nbg

This InputManifest will provision:

  • 3 Kubernetes control plane nodes in the Helsinki region
  • 2 Kubernetes worker nodes in the Helsinki region
  • 1 to 2 auto-scaled Kubernetes worker nodes in the Nuremberg region, depending on workload demand

Let's break down some of the key fields:

  • spec.providers » Contains configurations for supported cloud providers. It is referencing access credentials (previously created in a Secret object) and terraform template files for Hetzner (see more)
  • spec.nodePools.dynamic » Defines dynamic nodepools. Those are cloud provider VMs that Claudie is expected to create.
  • spec.kubernetes.clusters » Describes the Kubernetes cluster that will be created.

Communication between regional nodes runs over the overlay network 192.168.2.0/24, which we defined in the InputManifest. All inter-node traffic within this network is encrypted using WireGuard, eliminating the need for a virtual network resource.

This infrastructure can be modified at any time. You can add a new region, scale nodes up or down within existing regions, or even attach physical machines to the cluster. For more in-depth understanding of the Claudie InputManifest definition, visit the documentation site.

Step 4 - Deploy the cluster

Apply the InputManifest to the Management Cluster:

holu@<your_host>:~# kubectl apply -f inputmanifest.yml -n claudie
inputmanifest.claudie.io/multi-cloud-k8s created

Verify that the infrastructure is being deployed:

holu@<your_host>:~# kubectl get inputmanifest -n claudie
NAME              STATUS
multi-cloud-k8s   IN_PROGRESS

Wait until you see WATCHING_FOR_CHANGES in the STATUS column. You can follow the deployment progress by checking the operator logs:

holu@<your_host>:~# kubectl logs -f -l app.kubernetes.io/name=claudie-operator -n claudie

Once deployment is complete:

holu@<your_host>:~# kubectl get inputmanifest -n claudie
NAME              STATUS
multi-cloud-k8s   WATCHING_FOR_CHANGES

Step 5 - Access the Cluster

The kubeconfig will be saved to a Secret object in the claudie namespace.

Export the kubeconfig for the deployed cluster:

holu@<your_host>:~# kubectl get secrets -n claudie -l claudie.io/cluster=hetzner-cluster,claudie.io/output=kubeconfig -ojsonpath='{.items[0].data.kubeconfig}' | base64 -d > hetzner-cluster.yaml

Verify the deployed cluster:

holu@<your_host>:~# export KUBECONFIG=hetzner-cluster.yaml
holu@<your_host>:~# kubectl get nodes
NAME                  STATUS   ROLES           AGE   VERSION
cmpt-hel-vjh754v-01   Ready    <none>          9m   v1.34.0
cmpt-hel-vjh754v-02   Ready    <none>          9m   v1.34.0
cmpt-nbg-46oaf10-01   Ready    <none>          9m   v1.34.0
ctrl-hel-lkd2o3o-01   Ready    control-plane   9m   v1.34.0
ctrl-hel-lkd2o3o-02   Ready    control-plane   9m   v1.34.0
ctrl-hel-lkd2o3o-03   Ready    control-plane   9m   v1.34.0

As can be seen from the output above, we have three control plane nodes and two worker nodes in the Helsinki region, and one worker node in the Nuremberg region which can be horizontally autoscaled up to two nodes.

Conclusion

In this tutorial we walked through the process of deploying a Kubernetes cluster across two Hetzner regions using Claudie to manage the infrastructure. We began by setting up Claudie in a local kind cluster, created a Hetzner API key for authentication, and defined a Claudie manifest. After applying the manifest, we successfully created a Kubernetes cluster on Hetzner Cloud.

Using Claudie gives us flexibility in determining how many nodes to deploy and where to place them. It also improves resilience against cloud outages, helps mitigate resource shortages within a region, and enhances overall high availability.

License: MIT
Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue
Try Hetzner Cloud

Get €20/$20 free credit!

Valid until: 31 December 2026 Valid for: 3 months and only for new customers
Get started
Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more