
Hiljuti teatas üks tuntud ettevõte, et viib oma sülearvutite seeria üle ARM-arhitektuurile. Seda uudist kuuldes meenus mulle, et kui jälle vaatasin AWS-i EC2 hindu, siis märkasin Gravitoniid, mille hinnad olid tõeliselt ahvatlevad. Loomulikult oli aga põhiküsimus, et need on ARM. Siis ei tulnud mul üldse pähe, et ARM on tõeliselt tõsine…
Minu jaoks oli see arhitektuur alati seotud mobiilsete seadmete ja muude IoT-vidinatega. „Tõelised“ serverid ARM-is tundusid kuidagi ebatavalised, isegi hirmutavad… Siiski, uus mõte jäi mulle pähe kummitama, seega otsustasin ühel nädalavahetusel uurida, mida täpselt saab täna ARM-il käivitada. Ja selleks tahtsin alustada millegagi tuttavast — Kubernetes'e klasstrist. Ja mitte lihtsalt mõnest „klastrist“, vaid kõik pidi olema tõsiseltvõetav, et see oleks maksimaalselt sarnane sellele, kuidas ma olen harjunud seda nägema tootmises.
Minu plaani kohaselt peaks klaster olema ligipääsetav Internetis, seal peaks töötama veebirakendus ja olema vähemalt üks seire. Selle idee elluviimiseks on vajalik paar (või rohkem) Raspberry Pi vähemalt mudelist 3B+. Eksperimentideks sobiks ka AWS, kuid mind huvitasid just «maliinid» (mis seisis niisama). Seega loome neile Kubernetes klastriga koos Ingress, Prometheus ja Grafana.
«Maliinide» ettevalmistamine
Opsüsteemi ja SSH installimine
Opsüsteemi valimisel ei viibinud ma palju: lihtsalt võtsin kõige värskema Raspberry Pi OS Lite koos . Seal on saadaval , kõik toimingud tuleb teha kõikidel tulevase klastrite sõlmedel. Edasi tuleb teha järgmised toimingud (samuti kõikidel sõlmedel).
Monitori ja klaviatuuri ühendamisel tuleb eelnevalt seadistada võrk ja SSH:
- Klastri tööks peab põhiklosseril olema kindlasti staatiline IP-aadress, töötluspunktidel - vastavalt soovile. Mina eelistasin igal pool staatilisi aadresse seadistamise mugavuse nimel.
- Staatilist aadressi saab konfigureerida opsüsteemis (failis
/etc/dhcpcd.confon sobib näide) või tänu lease fikseerimisele DHCP-serveris, mida kasutatakse (minu puhul — kodus) ruuteris. - ssh-server lülitatakse lihtsalt sisse raspi-configis (liidese valikud → ssh).
Pärast seda saab juba sisse logida SSH kaudu (vaikimisi on kasutajanimi — pi, ja parool — raspberry või see, millele see on muutunud) ja jätkata seadistustega.
Muud seadistused
- Seadistame hostinime. Minu näites kasutatakse
pi-controljapi-worker. - Kontrollime, et failisüsteem on laiendatud kogu ketas (
df -h /). Vajadusel saab seda laiendada raspi-configi abil. - Muudame vaikimisi kasutaja parooli raspi-configis.
- Keen muutame swap-faili välja (see on Kubernetes'e nõue; kui teid huvitavad detailid, vaadake ):
dphys-swapfile swapoff systemctl disable dphys-swapfile - Uuendame paketid uusimatele versioonidele:
apt-get update && apt-get dist-upgrade -y - Installeerime Dockeri ja täiendavad paketid:
apt-get install -y docker docker.io apt-transport-https curl bridge-utils iptables-persistentInstalleerimisel
iptables-persistenton vajalik iptables'i seadistused salvestada ipv4 jaoks, ja faili/etc/iptables/rules.v4— lisada reeglid kettasseFORWARD, nii:# 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 - Alles jääb vaid restartida.
Nüüd on kõik valmis Kubernetes'e klastri installimiseks.
Kubernetes'e installatsioon
Sel etapil olen spetsiaalselt lisanud kõik oma ja meie ettevõtte automatiseerimise rakendamise ja K8s klustrierimise arendused. Selle asemel kasutame ametlikku dokumentatsiooni saidilt (veidi täiendatud kommentaaride ja kokkuvõtetega).
Lisame Kubernetes'i reposi:
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 updateEdasi dokumendis soovitatakse installida CRI (container runtime interface). Kuna Docker on juba installitud, liigume edasi ja installime põhikomponendid:
sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni Põhikomponentide installimise etapis lisasin kohe kubernetes-cni, mis on vajalik klusteri tööks. Siin on oluline punkt: pakett kubernetes-cni mingil põhjusel ei loo vaikimisi kausta CNI-liideste seadistamiseks, seega pidin selle käsitsi looma:
mkdir -p /etc/cni/net.dNetwork-bäkendi tööks, millest räägitakse allpool, on vajalik CNI plugina täiendav installimine. Valisin tuttava ja arusaadava plugina portmap (täielik nimekiri on nähtav punktis ):
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/ ./portmapKubernetesi seadistamine
Control plane'i sõlm
Klastri installimine on üsna lihtne. Protsessi kiirendamiseks ja selle kontrollimiseks, et Kubernetesi pildid on kergesti saadaval, võite eelnevalt käivitada järgmise käsu:
kubeadm config images pullNüüd teeme installatsiooni — initsialiseerime klastris control plane'i:
kubeadm init --pod-network-cidr=10.1.0.0/16 --service-cidr=10.2.0.0/16 --upload-certsPange tähele, et teenuste ja pod'ide alavõrgud ei tohi üksteisega ega olemasolevate võrkudega kattuda.
Lõpus kuuleme sõnumit, et kõik on hästi, ja antakse ka juhised, kuidas liita tööseisundid control plane'iga:
Teie Kubernetes juhtimislennuk on edukalt initsialiseeritud!
Klastri kasutamiseks peate tavalise kasutajana käivitama järgmised käsud:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Nüüd peaksite klastrisse kasutusele võtma pod-võrgu.
Käivitage "kubectl apply -f [podnetwork].yaml" ühe valiku abil, mis on loetletud aadressil:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Nüüd saate ühendada suvalise arvu juhtimislennuki sõlmi, käivitades järgmise käsu igaühel juurena:
kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4
--discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050
--control-plane --certificate-key 72a3c0a14c627d6d7fdade1f4c8d7a41b0fac31b1faf0d8fdf9678d74d7d2403
Palun pidage meeles, et sertifikaadi võti annab juurdepääsu klastrite tundlikule teabele, hoidke seda saladuses!
Kaitseks kustutatakse üleslaaditud sertifikaadid kahe tunni pärast; Kui vajalik, saate kasutada
"kubeadm init phase upload-certs --upload-certs" sertifikaatide uuesti laadimiseks.
Seejärel saate ühendada suvalise arvu töötlussõlmi, käivitades igaühel juurena järgmise käsu:
kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4
--discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050Teeme soovitused konfi lisamiseks kasutajale. Samuti soovitan kohe lisada kubectl jaoks automaatset täiendamist:
kubectl completion bash > ~/.kube/completion.bash.inc
printf "
# Kubectl shell completion
source '$HOME/.kube/completion.bash.inc'
" >> $HOME/.bash_profile
source $HOME/.bash_profileSelles etapis on juba võimalik näha klastris esimest sõlme (kuigi see pole veel valmis):
root@pi-control:~# kubectl get no
NIMED OLEK ROLLID VANUS VERSIOON
pi-control NotReady master 29s v1.18.6Võrgu konfiguratsioon
Edasi, nagu mainitud pärast installimist, on vaja seadistada võrk klastrisse. Dokumentatsioon pakub valikuid Calico, Cilium, contiv-vpp, Kube-router ja Weave Net... Siin ma kaldusin kõrvale ametlikest juhistest ja valisin endale tuttavama ja arusaadavama variandi: host-gw režiimis (rohkem saadaval olevate taustade kohta vt ).
Selle installimine klastrisse on üsna lihtne. Esiteks - laadige alla manifestid:
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Seejärel muudame seadetes tüübi vxlan järgnevaga host-gw:
sed -i 's/vxlan/host-gw/' kube-flannel.yml... ja pod'ide alamvõrk - vaikimisi väärtusest sellele, mis on määratud klastrit algatades:
sed -i 's#10.244.0.0/16#10.1.0.0/16#' kube-flannel.ymlPärast seda loome ressursid:
kubectl create -f kube-flannel.yml Valmis! Mõne aja pärast läheb esimene K8s sõlm olekusse Valmis:
NIMED OLEK ROLLID VANUS VERSIOON
pi-control Valmis master 2m v1.18.6Töötava sõlme lisamine
Nüüd saab lisada töötaja. Selleks tuleb pärast Kubernetes'i installimist eespool kirjeldatud stsenaariumi järgi lihtsalt täita eelnevalt saadud käsk:
kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4
--discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050Selle võib lugeda klastriks valmis:
root@pi-control:~# kubectl get no
NIMI OLEK ROLLID VANUS VERSIOON
pi-control Valmis master 28m v1.18.6
pi-worker Valmis 2m8s v1.18.6Mul oli käepärast ainult kaks Raspberry Pi, nii et mulle ei meeldinud üks neist ainult control plane'ile anda. Seetõttu eemaldasin automaatselt määratud taandi sõlme pi-control, käivitades:
root@pi-control:~# kubectl edit node pi-control… ja kustutasin read:
- effect: NoSchedule
key: node-role.kubernetes.io/masterKlastri vajalik minimaalne täitmine
Esiteks vajame Helm. Muidugi, saab kõik teha ka ilma selleta, kuid Helm võimaldab määrata teatud komponente täiesti ilma failide muutmiseta. Ja tegelikult on see lihtsalt binaarfail, mis "leiba ei küsi".
Nii et, läheme docs/installatsiooni sektsiooni ja täidame sealt selle käsu:
curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bashPärast seda lisame chartide reposi:
helm repo add stable https://kubernetes-charts.storage.googleapis.com/Nüüd paigaldame infrastruktuuri komponente vastavalt kavandatule:
- Ingress controller;
- Prometheus;
- Grafana;
- cert-manager.
Ingress controller
Esimene komponent — Ingress controller — on seda üsna lihtne seadistada ja see on «karbist» valmis kasutamiseks. Selleks piisab, kui minna ja käivitada sealt installimiskäsk:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/baremetal/deploy.yamlKuid sel hetkel hakkas «maliin» pingutama ja IOPS-i vastu seisma. Asi on selles, et koos Ingress-kontrolleriga installitakse suur hulk ressursse, tehtakse palju API-päringuid ja seega kirjutatakse palju andmeid etcd-sse. Ühesõnaga, kas 10. klassi mälukaart ei ole eriti efektiivne või SD-kaartide maht ei piisa sellise koormuse jaoks. Küll aga pärast viit minutit kõik käivitus.
Loodi namespace ja sinna tekkis kontroller koos kogu vajalikuga:
root@pi-control:~# kubectl -n ingress-nginx get pod
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-2hwdx 0/1 Completed 0 31s
ingress-nginx-admission-patch-cp55c 0/1 Completed 0 31s
ingress-nginx-controller-7fd7d8df56-68qp5 1/1 Running 0 48sPrometheus
Järgmised kaks komponenti on üsna lihtne installida Helm'i kaudu chart repo'st.
Leiame Prometheus, loome namespace ja installime sinna:
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"}Vaikimisi tellib Prometheus 2 ketast: ühte Prometheuse andmete jaoks ja teist AlertManageri andmete jaoks. Kuna klastris ei ole loodud storage class'i, ei tellita kettaid ja pod'id ei käivitu. Bare metal'ite Kubernetes'i installatsioonide puhul kasutame tavaliselt Ceph rbd, kuid Raspberry Pi puhul on see ilmselge ülemäärasus.
Seetõttu loome lihtsa kohalikku salvestust hostpath'il. PV (persistent volume) manifestid prometheus-server'i ja prometheus-alertmanager'i jaoks on ühendatud failis prometheus-pv.yaml ühes . PV jaoks tuleb ette luua kataloog soovitud sõlmes, millega tahame Prometheust siduda: näites on kirjeldatud nodeAffinity hostname järgi pi-worker ja seal on loodud kataloogid. /data/localstorage/prometheus-server ja /data/localstorage/prometheus-alertmanager.
Laadime (kloneerime) manifesti ja lisame Kubernetesesse:
kubectl create -f prometheus-pv.yamlSellel etapil kohtasin esmakordselt ARM-arkitektuuri probleemi. Kube-state-metrics, mis installitakse vaikimisi Prometheuse charts, keeldus käivitumisest. See andis vea:
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"Asi on selles, et kube-state-metrics kasutab CoreOS projekti pilti, mis ei ole ARM-i jaoks koostatav:
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.7Pidin veidi guugeldama ja leidma näiteks . Selleks kasuta uuendame välja, märkides ära, millist pilti kasutada kube-state-metrics'i jaoks:
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.6Kontrollime, et kõik oleks käimas:
root@pi-control:~# kubectl -n monitoring get po
NAME READY STATUS RESTARTS AGE
prometheus-alertmanager-df65d99d4-6d27g 2/2 Running 0 5m56s
prometheus-kube-state-metrics-5dc5fd89c6-ztmqr 1/1 Running 0 5m56s
prometheus-node-exporter-49zll 1/1 Running 0 5m51s
prometheus-node-exporter-vwl44 1/1 Running 0 4m20s
prometheus-pushgateway-c547cfc87-k28qx 1/1 Running 0 5m56s
prometheus-server-85666fd794-z9qnc 2/2 Running 0 4m52sGrafana ja cert-manager
Kuidas graafikute ja dashboardide jaoks paigaldada Grafana:
helm install grafana --namespace monitoring stable/grafana --set ingress.enabled=true --set ingress.hosts={"grafana.home.pi"}Väljundi lõpus näitame, kuidas saada autentimiskoode:
kubectl get secret --namespace monitoring grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echoSertifikaatide tellimiseks paigaldame cert-manager. Selle paigaldamiseks saame juhinduda , mis pakub vastavaid käske Helm'i jaoks:
helm repo add jetstack https://charts.jetstack.io
helm install
cert-manager jetstack/cert-manager
--namespace cert-manager
--version v0.16.0
--set installCRDs=trueIseendale allkirjastatud sertifikaatide jaoks on kodus selleks täiesti piisav. Kui aga soovite saada sama Let’s Encrypt, tuleb seadistada ka cluster issuer. Täiendava teabe leiate meie artiklist „».
Olen ise valiku teinud dokumentatsioonis olevast , решив, что staging-варианта LE будет достаточно. Изменяем в примере e-mail, сохраняем в файл и добавляем в кластер ():
kubectl create -f cert-manager-cluster-issuer.yamlNüüd saab tellida sertifikaadi, näiteks Grafana jaoks. Selleks on vajalik domeen ja juurdepääs klastrisse väljastpoolt. Domeen mul on, ja olen seadistanud liikluse suunamise portidele 80 ja 443 kodu ruuteris vastavalt loodud ingress-controller'i teenusele:
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 23d80. port suunisesed üleviakse 31303 ja 443 — 30498. (Portid genereeritakse juhuslikult, seega võivad need olla teised.)
Siin on näide sertifikaadist ():
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-stagingLisame selle klastrisse:
kubectl create -f cert-manager-grafana-certificate.yamlPärast seda ilmub Ingress ressurss, mille kaudu toimub Let’s Encrypt’i valideerimine:
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 Pärast valideerimise läbimist näeme, et ressurss certificate on valmis, ja ülaltoodud salajas grafana-tls — sertifikaat ja võti. Võime kohe kontrollida, kes sertifikaadi välja andis:
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 X1Naasime Grafanasse. Peame natuke muutma tema Helm-rakendust, muutes TLS-i seadeid vastavalt loodud sertifikaadile.
Selleks laadime charti alla, muudame ja värskendame kohalikust kataloogist:
helm pull --untar stable/grafana Redigeerime failis grafana/values.yaml TLS-i seaded:
tls:
- secretName: grafana-tls
hosts:
- grafana.home.pi Siin on otse võimalik seadistada installitud Prometheust andmeallikaks:
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus-server:80
access: proxy
isDefault: trueNüüd värskendame kohalikust kataloogist Grafana charti:
helm upgrade grafana --namespace monitoring ./grafana --set ingress.enabled=true --set ingress.hosts={"grafana.home.pi"} Kontrollime, et Ingress grafana oleks lisatud 443 port ja oleks juurdepääs HTTPS-i kaudu:
root@pi-control:~# kubectl -n monitoring get ing grafana
NAME CLASS HOSTS ADDRESS PORTS AGE
grafana <none> grafana.home.pi 192.168.88.31 80, 443 63m
root@pi-control:~# curl -kI https://grafana.home.pi
HTTP/2 302
server: nginx/1.19.1
date: Tue, 28 Jul 2020 19:01:31 GMT
content-type: text/html; charset=utf-8
cache-control: no-cache
expires: -1
location: /login
pragma: no-cache
set-cookie: redirect_to=%2F; Path=/; HttpOnly; SameSite=Lax
x-frame-options: deny
strict-transport-security: max-age=15724800; includeSubDomainsGrafana toimimise demonstreerimiseks saab alla laadida ja lisada Nii see välja näeb:

Soovitan ka lisada node exporter'i dashboardi: see näitab üksikasjalikult, mis toimub 'maliinidega' (CPU koormus, mälu, võrgu, ketta ja muu kasutus).
Pärast seda usun, et klaster on valmis rakenduste vastuvõtmiseks ja käitamiseks!
Märkus koostamise kohta
Rakenduste koostamiseks ARM-architektuuri alla on vähemalt kaks varianti. Esiteks, saab koostada ARM-seadmest. Kuid vaadates kahe Raspberry Pi praegust kasutust, sain aru, et nad ei peaks isegi koostamist vastu. Seega tellisin endale uue Raspberry Pi 4 (see on jõulisem ja seal on lausa 4 GB mälu) — plaanin sellel koostada.
Teine võimalus on multicontainer Docker'i pildi koostamine võimsamal masinal. Selleks on . Kui rakendus on koostatud keeles, mis vajab kompileerimist, siis on vajalik kross-kompileerimine ARM-i jaoks. Ma ei hakka kõiki seadistusi sellise tee jaoks kirjeldama, kuna see tooks kaasa eraldi artikli. Selle lähenemise rakendamisel on võimalik saavutada "üldised" pildid: Docker, mis töötab ARM-masinal, laadib automaatselt vastava arhitektuuri pildi.
Kokkuvõte
Tehtud katse ületas kõik mu ootused: [kuni] "vanilje" Kubernetes vajaliku baasi korral tunneb end ARM-il üsna hästi, ja selle seadistamise käigus tekkis vaid paar nüanssi.
Isegi Raspberry Pi 3B+ peavad CPU koormust, kuid nende SD-kaardid on selge pudelikael. Kolllegid ütlesid, et mõnedes versioonides on võimalus käivituda USB-st, kuhu saab ühendada SSD: siis on tõenäoliselt olukord parem.
Siin on näide CPU koormusest Grafana installimisel:

Eksperimentide ja „katsetamiseks“ arvan, et Kubernetes-klaster „malinatel“ edastab tunde eksploateerimisest tunduvalt paremini kui sama Minikube, kuna kõik klaseeri komponendid seadistatakse ja töötavad „täiskasvanulikult“.
Tulevikus on plaanis lisada klastrile kogu CI/CD tsükkel, mis on täielikult Rakvere Pi peal teostatud. Samuti oleksin tänulik, kui keegi jagaks oma kogemusi K8s seadistamise osas AWS Graviton'itel.
P.S. Jah, "production" võib olla lähemal, kui ma arvasin:

P.P.S.
Lugege ka meie blogist:
- «».
Allikas: habr.com
