Skip to content. | Skip to navigation

Navigation

You are here: Home / Support / Guides / Tools / Kubernetes / Setup

Personal tools

Setup

VMs

In this example, we're using the previously mentioned

  • one master node: 2 vCPU 4GB RAM 40GB disk
  • two worker nodes: 4 vCPU 16GB RAM 40GB disk

(total overkill!)

This example is running Fedora 35 on those VMs.

Per-VM Setup

Broadly following https://kubernetes.io/docs/setup/ ...

You only need to do the SWAP, containerd and kubernetes sections once per node but on all nodes.

SWAP

It must be gone. The installer will cat /proc/swaps and if anything is mentioned it will fail.

For Fedora:

# dnf remove -y zram-generator-defaults

(you may need to reboot, maybe run swapoff -a, maybe get generally annoyed)

The acid test is:

# cat /proc/swaps
Filename                                Type            Size            Used            Priority

We're good.

containerd

Following https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd

containerd requires a couple of kernel modules:

# cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

# sudo modprobe overlay
# sudo modprobe br_netfilter

# cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# sudo sysctl --system

before we can install it and (re-)generate the default config:

# dnf install -y containerd
# containerd config default | sudo tee /etc/containerd/config.toml

We need to edit that default config to assert the use of SystemD's cgroup mechanism. There's a long discussion about cgroups(7) which you can internalize before just going with the flow:

# vi +/runc.options /etc/containerd/config.toml
            SystemdCgroup = true

# systemctl enable --now containerd

Kubernetes

Following https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

The main control interface, if you like, will be listening on port 6443. You may want to open that up through, say, OpenStack, or any other intervening systems if you want to be able to manipulate Kubernetes from your desktop.

Technically, Kubernetes requires some kernel modules as well but these happen to overlap with containerd, above. For completeness:

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
EOF
sudo sysctl --system

Disable SELinux:

# sudo setenforce 0
# sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

For Fedora, we need to install a new repo, noting that it uses el7 binaries (shouldn't make any odds...):

# cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

Notice we exclude the three main binaries in the above repo then enable then just for the following installation line:

# sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

# sudo systemctl enable --now kubelet

which means that the three binaries will remain in lockstep.

Master Installation

Options

There are quite a few options here for which we can get a view of what might happen with:

# kubeadm config print init-defaults

and kubeadm init -h prints out the flags which let us manipulate the defaults.

  • it seems common enough to set the Pod network CIDR with --pod-network-cidr=10.254.0.0/16 -- and see the warning in Calico, below

  • the Service CIDR defaults to --service-cidr=10.96.0.0/12

  • the Service DNS domain defaults to --service-dns-domain cluster.local

    .local is, of course, in breach of RFC 6762 Section 3 although this is far from the first such breach, see https://en.wikipedia.org/wiki/.local

  • although the localAPIEndPoint.advertiseAddress is listed as 1.2.3.4 it appears to be 0.0.0.0 in practice

  • most usefully, we can add some subjectAlternateNames to the generated certificate

    This is particularly useful to us, with our OpenStack hats on, as the node's name and IP are internal and not necessarily going to match what external users will use.

    The format is --apiserver-cert-extra-sans "<IP> <host> ..." (noting that this is not quite the same as the IP:<IP> DNS:<host> format that the certificate itself uses).

    Again, OpenStack might prompt us to use constructions like $(curl -s http://169.254.169.254/2009-04-04/meta-data/public-ipv4) to get the VM's assigned Floating IP address.

    Note, though, that these are extra SANs and kubeadm does generate some default values including various hostnames and IP addresses.

Exceptions

Not everything gets a flag, though. Notably, the cluster is going to get a default name, kubernetes, which is fine on its own, unless you want a different one for which there are no available option flags.

Here, we would have to pass a YAML configuration file, --config FILE, with the appropriate option:

clusterName: soho-cluster

Install

Very simply:

# kubeadm init <options>

So, maybe:

# kubeadm init --pod-network-cidr=10.254.0.0/16 --apiserver-cert-extra-sans "$(curl -s http://169.254.169.254/2009-04-04/meta-data/public-ipv4)"

Important

kubeadm init will print out the appropriate kubeadm join command for the worker nodes which includes a token and a certificate hash. Make a note of the token as it has a 24hr expiry date.

You can create more tokens with kubeadm token create and recover the hash with:

# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
  openssl dgst -sha256 -hex | sed 's/^.* //'
admin.conf

kubeadm init will have created /etc/kubernetes/admin.conf which you, as the Kubernetes administrator, might want to copy to wield full power over the cluster.

Nominally, it might be copied to ~/.kube/config although equally, so long as it appears in the KUBECONFIG environment variable kubectl will be able to use it.

In the rest of this example, I'll use # as the prompt for kubectl using admin.conf (as ~/.kube/config or whatever) and $ as the prompt for kubectl with a less permissive configuration.

Calico

Calico is easy to install but a quick word of warning.

Warning

If you didn't define the Pod CIDR with kubeadm init, above, then Calico will use 192.168.0.0/16 and cannot be undone. Which is likely to conflict with your site networking and therefore be annoying.

Download the Calico YAML file and then apply it:

# curl https://projectcalico.docs.tigera.io/manifests/calico.yaml -O
# kubectl apply -f calico.yaml

If you're quick (OK, within 10s of seconds!) you can watch Calico bursting into life:

# kubectl get all -n kube-system

looking for the Pods to become ready.

Although ultimately you want to see that CoreDNS is running:

# kubectl cluster-info
Kubernetes control plane is running at https://<node-IP>:6443
CoreDNS is running at https://<node-IP>:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

Worker Installation

Having done the one-off per-node steps you can simply run the kubeadm join command printed out earlier:

# kubeadm join <master-node-IP>:6443 --token TOKEN \
       --discovery-token-ca-cert-hash sha256:HASH

Node Removal

On the master node, say:

# kubectl get nodes
# kubectl drain <node-name> --delete-local-data --force --ignore-daemonsets
# kubectl delete node <node-name>

and then on <node-name> itself:

# kubeadm reset

Although the suggestion is that there'll be further work to tidy up iptables, /etc/* and dnf.

Document Actions