Wiki workshop · Αγγλικά

Kubernetes Workshop: Fundamentals – Exercises with Solutions

Reference: 01-fundamentals-EN.md Difficulty level: Fundamentals Format: Hands-on lab with sample solutions and walkthroughs

Παραδείγματα workshop σε ZIP
Πρόοδος μάθησης στη web app

Σημειώστε κεφάλαια ως αναγνωσμένα, δείτε την πρόοδο ανάγνωσης και ολοκληρώστε πρακτικές ενότητες αφού ενεργοποιήσετε την προαιρετική web app. Η πρόοδος του workshop υπολογίζεται από τα κεφάλαια όλων των σελίδων τεκμηρίωσης. Οι επιλογές μένουν σε αυτή τη συσκευή· δεν υπάρχει λογαριασμός ή συγχρονισμός με server. Δεν απαιτείται εγκατάσταση. Η ανάκληση στις Ρυθμίσεις απορρήτου διαγράφει την πρόοδο.

Πρόοδος ανάγνωσης0%
0%
0 / 22 κεφάλαια που διαβάστηκαν

Δεν υπάρχει ακόμη ελληνική έκδοση αυτού του εγγράφου. Το περιεχόμενο εμφανίζεται στα αγγλικά.

Άλλη γλωσσική έκδοσηΓερμανικά ↗Ελληνικά ↗

Kubernetes Workshop: Fundamentals – Exercises with Solutions

Reference: 01-fundamentals-EN.md
Difficulty level: Fundamentals
Format: Hands-on lab with sample solutions and walkthroughs

Goal of this exercise document

This exercise document complements the Fundamentals workshop with concrete tasks, verifiable results, and complete solutions. The focus is on safe basic operation, the Kubernetes object model, kubectl, Pods, Deployments, ReplicaSets, Services, Labels, Selectors, ConfigMaps, Secrets, Namespaces, rollouts, scaling, rollback, and first-level troubleshooting.

You work only in a lab cluster. Do not use production cluster contexts or real credentials.

01 / 22

Prerequisites

You need:

  • kubectl
  • a local or provided Kubernetes cluster, for example kind, minikube, or k3d
  • a non-critical cluster context
  • write permissions in your own Namespace

Recommended Namespace for all exercises:

bash
export NS=workshop-fundamentals
02 / 22

Working rules

  1. Check the active context before each exercise.
  2. Work only in the $NS Namespace.
  3. Save manifests as files before applying them.
  4. Use kubectl apply --dry-run=server if your cluster supports it.
  5. After every change, check status, Events, and logs.
  6. Document the cleanup at the end.
03 / 22

Exercise overview

No. Topic Result
1 Context, cluster, and Namespace safe lab context and Namespace
2 Reading the object model Deployment manifest explained
3 Deployment and Service simple web app reachable internally
4 Labels and Selectors Service error diagnosed and fixed
5 ConfigMap and Secret configuration and sample Secret mounted
6 Rollout, scaling, and rollback image update, scaling, and rollback performed
7 Troubleshooting: ImagePullBackOff wrong image diagnosed and corrected
8 Troubleshooting: CrashLoopBackOff crashing application diagnosed and corrected
9 Operations note and cleanup resource list, validation, and cleanup documented

Part A – Exercises

04 / 22

Exercise 1: Check context, cluster, and Namespace

Goal

You make sure that you are working in the correct cluster and create your own Namespace.

Task

  1. Check the active context.
  2. Check cluster information and Nodes.
  3. Create the Namespace workshop-fundamentals.
  4. Set the Namespace for the current context.
  5. Document cluster name, number of Nodes, and Kubernetes version.

Expected result

  • The Namespace exists.
  • kubectl get pods shows resources from workshop-fundamentals by default.
  • You can explain why the context is checked before every lab.

05 / 22

Exercise 2: Read the Kubernetes object model

Goal

You read a Deployment manifest and identify apiVersion, kind, metadata, spec, selector, Pod template, and container configuration.

Task

Create the file deployment.yml:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: workshop-fundamentals
  labels:
    app: web
    tier: frontend
    environment: lab
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
        tier: frontend
        environment: lab
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80

Answer in writing:

  1. Which API group is used?
  2. Which resource is created?
  3. Where is the desired state defined?
  4. Which Labels do the Pods receive?
  5. What is the Selector used for?

06 / 22

Exercise 3: Roll out Deployment and Service

Goal

You roll out a simple web application and make it reachable through an internal ClusterIP Service.

Task

  1. Apply deployment.yml.
  2. Create the file service.yml:
