Kubernetes - Pytania Rekrutacyjne dla DevOps i Platform Engineera [2026]

Sławomir Plamowski 19 min czytania
devops helm k8s konteneryzacja kubernetes orkiestracja pytania-rekrutacyjne

Kubernetes stał się standardem dla produkcyjnych deploymentów kontenerów. W 2026 roku znajomość K8s jest praktycznie wymagana na stanowiskach DevOps, SRE i Platform Engineer. Nawet jeśli używasz managed Kubernetes (EKS, AKS, GKE), rekruterzy oczekują zrozumienia core concepts.

Ten przewodnik zawiera 60+ pytań rekrutacyjnych z odpowiedziami - od podstawowych obiektów po zaawansowane tematy jak Helm, networking i troubleshooting.

Spis treści


Podstawowe koncepcje

Czym jest Kubernetes i jakie problemy rozwiązuje?

Odpowiedź w 30 sekund: Kubernetes to platforma do orkiestracji kontenerów. Automatyzuje deployment, skalowanie, self-healing i zarządzanie aplikacjami kontenerowymi. Rozwiązuje problemy: jak uruchomić setki kontenerów, jak je skalować, jak obsługiwać awarie.

Odpowiedź w 2 minuty:

Kubernetes automatyzuje cały lifecycle aplikacji kontenerowych, rozwiązując fundamentalne problemy produkcyjnych deploymentów. Poniższa tabela pokazuje mapowanie problemów na konkretne mechanizmy K8s:

Problem Rozwiązanie Kubernetes
Deployment wielu kontenerów Deklaratywna konfiguracja, rolling updates
Skalowanie Horizontal Pod Autoscaler, replica sets
Awarie kontenerów Self-healing, restart policies
Service discovery DNS, Services, wewnętrzny load balancing
Konfiguracja ConfigMaps, Secrets oddzielone od obrazów
Load balancing Services, Ingress
Storage Persistent Volumes, Storage Classes
# Podstawowe komendy kubectl
kubectl get pods                    # Lista podów
kubectl get deployments             # Lista deploymentów
kubectl get services                # Lista serwisów
kubectl describe pod <name>         # Szczegóły poda
kubectl logs <pod-name>             # Logi poda
kubectl exec -it <pod> -- /bin/sh   # Shell w podzie

Wyjaśnij architekturę Kubernetes

Odpowiedź w 30 sekund: Klaster K8s składa się z Control Plane (zarządzanie) i Worker Nodes (uruchamianie aplikacji). Control Plane: API Server, etcd, Scheduler, Controller Manager. Worker Node: kubelet, kube-proxy, container runtime.

Odpowiedź w 2 minuty:

Architektura Kubernetes jest podzielona na dwie główne warstwy - Control Plane odpowiedzialny za zarządzanie klastrem oraz Worker Nodes gdzie faktycznie działają aplikacje. Poniższy diagram ilustruje tę strukturę:

┌─────────────────────────────────────────────────────────────┐
│                      CONTROL PLANE                          │
├─────────────┬─────────────┬───────────────┬────────────────┤
│ API Server  │    etcd     │  Scheduler    │ Controller Mgr │
│ (gateway)   │ (database)  │ (placement)   │ (reconcile)    │
└─────────────┴─────────────┴───────────────┴────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                      WORKER NODES                           │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                      │
│  │ kubelet │  │kube-proxy│  │container│  ← Każdy node       │
│  │         │  │         │  │ runtime │                      │
│  └─────────┘  └─────────┘  └─────────┘                      │
│                                                             │
│  ┌─────────────────────────────────────────┐                │
│  │    PODS (Twoje aplikacje)               │                │
│  └─────────────────────────────────────────┘                │
└─────────────────────────────────────────────────────────────┘

Komponenty Control Plane:

Komponent Rola
API Server Punkt wejścia dla wszystkich operacji, REST API
etcd Distributed key-value store, przechowuje stan klastra
Scheduler Decyduje na którym nodzie uruchomić Pod
Controller Manager Uruchamia kontrolery (Deployment, ReplicaSet, etc.)

Komponenty Worker Node:

Komponent Rola
kubelet Agent na każdym nodzie, uruchamia Pody
kube-proxy Networking, load balancing w obrębie klastra
Container runtime Docker, containerd, CRI-O

Czym jest deklaratywna vs imperatywna konfiguracja?

Odpowiedź w 30 sekund: Imperatywna: mówisz CO robić krok po kroku (kubectl create, kubectl scale). Deklaratywna: opisujesz DESIRED STATE w YAML, K8s sam dąży do tego stanu (kubectl apply). Deklaratywna jest preferowana - można wersjonować, review'ować, rollbackować.

Odpowiedź w 2 minuty:

Imperatywne podejście to szybkie komendy ad-hoc, podczas gdy deklaratywne to definiowanie desired state w plikach YAML. Poniżej przykłady obu podejść:

# Imperatywna (ad-hoc, nie dla produkcji)
kubectl create deployment nginx --image=nginx
kubectl scale deployment nginx --replicas=3
kubectl expose deployment nginx --port=80

# Deklaratywna (produkcyjna, GitOps)
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# lub cały katalog
kubectl apply -f manifests/
# deployment.yaml - deklaratywna definicja
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3          # Desired state: 3 repliki
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25

Zalety deklaratywnej:

  • Git jako source of truth
  • Code review dla zmian infrastruktury
  • Łatwy rollback (git revert + kubectl apply)
  • Idempotentność - można aplikować wielokrotnie

Pods i Deployments

Czym jest Pod i kiedy używać wielu kontenerów w Podzie?

Odpowiedź w 30 sekund: Pod to najmniejsza jednostka w K8s - jeden lub więcej kontenerów współdzielących sieć (localhost) i storage. Wiele kontenerów w Podzie: sidecar pattern - np. aplikacja + log collector, lub init container do setup'u.

Odpowiedź w 2 minuty:

Pod to podstawowa jednostka w Kubernetes - kontener lub grupa kontenerów współdzielących zasoby sieciowe i storage. Najczęściej używamy jednego kontenera na Pod, ale sidecar pattern jest powszechny w przypadku dodatkowej funkcjonalności:

# Pod z jednym kontenerem (typowy przypadek)
apiVersion: v1
kind: Pod
metadata:
  name: simple-pod
spec:
  containers:
  - name: app
    image: myapp:v1
    ports:
    - containerPort: 8080

# Pod z sidecar (log collector)
apiVersion: v1
kind: Pod
metadata:
  name: app-with-sidecar
spec:
  containers:
  - name: app
    image: myapp:v1
    volumeMounts:
    - name: logs
      mountPath: /var/log/app
  - name: log-collector
    image: fluentd:v1
    volumeMounts:
    - name: logs
      mountPath: /var/log/app
  volumes:
  - name: logs
    emptyDir: {}

Kiedy wiele kontenerów w Podzie:

Pattern Przykład Kiedy używać
Sidecar Log collector, proxy Rozszerzenie funkcjonalności
Ambassador Proxy do zewnętrznych serwisów Abstrakcja połączeń
Adapter Transformacja danych Standaryzacja outputu
Init Container Migracje DB, pobieranie config Jednorazowy setup

Ważne:

  • Kontenery w Podzie są zawsze schedulowane razem
  • Współdzielą sieć (mogą używać localhost)
  • Skalują się razem (nie można skalować jednego kontenera)

Czym jest Deployment i jak działa rolling update?

Odpowiedź w 30 sekund: Deployment zarządza Podami - definiuje desired state (ile replik, jaki obraz), obsługuje rolling updates i rollbacki. Rolling update stopniowo zastępuje stare Pody nowymi - zero downtime.

Odpowiedź w 2 minuty:

Deployment to kontroler zarządzający Podami, który automatyzuje aktualizacje aplikacji bez przestojów. Rolling update stopniowo wymienia stare wersje na nowe, kontrolując tempo zmian:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Max 4 pody podczas update (3+1)
      maxUnavailable: 0  # Wszystkie 3 muszą działać
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: myapi:v1
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

Przebieg Rolling Update:

Stan początkowy:    [v1] [v1] [v1]
1. Utwórz nowy:     [v1] [v1] [v1] [v2]  (maxSurge=1)
2. Czekaj na ready: [v1] [v1] [v1] [v2✓]
3. Usuń stary:      [v1] [v1] [v2✓]
4. Powtórz:         [v1] [v2✓] [v2✓]
5. Koniec:          [v2✓] [v2✓] [v2✓]
# Update image
kubectl set image deployment/api api=myapi:v2

# Sprawdź status
kubectl rollout status deployment/api

# Historia
kubectl rollout history deployment/api

