Kubernetes Lisapraktika
Eeldused: Kubernetes labor.md läbitud, e-pood töötab, Minikube seadistatud
Platvorm: Minikube, kubectl CLI
Need harjutused täiendavad põhilabi ja lähevad sügavamale Kubernetes kontseptsioonidesse. Kui labor.md tutvustas põhimõisteid, siis siin praktiseerid neid tõsisemates stsenaariumides.
Eeldus: Oled teinud labor.md lõpuni ja e-pood töötab (postgres, backend, frontend deployment'id on rakendatud).
Mida õpid:
- Labor näitas kuidas deployment luua → Siin õpid seda skaleerima ja load balancing'ut testima
- Labor näitas ConfigMap'e → Siin õpid neid muutma ilma downtime'ita
- Labor näitas probe'sid → Siin õpid neid seadistama ja testima
Nõuded:
- Minikube töötab (
minikube status) - kubectl installitud ja töötab
- Põhilab e-pood rakendatud (
kubectl get podsnäitab postgres-0, backend-api-xxx, frontend-xxx)
1. Skaleerimine ja Load Balancing
Labor.md näitas kubectl scale käsku põgusalt. Siin õpid skaleerima backend'i mitmeks koopiaks ja testima kuidas Kubernetes Service teeb load balancing'u. Backend skaleeritakse 1 → 5 pod'i ja vaatame kuidas päringud jaotuvad.
Service teeb round-robin load balancing: päring 1 → pod 1, päring 2 → pod 2, jne.
1.1 Probleem
Ühe pod'iga backend ei suuda käsitleda suurt päringute hulka. Kui kasutajaid on palju, tekivad latency probleemid või pod crashib high load all. Lahendus on skaleerida mitmeks pod'iks ja lasta Service'l jagada päringuid nende vahel.
1.2 Lahendus
Kubernetes Service teeb automaatset load balancing'ut kõigi tervete pod'ide vahel. Kui skaleeriksime backend'i 5 pod'iks, jagab Service päringud ühtlaselt kõigi vahel.
# Vaata praegust seisu
kubectl get pods -l app=backend
# Skalee 5 koopiaks
kubectl scale deployment backend-api --replicas=5
# Vaata kuidas pod'id luuakse
kubectl get pods -l app=backend -w
# Ctrl+C pärast kui kõik Running
# Kontrolli - peaks olema 5 pod'i
kubectl get pods -l app=backend
Testimine:
Lisa backend koodi juurde pod hostname, et näha kumba pod'i päring läks.
Lisa server.js faili /api/products endpoint'i juurde hostname:
// API: kõik tooted
app.get('/api/products', async (req, res) => {
try {
const result = await pool.query('SELECT * FROM products ORDER BY id');
res.json({
success: true,
count: result.rows.length,
pod: process.env.HOSTNAME, // ← LISA SEE RIDA
data: result.rows
});
} catch (err) {
console.error('Database error:', err);
res.status(500).json({ error: err.message });
}
});
# Rakenda muudatus
kubectl apply -f ~/k8s-lab/backend/1-configmap.yaml
# Restart pod'id
kubectl rollout restart deployment backend-api
kubectl rollout status deployment backend-api
# Port forward
kubectl port-forward service/backend-service 3000:3000 &
# Tee 10 päringut ja vaata pod'i nimesid
for i in {1..10}; do
curl -s http://localhost:3000/api/products | grep -o '"pod":"[^"]*"'
sleep 0.5
done
kill %1
Näed erinevaid pod nimesid - päringud jaotuvad kõigi pod'ide vahel!
1.3 Harjutus: Testi Load Balancing'u
Nõuded:
- Backend skaleeritud vähemalt 3 pod'iks
- Endpoint tagastab pod hostname'i
- 20 järjestikust päringut näitavad erinevaid pod nimesid
- Vaata Service endpoints:
kubectl get endpoints backend-service
Näpunäiteid:
- Service hoiab kõigi pod'ide IP'd:
kubectl describe endpoints backend-service - Kui pod'id ei käivitu, kontrolli ressursse:
kubectl describe nodes - Vähenda replikaid kui VM'il pole piisavalt ressursse
Testimine:
# Kontrolli et Service leiab kõik pod'id
kubectl get endpoints backend-service
# Peaks näitama 3+ IP aadressi
# Test load distribution
for i in {1..20}; do
curl -s http://localhost:3000/api/products | jq -r '.pod'
done | sort | uniq -c
# Peaks näitama ühtlast jaotust
Boonus:
- Tapa üks pod käsitsi:
kubectl delete pod <pod-name>ja vaata kuidas Service automaatselt eemaldab selle endpoints'ist - Skalee 10 pod'iks ja mõõda response time'i erinevust
2. Rolling Update ja Rollback
Labor.md näitas deployment'i loomist. Siin õpid uuendama rakendust zero downtime'iga. Kubernetes teeb rolling update - loob uued pod'id enne vanade kustutamist.
2.1 Probleem
Produktsioonis ei saa lihtsalt kõiki pod'e kustutada ja uued luua - tekib downtime. Kasutajad näeksid errori lehti update'i ajal. Rolling update lahendab selle luues uued pod'id järk-järgult ja kustutades vanad alles kui uued töötavad.
2.2 Lahendus
Kubernetes rolling update garanteerib, et alati on vähemalt 1 pod töötamas. Protsess: 1. Loo 1 uus pod uue versiooniga 2. Oota kuni see valmis (readiness probe) 3. Kustuta 1 vana pod 4. Korda kuni kõik uuendatud
# Vaata praegust versiooni
kubectl rollout history deployment/frontend
# Uuenda frontend (v2.0)
nano ~/k8s-lab/frontend/1-html.yaml
Muuda: 1. Background gradient (rea ~13):
- Versiooni number (rea ~25):
Rollback kui vaja:
# Vaata ajalugu
kubectl rollout history deployment/frontend
# Rollback eelmisele versioonile
kubectl rollout undo deployment/frontend
# Jälgi
kubectl rollout status deployment/frontend
2.3 Harjutus: Zero-Downtime Update
Nõuded:
- Frontend skaleeritud 3 pod'iks
- Deployment strategy seadistatud: maxUnavailable=1, maxSurge=1
- Tee update, mis muudab visuaali (värv või tekst)
- Jälgi rolling update protsessi:
kubectl get pods -w - Tee rollback eelmisele versioonile
Näpunäiteid:
- Muuda deployment strategy:
nano ~/k8s-lab/frontend/3-deployment.yaml - Lisa
spec.strategy.rollingUpdatesektsioon - Update'i ajal peaks alati olema vähemalt 2 pod'i running (kui 3 kokku)
Testimine:
# Muuda strategy
kubectl edit deployment frontend
# Lisa:
# strategy:
# type: RollingUpdate
# rollingUpdate:
# maxUnavailable: 1
# maxSurge: 1
# Tee update ja jälgi
kubectl set image deployment/frontend frontend=nginx:alpine
kubectl get pods -w
# Näed kuidas vanad pod'id termineeruvad järk-järgult
Boonus:
- Määra annotation rollout history'le:
kubernetes.io/change-cause: "Updated to v2.0" - Tee Blue-Green deployment simulatsioon kahe deployment'iga
3. ConfigMap Muutmine
Labor.md lõi ConfigMap'e, aga ei näidanud kuidas neid muuta. ConfigMap muutus EI UUENDA automaatselt pod'e - pead pod'id restartima.
3.1 Probleem
Backend vajab uut endpoint'i, aga ConfigMap muutmine ei rakendu automaatselt pod'ides. Pod'id mountivad ConfigMap'i käivituse ajal ja ei jälgi muudatusi.
3.2 Lahendus
Muuda ConfigMap'i ja restart pod'id rolling update'iga. Pod'id võtavad uue ConfigMap'i sisu käivituse ajal.
Lisa server.js faili lõppu:
// Uus endpoint - info
app.get('/api/info', (req, res) => {
res.json({
version: '1.0',
pod: process.env.HOSTNAME || 'unknown',
uptime: process.uptime(),
timestamp: new Date()
});
});
# Rakenda ConfigMap muudatus
kubectl apply -f ~/k8s-lab/backend/1-configmap.yaml
# TÄHTIS: ConfigMap on uuendatud, AGA pod'id kasutavad ikka vana!
# Test - vana kood veel töötab
kubectl port-forward service/backend-service 3000:3000 &
curl http://localhost:3000/api/info
# 404 Not Found ← Vana kood
kill %1
# Restart pod'id
kubectl rollout restart deployment backend-api
kubectl rollout status deployment backend-api
# Test - uus kood töötab
kubectl port-forward service/backend-service 3000:3000 &
curl http://localhost:3000/api/info
# {"version":"1.0","pod":"backend-api-xxx",...}
kill %1
3.3 Harjutus: Uuenda API Endpoint'i
Nõuded:
- Lisa backend ConfigMap'i uus endpoint
/api/health - Endpoint tagastab JSON:
{status: "healthy", checks: {...}} - Rakenda ConfigMap ilma pod'ide restartita
- Kontrolli et vana kood veel töötab
- Restart pod'id ja kontrolli et uus kood töötab
Näpunäiteid:
- ConfigMap muutus nähtav:
kubectl get configmap backend-code -o yaml - Pod'id kasutavad vana kuni restart'ini
- Rolling restart:
kubectl rollout restart deployment backend-api
Testimine:
# Kontrolli ConfigMap
kubectl describe configmap backend-code | grep -A10 "/api/health"
# Test enne restart'i (peaks failima)
curl http://localhost:3000/api/health
# Test pärast restart'i (peaks töötama)
curl http://localhost:3000/api/health
Boonus:
- Kasuta
subPathvolume mount'is, et muuta ainult üht faili ConfigMap'is - Kasuta
immutable: trueConfigMap'ile, et vältida kogemata muutmist
4. Multi-Node Klaster
Labor.md kasutasin single-node k3s (kõik ühes VM's). Siin õpid looma 2-node klasteri - nagu päris production'is.
4.1 Probleem
Single-node on hea õppimiseks, aga production'is on alati mitu node'i. Põhjused: - High Availability - kui üks server kukub, rakendus töötab edasi - Load Distribution - Pod'id jaotuvad mitme serveri vahel - Resource Isolation - saad eraldada töökoormuseid (database oma node'il, web app teises)
graph TB
subgraph "Single-Node (labor.md)"
SN[VM1: Control Plane + Worker<br/>Kui see kukub = KÕIK katki]
end
subgraph "Multi-Node (production)"
CP[VM1: Control Plane]
W1[VM2: Worker<br/>Pod Pod Pod]
W2[VM3: Worker<br/>Pod Pod Pod]
CP -.->|Haldab| W1
CP -.->|Haldab| W2
end
style SN fill:#f88,stroke:#f00
Stsenaarium: VM1 kukub. Single-node'is on kõik kadunud. Multi-node'is jätkavad VM2 ja VM3.
4.2 Lahendus: k3s Multi-Node
Loome 2 VM'i klasteri: - VM1 (master) - Control Plane (API server, scheduler, etcd) - VM2 (worker) - töötab Pod'e
Eeldus: Sul on 2 Proxmox VM'd (õpetaja loonud):
- VM1: 10.82.1.20 (master)
- VM2: 10.82.1.21 (worker)
# ===== VM1 (MASTER) =====
ssh student@10.82.1.20
# Installi k3s master
curl -sfL https://get.k3s.io | sh -
# Kontrolli
sudo systemctl status k3s
# Active: active (running)
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# vm1 Ready control-plane,master 30s v1.28.x+k3s1
# VÕTA TOKEN (vajad VM2 jaoks!)
sudo cat /var/lib/rancher/k3s/server/node-token
# K10abc123def456...KOPEERI SEE!
Token selgitus: Worker node vajab seda, et liituda klastriga. Token tõestab et worker on usaldusväärne.
# ===== VM2 (WORKER) =====
ssh student@10.82.1.21
# Installi k3s worker (asenda TOKEN!)
curl -sfL https://get.k3s.io | K3S_URL=https://10.82.1.20:6443 \
K3S_TOKEN=K10abc123def456... sh -
# Kontrolli
sudo systemctl status k3s-agent
# Active: active (running)
Kontrolli klastrit (VM1'is):
# VM1 (master)
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# vm1 Ready control-plane,master 5m v1.28.x+k3s1
# vm2 Ready <none> 1m v1.28.x+k3s1
# Vaata detaile
kubectl get nodes -o wide
# INTERNAL-IP näitab VM IP'd
Kuidas see töötab:
sequenceDiagram
participant W as Worker (VM2)
participant M as Master (VM1)
participant K as kubelet (VM2)
W->>M: Liitumise päring + Token
M->>M: Kontrolli Token
M->>W: OK, oled klastris
K->>M: Küsi tööd (API server)
M->>K: Käivita Pod X
K->>K: Käivita Docker container
K->>M: Pod töötab!
4.3 Harjutus: Deploy Pod'e Erinevatesse Node'idesse
Nõuded:
- [ ] 2-node klaster töötab (kubectl get nodes näitab 2 node'i)
- [ ] Deploy nginx 3 replikaga
- [ ] Kontrolli et Pod'id on mõlemas node'is
- [ ] Tapa worker node ja vaata mis juhtub
Deploy nginx:
# VM1 (master)
kubectl create deployment nginx --image=nginx:alpine --replicas=3
# Vaata kus Pod'id on
kubectl get pods -o wide
# NODE veerg näitab vm1 või vm2
Peaks nägema:
Scheduler jaotab Pod'id automaatselt!
Test: Tapa worker node
# VM2 (worker)
sudo systemctl stop k3s-agent
# VM1 (master) - vaata mis juhtub
kubectl get nodes
# vm2 on NotReady
kubectl get pods -o wide
# Pod'id vm2'l on Terminating...
# Peale 5 min luuakse vm1'le uued
Kubernetes märkab et vm2 on kadunud ja liigutab Pod'id vm1'le!
Näpunäiteid:
- kubectl describe node vm2 näitab miks NotReady
- kubectl top nodes näitab ressursse (kui metrics-server)
- Restart worker: sudo systemctl start k3s-agent
Boonus: Node Affinity
Sunni PostgreSQL alati vm1'le (master'ile):
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- vm1 # Ainult master node
containers:
- name: postgres
image: postgres:14-alpine
Taint & Toleration (advanced):
Blokeeri master node tavalistele Pod'idele:
# VM1 - lisa taint
kubectl taint nodes vm1 node-role.kubernetes.io/master=:NoSchedule
# Nüüd Pod'id lähevad ainult vm2'le
kubectl create deployment test --image=nginx --replicas=3
kubectl get pods -o wide
# Kõik vm2'l
# Eemalda taint
kubectl taint nodes vm1 node-role.kubernetes.io/master-
Validation: - [ ] 2 node'i klastris (vm1 master, vm2 worker) - [ ] Pod'id jagunevad mõlema vahel - [ ] Worker node stopimisel liiguvad Pod'id master'ile - [ ] Node affinity töötab (Pod ainult valitud node'il)
Kasulikud Ressursid
Dokumentatsioon:
Tööriistad:
- k9s
- Terminal UI Kubernetes'ele:
brew install k9s - kubectl plugins
- Laiendused:
kubectl krew install neat - Lens
- Desktop IDE: https://k8slens.dev/
Näited:
Need harjutused on mõeldud süvendama teie Kubernetes oskusi. Alustage esimesest ja liikuge järk-järgult keerulisemate poole. Kui miski ei tööta, kasutage kubectl describe ja kubectl logs käske debugimiseks.