Kubernetes - Pytania Rekrutacyjne dla DevOps i Platform Engineera [2026]
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
- Pods i Deployments
- Services i Networking
- Konfiguracja i Secrets
- Storage
- Skalowanie i autoscaling
- Helm
- Troubleshooting
- Zobacz też
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:
- Pod działa? (
kubectl get pods) - Service selector matchuje labels?
- Endpoints istnieją? (
kubectl get endpoints) - DNS działa? (
nslookup service-name) - NetworkPolicy blokuje?
- Port correct? (service port vs container port)
Zobacz też
- Kompletny Przewodnik - Rozmowa DevOps Engineer - pełny przewodnik przygotowania do rozmowy DevOps
- Docker - Pytania Rekrutacyjne - 42 pytania o konteneryzację
- Linux - Pytania Rekrutacyjne - 50+ pytań o komendy i bash scripting
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.
