Kubernetes K3s #1

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 Mikrusachce_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 🙂