Install K8s on Bare Metal or Hypervisor
Prepare the nodes
My setup will be four VMs:
kube-admin
- Control plane/master nodekube-0
- Compute node #1kube-1
- Compute node #2kube-2
- compute node #3
I can generate them using my kvmgr tool:
kvmgr.sh -c 2 -m 2048 -d 10G -o focal -n kube-admin
kvmgr.sh -c 2 -m 2048 -d 20G -o focal -n kube-0
kvmgr.sh -c 2 -m 2048 -d 20G -o focal -n kube-1
kvmgr.sh -c 2 -m 2048 -d 20G -o focal -n kube-2
After the VMs are up, add the IPs to /etc/hosts
192.168.122.42 kube-admin
192.168.122.89 kube-0
192.168.122.11 kube-1
192.168.122.102 kube-2
Kernel config
This procedure is run on all four nodes before installing kubernetes.
Configure the bridge module to load on every boot:
sudo modprobe br_netfilter
Configure the network stack to bridge correctly:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
Install Containerd
Containerd is the docker runtime for this setup.
sudo apt install -y containerd
Install Kubelet
First, install the prereqs for HTTPS repositories:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
Import the k8s keyring:
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
Add the Apt repo:
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-focal main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
Install the packages on the server:
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
Optionally, pin the current package versions to prevent upgrades.
sudo apt-mark hold kubelet kubeadm kubectl
Install admin node tools
Create a kubeadm-config.yaml file:
# kubeadm-config.yaml
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta2
kubernetesVersion: v1.21.0
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
Begin the init process:
sudo kubeadm init --pod-network-cidr="10.99.0.0/16"
This take a few minutes to start the kubelet.
When the command completes successfully:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Check the cluster status:
$ kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2m23s
Adding a node to the cluster
This command needs to be run on the rest of the nodes, kube-0
, kube-1
, kube-2
.
kubeadm join 192.168.122.42:6443 --token d3elti.x8dheeghld76txud \
--discovery-token-ca-cert-hash sha256:4dc30c96de01f73c26ea645fbf34e45822c232c04fb1df58aca3a58df7c9b827
Install Calico
Calico provides the pod network abstraction layer for this cluster.
Install it from the manifest:
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
Check status:
kubectl get pods -n kube-system
At this point the system should be ready:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-0 Ready <none> 8m19s v1.21.0
kube-1 Ready <none> 7m35s v1.21.0
kube-2 Ready <none> 7m2s v1.21.0
kube-admin Ready control-plane,master 32m v1.21.0
The cluster is now complete, though barebones. Additional considerations should be made for shared storage and load balancing.