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
2023-10-30
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 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.

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.27.3) :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.27.3
  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.12.0/cert-manager.yaml
  3. Deploy Claudie

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

    holu@<your_host>:~# kubectl -n claudie get pods
    NAME                                READY   STATUS      RESTARTS   AGE
    ansibler-858667d9d7-2r9z7           1/1     Running     0          2m17s
    builder-bd8d5f97b-89zpl             1/1     Running     0          2m17s
    claudie-operator-6bdcb4ddbf-ljhtd   1/1     Running     0          2m17s
    context-box-65484fbc88-w7xwk        1/1     Running     0          2m17s
    create-table-job-md8pm              0/1     Completed   1          2m17s
    dynamodb-6d65df988-98nkh            1/1     Running     0          2m17s
    kube-eleven-76b95985cb-rqtmj        1/1     Running     0          2m17s
    kuber-5dd64cd759-rqlkc              1/1     Running     0          2m17s
    make-bucket-job-jb6wg               0/1     Completed   0          2m17s
    minio-0                             1/1     Running     0          2m17s
    minio-1                             1/1     Running     0          2m17s
    minio-2                             1/1     Running     0          2m17s
    minio-3                             1/1     Running     0          2m17s
    mongodb-5574c9b7-hq8jh              1/1     Running     0          2m17s
    scheduler-8468dc885f-stqxn          1/1     Running     0          2m17s
    terraformer-7d75cf49fd-d4x4f        1/1     Running     0          2m17s

Step 2 - Create Hetzner API Key

  1. Login to your Hetzner Cloud 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'

Step 3 - Create a Claudie manifest file

Now, let's create a Claudie manifest file that describes the Kubernetes cluster you want to create on Hetzner. 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: kubernetes-hetzner
    spec:
      providers:
          - name: hetzner-secret
            providerType: hetzner
            secretRef:
              name: hetzner-secret
              namespace: default
      nodePools:
        dynamic:
          - name: control-hetzner-1
            providerSpec:
              name: hetzner-secret
              region: fsn1
              zone: fsn1-dc14
            count: 1
            serverType: cpx21
            image: ubuntu-22.04
    
          - name: compute-hetzner-1
            providerSpec:
              name: hetzner-secret
              region: fsn1
              zone: fsn1-dc14
            count: 3
            serverType: cpx21
            image: ubuntu-22.04
            storageDiskSize: 50
      kubernetes:
        clusters:
          - name: hetzner-cluster
            version: v1.27.0
            network: 192.168.2.0/24
            pools:
              control:
                - control-hetzner-1
              compute:
                - compute-hetzner-1

The above manifest file is used for defining a Kubernetes cluster. Let's break down some of the key fields in it:

  • spec.providers » Contains configurations for supported cloud providers. It is referencing access credentials that were previously created in a Secret object.
  • 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.

Provided example is relatively simple and deploys a Kubernetes cluster with one control node and three worker nodes. However, Claudie can be used for more advanced cluster scenarios, including deploying clusters across different cloud providers and on-premise in multi-cloud/hybrid architecture. Additionally, it's worth noting that the nodes will be connected using a WireGuard network, eliminating the need for a virtual network resource. For more in-depth understanding of Claudie inputmanifest definition, visit the documentation site.

Step 4 - Deploy the cluster


Important: Please note that applying the YAML file from above will automatically create:

  • 4 Hetzner Cloud servers of type CPX21 that will be charged
  • 3 Hetzner Cloud Volumes with a storage capacity of 50 GB each that will be charged
  • 1 Hetzner Cloud Firewall (free)
  • It will also add an SSH key to the project

Save the example above to an inputmanifest.yml file, and apply it to the kind cluster. If you are not prepared to pay for 4 servers of type CPX21 and 3 Volumes, you can adapt the YAML file above as needed before you run the following command:

holu@<your_host>:~# kubectl apply -f inputmanifest.yml
inputmanifest.claudie.io/kubernetes-hetzner created

Now you can follow the cluster deployment status. When the cluster is deployed, the status will state DONE.

holu@<your_host>:~# kubectl get inputmanifest
NAME                 STATUS
kubernetes-hetzner   IN_PROGRESS

holu@<your_host>:~# kubectl get inputmanifest
NAME                 STATUS
kubernetes-hetzner   DONE

Step 5 - Access the cluster

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

holu@<your_host>:~# kubectl get secrets -A
NAMESPACE      NAME                                      TYPE                            DATA   AGE
cert-manager   cert-manager-webhook-ca                   Opaque                          3      103m
claudie        claudie-webhook-certificate               kubernetes.io/tls               3      100m
claudie        dynamo-secret-td2bt2f272                  Opaque                          2      101m
claudie        hetzner-cluster-mgcdv9x-kubeconfig        Opaque                          1      12m
claudie        hetzner-cluster-mgcdv9x-metadata          Opaque                          1      12m
claudie        minio-secret-5hd7htgm7m                   Opaque                          2      101m
claudie        mongo-secret-gfc6d84tcf                   Opaque                          2      101m
default        hetzner-secret                            Opaque                          1      82m

In the command below, replace hetzner-cluster-mgcdv9x-kubeconfig with the actual name.

holu@<your_host>:~# kubectl get secrets -n claudie hetzner-cluster-mgcdv9x-kubeconfig -o jsonpath='{.data.kubeconfig}' | base64 -d
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <your_data>
    server: https://<203.0.113.1>:6443
  name: hetzner-cluster
contexts:
- context:
    cluster: hetzner-cluster
    user: kubernetes-admin
  name: kubernetes-admin@hetzner-cluster
current-context: kubernetes-admin@hetzner-cluster
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: <your_data>
    client-key-data: <your_data>

Confirm that the cluster is up and running:

In the command below, replace hetzner-cluster-mgcdv9x-kubeconfig with the actual name.

holu@<your_host>:~# kubectl get secrets -n claudie hetzner-cluster-mgcdv9x-kubeconfig -o jsonpath='{.data.kubeconfig}' | base64 -d > ~/.kube/hetzner
holu@<your_host>:~# export KUBECONFIG=~/.kube/hetzner
holu@<your_host>:~# kubectl get nodes
NAME                          STATUS   ROLES    AGE   VERSION
compute-hetzner-1-cyxbuh6-1   Ready    <none>   19m   v1.24.0
compute-hetzner-1-cyxbuh6-2   Ready    <none>   19m   v1.24.0
compute-hetzner-1-cyxbuh6-3   Ready    <none>   19m   v1.24.0
control-hetzner-1-ivfw0xn-1   Ready    <none>   20m   v1.24.0

Conclusion

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

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€ free credit!

Valid until: 31 December 2024 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