yaml
apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: workshop-fundamentals
  labels:
    app: web
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
    - name: http
      port: 80
      targetPort: 80
  1. Apply service.yml.
  2. Check Deployment, ReplicaSet, Pods, Service, Endpoints, and EndpointSlices.
  3. Test the Service with a temporary debug Pod.

Expected result

  • Two Pods are running.
  • The Service has Endpoints.
  • A temporary Pod can reach http://web.

07 / 22

Exercise 4: Intentionally break Labels and Selectors

Goal

You understand why Services find Pods through Labels and Selectors, not through Pod names.

Task

  1. Intentionally change the Service Selector in service.yml to an incorrect value:
yaml
selector:
  app: wrong-web
  1. Apply the change.
  2. Check Service, Endpoints, and EndpointSlices.
  3. Correct the Selector back to app: web.
  4. Check again.

Expected result

  • With the wrong Selector, the Service has no Endpoints.
  • After the correction, Endpoints are present again.

08 / 22

Exercise 5: Mount ConfigMap and Secret

Goal

You distinguish non-sensitive configuration from sensitive sample values and mount both into a Pod.

Task

Create configmap.yml:

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: web-config
  namespace: workshop-fundamentals
data:
  APP_MODE: lab
  WELCOME_TEXT: "Hello from Kubernetes"

Create secret.yml:

yaml
apiVersion: v1
kind: Secret
metadata:
  name: web-secret
  namespace: workshop-fundamentals
type: Opaque
stringData:
  DEMO_PASSWORD: "not-a-real-secret"

Extend your Deployment so that APP_MODE is mounted as an environment variable and DEMO_PASSWORD is mounted as a file.

Expected result

  • The ConfigMap exists.
  • The Secret exists.
  • The Pod contains APP_MODE as an environment variable.
  • The Secret is visible as a file in the container.

09 / 22

Exercise 6: Perform rollout, scaling, and rollback

Goal

You use Deployment rollouts in a controlled way and can revert a change.

Task

  1. Check the current rollout status.
  2. Scale the Deployment to three replicas.
  3. Change the image from nginx:1.27 to nginx:1.26.
  4. Check rollout status and rollout history.
  5. Perform a rollback.
  6. Check which image is active afterward.

Expected result

  • Three Pods are running.
  • The rollout history shows at least two revisions.
  • After the rollback, the previous image is running again.

10 / 22

Exercise 7: Diagnose ImagePullBackOff

Goal

You provoke an image pull error and fix it based on Events.

Task

Create bad-image.yml:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bad-image
  namespace: workshop-fundamentals
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bad-image
  template:
    metadata:
      labels:
        app: bad-image
    spec:
      containers:
        - name: app
          image: nginx:this-tag-does-not-exist
          ports:
            - containerPort: 80
  1. Apply the manifest.
  2. Check Pod status and Events.
  3. Correct the image to nginx:1.27.
  4. Check again.

11 / 22

Exercise 8: Diagnose CrashLoopBackOff

Goal

You provoke a crashing application, read logs, and correct the startup command.

Task

Create crashloop.yml:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: crashloop
  namespace: workshop-fundamentals
spec:
  replicas: 1
  selector:
    matchLabels:
      app: crashloop
  template:
    metadata:
      labels:
        app: crashloop
    spec:
      containers:
        - name: app
          image: busybox:1.36
          command: ["sh", "-c", "echo 'I terminate immediately'; exit 1"]
  1. Apply the manifest.
  2. Check the Pod status.
  3. Read logs and previous logs.
  4. Correct the command so that the container keeps running.
  5. Check again.

12 / 22

Exercise 9: Operations note and cleanup

Goal

You document what was created, how you verified the state, and how everything is cleaned up.

Task

Create notes.md with:

  • cluster context
  • Namespace
  • applied manifests
  • created resources
  • most important diagnostic commands
  • known errors and fixes
  • cleanup command

Part B – Solutions and walkthroughs

13 / 22

Solution 1: Check context, cluster, and Namespace

bash
kubectl config current-context
kubectl cluster-info
kubectl version --client
kubectl get nodes -o wide
kubectl create namespace workshop-fundamentals
kubectl config set-context --current --namespace=workshop-fundamentals
kubectl get pods

Validation:

bash
kubectl get namespace workshop-fundamentals
kubectl config view --minify --output 'jsonpath={..namespace}'

Sample explanation:

  • The context determines which cluster kubectl communicates with.
  • The Namespace limits the default view of kubectl, but it does not replace security isolation.
  • kubectl cluster-info shows API reachability.
  • kubectl get nodes -o wide shows Node status and runtime environment.

14 / 22

Solution 2: Read the Kubernetes object model

Sample answers:

