<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lucas Rattz</title>
    <description>The latest articles on DEV Community by Lucas Rattz (@lucasrattz).</description>
    <link>https://dev.to/lucasrattz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1696037%2F81329b61-6809-4624-aebd-b002d59d9de7.png</url>
      <title>DEV Community: Lucas Rattz</title>
      <link>https://dev.to/lucasrattz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lucasrattz"/>
    <language>en</language>
    <item>
      <title>Managing Kubernetes on Hetzner with Cluster API</title>
      <dc:creator>Lucas Rattz</dc:creator>
      <pubDate>Tue, 16 Jul 2024 20:56:06 +0000</pubDate>
      <link>https://dev.to/syself/managing-kubernetes-on-hetzner-with-cluster-api-59o8</link>
      <guid>https://dev.to/syself/managing-kubernetes-on-hetzner-with-cluster-api-59o8</guid>
      <description>&lt;h2&gt;
  
  
  In This Article
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Step 1 - Prepare your Hetzner Account&lt;/li&gt;
&lt;li&gt;Step 2 - Create a management cluster&lt;/li&gt;
&lt;li&gt;Step 3 - Create your workload cluster&lt;/li&gt;
&lt;li&gt;Step 4 - Install components in your cluster&lt;/li&gt;
&lt;li&gt;Step 5 - Move your management cluster to the created cluster on Hetzner (Optional)&lt;/li&gt;
&lt;li&gt;Next steps&lt;/li&gt;
&lt;li&gt;Baremetal&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Managing Kubernetes clusters can be a daunting task, especially at scale. The Cluster API (CAPI) is an official Kubernetes SIG project that aims to simplify the provisioning, upgrading, and operating multiple clusters in a declarative way.&lt;/p&gt;

&lt;p&gt;This approach offers several benefits over Infrastructure as Code tools, such as Terraform and Ansible, since it manages the entire lifecycle of your cluster. This includes automated creation, scaling, upgrades and self-healing, unlike IaC tools that run a predefined workflow only when triggered.&lt;/p&gt;

&lt;p&gt;These benefits can be better understood by comparing tools in the same scenario: If someone accidentally deletes or changes a virtual machine or a load balancer after the initial provisioning with IaC tools, your infrastructure will remain broken until the next time you make a change, or until you see the mistake by chance (or worse, when your customers start reporting issues). With Cluster API, the state of your cluster is continuously reconciled to match the desired state, automatically fixing configuration drift.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/syself/cluster-api-provider-hetzner" rel="noopener noreferrer"&gt;Cluster API Provider Hetzner (CAPH)&lt;/a&gt; is an open-source project (maintained by Syself and the community; not a Hetzner project) that allows you to leverage the capabilities of Cluster API to manage highly-available Kubernetes clusters on both Hetzner baremetal servers (Robot) and Hetzner cloud instances.&lt;/p&gt;

&lt;p&gt;This tutorial covers the process of setting up a highly-available Kubernetes cluster on Hetzner Cloud using CAPH.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;, for running containers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kind.sigs.k8s.io/docs/user/quick-start#installation" rel="noopener noreferrer"&gt;Kind&lt;/a&gt;, to create a local Kubernetes cluster&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kubernetes.io/docs/tasks/tools/#kubectl" rel="noopener noreferrer"&gt;kubectl&lt;/a&gt; and &lt;a href="https://cluster-api.sigs.k8s.io/user/quick-start#install-clusterctl" rel="noopener noreferrer"&gt;clusterctl&lt;/a&gt;, to access and manage your clusters&lt;/li&gt;
&lt;li&gt;A Hetzner Cloud account&lt;/li&gt;
&lt;li&gt;An SSH key&lt;/li&gt;
&lt;li&gt;Basic knowledge of Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1 - Prepare your Hetzner Account
&lt;/h2&gt;

&lt;p&gt;Create a new project in the Hetzner Cloud Console, go to the "Security" tab and create an API token with read and write access. Note it down.&lt;/p&gt;

&lt;p&gt;Next, add your public SSH key to the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 - Create a management cluster
&lt;/h2&gt;

&lt;p&gt;A Kubernetes cluster is needed to run the Cluster API and CAPH controllers. It will act as a management cluster, allowing you to manage workload clusters with Kubernetes objects. In this way, the controllers will handle the entire lifecycle of the machines and infrastructure.&lt;/p&gt;

&lt;p&gt;We will start with a local Kind cluster to serve as a temporary bootstrap cluster. Later, we will be able to run the controllers on the new workload cluster in Hetzner Cloud, and move our resources there. If you already have a running Kubernetes cluster, feel free to use it instead.&lt;/p&gt;

&lt;p&gt;Create a local Kind (Kubernetes in Docker) cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a cluster with Kind&lt;/span&gt;
kind create cluster &lt;span class="nt"&gt;--name&lt;/span&gt; caph-mgt-cluster


&lt;span class="c"&gt;# Initialize it&lt;/span&gt;
clusterctl init &lt;span class="nt"&gt;--core&lt;/span&gt; cluster-api &lt;span class="nt"&gt;--bootstrap&lt;/span&gt; kubeadm &lt;span class="nt"&gt;--control-plane&lt;/span&gt; kubeadm &lt;span class="nt"&gt;--infrastructure&lt;/span&gt; hetzner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a secret to enable CAPH to communicate with the Hetzner API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace &amp;lt;YOUR_HCLOUD_TOKEN&amp;gt; with the API token you generated in the previous step&lt;/span&gt;
kubectl create secret generic hetzner &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;hcloud&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;YOUR_HCLOUD_TOKEN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3 - Create your workload cluster
&lt;/h2&gt;

