Install Kubernetes on Arch (containerd)

Warning

This is not a step-by-step installation guide for beginners. This article assumes you have some previous experience with Linux and Kubernetes.

Install some needed utilities

pacman -S --noconfirm conntrack-tools containerd ebtables ethtool socat

Disable swap space. In systemd, also

{
swapoff -a
sed -e '/swap/ s/^#*/#/' -i /etc/fstab
}

list swap files in systemd. In my case it listed dev-sda2

systemctl --type swap --all
{
systemctl stop 'dev-sda2.swap'
systemctl mask 'dev-sda2.swap'
}

Set some kernel parameters

{
modprobe br_netfilter
sysctl net.bridge.bridge-nf-call-iptables=1
sysctl net.ipv4.ip_forward=1
echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf
echo "net.bridge.bridge-nf-call-iptables=1" > /etc/sysctl.d/br_netfilter.conf
echo "net.bridge.bridge-nf-call-ip6tables=1" >> /etc/sysctl.d/br_netfilter.conf
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/ip_forward.conf
}

Configure containerd

{
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
systemctl enable containerd --now
}

Download the latest kubernetes binaries

{
RELEASE="$(curl -sSL https://dl.k8s.io/release/stable.txt)"
ARCH="amd64"
cd /usr/local/bin
curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/${ARCH}/{kubeadm,kubelet,kubectl}
chmod +x {kubeadm,kubelet,kubectl} && cd
}

Add kubectl completion and alias

{
cat >> ~/.zshrc <<EOF
source <(kubectl completion zsh)
alias -g k=kubectl
complete -F __start_kubectl k
EOF
source ~/.zshrc
}

Download the latest container network interface

{
CNI_VERSION="v1.1.1"
mkdir -p /opt/cni/bin
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz" | tar -C /opt/cni/bin -xz
}

Download the latest CRI utilities

{
CRICTL_VERSION="v1.24.2"
curl -L "https://github.com/kubernetes-incubator/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-amd64.tar.gz" | tar -C /usr/local/bin -xz
}

Create systemd unit files for kubelet

{
cat >/etc/systemd/system/kubelet.service <<EOF
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=http://kubernetes.io/docs/
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

mkdir -p /etc/systemd/system/kubelet.service.d
cat >/etc/systemd/system/kubelet.service.d/10-kubeadm.conf <<EOF
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/local/bin/kubelet \$KUBELET_KUBECONFIG_ARGS \$KUBELET_CONFIG_ARGS \$KUBELET_KUBEADM_ARGS \$KUBELET_EXTRA_ARGS
EOF
}

Enable and start kubelet

{
systemctl enable kubelet --now
}

Initialize the cluster

Master node:

kubeadm init --pod-network-cidr=10.244.0.0/16

Worker node. Use the output from the previous command:

kubeadm join <Master node IP>:6443 --token <token> --discovery-token-ca-cert-hash sha256: <hash>

Copy the kubectl config file

{
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
}

Deploy a pod network to the cluster

Run “kubectl apply -f [podnetwork].yaml” with one of the options listed at https://kubernetes.io/docs/concepts/cluster-administration/addons/

eg:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Verify the install

kubectl get nodes

and you should see

NAME           STATUS   ROLES                  AGE    VERSION
k8smaster001   Ready    control-plane,master   7h5m   v1.24.3
k8sworker001   Ready    <none>                 7h3m   v1.24.3

Label the worker nodes

To change the role from <none> to worker simply update the label on the node

k label nodes k8sworker001 node-role.kubernetes.io/worker=

and then run kubectl get nodes again

NAME           STATUS   ROLES                  AGE    VERSION
k8smaster001   Ready    control-plane,master   7h5m   v1.24.3
k8sworker001   Ready    worker                 7h3m   v1.24.3