Spin up your Kubernetes lab with OpenTofu for 20 cents

Published on: July 26, 2024 by Alex Carnesecchi


Introduction


For one of our projects, we needed an easy and fast way to spin up an environment in the cloud, run our application, and destroy it to avoid additional costs. Originally, we had $200 worth of credits, but after seeing how cost-efficient the process was, we realized we could achieve our goals for much less.


Kubernetes has become the go-to solution for managing containerized applications at scale, but mastering it can require hands-on experience. Creating a personal Kubernetes lab is an excellent way to gain this experience. In this article, we explore how to set up a Kubernetes lab on Digital Ocean in a way that is both budget-friendly and educational. Readers can expect to learn the step-by-step process to deploy their own Kubernetes cluster, manage resources effectively, and understand the pricing structure to keep costs around $0.20 every three hours.


Main Content


Section 1: How does it work?


I am not going to explain the benefits and differences Digital Ocean has compared to some major cloud providers like GCP or AWS, but we found it easy to navigate. In this article, you will find a OpenTofu code you can use to spin up this environment and an in-depth explanation of what is being created and how to expand it if needed.


Prerequisites


In order to create the environment and connect to your new cluster, you will need to create a DIGITALOCEAN_TOKEN environment variable with your token:


export DIGITALOCEAN_TOKEN=$my-secret-token


  • Have Terraform or OpenTofu installed on your machine: You can learn more about OpenTofu and it's uses here

  • Have kubectl to connect to the cluster

  • Have doctl to manage your DigitalOcean account and resources: You can get it from here.

  • Clone our example repository:

git clone https://gitlab.com/kubernetes-today/k8s-cheap-lab-digital-ocean.git

Section 2: Moving on to OpenTofu


We opted for a somewhat minimal approach for our case, but you can tune this to your liking.


Take your time, review the templates, and then update terraform.tfvars to fit your needs. There are some things you must consider:



  • name must be unique. We went with the default k8s-version-region-randomNumbers, but you can tune this to whatever you want. The same thing applies to the pool name.

  • region, version, and size must match the ones they offer. You can use doctl kubernetes options to get a list of possibilities.

  • node_count can go all the way to 1 node if you want to save costs.

Once you think you are ready to continue, run tofu plan to review, and then tofu apply. This process can take up to 10 minutes. In our latest test, we had to wait for 9 minutes.


digitalocean_kubernetes_cluster.myk8scluster: Still creating... [8m40s elapsed]
digitalocean_kubernetes_cluster.myk8scluster: Still creating... [8m50s elapsed]
digitalocean_kubernetes_cluster.myk8scluster: Still creating... [9m0s elapsed]
digitalocean_kubernetes_cluster.myk8scluster: Provisioning with 'local-exec'...
digitalocean_kubernetes_cluster.myk8scluster (local-exec): Executing: ["/bin/sh" "-c" "./configure_kubectl.sh k8s-1-29-6-do-fra1-myk8scluster"]

Once done, you can use kubectl get nodes to confirm that you are connected to your new cluster:


$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
pool-12345678-b7w86 Ready <none> 6m v1.29.6
pool-12345678-b7w8a Ready <none> 4m25s v1.29.6
pool-12345678-b7w8t Ready <none> 4m14s v1.29.6

This works because of the local-exec provisioners you can find in the digitalocean_kubernetes_cluster block. It will execute one script on successful apply and another on destroy. These are simple scripts that update your kubectl configuration.


You can discover more about kubectl in this related post about kubectl.


Section 3: Going one step further


Alright, we have a Kubernetes cluster we can connect to, very cool, but what can we do now?


We have configured a simple deployment of our own blog that we use to preview changes and a service of type load balancer to get an external IP. Just run:


kubectl apply -f app/deploy.yml
kubectl apply -f app/service.yml
watch -n1 kubectl get svc

And wait for your service to get an IP. This can take some minutes because it is creating a Load Balancer for your Kubernetes cluster in Digital Ocean.


Once the IP appears, copy it into your browser and enjoy your own version of our blog!
When you are done admiring the beautiful moving Kubernetes logo in the background, delete the resources and destroy the cluster.



⚠️⚠️ It is very important that you first delete the resources before destroying the cluster, otherwise the load balancer the service created will not be deleted and will be billed ⚠️⚠️



kubectl delete -f app/
tofu destroy

And that's all for today's post. We are planning to make this the start of a series on customizing and managing a Kubernetes cluster, so stay tuned for that.