Oracle Cloud Infrastructure (OCI) a apărut în peisajul serviciilor cloud publice în anul 2016. Deși nu atât de vestit ca AWS, GCP sau MS Azure, OCI oferă anumite avantaje; mă refer strict la resursele pe care le oferă free și care vor fi întotdeaua free. Cu ajutorul celor 4 instanțe cu procesoare ARM și a uneia din celelalte două instanțe cu 1 OCPU (1OCPU = 2vCPUs) și 1 GB RAM, vom instala un cluster Kubernetes multi-master (cu 2 mastere - funcționează perfect cu doar 2 noduri master: am testat clusterul cu 2, 1 și iar cu 2 noduri master) și cu 2 workeri, folosind un super instrument numit k3s.
K3s (https://k3s.io/) este un Kubernetes destinat aplicațiilor IoT sau mediilor care au puține resurse la dispoziție, putând fi instalat și pe procesoarele ARM oferite de Oracle Cloud în pachetul lor always free.
Așadar, să începem:
Primul pas este, normal, crearea unui cont la Oracle Cloud Free Tier - durează în jur de 12 ore aprobarea și activarea lui.
Networking
Vom începe prin a crea un VCN (Virtual Cloud Network). Se merge la Networking - Virtual Cloud Networks, click pe Start VCN Wizzard; se selectează opțiunea Create VCN with Internet Connectivity:
Se configurează VCN-ul ca mai jos:
Click pe Next, se revizuiesc informațiile, apoi click pe Create:
Noul VCN va avea un subnet public și unul privat.
Configurare Security Lists
Vom configura firewall-ul: porturile prin care vom putea ajunge la aplicațiile instalare pe mașinile care vor fi ridicate în VCN-ul nostru.
În meniul VCN, se merge la Network - Security Lists:
În cele 2 subneturi (public și privat), vom adăuga următoarele reguli Ingress - regulile vor permite comunicarea între serviciile din aceste subneturi, vom deschide portul 80 către toate IP-urile și portul 6443 DOAR în subnetul public (pentru a putea accesa ulterior clusterul nostru k3s de pe mașina locală):
Instanțe necesare clusterului multi-master k3s
Clusterul nostru k3s va fi format dintr-o bază de date externă mysql (necesară pentru High Availability în k3s) instalată pe un shape VM.Standard.E2.1.Micro, 2 noduri master și 2 noduri worker instalate pe un shape VM.Standard.A1.Flex. Baza de date Mysql, un master și cei doi workeri vor fi creați în subnetul privat, iar un master va fi în subnetul public.
Din păcate, Oracle Cloud nu oferă o opțiune asemănătoare cu Launch more like this din AWS, așa că fiecare din cele 4 instanțe ale clusterului va trebui creată individual.
Baza de date Mysql
În meniul Oracle Cloud, mergem la Compute - Instances și click pe Create Instance. Vom alege imaginea Oracle Linux 7.9, iar ca shape, cum am mai spus, VM.Standard.E2.1.Micro; instanța va fi creată în subnetul privat din VCN-ul creat anterior:
Foarte important este să creăm local o cheie ssh pe care o vom folosi strict pentru conectarea la mașinile din Oracle Cloud. Vom selecta încărcarea cheii publice și criptare în tranzit pentru volumul de boot:
Se revizuiesc informațiile și click pe Create.
Nodurile pentru master
Aceste 2 mașini virtuale vor avea rolul de master pentru clusterul nostru kubernetes. Procesul de creare a instanțelor este asemănător cu cel de la baza de date mysql: vom folosi ca imagine tot Oracle Linux 7.9, iar ca shape VM.Standard.A1.Flex. La fel, încărcăm cheia publică și setăm criptarea în tranzit pentru discul de boot. De menționat că una din cele două instanțe va fi în subnetul public (pentru a ne putea conecta la ea prin intermediul IP-ului public), iar cealaltă va fi creată în subnetul privat. În imaginea de mai jos este prezentată crearea masterului din subnetul public:
Nodurile pentru worker
Vor folosi aceeași imagine Oracle Linux 7.9 și același shape VM.Standard.A1.Flex ca la nodurile pentru master, cu deosebirea că ambele vor fi create în subnetul privat.
La final, vom avea o instanță în subnetul public (va avea rolul de master) și 4 în subnetul privat (una va fi baza de date mysql, una va avea rolul de master și celelalte 2 vor fi noduri worker):
Crearea clusterului multi-master k3s
Ei..., abia acum începe partea frumoasă. 🙂
Ne vom conecta la mașina din subnetul privat folosind cheia privată și userul opc:
ssh -i /cale/catre/cheia/privata opc@<ip-public>
După logarea pe mașina din subnetul public, vom copia cheia privată de pe mașina locală, după care ne putem conecta la oricare din celelalte instanțe create.
Pentru a merge instalarea mai repede, vom dezactiva firewall-ul pe toate cele 5 mașini:
sudo systemctl disable --now firewalld
Nu este recomandat; normal este să deschideți doar porturile necesare (comenzi utile pentru firewalld aici):
- pe baza de date mysql - portul 3306
- pe noduri (k3s-servers și k3s-agents) - https://rancher.com/docs/rancher/v2.x/en/installation/requirements/ports/#ports-for-rancher-server-nodes-on-k3s:
- 80/TCP - pentru un eventual load balancer
- 443/TCP - atât pe nodurile master (k3s srevr), cât și pe nodurile worker (k3s-agent)
- 6443/TCP - pe master
- 8472/UDP - pe toate nodurile (doar în cazul în care se folosește Flannel ca soluție de networking în cluster)
- 10250/TCP - pe toate nodurile (pentru kubelet)
Configurare /etc/hosts
În fișierul /etc/hosts de pe fiecare mașină vom adăuga următoarele intrări - vom folosi IP-urile private ale fiecărei mașini (se va înlocui cu IP-ul privat corespunzător):
10.0.1.220 mysql-k3s
10.0.0.236 master-k3s-01
10.0.0.236 master-k3s
10.0.1.148 master-k3s-02
10.0.1.148 master-k3s
10.0.1.50 worker-k3s-02
Instalare și setup Mariadb
Ne conectăm la instanța destinată bazei de date mysql. Vom instala MariaDB 10.3. Vom adăuga repo-ul necesar:
cat << EOF > /etc/yum.repos.d/mariadb.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.3/centos73-amd64/
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
EOF
sudo yum install MariaDB-server MariaDB-client
sudo systemctl enable --now mariadb.service
## Doar in cazul in care aveti firewalld activat
sudo firewall-cmd --permanent --zone=public --add-service=mysql
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
Vom securiza baza de date proaspăt instalată rulând scriptul de mai jos (se setează parola de root pentru DB, se șterge userul anonymous, se șterge baza de date de test și se dezactivează logarea remote pentru userul root):
sudo mysql_secure_installation
În continuare, vom crea baza de date k3s și un user pentru a o accesa remote. Această bază de date va fi folosită de k3s-server (masterele) pentru High Availabiliy:
mysql -u root -p
use mysql;
UPDATE user SET plugin='' WHERE User='root';
FLUSH PRIVILEGES;
exit;
mysql -u root -p
CREATE database k3s;
CREATE user 'k3s'@'%' IDENTIFIED BY 'parola-buna';
GRANT ALL on k3s.* TO 'k3s'@'%';
FLUSH PRIVILEGES;
use mysql;
UPDATE user SET plugin='' WHERE User='k3s';
FLUSH PRIVILEGES;
exit;
Crearea clusterului k3s
Configurarea masterelor
Suntem conectați pe master-k3s-01 și vom rula comanda de mai jos (se înlocuiește xxx.xxx.xxx.xxx cu IP-ul public al nodului, pentru a permite configurarea certificatului din cluster și pentru adresa IP publică, nu numai pentru cele private ale nodurilor - este necesar pentru a accesa clusterul din exterior):
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--write-kubeconfig-mode 644 --token secret-f455-djjcd554 --tls-san xxx.xxx.xxx.xxx" sh -s - server --datastore-endpoint="mysql://k3s:parola-buna@tcp(mysql-k3s:3306)/k3s"
Explicații opțiuni de instalare:
- https://rancher.com/docs/k3s/latest/en/installation/install-options/server-config/
- https://rancher.com/docs/k3s/latest/en/installation/install-options/
După finalizarea execuției comenzii, ne asigurăm ca totul a decurs cum trebuie și că serviciul k3s e up and running:
systemctl status k3s
Acum, avem primul nod în noul nostru cluster. 🙂 După rularea comenzii kubectl get nodes
, vom avea:
Rulăm aceeași comandă și pe nodul destinat să fie masterul nr. 2.
Notă!
Pentru referințe ulterioare, să reținem că certificatele clusterului k3s se află în directorul /var/lib/rancher/k3s/server/tls (pentru mastere), iar pentru agenți în directorul /var/lib/rancher/k3s/agent.
Fișierul kubeconfig se află la /etc/rancher/k3s/k3s.yaml.
De asemenea, k3s se poate dezinstala rulând scripul situat la /usr/local/bin/k3s-uninstall.sh.
Configurarea workerilor
Tokenul necesar adăugării nodurilor worker în cluster se află pe master în /var/lib/rancher/k3s/server/node-token și va fi de forma:
K1035gfdsjksdhjfe6ab2a3071147c479083d56af01a0b9936ebfe3ee6ce4e0e32bbc1f::server:secret-f455-djjcd554
Copiem acest token și construim comanda necesară pentru adăugarea workerilor:
curl -sfL https://get.k3s.io | K3S_URL=https://master-k3s:6443 K3S_TOKEN=<aici_tokenul> sh -
Rulăm comanda pe cele 2 instanțe din subnetul privat destinate să fie worker. Ne asigurăm că serviciul k3s-agent rulează:
systemctl status k3s-agent
Verificare funcționalitate cluster k3s
Vom crea un pod nginx, îl vom expune, apoi vom verifica conectivitatea la pod și la serviciu.
kubectl run nginx --image=nginx
kubectl get po -owide
kubectl expose pod nginx --name nginx-service --type=ClusterIP --port=80
kubectl get svc
Vom ridica un pod de test cu imaginea alpine și vom folosi comenzile nslookup (pentru verificarea funționalității DNS-ului în cluster) și wget pentru a accesa podul și serviciul nginx (în imagine se observă răspunsurile pe care trebuie să le primim):
kubectl run test --image=alpine --restart=Never --rm -it -- sh
# nslookup nginx-service.default.svc.cluster.local
# nslookup 10-42-2-3.default.pod.cluster.local
# wget -O- nginx-service:80
# wget -O- 10.42.2.3:80
# nc -z -v -w 2 nginx-service 80
# exit
Totul pare să fie în regulă. 🙂
Accesarea din exterior a clusterului k3s
După ce am configurat și instalat propriul nostru cluster k3s în Oracle Cloud Free Tier, poate ne este mai ușor să-l accesăm de pe mașina locală, nemaitrebuind să ne conectăm de fiecare dată la masterul din subnetul public. Va trebui să copiem local fișierul kubeconfig, să-l edităm cu adresa IP publică a masterului și... cam gata.
Fișierul kubeconfig se află pe master în locația etc/rancher/k3s/k3s.yaml. Îl copiem pe mașina locală și-i schimbăm permisiunile:
scp -i ~/.ssh/oracle-cloud_ecdsa opc@IP_PUBLIC_MASTER-01:/etc/rancher/k3s/k3s.yaml .
chmod 600 ~.k3s.yaml
Îl edităm și, la adresa serverului k3s, în loc de 127.0.0.1 vom trece IP-ul masterului aflat în subnetul public. Deoarece am construit clusterul cu opțiunea --tls-san, certificatul clusterului are definită și adresa IP publică a masterului 01, iar noi vom putea să-l accesăm din exterior ca și cum am fi conectați pe mastere:
kubectl get node -owide --kubeconfig /cale/către/fișierul/kubeconfig/descărcat/k3s.yaml
sau, pentru a nu indica de fiecare dată calea către fișierul kubeconfig, vom exporta variabila corespunzătoare:
export KUBECONFIG=/cale/către/fișierul/kubeconfig/descărcat/k3s.yaml
kubectl get no
În partea superioară a imaginii de mai sus este clusterul k3s accesat de pe master-k3s-01, iar în partea de jos este clusterul accesat de pe mașina locală (cu Fedora 34).
Instalarea unei aplicații
Voi folosi pentru exemplificare cea mai simplă aplicație care permite trimiterea de requesturi http și https: httpbin.
Imaginea creată de dezvoltatorul aplicației nu permite (încă) rularea pe procesoare ARM, așa că o vom instala dintr-un fork: https://hub.docker.com/r/arnaudlacour/httpbin.
Ca să fie lucrurile un pic mai frumoase, vom folosi Helm și un chart httpbin: https://github.com/twingao/httpbin.
Vom începe prin a clona repository-ul chartului:
git clone https://github.com/twingao/httpbin.git
Va trebui să modificăm un pic fișierul values.yaml care vine din chart - vom schimba imaginea și vom folosi NodeSelector pentru a-i spune podului care va fi creat să se ducă pe nodul aflat în subnetul public (master-k3s-01), astfel încât să putem accesa aplicația din exterior:
cd httpbin
cp values.yaml my-values.yaml
vim my-values.yaml
Modificările în fișierul my-values.yaml sunt:
[...]
image:
repository: docker.io/arnaudlacour/httpbin
[...]
nodeSelector:
kubernetes.io/hostname: master-k3s-01
Instalăm chartul:
helm install httpbin httpbin -f httpbin/my-values.yaml --kubeconfig ~/k3s.yaml
Căutăm podul și ne asigurăm că s-a dus pe nodul care trebuie:
kubectl get po -owide --kubeconfig ~/k3s.yaml | grep httpbin
httpbin-5fc54dbfbc-vwnp5 1/1 Running 0 1m 10.42.0.13 master-k3s-01
Va trebui să deschidem portul 30080 pe nodul master-k3s-01 pentru a putea fi accesat din exterior. Mergem la Networking - Virtual Cloud Networks, selectăm VCN-ul main, click pe Public Subnet și edităm Default Security List prin adăugarea unei noi reguli Ingress:
Pentru a fi siguri că nimeni în afară de noi nu are acces la aplicație, la Source CIDR se poate specifica o singură adresă IP (a noastră), sub forma: AdresăIP/32.
Accesăm în browser adresa http://IP_Public_nod_master-k3s-01:30080:
Concluzii
Am făcut un cluster kubernetes perfect funcțional pe procesoare ARM - aplicațiile pe care le veți instala trebuie să suporte aceste procesoare.
Fiecare e liber să facă ce crede de cuviință: să folosească acest cluster k3s pentru testarea aplicațiilor containerizate sau pentru simpla învățare a kubernetesului.
Have fun!
[…] cazul în care folosiți clusterul k3s construit în contul free tier de la Oracle Cloud, acesta se află la /var/lib/rancher/k3s/server/tls/server-ca.crt, iar comanda va […]