Provide K3S Cluster by Terraform

Anh Duong Viet
3 min readJun 18, 2021

In recent years, the market for lightweight Kubernetes has been quite active with a series of names such as minikube, kind, k3s or most recently microk8s (developed by Canonical). The advantage of lightweight k8s is that it is light, the configuration is relatively simple, suitable for small and medium projects, or as a test environment, and the cost is also cheaper than deploying K8S on other cloud services like GKE or EKS.

But the most prominent thing is still K3S, developed by Rancher. The advantages of K3S come from simple installation and super flexible scalability.

There are quite a few ways to deploy a k3s cluster. You can climb each node to configure, install with Ansible, or use another tool like k3sup,... But basically, you need to provide your own infrastructure, configure the network, …
To simplify this, I created a repo that uses Terraform to automatically provision a private cluster on Google Cloud Platform. Simply put, it will help you do it all from creating VMs, configuring networks, firewalls, installing K3S and so on.
To be able to run and use this repo requires you to be familiar with Terraform, Kubernetes, GCP.

Prerequisite

You need to install the following before you start creating your own k3s cluster.

  • Terraform: is a tool to help you describe your complete infrastructure as code and build resources across providers. You can get the installation document in here.
  • GCloud SDK: just an SDK written by Google to help you interact with GCP by CLI. The installation document in here.
  • Kubectl: The Kubernetes command-line tool, allows you to run commands against Kubernetes cluster. You can install Kubectl follow by this document.

Installation

After installing the above tools, the next thing you need to do is clone my repo.

$ git clone https://github.com/vietanhduong/terraform-k3s.git

Terraform needs your Google credential to be able to deploy the infrastructure. There are many ways to provide Google credential, you can read here. But the easiest way is to log in with the GCloud SDK that you just installed above.

$ gcloud auth application-default login

Next, go to the cluster directory to prepare to deploy the cluster.

$ cd ./cluster

Before deploying the cluster, you need to provide some necessary information (variables) to configure your cluster.

$ touch variables.auto.tfvars

In the variables.auto.tfvars file you just created, you need to provide some following information.

# variables.auto.tfvarsproject_id           = "your_gcp_project_id" # requiredgroup_name           = "your_cluster_name" # requiredmachine_type         = "machine_type" # optional - default is e2-mediumzone                 = "vm_zone" # optional - default is asia-southeast1-bregion               = "vm_region" # optional - default is asia-southeast1boot_image           = "os_image" # optional - default is ubuntu-os-cloud/ubuntu-1804-ltsdisk_size            = 50 # optional - default is 50 ssh_key              = "you_public_key" # optional - ssh key must be formatted: [username]:[public_key]total_node           = 2 # optional - total worker node. Default is 2ip_cidr_range        = "private_ip_range" # required - e.g: 10.0.0.0/16ip_cidr_second_range = "second_private_ip_range" # required - e.g: 10.1.0.0/16allowed_ip           = [] # optional - allowed IPs to master node.

After you provide your variables, you run the following commands.

$ terraform init # download require libraries$ terraform plan # preflight

$ terraform apply -auto-approve # provide your cluster without your confirmation.

After executing the above commands, you have finished creating a k3s cluster.

To get kubeconfig, you access the master node by ssh and copy kubeconfig in the following path and paste it into your kubeconfig.

$ sudo cat /etc/rancher/k3s/k3s.yaml

Note that this kubeconfig server address will be the private IP of the master node. You need to replace it with the public IP of the master node in kubeconfig under your client by editing the address at clusters.cluster.server .

Now you will see it look like https://10.0.0.x:6443 you need to change it to https://{MASER_PUBLIC_IP}:6443.

To check the results:

$ kubectl get nodes

The result will look like this

NAME           STATUS     ROLES      AGE     VERSION
k3s-master Ready master 5m1s v1.18.8+k3s1
k3s-agent1 Ready <none> 3m3s v1.18.8+k3s1
k3s-agent2 Ready <none> 2m12s v1.18.8+k3s1

Good luck and enjoy your cluster!

--

--

Anh Duong Viet

I’m a Software / DevOps engineer. My main is focus on maintain and maintain and ensure the stability of the infrastructure.