Question Answer
API group apps/v1; resource from the Apps API group
Resource Deployment
desired state under spec
Pod Labels app=web, tier=frontend, environment=lab
Selector connects the Deployment with the Pods it manages

Helpful exploration:

bash
kubectl explain deployment
kubectl explain deployment.spec
kubectl explain deployment.spec.template.spec.containers
kubectl api-resources | grep -i deployment

15 / 22

Solution 3: Roll out Deployment and Service

bash
kubectl apply --dry-run=server -f deployment.yml
kubectl apply -f deployment.yml
kubectl rollout status deployment/web
kubectl apply --dry-run=server -f service.yml
kubectl apply -f service.yml

Check:

bash
kubectl get deployment,replicaset,pod,svc,endpoints,endpointslices
kubectl describe deployment web
kubectl describe svc web

Service test:

bash
kubectl run curl --rm -i --tty --restart=Never --image=curlimages/curl:8.8.0 -- http://web

Alternative if interactive kubectl run behaves differently in your environment:

bash
kubectl run curl --restart=Never --image=curlimages/curl:8.8.0 -- sleep 3600
kubectl wait --for=condition=Ready pod/curl --timeout=60s
kubectl exec curl -- curl -s http://web
kubectl delete pod curl

Expected state:

  • deployment.apps/web is available.
  • service/web has a ClusterIP.
  • endpoints/web contains Pod IP addresses.

16 / 22

Solution 4: Correct Labels and Selectors

Apply the incorrect Selector:

bash
kubectl apply -f service.yml
kubectl get svc,endpoints,endpointslices
kubectl describe svc web

Typical symptom:

text
Endpoints: <none>

Diagnosis:

bash
kubectl get pods --show-labels
kubectl get svc web -o yaml

Correction in service.yml:

yaml
selector:
  app: web

Afterward:

bash
kubectl apply -f service.yml
kubectl get endpoints web
kubectl get endpointslices -l kubernetes.io/service-name=web

Technical explanation:

A Service does not know fixed Pod names. It finds Pods through the Selector. If Selector and Pod Labels do not match, the Service exists, but it has no targets.


17 / 22

Solution 5: Mount ConfigMap and Secret

Apply ConfigMap and Secret:

bash
kubectl apply -f configmap.yml
kubectl apply -f secret.yml
kubectl get configmap,secret

Deployment extension:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: workshop-fundamentals
  labels:
    app: web
    tier: frontend
    environment: lab
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
        tier: frontend
        environment: lab
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80
          env:
            - name: APP_MODE
              valueFrom:
                configMapKeyRef:
                  name: web-config
                  key: APP_MODE
          volumeMounts:
            - name: web-secret-volume
              mountPath: /etc/demo-secret
              readOnly: true
      volumes:
        - name: web-secret-volume
          secret:
            secretName: web-secret

Apply and check:

bash
kubectl apply -f deployment.yml
kubectl rollout status deployment/web
POD=$(kubectl get pod -l app=web -o jsonpath='{.items[0].metadata.name}')
kubectl exec "$POD" -- printenv APP_MODE
kubectl exec "$POD" -- ls -l /etc/demo-secret
kubectl exec "$POD" -- cat /etc/demo-secret/DEMO_PASSWORD

Technical classification:

  • ConfigMaps are intended for non-sensitive configuration.
  • Secrets are intended for sensitive values, but Base64 is not encryption.
  • Real Secrets do not belong in learning manifests or plaintext Git.

18 / 22

Solution 6: Rollout, scaling, and rollback

Check status:

bash
kubectl rollout status deployment/web
kubectl get deployment web

Scale:

bash
kubectl scale deployment/web --replicas=3
kubectl rollout status deployment/web
kubectl get pods -l app=web

Change image:

bash
kubectl set image deployment/web nginx=nginx:1.26
kubectl rollout status deployment/web
kubectl rollout history deployment/web

Check active image:

bash
kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'

Rollback:

bash
kubectl rollout undo deployment/web
kubectl rollout status deployment/web
kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'

Sample explanation:

  • scale changes spec.replicas.
  • set image changes the Pod template and therefore creates a new revision.
  • rollout undo sets the previous revision back as the desired state.

19 / 22

Solution 7: ImagePullBackOff

Apply:

bash
kubectl apply -f bad-image.yml
kubectl get pods -l app=bad-image

Diagnosis:

bash
POD=$(kubectl get pod -l app=bad-image -o jsonpath='{.items[0].metadata.name}')
kubectl describe pod "$POD"
kubectl get events --sort-by=.metadata.creationTimestamp

Typical finding:

  • The image tag does not exist.
  • Events contain messages for Failed to pull image or ErrImagePull.

Correction:

