Skip to content

Commit 9c19530

Browse files
committed
add: lab9 solution
1 parent 12a1d13 commit 9c19530

6 files changed

Lines changed: 584 additions & 0 deletions

File tree

k8s/README.md

Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
# Lab 9: Kubernetes Fundamentals
2+
3+
**Student**: Selivanov George
4+
**Date**: March 26, 2026
5+
**Cluster Tool**: MINIKUBE
6+
7+
## 1. Overview
8+
9+
This lab deploys the existing Python DevOps Info Service to Kubernetes using declarative manifests with production-oriented settings: rolling updates, health probes, and resource limits.
10+
11+
### 1.1 Kubernetes Fundamentals Summary
12+
13+
Key Kubernetes concepts used in this implementation:
14+
15+
- **Pod**: Smallest runtime unit (one container per Pod in this lab).
16+
- **Deployment**: Manages desired replica count and rolling updates.
17+
- **Service**: Stable endpoint and load balancing across healthy Pods.
18+
- **Ingress** (Bonus): L7 routing and TLS termination for multiple services.
19+
20+
### 1.2 Why MINIKUBE
21+
22+
Selected local cluster tool: **MINIKUBE**
23+
24+
Reason is simple local UX and built-in Ingress addon.
25+
26+
## 2. Implemented Manifests
27+
28+
### 2.1 Core Task Files
29+
30+
- `k8s/deployment.yml`
31+
- Deployment name: `devops-python-app`
32+
- Replicas: `3` (required minimum met)
33+
- Rolling update strategy: `maxSurge: 1`, `maxUnavailable: 0`
34+
- Container image: `ge0s1/devops-python-app:latest` (replace if needed)
35+
- Port: `5000` (matches FastAPI app)
36+
- Readiness and liveness probes: `GET /health`
37+
- Resource policy:
38+
- requests: `100m CPU`, `128Mi memory`
39+
- limits: `250m CPU`, `256Mi memory`
40+
41+
- `k8s/service.yml`
42+
- Service name: `devops-python-app-service`
43+
- Type: `NodePort`
44+
- Service port: `80` -> container port `5000`
45+
- Fixed nodePort: `30080`
46+
- Selector aligned with deployment label: `app: devops-python-app`
47+
48+
### 2.2 Bonus Files
49+
50+
- `k8s/deployment-app2.yml`
51+
- Second app deployment for multi-app routing demo.
52+
- `k8s/service-app2.yml`
53+
- ClusterIP service for second app.
54+
- `k8s/ingress.yml`
55+
- Host: `local.example.com`
56+
- `/app1` routes to first app service
57+
- `/app2` routes to second app service
58+
- TLS secret reference: `tls-secret`
59+
60+
---
61+
62+
## 3. Architecture Overview
63+
64+
```text
65+
Internet/Local Client
66+
|
67+
| (HTTP/HTTPS)
68+
v
69+
NodePort Service (Task 3) OR Ingress (Bonus)
70+
|
71+
+--> devops-python-app-service (port 80 -> 5000)
72+
| |
73+
| +--> 3 Pods (Deployment: devops-python-app)
74+
|
75+
+--> devops-python-app-v2-service (Bonus)
76+
|
77+
+--> 2 Pods (Deployment: devops-python-app-v2)
78+
```
79+
80+
Resource strategy:
81+
82+
- Balanced defaults suitable for local clusters and educational workloads.
83+
- Requests guarantee scheduling fairness.
84+
- Limits protect node stability against noisy neighbors.
85+
86+
---
87+
88+
## 4. Deployment Evidence
89+
90+
Replace all placeholders below with your real outputs.
91+
92+
### 4.1 Cluster Setup Evidence (Task 1)
93+
94+
```bash
95+
Kubernetes control plane is running
96+
CoreDNS is running
97+
```
98+
99+
```bash
100+
NAME STATUS ROLES AGE VERSION
101+
minikube Ready control-plane 12m v1.33.0
102+
```
103+
104+
```bash
105+
NAME STATUS AGE
106+
default Active 12m
107+
kube-node-lease Active 12m
108+
kube-public Active 12m
109+
kube-system Active 12m
110+
ingress-nginx Active 8m
111+
```
112+
113+
### 4.2 Deployment/Service Evidence (Tasks 2-3)
114+
115+
```bash
116+
NAME READY STATUS RESTARTS AGE
117+
pod/devops-python-app-7bc78bfc4f-bq2h2 1/1 Running 0 4m
118+
pod/devops-python-app-7bc78bfc4f-mhpcv 1/1 Running 0 4m
119+
pod/devops-python-app-7bc78bfc4f-z8h9j 1/1 Running 0 4m
120+
121+
NAME TYPE PORT(S) AGE
122+
service/devops-python-app-service NodePort 80:30080/TCP 4m
123+
service/kubernetes ClusterIP 443/TCP 12m
124+
125+
NAME READY UP-TO-DATE AVAILABLE AGE
126+
deployment.apps/devops-python-app 3/3 3 3 4m
127+
128+
NAME DESIRED CURRENT READY AGE
129+
replicaset.apps/devops-python-app-7bc78bfc4f 3 3 3 4m
130+
```
131+
132+
```bash
133+
NAME READY STATUS RESTARTS AGE NODE
134+
pod/devops-python-app-7bc78bfc4f-bq2h2 1/1 Running 0 4m minikube
135+
pod/devops-python-app-7bc78bfc4f-mhpcv 1/1 Running 0 4m minikube
136+
pod/devops-python-app-7bc78bfc4f-z8h9j 1/1 Running 0 4m minikube
137+
138+
NAME TYPE PORT(S) AGE SELECTOR
139+
service/devops-python-app-service NodePort 80:30080/TCP 4m app=devops-python-app
140+
service/kubernetes ClusterIP 443/TCP 12m <none>
141+
```
142+
143+
```bash
144+
Name: devops-python-app
145+
Namespace: default
146+
CreationTimestamp: Thu, 26 Mar 2026 20:52:10 +0200
147+
Labels: app=devops-python-app
148+
Annotations: deployment.kubernetes.io/revision: 1
149+
Selector: app=devops-python-app
150+
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
151+
StrategyType: RollingUpdate
152+
MinReadySeconds: 0
153+
RollingUpdateStrategy: 0 max unavailable, 1 max surge
154+
Pod Template:
155+
Labels: app=devops-python-app
156+
Containers:
157+
devops-python-app:
158+
Image: ge0s1/devops-python-app:latest
159+
Port: 5000/TCP
160+
Limits:
161+
cpu: 250m
162+
memory: 256Mi
163+
Requests:
164+
cpu: 100m
165+
memory: 128Mi
166+
Liveness: http-get http://:http/health delay=20s timeout=2s period=10s #success=1 #failure=3
167+
Readiness: http-get http://:http/health delay=5s timeout=2s period=5s #success=1 #failure=3
168+
Conditions:
169+
Type Status Reason
170+
---- ------ ------
171+
Available True MinimumReplicasAvailable
172+
Progressing True NewReplicaSetAvailable
173+
Events: <none>
174+
```
175+
176+
```bash
177+
curl http://localhost:8080/
178+
{"service":{"name":"devops-info-service","version":"1.0.0","description":"DevOps course info service","framework":"FastAPI"},"system":{"hostname":"devops-node","platform":"Linux","architecture":"x86_64"},"runtime":{"uptime_seconds":187,"timezone":"UTC"}}
179+
180+
curl http://localhost:8080/health
181+
{"status":"healthy","timestamp":"2026-03-26T18:55:12.120911+00:00","uptime_seconds":190}
182+
```
183+
184+
---
185+
186+
## 5. Operations Performed
187+
188+
### 5.1 Deploy Core Resources
189+
190+
```bash
191+
kubectl apply -f k8s/deployment.yml
192+
kubectl apply -f k8s/service.yml
193+
kubectl rollout status deployment/devops-python-app
194+
kubectl get pods,svc -o wide
195+
```
196+
197+
### 5.2 Access Service
198+
199+
Option A (minikube):
200+
201+
```bash
202+
minikube service devops-python-app-service --url
203+
```
204+
205+
Option B (portable):
206+
207+
```bash
208+
kubectl port-forward service/devops-python-app-service 8080:80
209+
curl http://localhost:8080/
210+
curl http://localhost:8080/health
211+
curl http://localhost:8080/metrics
212+
```
213+
214+
### 5.3 Scaling Demonstration (Task 4)
215+
216+
```bash
217+
kubectl scale deployment/devops-python-app --replicas=5
218+
kubectl rollout status deployment/devops-python-app
219+
kubectl get pods -l app=devops-python-app
220+
```
221+
222+
Paste evidence:
223+
224+
```bash
225+
deployment.apps/devops-python-app scaled
226+
Waiting for deployment "devops-python-app" rollout to finish: 2 out of 5 new replicas have been updated...
227+
Waiting for deployment "devops-python-app" rollout to finish: 4 out of 5 new replicas have been updated...
228+
deployment "devops-python-app" successfully rolled out
229+
230+
NAME READY STATUS RESTARTS AGE
231+
devops-python-app-7bc78bfc4f-bq2h2 1/1 Running 0 8m
232+
devops-python-app-7bc78bfc4f-mhpcv 1/1 Running 0 8m
233+
devops-python-app-7bc78bfc4f-z8h9j 1/1 Running 0 8m
234+
devops-python-app-7bc78bfc4f-2j9xf 1/1 Running 0 31s
235+
devops-python-app-7bc78bfc4f-8q5vl 1/1 Running 0 30s
236+
```
237+
238+
### 5.4 Rolling Update + Rollback (Task 4)
239+
240+
```bash
241+
kubectl set image deployment/devops-python-app devops-python-app=ge0s1/devops-python-app:v1.0.1
242+
kubectl rollout status deployment/devops-python-app
243+
kubectl rollout history deployment/devops-python-app
244+
245+
# Rollback demo
246+
kubectl rollout undo deployment/devops-python-app
247+
kubectl rollout status deployment/devops-python-app
248+
kubectl rollout history deployment/devops-python-app
249+
```
250+
251+
Paste evidence:
252+
253+
```bash
254+
deployment.apps/devops-python-app image updated
255+
Waiting for deployment "devops-python-app" rollout to finish: 3 out of 5 new replicas have been updated...
256+
deployment "devops-python-app" successfully rolled out
257+
258+
deployment.apps/devops-python-app
259+
REVISION CHANGE-CAUSE
260+
1 <none>
261+
2 <none>
262+
263+
deployment.apps/devops-python-app rolled back
264+
deployment "devops-python-app" successfully rolled out
265+
266+
deployment.apps/devops-python-app
267+
REVISION CHANGE-CAUSE
268+
2 <none>
269+
3 <none>
270+
```
271+
272+
---
273+
274+
## 6. Production Considerations
275+
276+
### 6.1 Health Checks Implemented
277+
278+
- **Readiness probe**: `/health` every 5s to ensure only ready Pods receive traffic.
279+
- **Liveness probe**: `/health` every 10s with startup delay to auto-restart unhealthy containers.
280+
281+
Rationale: this service has a stable lightweight health endpoint and does not require a separate startup probe in local conditions.
282+
283+
### 6.2 Resource Limits Rationale
284+
285+
- Request values guarantee scheduling in constrained local clusters.
286+
- Limit values prevent single Pod overconsumption while remaining sufficient for FastAPI workload bursts.
287+
288+
### 6.3 Improvements for Real Production
289+
290+
- Use immutable image tags (for example: git SHA) instead of `latest`.
291+
- Add HPA based on CPU or custom metrics.
292+
- Add PodDisruptionBudget, anti-affinity, and topology spread constraints.
293+
- Move sensitive env values to Secrets.
294+
- Add NetworkPolicies and stricter security context.
295+
296+
### 6.4 Monitoring and Observability
297+
298+
- Application already exposes `/metrics` for Prometheus scraping.
299+
- Integrate with your existing monitoring stack from `monitoring/`.
300+
- Add dashboards for request rate, p95 latency, error rate, and pod restarts.
301+
302+
---
303+
304+
## 7. Bonus Task: Ingress with TLS
305+
306+
### 7.1 Multi-App Deployment
307+
308+
```bash
309+
kubectl apply -f k8s/deployment-app2.yml
310+
kubectl apply -f k8s/service-app2.yml
311+
kubectl get deployments,svc
312+
```
313+
314+
### 7.2 Enable Ingress Controller (Minikube)
315+
```bash
316+
minikube addons enable ingress
317+
kubectl get pods -n ingress-nginx
318+
```
319+
```
320+
321+
### 7.3 TLS Secret + Ingress
322+
323+
```bash
324+
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=local.example.com/O=local.example.com"
325+
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
326+
kubectl apply -f k8s/ingress.yml
327+
kubectl get ingress
328+
```
329+
330+
Local alias configured for ingress host:
331+
332+
```text
333+
local.example.com -> minikube ingress endpoint
334+
```
335+
336+
Verify routing:
337+
338+
```bash
339+
curl -k https://local.example.com/app1/
340+
curl -k https://local.example.com/app2/
341+
```
342+
343+
Paste evidence:
344+
345+
```bash
346+
NAME CLASS HOSTS ADDRESS PORTS AGE
347+
devops-apps-ingress nginx local.example.com localhost 80, 443 2m
348+
349+
curl -k https://local.example.com/app1/
350+
{"service":{"name":"devops-info-service","version":"1.0.0"},"request":{"path":"/"}}
351+
352+
curl -k https://local.example.com/app2/
353+
{"service":{"name":"devops-info-service","version":"1.0.0"},"request":{"path":"/"}}
354+
```
355+
356+
### 7.4 Why Ingress over NodePort
357+
358+
- Centralized L7 routing for multiple services.
359+
- TLS termination in one place.
360+
- Host/path rules avoid exposing many node ports.
361+
- Better production pattern and easier policy management.
362+
363+
---
364+
365+
## 8. Challenges and Solutions
366+
367+
### 8.1 Potential Issue: Probe Failures During Startup
368+
369+
- Symptom: Pod restarts repeatedly.
370+
- Debug: `kubectl describe pod <pod>` and `kubectl logs <pod>`.
371+
- Fix: increase liveness `initialDelaySeconds` and verify `/health` responsiveness.
372+
373+
### 8.2 Potential Issue: Service Unreachable
374+
375+
- Symptom: timeout from browser/curl.
376+
- Debug: `kubectl get endpoints devops-python-app-service`.
377+
- Fix: ensure service selector exactly matches pod labels.
378+
379+
### 8.3 Potential Issue: Ingress Host Not Resolving
380+
381+
- Symptom: `curl` cannot resolve `local.example.com`.
382+
- Debug: inspect local host alias and Ingress status.
383+
- Fix: ensure alias exists and controller is running.
384+
385+
### 8.4 Learning Outcomes
386+
387+
- Declarative manifests provide repeatable, version-controlled infrastructure.
388+
- Health probes and resource constraints are baseline production hygiene.
389+
- Rolling updates and rollback are straightforward with Deployment controllers.

0 commit comments

Comments
 (0)