# Rollback
kubectl rollout undo deployment/api
kubectl rollout undo deployment/api --to-revision=2

Czym jest ReplicaSet i StatefulSet?

Odpowiedź w 30 sekund: ReplicaSet utrzymuje określoną liczbę identycznych Podów (tworzone przez Deployment, nie bezpośrednio). StatefulSet dla aplikacji stateful - zapewnia stabilne nazwy sieciowe, persistent storage, ordered deployment (bazy danych, Kafka).

Odpowiedź w 2 minuty:

ReplicaSet jest używany przez Deployments do zarządzania bezstanowymi aplikacjami, podczas gdy StatefulSet jest specjalnie zaprojektowany dla aplikacji wymagających stabilnej tożsamości i trwałego storage. Kluczowe różnice:

ReplicaSet vs StatefulSet:

Cecha ReplicaSet (Deployment) StatefulSet
Nazwy podów Losowe (api-7d9f-abc) Numerowane (db-0, db-1)
Storage Współdzielony lub brak PVC per pod
Deployment order Równoległy Sekwencyjny
DNS Wspólny Service Stable hostname per pod
Użycie Stateless apps Databases, queues
# StatefulSet dla bazy danych
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        ports:
        - containerPort: 5432
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

Stable network identity:

# Pody StatefulSet mają przewidywalne nazwy
postgres-0.postgres.default.svc.cluster.local
postgres-1.postgres.default.svc.cluster.local
postgres-2.postgres.default.svc.cluster.local

Co to są liveness i readiness probes?

Odpowiedź w 30 sekund: Liveness probe sprawdza czy kontener żyje - jeśli fail, K8s restartuje Pod. Readiness probe sprawdza czy kontener jest gotowy na ruch - jeśli fail, Pod jest usuwany z Service (bez restartu). Zawsze definiuj oba!

Odpowiedź w 2 minuty:

Probes to mechanizmy health check w Kubernetes - liveness sprawdza czy aplikacja działa (restart przy fail), readiness czy jest gotowa na ruch (usunięcie z Service przy fail). Przykład konfiguracji wszystkich trzech typów:

spec:
  containers:
  - name: api
    image: myapi:v1
    ports:
    - containerPort: 8080

    # Liveness - czy aplikacja żyje?
    livenessProbe:
      httpGet:
        path: /health/live
        port: 8080
      initialDelaySeconds: 30    # Czekaj po starcie
      periodSeconds: 10          # Sprawdzaj co 10s
      failureThreshold: 3        # 3 faile = restart

    # Readiness - czy gotowa na ruch?
    readinessProbe:
      httpGet:
        path: /health/ready
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5
      failureThreshold: 3        # 3 faile = usuń z Service

    # Startup probe - dla wolno startujących aplikacji
    startupProbe:
      httpGet:
        path: /health/live
        port: 8080
      failureThreshold: 30
      periodSeconds: 10          # Max 5 minut na start

Typy probes:

Typ Użycie
httpGet HTTP GET, success = 2xx-3xx
tcpSocket Połączenie TCP
exec Wykonaj komendę, success = exit 0

Ważne różnice:

Probe Fail = ? Restart?
Liveness Aplikacja martwa TAK
Readiness Nie gotowa na ruch NIE (tylko usuń z Service)
Startup Jeszcze nie wystartowała TAK (po wyczerpaniu prób)

Services i Networking

Jakie są typy Service w Kubernetes?

Odpowiedź w 30 sekund: ClusterIP (domyślny) - wewnętrzny IP. NodePort - port na każdym nodzie (30000-32767). LoadBalancer - zewnętrzny LB w cloudzie. ExternalName - alias DNS. Dla HTTP lepiej Ingress.

Odpowiedź w 2 minuty:

Service w Kubernetes zapewnia stabilny endpoint do Podów, które mogą być dynamicznie tworzone i usuwane. Istnieją cztery główne typy Service, każdy dla innego przypadku użycia:

# ClusterIP - wewnętrzny (domyślny)
apiVersion: v1
kind: Service
metadata:
  name: api-internal
spec:
  type: ClusterIP
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 8080

---
# NodePort - dostęp zewnętrzny przez port na nodzie
apiVersion: v1
kind: Service
metadata:
  name: api-nodeport
spec:
  type: NodePort
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080    # Dostęp: <NodeIP>:30080

---
# LoadBalancer - external LB (cloud)
apiVersion: v1
kind: Service
metadata:
  name: api-lb
