NestJS course Β· Module 12: Containers and CI/CD
Kubernetes - Managing the Provinces of the Empire
In this lesson8
Salve, legionary! So far we have learned how to build legionary camps (Docker containers) and connect them with roads (Docker Compose). But the Roman Empire managed dozens of provinces simultaneously. It needed a system that automatically deployed legions, replaced fallen soldiers, and scaled forces in response to threats. In the world of applications, this role is fulfilled by Kubernetes (K8s).
What is Kubernetes?
Kubernetes is a platform for container orchestration - it automatically manages deploying, scaling, and operating containers across a cluster of servers. The name comes from the Greek word for "helmsman" - Kubernetes is the helmsman of our container legion.
1// Analogy: Roman Empire vs Kubernetes
2interface ImperiumKubernetes {
3 imperator: 'Control Plane'; // Command center
4 prowincje: 'Nodes (servers)'; // Machines in the cluster
5 legiony: 'Pods'; // Deployment units
6 edykty: 'Deployments'; // State declarations
7 drogi: 'Services'; // Network communication
8 bramy: 'Ingress'; // External entry
9}
10
11const k8sConcepts = {
12 pod: 'Smallest unit - one or more containers',
13 deployment: 'Manages pod replicas (how many legions)',
14 service: 'Stable network address for pods',
15 ingress: 'Entry gateway from outside (HTTP/HTTPS)',
16 configMap: 'Configuration without secrets (public edicts)',
17 secret: 'Encrypted sensitive data (secret dispatches)',
18 namespace: 'Resource isolation (provinces)',
19};Pod - The Smallest Unit
A Pod is the smallest deployment unit in Kubernetes. It contains one or more containers that share networking and 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 - The Deployment Edict
A Deployment is a declaration of what our desired state should look like. Kubernetes itself ensures that reality matches the declaration:
1# deployment.yaml - NestJS API Deployment
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: roman-api
6 labels:
7 app: roman-imperium
8spec:
9 replicas: 3 # 3 legions (instances)
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: # Is the legion alive?
31 httpGet:
32 path: /health
33 port: 4000
34 initialDelaySeconds: 30
35 periodSeconds: 10
36 readinessProbe: # Is the legion ready for battle?
37 httpGet:
38 path: /health
39 port: 4000
40 initialDelaySeconds: 5
41 periodSeconds: 5Service - Roads of the Empire
A Service provides a stable network address for pods, even when pods are being replaced:
1# service.yaml - Road to the 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 # External port
12 targetPort: 4000 # Container port
13 type: ClusterIP # Available only within the clusterIngress - Gateway of the Empire
Ingress routes HTTP/HTTPS traffic from outside to the appropriate services:
1# ingress.yaml - Gateway of the Empire
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 and Secret - Edicts and Secret Dispatches
1# configmap.yaml - Public configuration
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 - Encrypted secrets
12apiVersion: v1
13kind: Secret
14metadata:
15 name: roman-secrets
16type: Opaque
17data:
18 DATABASE: bW9uZ29kYjovL2ltcGVyYXRvcjpyb21hQG1vbmdvZGI6MjcwMTcvaW1wZXJpdW0=
19 JWT_SECRET: c3VwZXItc2VjcmV0LWtleS1jaGFuZ2UtbWU=HPA - Autoscaling Legions
Horizontal Pod Autoscaler automatically scales the number of pods in response to load:
1# hpa.yaml - Autoscaling
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 legions
12 maxReplicas: 10 # Maximum 10 legions
13 metrics:
14 - type: Resource
15 resource:
16 name: cpu
17 target:
18 type: Utilization
19 averageUtilization: 70 # Scale at 70% CPUBasic kubectl Commands
1# Deploy resources
2kubectl apply -f deployment.yaml
3
4# Check pods
5kubectl get pods
6
7# Check deployments
8kubectl get deployments
9
10# Pod logs
11kubectl logs roman-api-xxxxx
12
13# Scale manually
14kubectl scale deployment roman-api --replicas=5
15
16# Check HPA status
17kubectl get hpaKubernetes is the province management system of our Empire - it automatically deploys legions, replaces the fallen, and scales forces in response to threats. It is the foundation of modern production infrastructure.
Code for this lesson: src/kubernetes-concepts.ts
1// Kubernetes - Managing Imperium Provinces
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: 'Single legion',
16 description: 'Smallest unit - one or more containers',
17 },
18 {
19 name: 'Deployment',
20 kind: 'apps/v1/Deployment',
21 romanAnalogy: 'Deployment edict',
22 description: 'Manages pod replicas',
23 },
24 {
25 name: 'Service',
26 kind: 'v1/Service',
27 romanAnalogy: 'Roman roads',
28 description: 'Permanent network address for pods',
29 },
30 {
31 name: 'Ingress',
32 kind: 'networking.k8s.io/v1/Ingress',
33 romanAnalogy: 'Imperium Gate',
34 description: 'HTTP/HTTPS entry point from outside',
35 },
36 {
37 name: 'ConfigMap',
38 kind: 'v1/ConfigMap',
39 romanAnalogy: 'Public edicts',
40 description: 'Configuration without secrets',
41 },
42 {
43 name: 'Secret',
44 kind: 'v1/Secret',
45 romanAnalogy: 'Secret dispatches',
46 description: 'Encrypted sensitive data',
47 },
48 {
49 name: 'HPA',
50 kind: 'autoscaling/v2/HPA',
51 romanAnalogy: 'Autoscaling legions',
52 description: 'Automatic scaling under load',
53 },
54];
55
56console.log("Kubernetes resources:\n");
57resources.forEach((r, i) => {
58 console.log(`${i + 1}. ${r.name} (${r.kind})`);
59 console.log(` Analogy: ${r.romanAnalogy}`);
60 console.log(` Description: ${r.description}\n`);
61});
62
63// kubectl commands
64console.log("=== kubectl COMMANDS ===\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}`));
75Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What is Kubernetes (K8s)?
2. What is a Pod in Kubernetes?
These are 2 of 3 questions for this lesson. Solve the rest in the game.
Hands-on tasks in the game
- Code editor
Complete the definitions of K8s resources: Pod, Deployment, Service, Ingress, ConfigMap, Secret, HPA
- Vertical ordering
Arrange the steps of deploying a NestJS application in Kubernetes: