Part 1 - Deploy Kubernetes with Terraform and KubeOne
Introduction
This is my first blog post on Hashnode. I hope you enjoy it ๐
"Oh no! Yet another blog post about setting a Kubernetes Cluster" - That's probably what most of you think when you read the headline.
And you are not wrong at all. Except that I will try to share some of my experiences and some (best) practices I learned while working with those two tools.
To make things a bit clearer about what you can expect from this series, I will give you a brief overview:
Create Kubernetes infrastructure on Hetzner Cloud with Terraform
Provision a production-grade Kubernetes Cluster with Kubermatic KubeOne
To begin with this little journey, I assume that:
you already have set up a Hetzner account
you have installed Terraform on your machine
you have installed KubeOne on your machine
you have a basic understanding of Linux and Kubernetes
In the first part of this blog series, we are focussing on deploying the basic infrastructure with Terraform.
What is Kubermatic KubeOne?
KubeOne is a small wrapper around kubeadm. kubeadm is the official tool to install Kubernetes on Virtual Machines or Bare Metal nodes. But deploying Kubernetes with kubeadm is very cumbersome.
KubeOne tries to solve this problem by providing a wrapper, which automates the operations of Kubernetes Clusters. It provides full lifecycle management of your clusters, including provisioning, upgrading and (when necessary) repairing them.
Let's get started
We begin with provisioning our needed infrastructure with Terraform on Hetzner. We clone the Kubermatic provided Terraform examples.
git clone https://github.com/kubermatic/kubeone.git
When we change the directory to examples/terraform/hetzner
we find a ready to use terraform module, that provisions the basic infrastructure on our cloud provider. This includes:
hcloud_network
hcloud_network_subnet
hcloud_firewall
hcloud_server
Add Bastion Host
Currently, there will be only servers created for Kubernetes. To increase the level of security we will add another server resource and create a bastion server/jump host. This allows us to restrict ssh connections only if they are tunnel through this specific host. Of course we also have to make some adjustments on the Hetzner Firewall.
First we change the firewall configuration. Open the main.tf
file with a text editor of your choice and find go to line 80. Change the rule allow SSH from any
from:
rule {
description = "allow SSH from any"
direction = "in"
protocol = "tcp"
port = "22"
source_ips = [
"0.0.0.0/0",
]
}
to:
rule {
description = "allow SSH via bastion"
direction = "in"
protocol = "tcp"
port = "22"
source_ips = [
format("%s/32", hcloud_server.bastion.ipv4_address)
]
}
The changes make sure that only SSH connections coming from the public IP are allowed on the Kubernetes nodes. The next change is to add the code for the bastion server.
resource "hcloud_server" "bastion" {
name = "${var.cluster_name}-bastion-host"
server_type = "cx11
image = local.image
location = "nbg1"
labels = {
"kubeone_cluster_name" = var.cluster_name
"role" = "bastion"
}
}
The README.md
in the project directory gives us a brief explanation of inputs and outputs and gives us hints about load balancers. Most of the inputs have defaults except the variable cluster_name
. Create a file called terraform.tfvars
in the same directory and add the following line to it:
cluster_name = "<your-cluster-name-here>"
This makes sure that the input cluster_name
is set and we are ready to go.
Apply Terraform code
Before we can run terraform to create the resources for us, we have to provide the API Token for Hetzner. There are several ways to do this but we will just export the token as an environment variable. If you take a look at the terraform provider documentation you will find the variable HCLOUD_TOKEN
.
$ export HCLOUD_TOKEN="<your-hcloud-token>"
For provisioning the infrastructure we do the following:
$ terraform init
$ terraform apply
The command terraform init
will initialize Terraform and download the provider. terraform apply
will prompt you for confirmation and then will create the infrastructure in only a few seconds. You now should see a JSON formatted output. This output will be used for filling KubeOne with information, on where to provision Kubernetes.
Configuring KubeOne and installing Kubernetes will be in Part 2 of this blog series. So stay tuned!
To get notified on the second part make sure to follow 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