spec:
  type: LoadBalancer
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 8080

Porównanie:

Typ Dostęp Kiedy używać
ClusterIP Tylko wewnętrzny Komunikacja między serwisami
NodePort <NodeIP>:30000-32767 Dev/test, on-premise
LoadBalancer External IP Cloud, produkcja
ExternalName DNS CNAME Alias do zewnętrznego serwisu

Czym jest Ingress i jak działa?

Odpowiedź w 30 sekund: Ingress to L7 (HTTP) load balancer - routing po host/path, SSL termination, jeden punkt wejścia do wielu serwisów. Wymaga Ingress Controller (nginx, traefik, AWS ALB). Service LoadBalancer to L4 (TCP/UDP).

Odpowiedź w 2 minuty:

Ingress działa na warstwie aplikacji (HTTP/HTTPS) i pozwala na zaawansowany routing oparty na hostname i path, w przeciwieństwie do Service LoadBalancer który działa na warstwie transportu. Przykład konfiguracji z SSL i routing'iem:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1
            port:
              number: 80
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2
            port:
              number: 80
Internet → Ingress Controller → Ingress Rules → Services → Pods

                    ┌─────────────────────────┐
                    │    Ingress Controller   │
                    │    (nginx, traefik)     │
                    └───────────┬─────────────┘
                                │
            ┌───────────────────┼───────────────────┐
            │                   │                   │
    api.example.com/v1  api.example.com/v2  web.example.com
            │                   │                   │
            ▼                   ▼                   ▼
      ┌──────────┐       ┌──────────┐       ┌──────────┐
      │ api-v1   │       │ api-v2   │       │   web    │
      │ Service  │       │ Service  │       │ Service  │
      └──────────┘       └──────────┘       └──────────┘

Popularne Ingress Controllers:

  • nginx-ingress - najpopularniejszy
  • traefik - automatyczne discovery
  • AWS ALB Ingress - natywny dla AWS
  • GCE Ingress - natywny dla GCP

Jak działa DNS w Kubernetes?

Odpowiedź w 30 sekund: CoreDNS (lub kube-dns) zapewnia service discovery. Każdy Service dostaje DNS: service-name.namespace.svc.cluster.local. Pody mogą używać krótkiej nazwy service-name w tym samym namespace.

Odpowiedź w 2 minuty:

Każdy Service w Kubernetes automatycznie otrzymuje wpis DNS, co pozwala na łatwe service discovery bez hardcoded IP. CoreDNS tworzy hierarchiczny naming convention:

# Pełna nazwa DNS Service
<service-name>.<namespace>.svc.cluster.local

# Przykłady
api.default.svc.cluster.local      # Service 'api' w 'default'
postgres.database.svc.cluster.local # Service 'postgres' w 'database'

# W tym samym namespace można skrócić
curl http://api                     # W namespace 'default'
curl http://api.default             # Też działa
curl http://api.default.svc         # Też działa
# Headless Service (bez ClusterIP) - dla StatefulSet
apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  clusterIP: None    # Headless!
  selector:
    app: postgres
  ports:
  - port: 5432

Headless Service DNS:

# Zwraca A records dla każdego Poda
postgres-0.postgres.default.svc.cluster.local
postgres-1.postgres.default.svc.cluster.local

Co to jest NetworkPolicy?

Odpowiedź w 30 sekund: NetworkPolicy to firewall dla Podów - kontroluje ingress i egress traffic na podstawie labels. Domyślnie wszystko jest dozwolone. Po dodaniu NetworkPolicy - tylko jawnie dozwolony ruch przechodzi.

Odpowiedź w 2 minuty:

NetworkPolicy działa jak firewall dla Podów, pozwalając na precyzyjną kontrolę ruchu przychodzącego i wychodzącego na podstawie labels, namespaces i portów. Przykład restrykcyjnej polityki dla API:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-network-policy
  namespace: production
spec:
  # Dotyczy Podów z labelem app=api
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  - Egress

  ingress:
  # Pozwól na ruch z podów z labelem role=frontend
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 8080

  egress:
  # Pozwól na połączenia do bazy danych
  - to:
    - podSelector:
        matchLabels:
          app: postgres
    ports:
    - protocol: TCP
      port: 5432
  # Pozwól na DNS
  - to:
    ports:
    - protocol: UDP
      port: 53

