A step-by-step guide to get rancher/k3s running inside an LXC container.
This guide is an alternative to minikube which also offers a local kubernetes environment. The advantage of the LXC approach is that everything runs natively on the host kernel without any virtualization costs from a Virtual Machine. For example, minikube causes such high CPU usage on the host (see minikube issue #3207), that development is impaired. The downside is more setup work to get the kubernetes environment running, its administration costs, and lower isolation of the kubernetes cluster.
Below, you find a step-by-step guide to setup an LXC container and install rancher/k3s on it.
Lxc is similar to docker but aims more to be an OS container instead of just application containers.
To use it, install lxd and initialize it using lxd init. When prompted, answer the following questions:
- Would you like to use LXD clustering? (yes/no) [default=no]:
- Do you want to configure a new storage pool? (yes/no) [default=yes]: yes -> dir (any directory based provider should work)
- Would you like to connect to a MAAS server? (yes/no) [default=no]:
- Would you like to create a new local network bridge? (yes/no) [default=yes]:
- What should the new bridge be called? [default=lxdbr0]:
- What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
- What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
- Would you like LXD to be available over the network? (yes/no) [default=no]: no
- Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
- Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
-
Before you can fire up your lxc container, you have to make sure to create
/etc/subuidand/etc/subgidwith the following entries:root:1000000:1000000000 <youruserid>:1000000:1000000000Run
systemctl restart lxdto have LXD detect your new maps. -
As the base system for our kubernetes we will use Debian and call the lxc machine
k3s-lxc. Now create your kubernetes host machine withlxc launch images:debian/10 k3s-lxcRun
lxc listto ensure that your machinek3s-lxcis up and running.Note: To get an overview over the supported base images, run
lxc image list images: -
Usual lxc containers are quite restricted in their capabilities. Because k3s needs to set up nested containers, it is required to give the lxc container the capabilities to manage networking configuration and create cgroups. For that, run
lxc config edit k3s-lxcand merge in the following settings:config: linux.kernel_modules: ip_tables,ip6_tables,netlink_diag,nf_nat,overlay raw.lxc: lxc.mount.auto=proc:rw sys:rw security.privileged: "true" security.nesting: "true"
kernel_modules: depending on the kernel of your host system, you need to add further kernel modules here. The ones listed above are for networking and for dockers overlay filesystem.raw.lxc: this configures lxc to make container configuration inside the lxc container possible.security.privilegedandsecurity.nesting: for a privileged container which may create nested cgroups
Below, some commands will need to be executed inside the lxc container and others on the host.
- $-prefix means to be executed on the host machine.
- @-prefix means to be executed inside the lxc container.
To enter the container as root, do
$ lxc exec k3s-lxc /bin/bash. - no prefix means it does not matter where the command is executed.
-
On your host, ensure that
$ conntrack -Lproduces some output (this means it works). If this requires additional kernel modules to be loaded, add those to the lxc container config. For example you might need to add in$ lxc config edit k3s-lxcconfig: linux.kernel_modules: xt_conntrack,...
-
Pull
k3son your host system, and push it into the container:$ curl -Lo k3s https://github.com/rancher/k3s/releases/download/v0.9.1/k3s $ chmod +x k3s $ lxc file push k3s k3s-lxc/usr/local/bin/k3s
-
Install
ca-certificatesin k3s-lxc.@ apt-get install -y ca-certificates
If you skip this, image pulling will not work due to certificate validation errors.
-
Newer versions of k3s want to read from
/dev/kmsgwhich is not present in the container. You need to instruct systemd to always create a symlink to/dev/consoleinstead:@ echo 'L /dev/kmsg - - - - /dev/console' > /etc/tmpfiles.d/kmsg.conf
-
Restart your lxc container with
$ lxc restart k3s-lxc
If this does not work, try the hard way
$ lxc exec k3s-lxc reboot -
Now it is time to try out if
k3sruns in your container:@ k3s server
Congratulations, if the last command worked, you now have k3s/kubernetes running in your lxc container.
If this isn't working, you need to trouble-shoot. Then stop
k3s(Ctrl+C). -
Automatically start
k3swhen the container starts. Run@ systemctl edit --force --full k3s.serviceand paste the the content of the
k3sunit file and remove theEnvironmentFileline. Finally, enable the unit with@ systemctl enable k3s @ systemctl start k3s
-
On your host machine, add a host entry to access your
k3s-lxccontainer by DNS name. Find out the IP of your lxc container by running$ lxc list k3s-lxc. Add its IP in/etc/hosts<k3s-lxc-ip> k3s-lxcAfter that, it should be possible to ping the container with
ping k3s-lxc. -
Set up a kubectl context on your host system to talk to your
k3sinstallation in the lxc container:$ lxc file pull k3s-lxc/etc/rancher/k3s/k3s.yaml . $ sed -i 's:127.0.0.1:k3s-lxc:;s:default:k3s-lxc:g' k3s.yaml $ KUBECONFIG=~/.kube/config:k3s.yaml kubectl config view --raw > config.tmp $ mv config.tmp ~/.kube/config $ kubectl config use-context k3s-lxc
The third line does some magic to merge the rancher config into your existing
KUBECONFIGfile. -
(Optional) Check if everything is running correctly by deploying a small test application
kubectl apply -f src/test-k3s-lxc.yaml
You should be able to access the application from your browser http://k3s-lxc.
If that does not work, try to access the test service from within your kubernetes network.
$ kubectl run --generator=run-pod/v1 -ti --image nicolaka/netshoot curl > curl test # should fetch a minimal greeting Ctrl-D $ kubectl delete pod curl
- Start your lxc container with
lxc start k3s-lxc - Show your running container with its IP
lxc list - Open a privileged shell in your container with
lxc exec k3s-lxc /bin/bash