I’ve been setting up and tearing down Kubernetes clusters for testing various things for the past year, mostly using Vagrant/Virtualbox but also some VMware vSphere and OpenStack deployments.
I wanted to set something a little more permanent up at my home lab — a cluster where I could add and remove nodes, run nodes on multiple physical machines, and use different types of compute hardware.
Set up the virtual machines
To get started I used a desktop System76 Wild Dog Pro Linux box (4.5 GHz i7-7700K, 64GB DDR4) and my create-vm script to create six Ubuntu 18.04 “Bionic Beaver” VMs for the cluster:
for n in $(seq 1 6); do
create-vm -n node$n \
-i ./ubuntu-18.04-server-amd64.iso \
-k ./ubuntu.ks \
-r 4096 \
-c 2 \
-s 40
done
With these parameters each VM will have 4GB RAM, 2 VCPUs, and a 40GB hard drive.
Install and configure Kubespray
I cloned Kubespray into a directory and created an Ansible inventory file following the instructions from the README.
git clone git@github.com:kubernetes-sigs/kubespray.git
cd kubespray
pip install -r requirements.txt
rm -Rf inventory/mycluster/
cp -rfp inventory/sample inventory/mycluster
declare -a IPS=($(for n in $(seq 1 6); do get-vm-ip node$n; done))
CONFIG_FILE=inventory/mycluster/hosts.ini \
python3 contrib/inventory_builder/inventory.py ${IPS[@]}
The
get-vm-ip
script is in the same repo as thecreate-vm
script, and both are described in my Use .iso and Kickstart files to automatically create Ubuntu VMs article.
The inventory.py
script generates an Ansible hosts inventory file in inventory/mycluster/hosts.ini
with all of your VM IP addresses.
I like to add one variable override to the bottom of hosts.ini
which copies the kubectl
credentials over to my host machine. That way I can run kubectl
commands directly from my desktop. The extra lines to add to the bottom of hosts.ini
are:
[all:vars]
kubectl_localhost=true
Install Kubernetes
To install Kubernetes on the VMs I run the Kubespray cluster.yaml
playbook:
export ANSIBLE_REMOTE_USER=ansible
ansible-playbook -i inventory/mycluster/hosts.ini \
--become --become-user=root cluster.yml
Once the playbooks have finished, you should have a fully-operational Kubernetes cluster running on your desktop.
At this point you should be able to query the cluster from your desktop using kubectl
. For example:
$ kubectl cluster-info
Kubernetes master is running at https://192.168.122.251:6443
coredns is running at https://192.168.122.251:6443/api/v1/namespaces/kube-system/services/coredns:dns/proxy
kubernetes-dashboard is running at https://192.168.122.251:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
node1 Ready master,node 3d6h v1.13.0
node2 Ready master,node 3d6h v1.13.0
node3 Ready node 3d6h v1.13.0
node4 Ready node 3d6h v1.13.0
node5 Ready node 3d6h v1.13.0
node6 Ready node 3d6h v1.13.0
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-67f89845f-6zbvx 1/1 Running 1 3d6h
kube-system calico-node-jh7ng 1/1 Running 2 3d6h
kube-system calico-node-l9vfb 1/1 Running 2 3d6h
kube-system calico-node-mqxjx 1/1 Running 2 3d6h
...
Set up the Kubernetes Dashboard
One of the first things I like to do is set up access to the Kubernetes dashboard. First I set up a service account for the admin user:
$ cat ~/Projects/k8s-cluster/dashboard-adminuser.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
$ kubectl apply -f ~/Projects/k8s-cluster/dashboard-adminuser.yaml
Next I get the bearer token for the user account:
$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
Finally I plug the dashboard URL that I got from kubectl cluster-info
into my browser, select “Token” authentication, and cut and paste in the bearer token to log into the system.
Once logged in, an overview of my cluster pops up:
With a minimal amount of working compute infrastructure, it’s easy to set up your own production-quality Kubernetes cluster using Kubespray.
Hope you find this useful.
Very cool stuff Earl!!! I don’t know the language but understand…. looks like a great pet-time consultant opportunity for fun! My brain only understands binary arguments!
there is kind of a syntax error in your yaml above, it should be
“`
subjects:
– kind: ServiceAccount
name: admin-user
namespace: kube-system
“`
so ‘kind’ is an array under subjects
and name and namespace should be indented by two
Thanks! Good catch. My original code is correct, must have been a cut-n-paste problem when I pasted the code into WordPress. I have corrected the code above.