Skip to main content

Local K3s Cluster Made Easy With Multipass

Luc Juggery

Nov 8, 2019 · 4 min read · source

A couple of weeks ago, I stumble upon Multipass, a tool that allows you to spin up Ubuntu VMs in a matter of seconds on a Mac, Linux, or Windows workstation.

Depending upon your OS, Multipass uses Hyper-V, HyperKit, KVM, or VirtualBox natively for the fastest startup time.

In this short article, we’ll set up a K3s Kubernetes cluster on virtual machines created with Multipass.

Getting Multipass​

Just head up to Multipass, and download the binary for your platform. Once installed, you can get the list of the available commands. We’ll only use a couple of them in this article.

$ multipass  
Usage: multipass \[options\] <command>
Create, control and connect to Ubuntu instances.This is a command line utility for multipass, a
service that manages Ubuntu instances.Options:
-h, --help Display this help
-v, --verbose Increase logging verbosity, repeat up to three times for more
detailAvailable commands:
delete Delete instances
exec Run a command on an instance
find Display available images to create instances from
get Get a configuration option
help Display help about a command
info Display information about instances
launch Create and start an Ubuntu instance
list List all available instances
mount Mount a local directory in the instance
purge Purge all deleted instances permanently
recover Recover deleted instances
restart Restart instances
set Set a configuration option
shell Open a shell on a running instance
start Start instances
stop Stop running instances
suspend Suspend running instances
transfer Transfer files between the host and instances
umount Unmount a directory from an instance
version Show version details

Creation of the VMs​

First, we create three VMs, keeping the default configuration of one CPU and 1GB RAM.

$ multipass launch -n node1  
$ multipass launch -n node2
$ multipass launch -n node3

Next, we verify the three VMs are in the running state

$ multipass list  
Name State IPv4 Image
node3 Running 192.168.64.13 Ubuntu 18.04 LTS
node2 Running 192.168.64.12 Ubuntu 18.04 LTS
node1 Running 192.168.64.11 Ubuntu 18.04 LTS

Note: In this example, I use Multipass on MacOS, so the VMs are run on HyperKit as I can confirm listing the HyperKit-related processes.

luc@saturn:~$ ps aux | grep -i "\[h\]yperkit"  
... com.docker.hyperkit ...
... com.canonical.multipass/bin/hyperkit...
... com.canonical.multipass/bin/hyperkit...
... com.canonical.multipass/bin/hyperkit...

Among those processes, the first one is the Docker daemon already running on my machine. The next three are the VMs created above.

Initialize K3s on node1​

First, we run a command on node1 (using the exec subcommand of Multipass) to install K3s as defined in the documentation.

$ multipass exec node1 -- \  
bash -c "curl -sfL https://get.k3s.io | sh -"

Note: The K3s initialisation took less than 30 seconds … really impressive for a certified Kubernetes distribution.

Then, from the local machine, we gather the elements we’ll need to add additional nodes to the cluster:

  • The token to join the cluster
$ TOKEN=$(multipass exec node1 sudo cat /var/lib/rancher/k3s/server/node-token)
  • The IP of the API server running on node1
$ IP=$(multipass info node1 | grep IPv4 | awk '{print $2}')

Join node2 and node3 to the Cluster​

From the local machine, we run the following commands to add node2 and node3 to the cluster.

# Joining node2
$ multipass exec node2 -- \
bash -c "curl -sfL https://get.k3s.io | K3S_URL=\"https://$IP:6443\" K3S_TOKEN=\"$TOKEN\" sh -"
# Joining node3
$ multipass exec node3 -- \
bash -c "curl -sfL https://get.k3s.io | K3S_URL=\"https://$IP:6443\" K3S_TOKEN=\"$TOKEN\" sh -"

As we can see, those commands use the TOKEN and IP address we defined above.

Get the Cluster Configuration​

Running the following command, we can list all the nodes of the cluster:

$ multipass exec node1 -- sudo kubectl get nodes  
NAME STATUS ROLES AGE VERSION
node1 Ready master 5m31s v1.16.2-k3s.1
node3 Ready <none> 21s v1.16.2-k3s.1
node2 Ready <none> 45s v1.16.2-k3s.1

To access the cluster’s API server from our local machine, we only need to get the kubeconfig file created on node1 during the setup.

$ multipass exec node1 sudo cat /etc/rancher/k3s/k3s.yaml > k3s.yaml

We then need to change the server key so it references the remote IP address of node1 instead of the localhost.

sed -i '' "s/127.0.0.1/$IP/" k3s.yaml

Finally, we configure our local kubectl so it uses the kubeconfig file (k3s.yaml) we’ve just retrieved. A simple way is to set the KUBECONFIG environment variable so it points towards the configuration file.

export KUBECONFIG=$PWD/k3s.yaml

We’re all set, we can now communicate with the cluster from your local machine.

$ kubectl get nodes  
NAME STATUS ROLES AGE VERSION
node1 Ready master 10h v1.16.2-k3s.1
node2 Ready <none> 10h v1.16.2-k3s.1
node3 Ready <none> 10h v1.16.2-k3s.1

Note: all the steps defined in this post can be run from the following gist:

https://gist.github.com/lucj/5a0e2286b40130d02388a264e6924ed4

Summary​

Multipass is a very useful tool. Its integration with low-level hypervisors makes it a good choice to deploy multiple VMs locally and to play with many distributed solutions such as the great K3s Kubernetes distribution.

Responses (4)​

Yohannes Russom​

11 months ago​

2

Thank you ,

I am facing an issue with kubectl command not found` and i guess its becuase the k3s deployment didnt get succeded.

Zulhilmi Zainudin​

6 months ago​

Hi. I’m curious, why you put “h” in square brackets for this command? ps aux | grep -i “\[h\]yperkit”

Scott Lett​

7 months ago​

Nice work!

On my Ubuntu box, the the sed command doesn’t work unless I add “-e” before the substitution expression.

Praveen Shastrula​

3 months ago​

Very simple and completely automated. Thank you! (I followed a different article first, but it had some missing instruction and crashed my nodes!, but yours works!)

You have 2 free member-only stories left this month.​