Kurs NestJS · Moduł 12: Konteneryzacja i CI/CD
Kubernetes - Zarządzanie Prowincjami Imperium
W tej lekcji8
Salve, legioniście! Dotychczas nauczyliśmy się budować obozy legionowe (kontenery Docker) i łączyć je drogami (Docker Compose). Ale Imperium Rzymskie zarządzało dziesiątkami prowincji jednocześnie. Potrzebowało systemu, który automatycznie rozmieszczał legiony, zastępował poległych żołnierzy i skalował siły w odpowiedzi na zagrożenia. W świecie aplikacji, tę rolę pełni Kubernetes (K8s).
Czym jest Kubernetes?
Kubernetes to platforma do orkiestracji kontenerów - automatycznie zarządza wdrażaniem, skalowaniem i operowaniem kontenerami na klastrze serwerów. Nazwa pochodzi od greckiego słowa "sternik" - Kubernetes jest sternikiem naszego legionu kontenerów.
1// Analogia: Imperium Rzymskie vs Kubernetes
2interface ImperiumKubernetes {
3 imperator: 'Control Plane'; // Centrum dowodzenia
4 prowincje: 'Nodes (serwery)'; // Maszyny w klastrze
5 legiony: 'Pods'; // Jednostki wdrożeniowe
6 edykty: 'Deployments'; // Deklaracje stanu
7 drogi: 'Services'; // Komunikacja sieciowa
8 bramy: 'Ingress'; // Wejście z zewnątrz
9}
10
11const k8sConcepts = {
12 pod: 'Najmniejsza jednostka - jeden lub więcej kontenerów',
13 deployment: 'Zarządza replikami podów (ile legionów)',
14 service: 'Stały adres sieciowy dla podów',
15 ingress: 'Brama wejściowa z zewnątrz (HTTP/HTTPS)',
16 configMap: 'Konfiguracja bez sekretów (edykty publiczne)',
17 secret: 'Zaszyfrowane dane wrażliwe (tajne depesze)',
18 namespace: 'Izolacja zasobów (prowincje)',
19};Pod - Najmniejsza jednostka
Pod to najmniejsza jednostka wdrożeniowa w Kubernetes. Zawiera jeden lub więcej kontenerów, które współdzielą sieć i storage:
1# pod-definition.yaml
2apiVersion: v1
3kind: Pod
4metadata:
5 name: roman-api-pod
6 labels:
7 app: roman-imperium
8 tier: backend
9spec:
10 containers:
11 - name: api
12 image: roman-imperium-api:1.0
13 ports:
14 - containerPort: 4000
15 env:
16 - name: NODE_ENV
17 value: "production"Deployment - Edykt wdrożeniowy
Deployment to deklaracja, jak ma wyglądać nasz stan docelowy. Kubernetes sam dba o to, żeby rzeczywistość odpowiadała deklaracji:
1# deployment.yaml - Wdrożenie API NestJS
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: roman-api
6 labels:
7 app: roman-imperium
8spec:
9 replicas: 3 # 3 legiony (instancje)
10 selector:
11 matchLabels:
12 app: roman-imperium
13 template:
14 metadata:
15 labels:
16 app: roman-imperium
17 spec:
18 containers:
19 - name: api
20 image: roman-imperium-api:1.0
21 ports:
22 - containerPort: 4000
23 resources:
24 requests:
25 memory: "256Mi"
26 cpu: "250m"
27 limits:
28 memory: "512Mi"
29 cpu: "500m"
30 livenessProbe: # Czy legion żyje?
31 httpGet:
32 path: /health
33 port: 4000
34 initialDelaySeconds: 30
35 periodSeconds: 10
36 readinessProbe: # Czy legion gotowy do walki?
37 httpGet:
38 path: /health
39 port: 4000
40 initialDelaySeconds: 5
41 periodSeconds: 5Service - Drogi Imperium
Service zapewnia stały adres sieciowy dla podów, nawet gdy pody są zastępowane:
1# service.yaml - Droga do API
2apiVersion: v1
3kind: Service
4metadata:
5 name: roman-api-service
6spec:
7 selector:
8 app: roman-imperium
9 ports:
10 - protocol: TCP
11 port: 80 # Port zewnętrzny
12 targetPort: 4000 # Port kontenera
13 type: ClusterIP # Dostępny tylko wewnątrz klastraIngress - Brama Imperium
Ingress kieruje ruch HTTP/HTTPS z zewnątrz do odpowiednich serwisów:
1# ingress.yaml - Brama Imperium
2apiVersion: networking.k8s.io/v1
3kind: Ingress
4metadata:
5 name: roman-ingress
6 annotations:
7 nginx.ingress.kubernetes.io/rewrite-target: /
8spec:
9 rules:
10 - host: api.roman-imperium.com
11 http:
12 paths:
13 - path: /
14 pathType: Prefix
15 backend:
16 service:
17 name: roman-api-service
18 port:
19 number: 80ConfigMap i Secret - Edykty i tajne depesze
1# configmap.yaml - Publiczna konfiguracja
2apiVersion: v1
3kind: ConfigMap
4metadata:
5 name: roman-config
6data:
7 NODE_ENV: "production"
8 PORT: "4000"
9 LOG_LEVEL: "warn"
10---
11# secret.yaml - Zaszyfrowane sekrety
12apiVersion: v1
13kind: Secret
14metadata:
15 name: roman-secrets
16type: Opaque
17data:
18 DATABASE: bW9uZ29kYjovL2ltcGVyYXRvcjpyb21hQG1vbmdvZGI6MjcwMTcvaW1wZXJpdW0=
19 JWT_SECRET: c3VwZXItc2VjcmV0LWtleS1jaGFuZ2UtbWU=HPA - Autoskalowanie legionów
Horizontal Pod Autoscaler automatycznie skaluje liczbę podów w odpowiedzi na obciążenie:
1# hpa.yaml - Autoskalowanie
2apiVersion: autoscaling/v2
3kind: HorizontalPodAutoscaler
4metadata:
5 name: roman-api-hpa
6spec:
7 scaleTargetRef:
8 apiVersion: apps/v1
9 kind: Deployment
10 name: roman-api
11 minReplicas: 2 # Minimum 2 legiony
12 maxReplicas: 10 # Maksimum 10 legionów
13 metrics:
14 - type: Resource
15 resource:
16 name: cpu
17 target:
18 type: Utilization
19 averageUtilization: 70 # Skaluj przy 70% CPUPodstawowe komendy kubectl
1# Wdróż zasoby
2kubectl apply -f deployment.yaml
3
4# Sprawdź pody
5kubectl get pods
6
7# Sprawdź deploymenty
8kubectl get deployments
9
10# Logi poda
11kubectl logs roman-api-xxxxx
12
13# Skaluj ręcznie
14kubectl scale deployment roman-api --replicas=5
15
16# Sprawdź status HPA
17kubectl get hpaKubernetes to system zarządzania prowincjami naszego Imperium - automatycznie rozmieszcza legiony, zastępuje poległych i skaluje siły w odpowiedzi na zagrożenia. To fundament nowoczesnej infrastruktury produkcyjnej.
Kod do tej lekcji: src/kubernetes-concepts.ts
1// Kubernetes - Zarzadzanie Prowincjami Imperium
2console.log("=== KUBERNETES (K8s) ===\n");
3
4interface K8sResource {
5 name: string;
6 kind: string;
7 romanAnalogy: string;
8 description: string;
9}
10
11const resources: K8sResource[] = [
12 {
13 name: 'Pod',
14 kind: 'v1/Pod',
15 romanAnalogy: 'Pojedynczy legion',
16 description: 'Najmniejsza jednostka - jeden lub wiecej kontenerow',
17 },
18 {
19 name: 'Deployment',
20 kind: 'apps/v1/Deployment',
21 romanAnalogy: 'Edykt wdrozeniowy',
22 description: 'Zarzadza replikami podow',
23 },
24 {
25 name: 'Service',
26 kind: 'v1/Service',
27 romanAnalogy: 'Drogi rzymskie',
28 description: 'Staly adres sieciowy dla podow',
29 },
30 {
31 name: 'Ingress',
32 kind: 'networking.k8s.io/v1/Ingress',
33 romanAnalogy: 'Brama Imperium',
34 description: 'Wejscie HTTP/HTTPS z zewnatrz',
35 },
36 {
37 name: 'ConfigMap',
38 kind: 'v1/ConfigMap',
39 romanAnalogy: 'Edykty publiczne',
40 description: 'Konfiguracja bez sekretow',
41 },
42 {
43 name: 'Secret',
44 kind: 'v1/Secret',
45 romanAnalogy: 'Tajne depesze',
46 description: 'Zaszyfrowane dane wrazliwe',
47 },
48 {
49 name: 'HPA',
50 kind: 'autoscaling/v2/HPA',
51 romanAnalogy: 'Autoskalowanie legionow',
52 description: 'Automatyczne skalowanie przy obciazeniu',
53 },
54];
55
56console.log("Zasoby Kubernetes:\n");
57resources.forEach((r, i) => {
58 console.log(`${i + 1}. ${r.name} (${r.kind})`);
59 console.log(` Analogia: ${r.romanAnalogy}`);
60 console.log(` Opis: ${r.description}\n`);
61});
62
63// Komendy kubectl
64console.log("=== KOMENDY kubectl ===\n");
65const commands = [
66 'kubectl apply -f deployment.yaml',
67 'kubectl get pods',
68 'kubectl get services',
69 'kubectl logs <pod-name>',
70 'kubectl scale deployment roman-api --replicas=5',
71 'kubectl get hpa',
72];
73
74commands.forEach(cmd => console.log(` $ ${cmd}`));
75Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Czym jest Kubernetes (K8s)?
2. Czym jest Pod w Kubernetes?
To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Edytor kodu
Uzupełnij definicje zasobów K8s: Pod, Deployment, Service, Ingress, ConfigMap, Secret, HPA
- Układanie w pionie
Uporządkuj kroki wdrożenia aplikacji NestJS w Kubernetes: