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.