Cześć! Po wielu (nieudanych) próbach postawienia klastra Dockerowego na Mikrusie, postanowiłem dzisiaj postawić klaster Kubernetesa 🙂
Dlaczego K3s?
Odpowiedź jest prosta, tak samo jak złożoność K3s. K3s jest bardzo prosty w instalacji i jest nawet skrypt do jego uruchomienia na serwerach Mikrusa – chce_k3s.sh – autorstwa Macieja Lopera, wraz z moimi poprawkami i poprawką Grzegorza „es1o” Eliszewskiego, która dodawała do skryptu dual-stack (IPv4 + IPv6).
Pewna osoba poleciła mi pobawić się takim czymś jak minikube ale dla dobra Was wszystkich, moi drodzy czytelnicy, nie próbujcie tego tykać, jeżeli nie chcecie stracić ani chwili cennego czasu na jakiekolwiek testy.
Instalacja K3s
Tak jak już napisałem, instalacja K3s jest prosta, gdyż na serwerach Mikrusa wystarczy uruchomić skrypt chce_k3s.sh, lecz ja chciałbym Was przeprowadzić krok po kroku abyście mogli się nauczyć stawiania K3s w nowszych i starszych wersjach 🙂
Pobieramy sobie na początek binarkę K3s w wersji w której działa dual-stack
wget -O /usr/local/bin/k3s https://github.com/k3s-io/k3s/releases/download/v1.27.6%2Bk3s1/k3s
Następnie nadajemy jej uprawnienia do uruchamiania
chmod +x /usr/local/bin/k3s
oraz tworzymy konfigurację pod systemd
cat <<EOF >"/etc/systemd/system/k3s.service"
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
After=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Type=notify
EnvironmentFile=-/etc/default/%N
EnvironmentFile=-/etc/sysconfig/%N
EnvironmentFile=-/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
ExecStart=/usr/local/bin/k3s \\
server \\
--cluster-cidr=10.42.0.0/16,2001:cafe:42:0::/56 \\
--service-cidr=10.43.0.0/16,2001:cafe:42:1::/112 \\
--kubelet-arg=feature-gates=KubeletInUserNamespace=true \\
--kube-controller-manager-arg=feature-gates=KubeletInUserNamespace=true \\
--kube-apiserver-arg=feature-gates=KubeletInUserNamespace=true \\
--cluster-init
EOF
Poniższe linie włączają dual-stack, więc jeśli ktoś by miał problem z nowszą wersję to prawdopodobnie przez te linie:
--cluster-cidr=10.42.0.0/16,2001:cafe:42:0::/56 \\
--service-cidr=10.43.0.0/16,2001:cafe:42:1::/112 \\
W tym momencie wystarczy wykonać polenie włączenia serwisu k3s w systemie i uruchomienia jej
systemctl enable --now k3s.service
K3s na serwerach z pełną wirtualizacją, bądź na serwerach fizycznych (czyli nie na LXC – jak w przypadku Mikrusa), wymaga jeszcze dodania dodatkowej linijki w pliku /etc/default/grub pod linią GRUB_CMDLINE_LINUX:
GRUB_CMDLINE_LINUX="cgroup_enable=memory cgroup_memory=1 swapaccount=1 systemd.unified_cgroup_hierarchy=0"
oraz zrobienia update’u gruba i zrestartowania systemu:
update-grub
reboot now
Od tego momentu wszystkie rzeczy wykonujemy lokalnie na naszym komputerze.
Wgrywanie kubectl
Instrukcje instalacji można znaleźć pod tym linkiem: https://kubernetes.io/docs/tasks/tools/#kubectl
Wgrywanie Helma
Aby wgrać Helma na nasz komputer wystarczy wykonać jedno polecenie:
MacOS:
brew install helm
Linux/Unix:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Windows (wystarczy pobrać, rozpakować i pracować na binarce helm.exe):
https://get.helm.sh/helm-v3.13.2-windows-amd64.zip
Teraz możemy sobie sprawdzić czy działa nam helm poprzez przykładowe polecenie, które powinno wyprintować nam pomoc helma:
helm help
Zgrywanie konfiguracji kubeconfig
Aby zgrać sobie konfigurację kubeconfig należy wejść na serwer i zgrać sobie plik /etc/rancher/k3s/k3s.yaml
Mając już ten plik wystarczy w systemie MacOS/Linux/Unix (niestety ale nie mam zielonego pojęcia jak zrobić to w Windowsie) ustawić dwie zmienne środowiskowe które definiują ścieżkę do pliku k3s.yaml:
export KUBE_CONFIG_PATH=/sciezka/do/pliku/k3s.yaml
export KUBECONFIG=/sciezka/do/pliku/k3s.yaml
Po wykonaniu tych dwóch poleceń należy jeszcze ustawić port forwarding.
Tak na marginesie to do pracy na Kubernetesie polecam takie narzędzie jak OpenLens. Jest to graficzna nakładka na kubectl.
SSH port forwarding
Jeżeli będziemy chcieli połączyć się z naszym Kubernetesem za pomocą kubectl to polecam zrobić sobie port forwarding, gdyż jeżeli nie posiadamy adresu IPv6 to dostanie się po IPv4 jest niemożliwe – no chyba, że jest postawiony serwer VPN który łączy się z Mikrusem, to wówczas można dostać się po adresacji VPN.
Sposoby na utworzenie przekierowania portu:
Linux/Unix/MacOS
ssh uzytkownik@adres_ip_mikrusa -p port_mikrusa -L 6443:localhost:6443
Windows
Dla systemu Windows pobieramy program PuTTy. Pobieramy ten program i instalujemy i uruchamiamy albo uruchamiamy (w zależności od pobranej wersji).
Otwieramy program PuTTy i podajemy dane do serwera SSH, a następnie w kategoriach przechodzimy do SSH -> Tunnels
Teraz podajemy dane dla tunelu i klikamy Add
Od tej pory będziemy mieli dostępny port serwera 6443 u nas lokalnie na komputerze, a więc będziemy mogli wykonywać operacje na Kubernetesie.
No chyba, że posiada ktoś adres IPv6 w swojej sieci domowej to niepotrzebne jest robienie przekierowania portu, gdyż port jest wystawiony na świat po adresacji IPv6, choć zawsze można to zmienić 🙂
Instalacja Ingressa NGINX
Aby zainstalować ingressa ważne jest aby wyłączyć i usunąć traefika z Kubernetesa.
kubectl -n kube-system scale deploy traefik --replicas=0
kubectl -n kube-system delete deploy traefik
kubectl -n kube-system delete svc traefik
kubectl -n kube-system delete svc traefik-dashboard
Ostatnie polecenie może zakończyć się błędem z powodu braku traefik-dashboard. Tak czy inaczej, wszystko jest okej 🙂
Na początek dodajemy repozytorium ingress-nginxa do naszego helma:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
Aktualizujemy repozytorium:
helm repo update
Tworzymy namespace dla ingressa:
kubectl create ns ingress-nginx
Tworzymy plik ingress-values.yml wraz z poniższą zawartością
controller:
service:
enabled: true
ipFamilies:
- IPv6
Następnie możemy wgrać ingressa na naszego Kubernetesa:
helm upgrade --install nginx-ingress ingress-nginx/ingress-nginx --namespace ingress-nginx -f ingress-values.yml
Z wgrywaniem ingressa mogą być problemy, ale po dłuższym odczekaniu ingress zostanie zainstalowany:
Deployowanie pierwszej aplikacji
Teraz aby sprawdzić czy ingress działa tworzymy sobie pliczek first-deployment.yaml z poniższą zawartością
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: nginx
rules:
- host: twojadomena.tld # tu wpisz swoją domenę
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
gdzie w miejsce twojadomena.tld podstaw swoją domenę/subdomenę, najlepiej skierowaną przez Cloudflare’a, bądź dodaną poprzez Subdomeny w panelu użytkownika.
Teraz możemy zrobić deploy aplikacji i zobaczyć czy usługa działa:
Jak widzicie, ingress działa poprawnie 🙂
O to koniec części pierwszej związanej ze stawianiem klastra Kubernetesowego. W następnej notce będą przedstawione sposoby na dodawanie node’ów do klastra Kubernetesowego 🙂