Ważne:

  • NetworkPolicy wymaga CNI plugin z obsługą (Calico, Cilium, Weave)
  • Domyślna polityka: pozwól wszystko
  • Po dodaniu policy dla poda: deny all, pozwól tylko to co w policy

Konfiguracja i Secrets

Jak używać ConfigMap?

Odpowiedź w 30 sekund: ConfigMap przechowuje konfigurację (key-value lub pliki) oddzieloną od obrazu. Można montować jako zmienne env lub jako pliki. Zmiana ConfigMap nie restartuje Podów automatycznie.

Odpowiedź w 2 minuty:

ConfigMap umożliwia separację konfiguracji od kodu aplikacji, co jest kluczowe dla 12-factor apps. Możesz przechowywać zarówno pojedyncze wartości jak i całe pliki konfiguracyjne:

# Tworzenie ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  # Key-value
  LOG_LEVEL: "debug"
  API_URL: "https://api.example.com"

  # Plik konfiguracyjny
  config.json: |
    {
      "database": "postgres",
      "port": 5432
    }
# Użycie w Pod
spec:
  containers:
  - name: app
    image: myapp:v1

    # Jako zmienne env (pojedyncze klucze)
    env:
    - name: LOG_LEVEL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: LOG_LEVEL

    # Wszystkie klucze jako env
    envFrom:
    - configMapRef:
        name: app-config

    # Jako plik
    volumeMounts:
    - name: config
      mountPath: /app/config

  volumes:
  - name: config
    configMap:
      name: app-config
# Imperatywne tworzenie
kubectl create configmap app-config \
  --from-literal=LOG_LEVEL=debug \
  --from-file=config.json

Jak bezpiecznie przechowywać sekrety?

Odpowiedź w 30 sekund: Secret przechowuje wrażliwe dane (hasła, tokeny, certyfikaty). Dane są base64 encoded (nie encrypted!). Dla prawdziwego bezpieczeństwa: External Secrets Operator + Vault/AWS Secrets Manager, lub sealed-secrets.

Odpowiedź w 2 minuty:

Secret w Kubernetes oferuje podstawową ochronę danych wrażliwych przez base64 encoding, ale dla prawdziwego bezpieczeństwa produkcyjnego potrzebne są zewnętrzne systemy zarządzania sekretami. Przykład użycia:

# Tworzenie Secret
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  # Base64 encoded!
  username: cG9zdGdyZXM=      # echo -n 'postgres' | base64
  password: c2VjcmV0MTIz      # echo -n 'secret123' | base64
# Użycie w Pod
spec:
  containers:
  - name: app
    image: myapp:v1
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: db-credentials
          key: username
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-credentials
          key: password

    # Jako pliki
    volumeMounts:
    - name: secrets
      mountPath: /app/secrets
      readOnly: true

  volumes:
  - name: secrets
    secret:
      secretName: db-credentials

Dobre praktyki:

# ❌ Nie commituj sekretów do git!
# ❌ Base64 to nie encryption!

# ✅ External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  secretStoreRef:
    name: vault
    kind: SecretStore
  target:
    name: db-credentials
  data:
  - secretKey: password
    remoteRef:
      key: secret/db
      property: password

Storage

Czym jest PersistentVolume i PersistentVolumeClaim?

Odpowiedź w 30 sekund: PersistentVolume (PV) to zasób storage w klastrze (jak dysk). PersistentVolumeClaim (PVC) to request na storage - Pod używa PVC, K8s binduje do odpowiedniego PV. StorageClass automatyzuje provisioning.

Odpowiedź w 2 minuty:

System storage w Kubernetes oddziela definicję zasobów (PV) od ich użycia (PVC), co pozwala na abstraction layer między aplikacją a fizycznym storage. Przykład kompletnego flow:

# PersistentVolume (zazwyczaj tworzony przez admina lub dynamicznie)
apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: fast-ssd
  hostPath:  # Tylko dev! W produkcji: EBS, GCE PD, NFS
    path: /data/postgres

---
# PersistentVolumeClaim (request od aplikacji)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: fast-ssd

---
# Pod używający PVC
spec:
  containers:
  - name: postgres
    image: postgres:15
    volumeMounts:
    - name: data
      mountPath: /var/lib/postgresql/data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: postgres-pvc

Access Modes:

Mode Skrót Opis
ReadWriteOnce RWO Jeden node może pisać
ReadOnlyMany ROX Wiele nodów może czytać
ReadWriteMany RWX Wiele nodów może pisać

