Part 2 - Deploy Kubernetes with Terraform and KubeOne
Introduction
This is the second part of my Blog Series "Deploy Kubernetes with Terraform and KubeOne". If you missed the first part of the series, follow this link to read it. In the first part, we talked about how we provide the basic infrastructure with Terraform.
What we got so far
At the moment we built the basic infrastructure on Hetzner Cloud. We got
3 x Control Plane Server
1 x Hetzner Firewall
1 x Hetzner Network
1 x Hetzner Load Balancer
The 3 Control Plane Servers are just basic Ubuntu 22.04 Servers with no additional software installed. Now it is time for KubeOne to actually do its job.
Default configuration
By default, KubeOne installs the following components:
Container Runtime: containerd for Kubernetes 1.22+ clusters, otherwise Docker
CNI: Canal (based on Calico and Flannel)
- Cilium, WeaveNet, and user-provided CNI are supported as an alternative
metrics-server for collecting and exposing metrics from Kubelets
NodeLocal DNSCache for caching DNS queries to improve the cluster performance
Kubermatic machine controller, a Cluster-API-based implementation for managing worker nodes
It’s possible to configure which components are installed and how they are configured by adjusting the KubeOne configuration manifest. To see possible configuration options, refer to the configuration manifest reference which can be obtained by running kubeone config print --full
.
Provision the Cluster
Now that the infrastructure is up and running, we can provision our Kubernetes Cluster with KubeOne. The first step is to create a KubeOne configuration manifest that describes our Cluster configuration, like the Kubernetes Version, Addons to be deployed and many more options. The manifest should be saved in a file called kubeone.yaml
. Because we are using Hetzner Cloud, you need to configure KubeOne at least like this:
apiVersion: kubeone.k8c.io/v1beta2
kind: KubeOneCluster
versions:
kubernetes: '1.25.6'
cloudProvider:
hetzner: {}
external: true
I customized the default configuration a little bit and added some plugins provided by Kubermatic. You can get a full list of addons on the KubeOne GitHub repository: https://github.com/kubermatic/kubeone/tree/main/addons
Of course, you can write your own add-ons, but this would be a separate topic.
In the first article, I mentioned KubeOne utilizes Terraform to configure the configuration. This information is used for accessing the instances, provisioning the cluster, and later creating the worker nodes. The format is already defined in a file called output.tf
and everything you need to do is to run the output
command:
terraform output -json > tf.json
This command creates a file called tf.json
in the current directory. Its content is a JSON-formatted representation of the Terraform state that can be parsed by KubeOne. With our kubeone.yaml
and the tf.json
file, we are ready to provision our cluster. This is done by running the kubeone apply
command and providing it the configuration manifest and the Terraform state file that we created in the previous step.
kubeone apply -m kubeone.yaml -t tf.json
INFO[16:42:43 CET] Determine hostname...
INFO[16:42:46 CET] Determine operating system...
INFO[16:42:46 CET] Running host probes...
INFO[16:42:49 CET] Electing cluster leader...
INFO[16:42:49 CET] Elected leader "hcloud-k8s-control-plane-1"...
INFO[16:42:52 CET] Building Kubernetes clientset...
INFO[16:42:53 CET] Running cluster probes...
The following actions will be taken:
Run with --verbose flag for more information.
~ ensure credential
~ ensure embedded addons
~ ensure custom addons
~ ensure external CCM
Do you want to proceed (yes/no): yes
INFO[22:43:14 CET] Determine hostname...
INFO[22:43:14 CET] Determine operating system...
INFO[22:43:14 CET] Installing prerequisites...
INFO[22:43:14 CET] Creating environment file... node=116.203.140.93 os=ubuntu
INFO[22:43:14 CET] Creating environment file... node=116.201.139.92 os=ubuntu
INFO[22:43:14 CET] Creating environment file... node=116.203.200.170 os=ubuntu
INFO[22:43:14 CET] Configuring proxy... node=116.201.139.92 os=ubuntu
INFO[22:43:14 CET] Installing kubeadm... node=116.201.139.92 os=ubuntu
INFO[22:43:14 CET] Configuring proxy... node=116.203.200.170 os=ubuntu
INFO[22:43:14 CET] Installing kubeadm... node=116.203.200.170 os=ubuntu
INFO[22:43:14 CET] Configuring proxy... node=116.203.140.93 os=ubuntu
INFO[22:43:14 CET] Installing kubeadm... node=116.203.140.93 os=ubuntu
...
...
INFO[22:49:54 CET] Installing machine-controller...
INFO[22:49:57 CET] Installing machine-controller webhooks...
INFO[22:49:58 CET] Waiting for machine-controller to come up...
INFO[22:50:34 CET] Creating worker machines...
At this point, your cluster is provisioned, but it may take several more minutes for worker nodes to get created by the Kubermatic machine controller and join the cluster. Meanwhile, you can configure access to the cluster.
Getting access to the cluster
KubeOne automatically downloads the kubeconfig file for the cluster. You can use it with kubectl such as:
kubectl --kubeconfig=<cluster_name>-kubeconfig
or export the KUBECONFIG
environment variable:
export KUBECONFIG=$PWD/<cluster_name>-kubeconfig
Final Words
Awesome! We created our first Kubernetes Cluster with Kubermatic KubeOne! We are now able to deploy workloads on our Cluster.
Maybe there will be another article in the future for this series.
If there are any questions or problems, feel free to ask me in the comments or connect with me on my social media:
Instagram - cpt.chaozz
Twitter - cpt_chaoz
Subscribe to my newsletter
Read articles from Dominic Cardellino directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by