bash
kubectl set image deployment/bad-image app=nginx:1.27
kubectl rollout status deployment/bad-image
kubectl get pods -l app=bad-image

Or correct the file and apply it again:

bash
sed -i 's/nginx:this-tag-does-not-exist/nginx:1.27/' bad-image.yml
kubectl apply -f bad-image.yml

20 / 22

Solution 8: CrashLoopBackOff

Apply:

bash
kubectl apply -f crashloop.yml
kubectl get pods -l app=crashloop

Diagnosis:

bash
POD=$(kubectl get pod -l app=crashloop -o jsonpath='{.items[0].metadata.name}')
kubectl describe pod "$POD"
kubectl logs "$POD"
kubectl logs "$POD" --previous

Typical finding:

  • The container starts.
  • The command exits with exit code 1.
  • Kubernetes restarts it; this creates CrashLoopBackOff.

Correction by manifest:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: crashloop
  namespace: workshop-fundamentals
spec:
  replicas: 1
  selector:
    matchLabels:
      app: crashloop
  template:
    metadata:
      labels:
        app: crashloop
    spec:
      containers:
        - name: app
          image: busybox:1.36
          command: ["sh", "-c", "echo 'I stay active'; sleep 3600"]

Apply:

bash
kubectl apply -f crashloop.yml
kubectl rollout status deployment/crashloop
kubectl get pods -l app=crashloop

21 / 22

Solution 9: Operations note and cleanup

Template for notes.md:

markdown
# Operations Note – Fundamentals Lab

## Context

- Cluster context: <from kubectl config current-context>
- Namespace: workshop-fundamentals
- Date: <enter date>

## Manifests

- deployment.yml
- service.yml
- configmap.yml
- secret.yml
- bad-image.yml
- crashloop.yml

## Validation

- kubectl get deployment,rs,pod,svc,endpoints,endpointslices
- kubectl rollout status deployment/web
- kubectl describe pod <pod>
- kubectl logs <pod>

## Errors and fixes

| Error | Cause | Fix |
| --- | --- | --- |
| Service without Endpoints | wrong Selector | corrected Selector to app=web |
| ImagePullBackOff | invalid image tag | set image to nginx:1.27 |
| CrashLoopBackOff | process exits with exit 1 | changed command to sleep 3600 |

## Cleanup

kubectl delete namespace workshop-fundamentals

Cleanup:

bash
kubectl delete namespace workshop-fundamentals

Validation after cleanup:

bash
kubectl get namespace workshop-fundamentals

Expected state: The Namespace is deleted or briefly in Terminating state.


Assessment checklist

Criterion Completed?
Context checked before applying changes ☐
own Namespace used ☐
Deployment manifest explained ☐
Service with Endpoints created ☐
Selector error diagnosed ☐
ConfigMap and Secret mounted correctly ☐
Rollout, scaling, and rollback performed ☐
ImagePullBackOff explained based on Events ☐
CrashLoopBackOff explained based on logs ☐
Cleanup documented ☐
22 / 22

K8S · Orthevs Academy

31 modules ως ενιαία διαδρομή μάθησης.

Η σειρά παραμένει αμετάβλητη: από τη βασική δομή του lab μέσω τεχνικών θεμελίων και λειτουργικών μοντέλων έως το τελικό troubleshooting. Τα τεχνικά ονόματα καταλόγων διατηρούνται σκόπιμα.

Orthevs – Η μηχανική ως βάση για όσα ακολουθούν.

Το Orthevs ως εφαρμογή

Εγκατάσταση του Orthevs

Η web app του Orthevs μπορεί να εγκατασταθεί σε υποστηριζόμενες κινητές συσκευές και browsers υπολογιστή.

iPhone και iPad

Ανοίξτε το Orthevs στο Safari. Πατήστε Κοινή χρήση και μετά Προσθήκη στην οθόνη αφετηρίας. Ενεργοποιήστε το Άνοιγμα ως web app, αν εμφανίζεται, και πατήστε Προσθήκη.

Android

Για τη web app, ανοίξτε το μενού του browser και επιλέξτε Εγκατάσταση εφαρμογής ή Προσθήκη στην αρχική οθόνη. Επιβεβαιώστε την εγκατάσταση.

Browser υπολογιστή

Ανοίξτε το μενού του browser ή το εικονίδιο εγκατάστασης στη γραμμή διευθύνσεων και επιλέξτε Εγκατάσταση εφαρμογής ή Προσθήκη στο Dock.

Η εγκατάσταση της web app εξαρτάται από τον browser. Αν δεν εμφανιστεί διάλογος εγκατάστασης, ακολουθήστε τα βήματα του browser που αναφέρονται παραπάνω.