Reclaim Policies:

Policy Co się dzieje po usunięciu PVC
Retain PV zostaje, dane zachowane
Delete PV i dane usuwane
Recycle Deprecated

Czym jest StorageClass?

Odpowiedź w 30 sekund: StorageClass definiuje "klasę" storage (typ dysku, provisioner). Pozwala na dynamiczne tworzenie PV - gdy PVC request'uje storage, K8s automatycznie tworzy PV. Różne klasy dla różnych potrzeb (fast-ssd, slow-hdd).

Odpowiedź w 2 minuty:

StorageClass wprowadza dynamic provisioning - zamiast ręcznie tworzyć PV dla każdego PVC, K8s automatycznie tworzy odpowiedni volume w cloud provider'ze. Przykład dla AWS:

# StorageClass dla AWS EBS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

---
# PVC używający StorageClass
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: fast-ssd  # K8s automatycznie tworzy PV!
# Lista StorageClasses
kubectl get storageclass

# Typowe providery
# AWS: ebs.csi.aws.com
# GCP: pd.csi.storage.gke.io
# Azure: disk.csi.azure.com

Skalowanie i autoscaling

Jak działa Horizontal Pod Autoscaler?

Odpowiedź w 30 sekund: HPA automatycznie skaluje liczbę replik na podstawie CPU, memory lub custom metrics. Sprawdza metryki co 15s (domyślnie). Wymaga metrics-server. Definiujesz min/max replik i target utilization.

Odpowiedź w 2 minuty:

HPA monitoruje metryki Podów i automatycznie dostosowuje liczbę replik aby utrzymać target utilization. Wspiera zarówno resource metrics (CPU, memory) jak i custom metrics:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70    # Skaluj gdy CPU > 70%
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300  # Czekaj 5 min przed scale down
# Imperatywne tworzenie
kubectl autoscale deployment api --min=2 --max=10 --cpu-percent=70

# Status
kubectl get hpa
kubectl describe hpa api-hpa

Ważne:

  • Deployment musi mieć zdefiniowane resources.requests
  • Metrics Server musi być zainstalowany
  • Scale down jest wolniejszy (stabilization window)

Jak ustawić resource limits?

Odpowiedź w 30 sekund: requests to minimum gwarantowane (używane do schedulingu). limits to maksimum (przekroczenie CPU = throttling, memory = OOM kill). Zawsze definiuj oba dla produkcji.

Odpowiedź w 2 minuty:

Resource requests i limits definiują ile zasobów kontener potrzebuje i może wykorzystać. Kubernetes używa requests do decyzji o umieszczeniu Poda, a limits do egzekwowania ograniczeń:

spec:
  containers:
  - name: api
    image: myapi:v1
    resources:
      requests:
        memory: "256Mi"   # Gwarantowane 256Mi
        cpu: "100m"       # Gwarantowane 0.1 CPU
      limits:
        memory: "512Mi"   # Max 512Mi (OOM kill jeśli więcej)
        cpu: "500m"       # Max 0.5 CPU (throttling)

CPU units:

  • 1 = 1 vCPU/core
  • 500m = 0.5 CPU (500 millicores)
  • 100m = 0.1 CPU

Memory units:

  • 256Mi = 256 MiB (mebibytes)
  • 1Gi = 1 GiB (gibibytes)

QoS Classes:

Class Warunki Priorytet eviction
Guaranteed requests = limits Najniższy (ostatni evicted)
Burstable requests < limits Średni
BestEffort Brak requests/limits Najwyższy (pierwszy evicted)

Helm

Czym jest Helm i po co go używać?

Odpowiedź w 30 sekund: Helm to package manager dla K8s. Chart to zbiór szablonów YAML z parametryzacją (values.yaml). Upraszcza instalację złożonych aplikacji, wersjonowanie, upgrade'y i rollbacki. Helm 3 nie wymaga Tiller (bezpieczniejszy).

Odpowiedź w 2 minuty:

Helm umożliwia pakowanie aplikacji K8s jako charty z parametryzacją, co znacząco upraszcza zarządzanie złożonymi deploymentami. Podstawowe operacje:

# Instalacja z repozytorium
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install my-postgres bitnami/postgresql

# Instalacja z custom values
helm install my-postgres bitnami/postgresql -f values.yaml

# Upgrade
helm upgrade my-postgres bitnami/postgresql --set primary.persistence.size=20Gi

