Kubernetes on a single machine
by Camille Rodriguez on 17 October 2019
As developers, we do not always have access to a production-like environment to test new features and run proof-of-concepts. This is why it can be very interesting to deploy Kubernetes on a single machine. Of course, there is the new microk8s snap that allows a super fast deployment of a k8s cluster on a laptop (and it is definitely worth a try, look here to see how I deployed and tested it in just a few minutes), but if you’re looking for the full experience, here’s how I deployed the Charmed Distribution of Kubernetes on LXD containers in a single bare-metal machine.
Note: This is an adaptation of Michael Iatrou’s post with the newer LXD version 3.18 and Ubuntu 18.04 Bionic Beaver.
You will need a machine equipped with at least 4 CPU cores, 16GB RAM,100GB free disk space, preferably SSD and one NIC. I am using MAAS to deploy Ubuntu 18.04.3 LTS on a machine. I configured a Linux bridge (br0) and attached one NIC (eno1) to it. Here is the /etc/netplan/config.yaml configuration of my machine.
$ cat /etc/netplan/config.yaml
network:
bridges:
br0:
addresses:
- 172.16.7.50/24
gateway4: 172.16.7.1
interfaces:
- eno1
macaddress: 2c:60:0c:f9:3c:23
mtu: 1500
nameservers:
addresses:
- 10.246.96.1
search:
- maas
parameters:
forward-delay: 15
stp: false
ethernets:
eno1:
match:
macaddress: 2c:60:0c:f9:3c:23
mtu: 1500
set-name: eno1
First step is to SSH into our machine and download the various components needed for this task. Juju and LXD are now available with snaps, which is the recommended way to deploy these tools.
$ sudo apt update
$ sudo apt dist-upgrade -y
$ sudo snap install juju --classic
$ sudo snap install lxd
We get the Juju version 2.6.9-bionic-amd64 and the LXD version 3.18. The next step is to launch the LXD init to set it up.
$ /snap/bin/lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want ot configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, ceph, dir, lvm, zfs) [default=zfs]: dir
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]: no
Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]: yes
Name of the existing bridge or host interface: br0
Would you like LXD to be available over the network? (yes/no) [default=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]:
We can now bootstrap our local Juju controller with LXD. Juju is the tool with which we will deploy a Kubernetes environment.
$ juju bootstrap lxd lxd-local
If this command ran successfully, you should get a message saying that a controller was launched on localhost/localhost, and that an initial model “default” has been added. You can double check by looking at the output of these two following commands.
$ juju controllers
Use --refresh option with this command to see the latest information.
Controller Model User Access Cloud/Region Models Nodes HA Version
lxd-local* default admin superuser localhost/localhost 3 1 none 2.6.9
$ juju models
Controller: lxd-local
Model Cloud/Region Type Status Machines Cores Units Access Last connection
controller localhost/localhost lxd available 1 - - admin just now
default* localhost/localhost lxd available 0 - - admin 20 hours ago
And you can see that the controller that was spawned is listed in the lxc container list.
$ lxc list
Great! Now, we need to create a new model for our Kubernetes deployment:
$ juju add-model kubernetes
$ juju models
Controller: lxd-local
Model Cloud/Region Type Status Machines Cores Units Access Last connection
controller localhost/localhost lxd available 1 - - admin just now
default localhost/localhost lxd available 0 - - admin 20 hours ago
kubernetes* localhost/localhost lxd available 0 - - admin 59 minutes ago
For our Kubernetes machines, we need to create a LXD profile that enables privilege machine containers and add an SSH key to it. Create a new YAML file juju-lxd-profile.yaml
with the following configuration:
name: juju-kubernetes
config:
user.user-data: |
#cloud-config
ssh_authorized_keys:
- @@SSHPUB@@
boot.autostart: "true"
linux.kernel_modules: ip_tables,ip6_tables,netlink_diag,nf_nat,overlay
raw.lxc: |
lxc.apparmor.profile=unconfined
lxc.mount.auto=proc:rw sys:rw
lxc.cap.drop=
security.nesting: "true"
security.privileged: "true"
description: ""
devices:
aadisable:
path: /sys/module/nf_conntrack/parameters/hashsize
source: /dev/null
type: disk
aadisable1:
path: /sys/module/apparmor/parameters/enabled
source: /dev/null
type: disk
Make sure that you have generated an SSH key pair for user “ubuntu”, before you execute the following one-liner:
$ sed -ri "s'@@SSHPUB@@'$(cat ~/.ssh/id_rsa.pub)'" juju-lxd-profile.yaml
Then update the juju-kubernetes LXD profile:
$ lxc profile edit "juju-kubernetes" < juju-lxd-profile.yaml
Finally, deploy Kubernetes!
$ juju deploy charmed-kubernetes
At the time of writing this post, it is the version charmed-kubernetes-798 that was fetched and deployed. You can watch the status of each component as they get installed via the following:
When everything is green, active and idle, your deployment is ready to be used!
Note: if you are deploying on a machine behind a proxy, check this out! You will need to set the proxy in the Juju model and for some specific components.