&lt;p&gt;Define your cluster variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HCLOUD_SSH_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;ssh-key-name&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HCLOUD_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"fsn1"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CONTROL_PLANE_MACHINE_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;WORKER_MACHINE_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBERNETES_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.29.4 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HCLOUD_CONTROL_PLANE_MACHINE_TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;cpx31 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HCLOUD_WORKER_MACHINE_TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;cpx31
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And create your cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate the manifests defining a workload cluster, and apply them to the bootstrap cluster&lt;/span&gt;
clusterctl generate cluster &lt;span class="nt"&gt;--infrastructure&lt;/span&gt; hetzner:v1.0.0-beta.35 hetzner-cluster | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -


&lt;span class="c"&gt;# Get the kubeconfig for this new cluster&lt;/span&gt;
clusterctl get kubeconfig hetzner-cluster &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; hetzner-cluster-kubeconfig.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every component and configuration of this workload cluster can be defined declaratively in the management cluster. If you run the clusterctl generate command again, you will see the actual manifests that were applied to it. This means you can scale, delete, and modify clusters only by interacting with Kubernetes resources.&lt;/p&gt;

&lt;p&gt;Before you use Cluster API Provider Hetzner in a production scenario, you should read through the &lt;a href="https://syself.com/docs/caph" rel="noopener noreferrer"&gt;CAPH&lt;/a&gt; and &lt;a href="https://cluster-api.sigs.k8s.io" rel="noopener noreferrer"&gt;CAPI&lt;/a&gt; documentations, and familiarize yourself with the main resources you'll be interacting with like Clusters, Machines, Machine Deployments, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 - Install components in your cluster
&lt;/h2&gt;

&lt;p&gt;Your newly created cluster needs a few key components before you can host your workloads in it. These are a Container Network Interface (CNI), responsible for networking capabilities, and a Cloud Controller Manager (CCM), which allows you to properly use Hetzner resources such as Load Balancers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hetzner-cluster-kubeconfig.yaml

&lt;span class="c"&gt;# Install Hetzner CCM&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/hetznercloud/hcloud-cloud-controller-manager/releases/latest/download/ccm.yaml

&lt;span class="c"&gt;# Install Flannel CNI - You can use your preferred CNI instead, e.g. Cilium&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! You now have a working Kubernetes cluster in Hetzner Cloud.&lt;/p&gt;

&lt;p&gt;If you want to delete the cluster, you can run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete cluster hetzner-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will delete the cluster and all resources created for it, like machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 - Move your management cluster to the created cluster on Hetzner (Optional)
&lt;/h2&gt;

&lt;p&gt;You can use your new cluster on Hetzner as a management cluster, moving away from your temporary bootstrap cluster.&lt;/p&gt;

&lt;p&gt;Run the clusterctl init command to deploy CAPI and CAPH controllers to your new cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hetzner-cluster-kubeconfig.yaml clusterctl init &lt;span class="nt"&gt;--core&lt;/span&gt; cluster-api &lt;span class="nt"&gt;--bootstrap&lt;/span&gt; kubeadm &lt;span class="nt"&gt;--control-plane&lt;/span&gt; kubeadm &lt;span class="nt"&gt;--infrastructure&lt;/span&gt; hetzner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, back on your local kind cluster, use clusterctl to move your resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This will make the secret automatically move to the target cluster&lt;/span&gt;
kubectl patch secret hetzner &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"metadata":{"labels":{"clusterctl.cluster.x-k8s.io/move":""}}}'&lt;/span&gt;

&lt;span class="c"&gt;# Move the cluster definitions to the new cluster, you can omit the namespace to use default&lt;/span&gt;
clusterctl move &lt;span class="nt"&gt;--to-kubeconfig&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hetzner-cluster-kubeconfig.yaml --namespace=&amp;lt;target-namespace&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the move, you can safely delete the local Kind cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kind delete cluster &lt;span class="nt"&gt;--name&lt;/span&gt; caph-mgt-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Your workload cluster was created with the default kubeadm bootstrap and controlplane providers. For production use, you may want to add additional layers to this configuration and create your own node images, as the default configuration provides only the basics to have a running cluster.&lt;/p&gt;

&lt;p&gt;For more information on which aspects are handled by CAPH, you can check the project's &lt;a href="https://github.com/syself/cluster-api-provider-hetzner?tab=readme-ov-file#-clarifying-scope" rel="noopener noreferrer"&gt;GitHub readme&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Baremetal
&lt;/h2&gt;

&lt;p&gt;In the introduction to this article, it was stated that CAPH fully supports the use of Hetzner baremetal servers (Hetzner Robot). A second guide focusing on this feature is in the works, but if it hasn't been published by the time you read this, you can visit the &lt;a href="https://syself.com/docs/caph/topics/baremetal/introduction" rel="noopener noreferrer"&gt;CAPH docs&lt;/a&gt; if you're interested in managing Hetzner baremetal servers with Cluster API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With Cluster API Provider Hetzner, you can create and manage highly available Kubernetes clusters in Hetzner, in a declarative and cloud-native way. This enables you to operate and scale your clusters seamlessly. A single Cluster API management cluster can handle approximately one hundred clusters, depending on the number of nodes.&lt;/p&gt;

&lt;p&gt;In this tutorial, you created your own highly available Kubernetes cluster on Hetzner, with a fully managed lifecycle. As you continue to work with Kubernetes and the Cluster API Provider Hetzner, you can explore additional features and configuration options to optimize your cluster management, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementing custom node images and configurations tailored to your specific workloads&lt;/li&gt;
&lt;li&gt;Integrating with other Kubernetes tools and add-ons such as a CNI, metric-server, konnectivity, etc&lt;/li&gt;
&lt;li&gt;Increase the reliability of your cluster with backups, monitoring and alerting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have any questions or feedback, please write a comment!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>clusterapi</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
