Skip to content

Install and set up

Install a new Linux server with Docker

  • Create a new remote VPS ("virtual private server").
  • Deploy the latest Ubuntu LTS ("long term support") version. At the time of this writing it's Ubuntu 20.04.
  • Connect to it via SSH, e.g.:
ssh root@
  • Define a server name using a subdomain of a domain you own, for example
  • Make sure the subdomain DNS records point to your VPS's IP address. Either all the desired subdomains, or use a wildcard. An A record from * to the VPS IP would work.
  • Create a temporal environment variable with the name of the host to be used later, we will also set the email to be used with letsencrypt (using a fake/testing email here might cause it to fail) as well as the version of this guide. Remember to set it to the latest version.

  • Set up your domain

  • Set up your email
  • Set up the server hostname if necessary:
# Set up the server hostname
echo $USE_HOSTNAME > /etc/hostname
hostname -F /etc/hostname

Note: If you are not a root user, you might need to add sudo to these commands. The shell will tell you when you don't have enough permissions. Note that sudo does not preserve environment variables by default, but this can be enabled via the -E flag.

  • Update packages:
# Install the latest updates, open-iscsi for longhorn and wireguard
apt update && \
apt upgrade -y && \
apt install open-iscsi -y && \
apt install wireguard -y

Get manifests / repo

Note: You can just copy paste these manifests as you please, but to follow along with this guide, it is conveniant to have them on disk.

git clone

Get tools

These tools can be on any machine, including your local. But it needs to have kubectl installed. If you have activated kubernetes in your docker desktop installation, you already have it. Kubectl is optional but recommended. The bash snippet below installs arkade and uses it to install the other tools. Its fine for testing, but for your local machine i would consider installing them separately.

  • Install Arkade + Helm + Kubectl autocomplete
curl -sLS | sh && \
arkade get helm && \
mv /root/.arkade/bin/helm /usr/local/bin/ && \
arkade get kubectl && \
mv /root/.arkade/bin/kubectl /usr/local/bin/ && \
source <(kubectl completion bash) && \
echo "source <(kubectl completion bash)" >> ~/.bashrc

In K3S you have one or more "master" nodes and one or more "worker" nodes, but the manager nodes can also run workloads. For a high availability set up, it is often recommended to use 3 master nodes, but a single node will be fine for testing.

The first step is to configure one (or more) manager nodes.

First master

Note: Remember to have your environment variables set!

Not that we also alter the default deployment of the traefik ingress controller, see helm chart values for all the other options. Even K3S internally uses a helmchartconfig, changes can be applied with vanilla kubectl as we do here.

Goto manifests folder


Install k3s

# Remeber to have your environment variables set!
curl -sfL | INSTALL_K3S_VERSION=v1.21.0+k3s1 sh -s server --cluster-init --flannel-backend=wireguard && \
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml  && \
cat traefik-config.yaml | envsubst | kubectl apply -f -

Add longhorn (optional)

kubectl apply -f

Get the token (Optional)

This token is only needed if you would like to join more masters and workers to the cluster. (There are more secure ways to do this, but its fine for testing)

cat /var/lib/rancher/k3s/server/node-token

Additional masters (optional)

  • Set the environment variables
export K3S_TOKEN=<Token from master>
export MASTER_IP=<master node IP>
  • Run the installer
curl -sfL | INSTALL_K3S_VERSION=v1.21.0+k3s1 K3S_TOKEN="${K3S_TOKEN}" sh -s server --flannel-backend=wireguard --server https://${MASTER_IP}:6443

Add worker nodes (optional)

  • Set the environment variables
export K3S_TOKEN=<Token from master>
export MASTER_IP=<master node IP>
curl -sfL | INSTALL_K3S_VERSION=v1.21.0+k3s1 K3S_TOKEN="${K3S_TOKEN}" K3S_URL=https://${MASTER_IP}:6443 sh -

Check the cluster

kubectl get nodes

Should output something like this (if you start with one master and add another master):

NAME   STATUS   ROLES                       AGE     VERSION
m1     Ready    control-plane,etcd,master   3m26s   v1.20.6+k3s1   
m2     Ready    control-plane,etcd,master   17s     v1.20.6+k3s1   


That's it. You have a single or multi node kubernetes cluster set up.

Continue with the guide to see how to set up some sample applications, basic auth, HTTPS etc.