Skip to content

Instalacja klastra Kubernetes z użyciem kubeadm

Instalacja odbyła się dla wersji 1.35 Kubernetes. Przykładowa instalacja składała się z jednego węzła Control-plane oraz 2 węzłów Worker Node. Tutaj jest opis jak robić w przypadku klastra HA: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/

Aktualizacja systemu, instalacja potrzebnego oprogramowania

Info

Robimy to na każdym węźle (Control-plane, Nodes).

Aktualizujemy cache apt, instalujemy potrzebne paczki

sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

Tworzymy lokalizację na klucz GPG do podpisu paczek z repozytorium Kubernetes

# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

Aktualizujemy cache apt, instalujemy potrzebne paczki

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Instalujemy Container Runtime (CRI)

Wybrany został CRI containerd.

Info

Robimy to na każdym węźle - ControlPlane, Nodes.

Aktualizujemy indeksy apt, instalujemy containerd

sudo apt update
sudo apt install containerd -y

Konfigurujemy parametr containerd odnośnie użycia systemd jako drivera do cgroups

Tworzymy katalog do konfiguracji containerd

sudo mkdir /etc/containerd

Tworzymy konfigurację dla containerd

containerd config default | sed 's/SystemdCgroup = false/SystemdCgroup = true/' | sudo tee /etc/containerd/config.toml

Polecenie to wykonuje wyświetlenie domyślnego configu, zmianę parametru SystemdCgroup na wartość true, a następnie umieszczenie tego w pliku /etc/containerd/config.toml.

Sprawdzamy poprawność konfiguracji

grep -B 20 'SystemdCgroup' /etc/containerd/config.toml

Restartujemy containerd

sudo systemctl restart containerd

Inicjalizujemy Control-plane

Info

Robimy tylko na węzłach Control-plane.

Konfigurujemy sieć

Musimy robić to na koncie root.

Ładujemy moduł br_netfilter do kernela

echo br_netfilter | sudo tee /etc/modules-load.d/br_netfilter.conf

Zezwalamy na ruch bridge dla iptables, włączamy routing pakietów

echo 'net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1' | tee /etc/sysctl.d/99-network.conf

Restartujemy system

reboot now

Sprawdzamy wdrożone zmiany

lsmod | grep br_netfilter
sysctl net.bridge.bridge-nf-call-iptables
sysctl net.ipv4.ip_forward

Uruchomienie kubeadm

Uruchomiene węzła Control-plane

Polecenie kubeadm na Control-plane wygeneruje: kube-apiserver, kube-scheduler, kube-controller-manager, etcd w formie Static Podów.

W przypadku wielu instancji Controlplane należy dodać pole --control-plane-endpoint.

sudo kubeadm init \
--apiserver-advertise-address <adres_IP_controlplane> \
--pod-network-cidr "<cidr_dla_pod_sieci/maska>" \
--upload-certs

gdzie: --apiserver-advertise-address - adres IP apiserver, czyli adres Controlplane --pod-network-cidr - CIDR dla sieci dla Podów, np. 10.1.1.1/16 --upload-certs - konfiguracja certyfikatów control-plane, szyfruje i uploaduje certy control-plane do klastra. Automatycznie generowane są certyfikaty, nie trzeba tego robić.

np.

sudo kubeadm init \
--apiserver-advertise-address 192.168.56.11 \
--pod-network-cidr "10.244.0.0/16" \
--upload-certs

Warto dodać jeszcze flagę --control-plane-endpoint= np. --control-plane-endpoint=192.168.56.11. Określamy adres po którym węzły dołączają do klastra.

Skopiowanie konfiguracji domyślnego użytkownika

Będzie on wykorzystywany do zarządzania klastrem. Polecenia te możemy dostać w opisie wygenerowanego configu dla Control-plane.

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

Kopiujemy Token do dołączenia do klastra dla Workerów

Tutaj przykładowy dla Master Node pod adresem 192.168.1.100.

kubeadm join 192.168.1.100:6443 --token t80isp.d0y2lsx7sf09ce7u \
--discovery-token-ca-cert-hash sha256:5efa1a6ce6456201f832dc1a62ea426dc0ee41b9bf1b3dc0fff790c14409159d

Wdrażamy CNI

W tym przypadku był to Flannel.

Wystarczy jedynie wczytać manifest dostępny na Github: https://github.com/flannel-io/flannel#deploying-flannel-manually jeżeli sieć dla Podów jest domyślna (10.244.0.0/16).

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

Po wdrożeniu CNI status node Control-plane powinien być Ready, np. przy poleceniu kubectl get nodes:

$ kubectl get nodes                                                             
NAME           STATUS   ROLES           AGE   VERSION                                                 
controlplane   Ready    control-plane   13m   v1.35.0        

Wdrażamy kubeadm na węzłach Worker

Info

Robimy to na każdym węźle Worker Node.

Konfigurujemy sieć

Musimy robić to na koncie root.

Ładujemy moduł br_netfilter do kernela

echo br_netfilter | sudo tee /etc/modules-load.d/br_netfilter.conf

Zezwalamy na ruch bridge dla iptables, włączamy routing pakietów

echo 'net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1' | tee /etc/sysctl.d/99-network.conf

Restartujemy system

reboot now

Sprawdzamy wdrożone zmiany

lsmod | grep br_netfilter
sysctl net.bridge.bridge-nf-call-iptables
sysctl net.ipv4.ip_forward

Uruchomienie kubeadm

Uruchomiene kubeadm

Kopiujemy polecenie wygenerowane przez Controlplane:

kubeadm join 192.168.1.100:6443 --token bbb \
--discovery-token-ca-cert-hash sha256:aa

Możemy także wygenerować token ponownie:

kubeadm token create --print-join-command

A następnie po stronie Controlplane sprawdzamy, czy wszystkie Node działają:

$ kubectl get nodes
NAME           STATUS   ROLES           AGE   VERSION
controlplane   Ready    control-plane   24m   v1.35.0
node01         Ready    <none>          40s   v1.35.0
node02         Ready    <none>          40s   v1.35.0

Uruchamiamy testowego Poda

kubectl run web --image=nginx

Sprawdzamy, czy uruchomił się i działa poprawnie:

kubectl get pods

Wszystko działa poprawnie:

NAME   READY   STATUS    RESTARTS   AGE
web    1/1     Running   0          36s

Gotowe!