Pełnoprawny Kubernetes od podstaw na Raspberry Pi

Pełnoprawny Kubernetes od podstaw na Raspberry Pi

Niedawno jedna znana firma ogłosiła, że przenosi swoją linię laptopów na architekturę ARM. Kiedy usłyszałem tę wiadomość, przypomniałem sobie, przeglądając po raz kolejny ceny EC2 w AWS, zwróciłem uwagę na Graviton’y w bardzo atrakcyjnej cenie. Zgadza się, problemem była architektura ARM. Wtedy nawet nie podejrzewałem, jak poważna może być ARM...

Dla mnie ta architektura zawsze była domeną urządzeń mobilnych i różnych gadżetów IoT. "Prawdziwe" serwery na ARM — to jakoś dziwne, a miejscami nawet szalone... Jednak nowa myśl zafiksowała się w mojej głowie, dlatego w jeden z weekendów postanowiłem sprawdzić, co w ogóle można dzisiaj uruchomić na ARM. I dla tego zdecydowałem się zacząć od czegoś bliskiego i znajomego — klastra Kubernetes. I to nie jakiegoś wirtualnego „klastra”, ale całkiem „na poważnie”, aby był maksymalnie podobny do tego, co znam z produkcji.

Zamysł był taki, aby klaster był dostępny z internetu, w nim miała działać jakaś aplikacja internetowa i przynajmniej powinien być monitoring. Do realizacji tego pomysłu potrzebne będą dwa (lub więcej) Raspberry Pi w co najmniej modelu 3B+. Miejscem do eksperymentów mogłaby być również AWS, ale mnie interesowały głównie „maliny” (które i tak leżały bezczynnie). Zatem zbudujemy na nich klaster Kubernetes z Ingress, Prometheus i Grafana.

Przygotowanie „malin”

Instalacja systemu operacyjnego i SSH

Nie przesadzałem z wyborem systemu operacyjnego do instalacji: po prostu wziąłem najnowszą wersję Raspberry Pi OS Lite z oficjalnej strony. Tam też dostępna jest dokumentacja instalacji, wszystkie działania należy wykonać na wszystkich węzłach przyszłego klastra. Następnie należy wykonać następujące manipulacje (też na wszystkich węzłach).

Po podłączeniu monitora i klawiatury, musisz najpierw skonfigurować sieć i SSH:

  1. Aby klaster działał, master musi mieć statyczny adres IP, a węzły robocze — według uznania. Preferowałem statyczne adresy wszędzie dla wygody konfiguracji.
  2. Statyczny adres można skonfigurować w OS (w pliku /etc/dhcpcd.conf jest odpowiedni przykład) lub poprzez zablokowanie lease w DHCP serwerze używanego (w moim przypadku — domowego) routera.
  3. serwer ssh można po prostu włączyć w raspi-config (opciones interfejsu → ssh).

Po tym możesz już zalogować się przez SSH (domyślnie login to pi, a hasło to raspberry lub to, na które zostało zmienione) i kontynuować konfigurację.

