DEV Community

Cover image for Automate homelab microK8s cluster provisioning with Vagrant and Ansible
Caio Campos Borges Rosa
Caio Campos Borges Rosa

Posted on

Automate homelab microK8s cluster provisioning with Vagrant and Ansible

Getting quick feedback is essential while developing. When it comes to setting up infrastructure, it often involves tons of scripting and is good to have a simple workflow you can iterate on. This tutorial is all about giving you a solid head start if you're itching to dive into DevOps and build your own homelab. We'll be installing microk8s, a fully compliant and up-to-date Kubernetes distribution that boasts minimal machine requirements.

To manage our VMs we will use Vagrant, its a complete cli tool to manage virtual machines and provides a simple but complete workflow. Vagrant is very good at giving us a context to our project, instead of configuring each VM individually and running provisioning scripts against them we have one declarative file that describe the project.

Vagrant installation

$ brew install virtualbox $ brew cask install vagrant 
Enter fullscreen mode Exit fullscreen mode

Vagrantfile

Vagrant uses a Vagrantfile to describe the machines the project is going to need. Here we will have our provisioning script that will install update repositories, install Ansible, and setup host records. For each machine we describe we will run the provisioning script when we call "vagrant up ".

# -*- mode: ruby -*- # vi: set ft=ruby : $script = <<-SCRIPT apt-get update apt-get install -y ansible sshpass echo "192.168.56.11 controller" >> /etc/hosts echo "192.168.56.12 node-1" >> /etc/hosts SCRIPT Vagrant.configure("2") do |config| config.vm.define "controller" do |controller| controller.vm.box = "ubuntu/focal64" controller.vm.network "private_network", ip: "192.168.56.11" controller.vm.hostname = "controller" controller.vm.provider "virtualbox" do |vb| vb.memory = "2048" end controller.vm.provision "shell", inline: $script end config.vm.define "node1" do |node1| node1.vm.box = "ubuntu/focal64" node1.vm.network "private_network", ip: "192.168.56.12" node1.vm.hostname = "node1" node1.vm.provider "virtualbox" do |vb| vb.memory = "1024" end node1.vm.provision "shell", inline: $script end end 
Enter fullscreen mode Exit fullscreen mode

NOTE: if you need a ip range out of vagrant default '192.168.56.0/21', create a file '/etc/vbox/networks.conf' and add the line with the range you need. Ex: * 192.168.32.0/24.

Next we call vagrant up:

$ vagrant up controller 
Enter fullscreen mode Exit fullscreen mode

If you already run and need to make changes to any VM described in the Vagrantfile, run the command again with the flag --provision, that will run the provisioning script again for the targeted VM.

Ansible playbook

For k8s provisioning we will be using a Ansible. Ansible is a powerful automation to provision and manage resources, we can automate rolling updates and state management of our deployments in a declarative file. Here we will use in its simplest form to install microk8s and add alias to kubectl and completion using a playbook.

--- - name: Install Microk8s hosts: localhost gather_facts: false become: true tasks: - name: Install microk8s snap: name: microk8s state: present classic: yes - name: Add alias to kubectl become: false lineinfile: path: '{{ lookup("env", "HOME") }}/.bashrc' regexp: '^alias kubectl=' line: 'alias kubectl="microk8s kubectl"' state: present - name: Add bash completion for kubectl become: false lineinfile: path: '{{ lookup("env", "HOME") }}/.bashrc' regexp: '^source \<\(kubectl' line: 'source <(kubectl completion bash)' state: present 
Enter fullscreen mode Exit fullscreen mode

Now we just need to access the vm using ssh, Vagrant already setup a user with ssh access to the machines, so we only need to run:

vagrant ssh controller 
Enter fullscreen mode Exit fullscreen mode

Ansible is already installed, we did that in the provisioning script so now we only need to run the playbook:

$ ansible-playbook /vagrant/homelab-microk8s.yml 
Enter fullscreen mode Exit fullscreen mode

After ansible finish to run the playbook, we need to source the .bashrc, you can just log out wait 2s and log back in with vagrant ssh:

$ exit $ vagrant ssh controller 
Enter fullscreen mode Exit fullscreen mode

Now you can use kubectl with completion and get info of the services running:

$ kubectl get nodes NAME STATUS ROLES AGE VERSION controller Ready <none> 60m v1.28.3 
Enter fullscreen mode Exit fullscreen mode
$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-node-sfngb 1/1 Running 0 61m kube-system coredns-864597b5fd-drm79 1/1 Running 0 60m kube-system calico-kube-controllers-77bd7c5b-vnx5j 1/1 Running 0 60m 
Enter fullscreen mode Exit fullscreen mode

references:
https://developer.hashicorp.com/vagrant/docs/vagrantfile
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html

Here you will find a repo with the files used in this guide.

Photo by Jordan Harrison on Unsplash

Top comments (1)

Collapse
 
sibelius profile image
Sibelius Seraphini

how to install virtualbox on m1 ?