# Rollback
helm rollback my-postgres 1

# Lista releases
helm list

# Historia
helm history my-postgres

Struktura Chart:

mychart/
├── Chart.yaml          # Metadane (nazwa, wersja)
├── values.yaml         # Domyślne wartości
├── templates/          # Szablony YAML
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── _helpers.tpl    # Funkcje pomocnicze
└── charts/             # Zależności (subcharty)
# values.yaml
replicaCount: 3
image:
  repository: myapp
  tag: v1.0

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-app
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
      - name: app
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

Troubleshooting

Jak debugować problemy z Podami?

Odpowiedź w 30 sekund: kubectl describe pod - eventy i status. kubectl logs - logi kontenera. kubectl exec - shell w kontenerze. Sprawdź: ImagePullBackOff (obraz), CrashLoopBackOff (crash), Pending (scheduling).

Odpowiedź w 2 minuty:

Debugowanie Podów wymaga systematycznego podejścia - od sprawdzenia statusu, przez analizę eventów, po inspekcję logów i shell access. Podstawowe komendy diagnostyczne:

# Status podów
kubectl get pods
kubectl get pods -o wide          # Więcej info (node, IP)

# Szczegóły i eventy
kubectl describe pod <name>
# Szukaj: Events, Conditions, Container State

# Logi
kubectl logs <pod>                  # Logi
kubectl logs <pod> -c <container>   # Konkretny kontener
kubectl logs <pod> --previous       # Poprzedni kontener (po restart)
kubectl logs <pod> -f               # Follow

# Shell w kontenerze
kubectl exec -it <pod> -- /bin/sh
kubectl exec -it <pod> -c <container> -- /bin/bash

# Debug pod (gdy kontener crashuje)
kubectl debug <pod> -it --image=busybox

Typowe problemy:

Status Przyczyna Rozwiązanie
Pending Brak zasobów, affinity Sprawdź describe, dodaj node
ImagePullBackOff Zły obraz, brak dostępu Sprawdź image name, imagePullSecrets
CrashLoopBackOff Aplikacja crashuje Sprawdź logs, command/args
OOMKilled Out of memory Zwiększ limits.memory
Evicted Node pressure Sprawdź node resources

Jak debugować problemy z siecią?

Odpowiedź w 30 sekund: Sprawdź Service selector (matchuje labels?), Endpoints (kubectl get endpoints), DNS (nslookup), NetworkPolicy. Debug pod z curl/wget do testowania połączeń.

Odpowiedź w 2 minuty:

Problemy z siecią w Kubernetes najczęściej wynikają z nieprawidłowej konfiguracji Service selectors, DNS lub NetworkPolicy. Metodyczny proces debugowania:

# Sprawdź Service i Endpoints
kubectl get svc
kubectl get endpoints <service>
kubectl describe svc <service>
# Endpoints puste? = selector nie matchuje labels podów

# Sprawdź labels
kubectl get pods --show-labels
kubectl get pods -l app=api

# Test DNS z poda
kubectl run debug --rm -it --image=busybox -- /bin/sh
> nslookup api-service
> wget -qO- http://api-service:8080/health

# Sprawdź NetworkPolicy
kubectl get networkpolicy
kubectl describe networkpolicy <name>

# Port-forward do testowania
kubectl port-forward svc/api-service 8080:80
# Teraz curl http://localhost:8080

# Sprawdź czy pod odpowiada
kubectl exec <pod> -- curl localhost:8080/health

Checklist sieci:

  1. Pod działa? (kubectl get pods)
  2. Service selector matchuje labels?
  3. Endpoints istnieją? (kubectl get endpoints)
  4. DNS działa? (nslookup service-name)
  5. NetworkPolicy blokuje?
  6. Port correct? (service port vs container port)

Zobacz też


Ten artykuł jest częścią serii przygotowującej do rozmów rekrutacyjnych na stanowisko DevOps Engineer. Opanuj Kubernetes i inne technologie DevOps z naszymi fiszkami do nauki.

Chcesz więcej pytań rekrutacyjnych?

To tylko jeden temat z naszego kompletnego przewodnika po rozmowach rekrutacyjnych. Uzyskaj dostęp do 800+ pytań z 13 technologii.

Kup pełny dostęp Zobacz bezpłatny podgląd
Powrót do blogu

Zostaw komentarz

Pamiętaj, że komentarze muszą zostać zatwierdzone przed ich opublikowaniem.