Inne ustawienia

  1. Ustaw nazwę hosta. W moim przykładzie użyjemy pi-control i pi-worker.
  2. Sprawdźmy, czy system plików został rozszerzony na cały dysk (df -h /). W razie potrzeby można go rozszerzyć za pomocą raspi-config.
  3. Zmienimy domyślne hasło użytkownika w raspi-config.
  4. Wyłączymy plik swap (takie są wymagania Kubernetes; jeśli chcesz poznać szczegóły na ten temat, zob. issue #53533):
    dphys-swapfile swapoff
    systemctl disable dphys-swapfile
  5. Zaktualizujemy pakiety do najnowszych wersji:
    apt-get update && apt-get dist-upgrade -y
  6. Zainstalujemy Dockera oraz dodatkowe pakiety:
    apt-get install -y docker docker.io apt-transport-https curl bridge-utils iptables-persistent

    Podczas instalacji iptables-persistent będzie wymagane zapisanie ustawień iptables dla ipv4, a w pliku /etc/iptables/rules.v4 — dodaj reguły do łańcucha FORWARD, w ten sposób:

    # Generated by xtables-save v1.8.2 on Sun Jul 19 00:27:43 2020
    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    -A FORWARD -s 10.1.0.0/16  -j ACCEPT
    -A FORWARD -d 10.1.0.0/16  -j ACCEPT
    COMMIT
  7. Teraz wystarczy tylko się zrestartować.

Teraz wszystko jest gotowe do instalacji klastra Kubernetes.

Instalacja Kubernetes

Na tym etapie celowo odłożyłem wszystkie nasze korporacyjne rozwiązania dotyczące automatyzacji instalacji i konfiguracji klastra K8s. Zamiast tego, skorzystamy z oficjalnej dokumentacji z kubernetes.io (lekko uzupełnione komentarzami i skrótami).

Dodajemy repozytorium Kubernetes:

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update

Następnie dokumentacja sugeruje zainstalowanie CRI (interfejs czasu uruchomienia kontenera). Ponieważ Docker jest już zainstalowany, przechodzimy dalej i instalujemy podstawowe komponenty:

sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni

Na etapie instalacji podstawowych komponentów od razu dodałem kubernetes-cni, który jest niezbędny do działania klastra. Jest tu ważny aspekt: pakiet kubernetes-cni z jakiegoś powodu nie tworzy domyślnego katalogu dla konfiguracji interfejsów CNI, więc musiałem utworzyć go ręcznie:

mkdir -p /etc/cni/net.d

Aby uruchomić backend sieciowy, o którym mowa poniżej, należy doinstalować wtyczkę dla CNI. Wybrałem dobrze znajomą mi wtyczkę portmap (pełna lista dostępna w dokumentacji):

curl -sL https://github.com/containernetworking/plugins/releases/download/v0.7.5/cni-plugins-arm-v0.7.5.tgz | tar zxvf - -C /opt/cni/bin/ ./portmap

Konfiguracja Kubernetes

Węzeł z control plane

Instalacja samego klastra przebiega dosyć prosto. Aby przyspieszyć ten proces oraz sprawdzić, że obrazy Kubernetes są dostępne, można wstępnie wykonać:

kubeadm config images pull

Teraz przeprowadzamy samą instalację — inicjujemy control plane klastra:

kubeadm init --pod-network-cidr=10.1.0.0/16 --service-cidr=10.2.0.0/16 --upload-certs

Zwróć uwagę, że podsieci dla usług i pod’ów nie powinny się ze sobą krzyżować ani z istniejącymi sieciami.

Na koniec zobaczymy komunikat informujący, że wszystko jest w porządku, a także wskazówki, jak dołączyć węzły robocze do control plane:

Twój kontroler Kubernetes został pomyślnie zainicjowany!
Aby zacząć korzystać ze swojego klastra, musisz uruchomić następujące polecenia jako zwykły użytkownik:
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config
Teraz powinieneś wdrożyć sieć podów do klastra.
Uruchom "kubectl apply -f [podnetwork].yaml" z jedną z opcji wymienionych na:
 https://kubernetes.io/docs/concepts/cluster-administration/addons/
Możesz teraz dołączyć dowolną liczbę węzłów control-plane, uruchamiając polecenie na każdym z nich jako root:
 kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4 
   --discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050 
   --contrl-plane --certificate-key 72a3c0a14c627d6d7fdade1f4c8d7a41b0fac31b1faf0d8fdf9678d74d7d2403
Pamiętaj, że klucz certyfikatu daje dostęp do wrażliwych danych klastra, trzymaj go w tajemnicy!
Dla bezpieczeństwa, przesłane certyfikaty zostaną usunięte w ciągu dwóch godzin; W razie potrzeby możesz użyć
"kubeadm init phase upload-certs --upload-certs", aby załadować certyfikaty ponownie.
Następnie możesz dołączyć dowolną liczbę węzłów roboczych, uruchamiając następujące polecenie na każdym z nich jako root:
kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4 
   --discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050

Wykonaj zalecenia dotyczące dodania konfiguracji dla użytkownika. A przy okazji zalecam od razu dodać autouzupełnianie dla kubectl:

 kubectl completion bash > $HOME/.kube/completion.bash.inc
 printf "
 # Autouzupełnianie powłoki Kubectl
 source '$HOME/.kube/completion.bash.inc'
 " >> $HOME/.bash_profile
 source $HOME/.bash_profile

Na tym etapie można już zobaczyć pierwszy węzeł w klastrze (choć jeszcze nie jest gotowy):

root@pi-control:~# kubectl get no
NAME         STATUS     ROLES    AGE   VERSION
pi-control   NotReady   master   29s   v1.18.6

Konfiguracja sieci

Jak zostało powiedziane w komunikacie po instalacji, konieczne będzie zainstalowanie sieci w klastrze. W dokumentacji oferują wybór z Calico, Cilium, contiv-vpp, Kube-router i Weave Net… Tutaj odstąpiłem od oficjalnej instrukcji i wybrałem bardziej znajomą i zrozumiałą dla mnie opcję: flannel w trybie host-gw (więcej o dostępnych backendach patrz w dokumentacji projektu).

Zainstalowanie go w klastrze jest dość proste. Na początek — pobieramy manifesty:

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Następnie zmieniamy w ustawieniach typ z vxlan na host-gw:

sed -i 's/vxlan/host-gw/' kube-flannel.yml

… oraz podsieć podów — z wartości domyślnej na tę, która została podana podczas inicjalizacji klastra:

sed -i 's#10.244.0.0/16#10.1.0.0/16#' kube-flannel.yml

Po tym tworzymy zasoby:

kubectl create -f kube-flannel.yml

Gotowe! Po chwili pierwszy węzeł K8s przejdzie w status Gotowy:

NAME         STATUS   ROLES    AGE   VERSION
pi-control   Ready    master   2m    v1.18.6

Dodawanie węzła roboczego

Można teraz dodać workera. W tym celu na nim — po zainstalowaniu samego Kubernetes zgodnie ze scenariuszem opisanym powyżej — wystarczy po prostu wykonać wcześniej otrzymane polecenie:

kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4 
    --discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050

Można uznać, że klaster jest gotowy:

root@pi-control:~# kubectl get no
NAME         STATUS   ROLES    AGE    VERSION
pi-control   Gotowy   master   28m    v1.18.6
pi-worker    Gotowy      2m8s   v1.18.6

Miałem tylko dwie Raspberry Pi, więc nie chciałem oddawać jednej z nich tylko pod control plane. Dlatego usunąłem automatycznie ustawiony taint z węzła pi-control, uruchamiając:

root@pi-control:~# kubectl edit node pi-control

… i usuwając linie:

 - efekt: NoSchedule
   klucz: node-role.kubernetes.io/master

Wypełnienie klastra niezbędnym minimum

Najpierw będziemy potrzebować Helm. Oczywiście można wszystko robić i bez niego, ale Helm pozwala dosłownie bez edytowania plików konfigurować niektóre komponenty według własnych potrzeb. A w rzeczywistości jest to po prostu plik binarny, który "nie prosi o pożywienie."

Zatem wchodzimy na helm.sh na sekcję docs/installation i wykonujemy polecenie stamtąd:

curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

Po tym dodajemy repozytorium chartów:

helm repo add stable https://kubernetes-charts.storage.googleapis.com/

Teraz zainstalujemy komponenty infrastrukturalne zgodnie z zamysłem:

  • Ingress controller;
  • Prometheus;
  • Grafana;
  • cert-manager.

Ingress controller

Pierwszy komponent — Ingress controller — instalowany jest dość prosto i gotowy do użycia "z pudełka." W tym celu wystarczy wejść do sekcji bare-metal na stronie i wykonać polecenie instalacji stamtąd:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/baremetal/deploy.yaml

Jednak w tym momencie "malina" zaczęła się dusić i napotykać na problemy z IOPS dysku. Problem polega na tym, że razem z Ingress-controllerem instalowanych jest wiele zasobów, wykonuje się wiele zapytań do API i w związku z tym do etcd zapisywana jest duża ilość danych. Ogólnie rzecz biorąc, albo karta pamięci klasy 10 nie jest zbyt wydajna, albo po prostu brakuje SD-kart do takiego obciążenia. Niemniej jednak, po około 5 minutach wszystko ruszyło.

Utworzono namespace, a w nim pojawił się kontroler oraz wszystko, co jest mu potrzebne:

root@pi-control:~# kubectl -n ingress-nginx get pod
NAME                                        READY   STATUS      RESTARTS   AGE
 ingress-nginx-admission-create-2hwdx        0/1     Zakończono   0          31s
 ingress-nginx-admission-patch-cp55c         0/1     Zakończono   0          31s
 ingress-nginx-controller-7fd7d8df56-68qp5   1/1     Działa     0          48s

Prometheus

Następne dwa komponenty są dość łatwe do zainstalowania za pomocą Helm z repozytorium chart.

Znajdujemy Prometheus, tworzymy namespace i instalujemy go w nim:

helm search repo stable | grep prometheus
kubectl create ns monitoring
helm install prometheus --namespace monitoring stable/prometheus --set server.ingress.enabled=True --set server.ingress.hosts={"prometheus.home.pi"}

Domyślnie Prometheus zamawia 2 dyski: na dane samego Prometheusa i na dane AlertManagera. Ponieważ w klastrze nie stworzono klasy storage, dyski nie zostaną zamówione i pod'y nie zostaną uruchomione. W przypadku instalacji na bare metal Kubernetes zazwyczaj używamy Ceph rbd, jednak w przypadku Raspberry Pi to jest oczywiste przesycenie.

Dlatego stworzymy prostą lokalną pamięć na hostpath. Manifesty PV (persistent volume) dla prometheus-server i prometheus-alertmanager są połączone w pliku prometheus-pv.yaml do Repozytoria Git z przykładami dla artykułu. Katalog dla PV należy wcześniej utworzyć na dysku tego węzła, do którego chcemy przypisać Prometheusa: w przykładzie wymieniono nodeAffinity według hostname pi-worker i na nim utworzono katalogi /data/localstorage/prometheus-server i /data/localstorage/prometheus-alertmanager.

Pobieramy (klonujemy) manifest i dodajemy go do Kubernetes:

kubectl create -f prometheus-pv.yaml

Na tym etapie pierwszy raz napotkałem problem z architekturą ARM. Kube-state-metrics, który domyślnie jest instalowany w charcie Prometheusa, odmówił uruchomienia. Zgłosił błąd:

root@pi-control:~# kubectl -n monitoring logs prometheus-kube-state-metrics-c65b87574-l66d8
standard_init_linux.go:207: exec user process caused "exec format error"

Chodzi o to, że dla kube-state-metrics używany jest obraz projektu CoreOS, który nie jest budowany pod ARM:

kubectl -n monitoring get deployments.apps prometheus-kube-state-metrics -o=jsonpath={.spec.template.spec.containers[].image}
quay.io/coreos/kube-state-metrics:v1.9.7

Musiałem lekko poguglać i znaleźć na przykład ten obraz. Aby go wykorzystać, zaktualizujemy wydanie, podając, jaki obraz ma być użyty dla kube-state-metrics:

helm upgrade prometheus --namespace monitoring stable/prometheus --set server.ingress.enabled=True --set server.ingress.hosts={"prometheus.home.pi"} --set kube-state-metrics.image.repository=carlosedp/kube-state-metrics --set kube-state-metrics.image.tag=v1.9.6

Sprawdzamy, czy wszystko się uruchomiło:

root@pi-control:~# kubectl -n monitoring get po
NAZWA                                             GOTOWY   STATUS              RESTARTY   WIEK
prometheus-alertmanager-df65d99d4-6d27g          2/2     Działa             0          5m56s
prometheus-kube-state-metrics-5dc5fd89c6-ztmqr   1/1     Działa             0          5m56s
prometheus-node-exporter-49zll                   1/1     Działa             0          5m51s
prometheus-node-exporter-vwl44                   1/1     Działa             0          4m20s
prometheus-pushgateway-c547cfc87-k28qx           1/1     Działa             0          5m56s
prometheus-server-85666fd794-z9qnc               2/2     Działa             0          4m52s

Grafana i cert-manager

Dla wykresów i dashboardów instalujemy Grafana:

helm install grafana --namespace monitoring stable/grafana  --set ingress.enabled=true --set ingress.hosts={"grafana.home.pi"}

Na końcu wyjścia pokażą nam, jak uzyskać hasło do dostępu:

kubectl get secret --namespace monitoring grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

Aby zamówić certyfikaty, zainstalujemy cert-manager. W tym celu zwrócimy się do dokumentacji, która oferuje odpowiednie komendy dla Helm:

helm repo add jetstack https://charts.jetstack.io

helm install 
  cert-manager jetstack/cert-manager 
  --namespace cert-manager 
  --version v0.16.0 
  --set installCRDs=true

Dla certyfikatów self-signed do użytku domowego tego wystarczy. Jeśli jednak potrzebujemy uzyskać ten sam Let’s Encrypt, musimy jeszcze skonfigurować cluster issuer. Szczegóły na ten temat można znaleźć w naszym artykule „Certyfikaty SSL od Let's Encrypt z cert-manager w Kubernetes».

Osobiście zatrzymałem się na wariancie z przykładu w dokumentacji, uznając, że wariant stagingowy LE będzie wystarczający. Zmieniamy w przykładzie e-mail, zapisujemy do pliku i dodajemy do klastra (cert-manager-cluster-issuer.yaml):

kubectl create -f cert-manager-cluster-issuer.yaml

Teraz możemy zamówić certyfikat, na przykład dla Grafany. W tym celu potrzebna jest domena i zewnętrzny dostęp do klastra. Mam domenę, a ruch skonfigurowałem przekierowując porty 80 i 443 na domowym routerze zgodnie z utworzonym serwisem ingress-controller’a:

kubectl -n ingress-nginx get svc
NAME                                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.2.206.61            80:31303/TCP,443:30498/TCP   23d

Port 80 w tym przypadku jest przekierowywany na 31303, a 443 — na 30498. (Porty są generowane losowo, więc u Ciebie będą inne.)

Oto przykład certyfikatu (cert-manager-grafana-certificate.yaml):

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: grafana
  namespace: monitoring
spec:
  dnsNames:
    - grafana.home.pi
  secretName: grafana-tls
  issuerRef:
    kind: ClusterIssuer
    name: letsencrypt-staging

Dodajemy go do klastra:

kubectl create -f cert-manager-grafana-certificate.yaml

Po tym pojawi się zasób Ingress, przez który będzie przebiegać walidacja Let’s Encrypt:

root@pi-control:~# kubectl -n monitoring get ing
NAME                        CLASS    HOSTS                        ADDRESS         PORTS   AGE
cm-acme-http-solver-rkf8l      grafana.home.pi      192.168.88.31   80      72s
grafana                        grafana.home.pi      192.168.88.31   80      6d17h
prometheus-server              prometheus.home.pi   192.168.88.31   80      8d

Po zakończeniu walidacji zobaczymy, że zasób certificate jest gotowy, a w powyżej wskazanym sekrecie grafana-tls — certyfikat i klucz. Można od razu sprawdzić, kto wydał certyfikat:

root@pi-control:~# kubectl -n monitoring get certificate
NAME      READY   SECRET        AGE
grafana   True    grafana-tls   13m

root@pi-control:~# kubectl -n monitoring get secrets grafana-tls -ojsonpath="{.data['tls.crt']}" | base64 -d | openssl x509 -issuer -noout
issuer=CN = Fake LE Intermediate X1

Wracamy do Grafany. Musimy nieco zmodyfikować jej wyzwolenie Helm, zmieniając ustawienia TLS zgodnie z utworzonym certyfikatem.

Aby to zrobić, pobieramy chart, edytujemy i aktualizujemy z lokalnego katalogu:

helm pull --untar stable/grafana

Edycja w pliku grafana/values.yaml parametry TLS:

  tls:
    - secretName: grafana-tls
      hosts:
        - grafana.home.pi

Możemy tutaj również od razu skonfigurować zainstalowany Prometheus jako źródło danych:

datasources:
  datasources.yaml:
    apiVersion: 1
    datasources:
    - name: Prometheus
      type: prometheus
      url: http://prometheus-server:80
      access: proxy
      isDefault: true

Teraz aktualizujemy chart Grafana z lokalnego katalogu:

helm upgrade grafana --namespace monitoring ./grafana  --set ingress.enabled=true --set ingress.hosts={"grafana.home.pi"}

Sprawdzamy, czy w Ingress grafana dodano port 443 i dostęp przez HTTPS:

root@pi-control:~# kubectl -n monitoring get ing grafana
NAZWA KLASA HOSY ADRES PORTY WIEK
grafana <brak> grafana.home.pi 192.168.88.31 80, 443 63m

root@pi-control:~# curl -kI https://grafana.home.pi
HTTP/2 302
serwer: nginx/1.19.1
data: Wt, 28 lip 2020 19:01:31 GMT
typ-treści: text/html; charset=utf-8
cache-control: no-cache
expires: -1
lokalizacja: /login
pragma: no-cache
set-cookie: redirect_to=; Path=/; HttpOnly; SameSite=Lax
x-frame-options: deny
strict-transport-security: max-age=15724800; includeSubDomains

Aby zademonstrować Grafanę w działaniu, można pobrać i dodać dashboard dla kube-state-metrics.Oto jak to wygląda:

Pełnoprawny Kubernetes od podstaw na Raspberry Pi

Zalecam również dodanie dashboardu dla node exporter: szczegółowo pokaże, co dzieje się z „malinami” (obciążenie CPU, wykorzystanie pamięci, sieci, dysku itp.).

Po tym uważam, że klaster jest gotowy do przyjmowania i uruchamiania aplikacji!

Uwagi dotyczące budowy

Do budowy aplikacji pod architekturę ARM istnieją co najmniej dwie możliwości. Po pierwsze, można budować na urządzeniu ARM. Jednak patrząc na obecne wykorzystanie dwóch Raspberry Pi, zrozumiałem, że nie poradzą sobie nawet z budową. Dlatego zamówiłem nową Raspberry Pi 4 (jest mocniejsza i ma aż 4 GB pamięci) — planuję budować na niej.

Drugą opcją jest zbudowanie wieloarchitektonicznego obrazu Docker na mocniejszej maszynie. Do tego służy rozszerzenie docker buildx. Jeśli aplikacja jest napisana w języku kompilowanym, będzie wymagana cross-kompilacja dla ARM. Nie będę opisywał wszystkich konfiguracji dla takiej drogi, ponieważ to zajmie osobny artykuł. Przy wdrożeniu takiego podejścia można osiągnąć „uniwersalne” obrazy: Docker uruchomiony na maszynie ARM samodzielnie automatycznie pobierze odpowiedni obraz architektury.

Podsumowanie

Przeprowadzony eksperyment przerósł moje oczekiwania: [przynajmniej] „waniliowy” Kubernetes z niezbędną bazą radzi sobie całkiem dobrze na ARM, a podczas jego konfiguracji pojawiło się tylko kilka niuansów.

Raspberry Pi 3B+ radzą sobie z obciążeniem CPU, jednak ich karty SD są wyraźnym wąskim gardłem. Koledzy podpowiedzieli, że w niektórych wersjach jest możliwość uruchamiania z USB, gdzie można podłączyć SSD: prawdopodobnie wówczas sytuacja się poprawi.

Oto przykład obciążenia CPU podczas instalacji Grafana:

Pełnoprawny Kubernetes od podstaw na Raspberry Pi

Moim zdaniem, dla eksperymentów i „żeby spróbować”, klaster Kubernetes na „malinach” dużo lepiej oddaje wrażenia z eksploatacji niż ten sam Minikube, ponieważ wszystkie komponenty klastra są zarówno instalowane, jak i działają „jak należy”.

W perspektywie istnieje pomysł, aby dodać do klastra cały cykl CI/CD, zrealizowany całkowicie na Raspberry Pi. Będę również wdzięczny, jeśli ktoś podzieli się swoim doświadczeniem w konfiguracji K8s na AWS Gravitonach.

P.S. Tak, „produkcja” może być bliżej, niż myślałem:

Pełnoprawny Kubernetes od podstaw na Raspberry Pi

P.P.S.

Przeczytaj także na naszym blogu:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster