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'
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
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 🙂

Mikrus – Alpine jako LAMP

Siema Ubuntu, ooo Debian! Gdzie CentOS? Ooo tu jesteś! Fajnie Was widzieć. Mam złe wieści, Alpine przyjeżdża na plan.

Wszyscy wiedzą że jestem ogromnym fanem Linuxa i że dla mnie nie ma nigdzie miejsca dla Windowsa, a tym bardziej jakbym miał robić swój serwer (windows pfu!). Jak wiecie z poprzednich notek, że ja i Bonn333 staramy się pokazać zalety innych systemów z rodziny Linux – tym razem jest to Alpine 🙂

Najważniejsza zaleta Alpine to minimalizm. Alpine korzysta z OpenRC, zaś taki Debian czy Ubuntu aktualnie ze systemd, a w dodatku na Alpine postawienie pełnego serwera WWW (np. LAMP – Linux Apache2 MySQL PHP) jest o wiele prostsze niż na innych systemach. W tej notce pokażę Wam jak to bardzo prosto można zrobić. Zapraszam do lektury! 🙂

Zaczynamy więc od instalacji potrzebnych nam pakietów (przy okazji proponuję jak zwykle zaaktualizować system 🙂 ):

apk add apache2 apache2-ssl php7-apache2 mysql mysql-client php7-common php7-iconv php7-json php7-gd php7-curl php7-xml php7-mysqli php7-imap php7-cgi fcgi php7-pdo php7-pdo_mysql php7-soap php7-xmlrpc php7-mcrypt php7-gettext php7-ctype php7-dom

Jak już mamy zainstalowane potrzebne nam pakiety to można ruszać z uruchomieniem bazy danych więc wpisujemy:

mysql_install_db --user=mysql --datadir=/var/lib/mysql

No i MariaDB zainicjowała nam bazę danych w katalogu /var/lib/mysql czyli w domyślnym miejscu. Teraz przyda się dodanie procesów apache2 oraz mariadb do autostartu więc wpisujemy:

rc-update add apache2
rc-update add mariadb

Teraz tak, Ci co są chętni zoptymalizować swoją bazę danych mogą skonfigurować MariaDB oraz Apache2 tak aby zyskać na pamięci RAM, Ci co mają dużą ilość ramu to mogą to pominąć całkowicie.
W pliku /etc/my.cnf.d/mariadb-server.cnf dodajemy pod skip-networking takie o to linijki:

innodb=OFF
default-storage-engine=MyISAM

zaś w pliku /etc/apache2/httpd.conf w linii 29 zmieniamy na:

ServerTokens Minimal

a następnie w pliku /etc/apache2/conf.d/mpm.conf w liniach 28-34:

<IfModule mpm_prefork_module>
StartServers 2
MinSpareServers 2
MaxSpareServers 5
MaxRequestWorkers 200
MaxConnectionsPerChild 200
</IfModule>

Jeśli już jest to gotowe to teraz można uruchomić serwer www oraz bazę danych i ustawić hasło do serwera bazy danych 🙂

rc-service apache2 start
rc-service mariadb start
/usr/bin/mysqladmin -u root password 'password'

W miejsce 'password’ wpisać hasło do bazy mysql jakie ma być ustawione.
Od tej pory można robić sobie powolutku własną stronę www w katalogu /var/www/localhost/htdocs/ który jest domyślnym katalogiem dla stron www. WordPress powinien na takiej konfiguracji działać bez żadnych problemów.

Dlaczego akurat w tym poradniku piszę o Alpine? Kto wie ten wie, kto nie wie ten się teraz dowie, że jestem administratorem w projekcie Mikrus i tam system Alpine Linux działa najlepiej i najwydajniej ze wszystkich. Osobiście polecam poeksperymentować z każdym systemem, a później wybrać jeden ze wszystkich, taki z którym najlepiej się współpracuje i w jego kierunku się rozwijać. Jak to powiedział mój dawny nauczyciel ze szkoły średniej, by wybrać jeden system i powoli stawać się specjalistą z zakresu tego systemu 🙂 Miłej zabawy!

PS. Kto zejdzie tak nisko z pamięcią ram?