Rozmowa kwalifikacyjna z Kubernetes: Pods, Services i Deployments w praktyce

Kompletny przewodnik po pytaniach rekrutacyjnych dotyczących Kubernetes Pods, Services i Deployments z przykładami YAML i strategiami skalowania na 2026 rok.

Kubernetes Pods, Services i Deployments - przewodnik do rozmowy kwalifikacyjnej

Rozmowy kwalifikacyjne na stanowiska DevOps i Cloud Engineering niemal zawsze obejmują pytania o Kubernetes. Trzy fundamentalne obiekty -- Pods, Services i Deployments -- stanowią podstawę każdego klastra produkcyjnego. Zrozumienie ich wzajemnych zależności pozwala nie tylko odpowiedzieć na pytania rekrutacyjne, ale także budować skalowalne systemy w praktyce.

Kluczowe obiekty Kubernetes w pigułce

Pod to najmniejsza jednostka wdrożeniowa -- jeden lub kilka kontenerów ze wspólnym adresem sieciowym. Deployment zarządza cyklem życia Podów, zapewniając deklaratywne aktualizacje i rollbacki. Service udostępnia stabilny adres sieciowy dla grupy Podów, niezależnie od ich liczby czy lokalizacji w klastrze.

Czym są Pods w Kubernetes i jak działają

Pod to atomowa jednostka w Kubernetes -- nie da się uruchomić kontenera bez Poda. Każdy Pod otrzymuje własny adres IP w klastrze, a kontenery wewnątrz niego współdzielą przestrzeń sieciową i wolumeny. W praktyce większość Podów zawiera jeden kontener, ale wzorzec sidecar (np. kontener do zbierania logów obok kontenera aplikacji) jest szeroko stosowany w architekturach produkcyjnych.

Poniższy manifest YAML definiuje Pod z kontenerem API, limitami zasobów oraz sondami readiness i liveness. Sondy te są kluczowe -- bez readinessProbe Kubernetes może kierować ruch do Poda, który nie jest jeszcze gotowy do obsługi zapytań.

yaml
# api-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: api-server
  labels:
    app: api
    version: v2
spec:
  containers:
    - name: api
      image: registry.example.com/api:3.1.0
      ports:
        - containerPort: 8080
      resources:
        requests:
          cpu: "250m"        # 0.25 CPU core reserved
          memory: "256Mi"    # 256 MB reserved
        limits:
          cpu: "500m"        # hard cap at 0.5 core
          memory: "512Mi"    # OOMKilled beyond this
      readinessProbe:
        httpGet:
          path: /healthz
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 10
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
        initialDelaySeconds: 15
        periodSeconds: 20

Sekcja resources.requests określa minimalne zasoby gwarantowane przez scheduler -- Pod zostanie umieszczony tylko na węźle z wystarczającą ilością wolnych zasobów. Sekcja limits definiuje twarde ograniczenia: przekroczenie limitu pamięci prowadzi do natychmiastowego zakończenia procesu (OOMKilled).

Typowy błąd na rozmowie kwalifikacyjnej

Pominięcie resources.limits w manifeście Poda to częsty błąd. Bez limitów pojedynczy Pod może zużywać zasoby całego węzła, co prowadzi do niestabilności całego klastra. Na rozmowie warto podkreślić, że requests i limits to dwa różne mechanizmy -- requests wpływa na scheduling, limits na runtime enforcement.

Cykl życia Poda i polityki restartowania

Każdy Pod przechodzi przez określone fazy życia, a zrozumienie tych faz jest niezbędne do diagnostyki problemów w produkcji. Kubernetes definiuje pięć głównych stanów Poda.

| Faza | Opis | Typowa przyczyna | |------|------|------------------| | Pending | Pod zaakceptowany, ale kontenery jeszcze nie uruchomione | Brak zasobów na węzłach, pobieranie obrazu | | Running | Przynajmniej jeden kontener działa | Normalna praca | | Succeeded | Wszystkie kontenery zakończyły się kodem 0 | Zadania batch (Jobs) | | Failed | Przynajmniej jeden kontener zakończył się błędem | Błąd aplikacji, brak zasobów | | Unknown | Nie można ustalić stanu Poda | Utrata komunikacji z węzłem |

Polityka restartPolicy określa, co Kubernetes robi po zakończeniu kontenera. Dostępne są trzy wartości: Always (domyślna -- restartuje zawsze), OnFailure (restartuje tylko po błędzie) i Never (nigdy nie restartuje). Dla długo działających serwerów stosuje się Always, dla zadań jednorazowych -- OnFailure lub Never.

Poniższy manifest przedstawia Pod służący do jednorazowej migracji bazy danych. Używa restartPolicy: OnFailure, dzięki czemu Kubernetes automatycznie ponowi próbę w przypadku awarii, ale nie będzie restartował procesu po pomyślnym zakończeniu.

yaml
# batch-job-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: data-migration
spec:
  restartPolicy: OnFailure   # restart only on crash
  containers:
    - name: migrate
      image: registry.example.com/migrate:1.0.0
      command: ["python", "migrate.py"]
      env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: connection-string

Warto zwrócić uwagę na użycie secretKeyRef zamiast bezpośredniego umieszczania connection stringa w manifeście. Na rozmowie kwalifikacyjnej znajomość mechanizmów Secrets i ConfigMaps jest często weryfikowana jako element bezpieczeństwa klastrów.

Deployments -- deklaratywne zarządzanie Podami

Bezpośrednie tworzenie Podów za pomocą manifestów nie jest zalecane w środowiskach produkcyjnych. Deployment to kontroler wyższego poziomu, który zarządza ReplicaSet, a ten z kolei zarządza Podami. Taka hierarchia pozwala na deklaratywne aktualizacje, automatyczne skalowanie i rollbacki bez przestojów.

Deployment rozwiązuje trzy kluczowe problemy: utrzymuje żądaną liczbę replik (jeśli Pod padnie, zostanie automatycznie odtworzony), umożliwia rolling updates (aktualizacja bez downtime'u) oraz przechowuje historię rewizji do szybkiego rollbacku.

yaml
# api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
  labels:
    app: api
spec:
  replicas: 3                    # run 3 identical Pods
  revisionHistoryLimit: 5        # keep 5 old ReplicaSets for rollback
  selector:
    matchLabels:
      app: api                   # must match Pod template labels
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1          # at most 1 Pod down during update
      maxSurge: 1                # at most 1 extra Pod during update
  template:
    metadata:
      labels:
        app: api
        version: v2
    spec:
      containers:
        - name: api
          image: registry.example.com/api:3.1.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10

Parametry maxUnavailable i maxSurge kontrolują tempo aktualizacji. Przy 3 replikach i maxUnavailable: 1 Kubernetes gwarantuje, że co najmniej 2 Pody będą dostępne w każdym momencie aktualizacji. Parametr maxSurge: 1 oznacza, że tymczasowo może istnieć maksymalnie 4 Pody (3 + 1) podczas przejścia na nową wersję.

Rollback Deploymentu do poprzedniej wersji

Każda zmiana w specyfikacji Deploymentu tworzy nową rewizję. Kubernetes przechowuje historię rewizji (kontrolowaną przez revisionHistoryLimit), co pozwala na natychmiastowy powrót do dowolnej poprzedniej wersji. W środowisku produkcyjnym rollback jest jednym z najczęściej wykonywanych działań awaryjnych.

bash
# Check rollout status
kubectl rollout status deployment/api-server

# View revision history
kubectl rollout history deployment/api-server

# Roll back to previous version
kubectl rollout undo deployment/api-server

# Roll back to specific revision
kubectl rollout undo deployment/api-server --to-revision=3

Komenda kubectl rollout undo przywraca poprzednią wersję ReplicaSet, a nowa wersja jest stopniowo wygaszana -- dokładnie odwrotnie do procesu aktualizacji. Cały mechanizm opiera się na etykietach (labels) i selektorach, dlatego ich prawidłowa konfiguracja jest krytyczna.

Gotowy na rozmowy o DevOps?

Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.

Services -- stabilna warstwa sieciowa dla Podów

Pody są efemeryczne -- mogą być tworzone, niszczone i przenoszone między węzłami. Każdy nowy Pod otrzymuje nowy adres IP, co sprawia, że bezpośrednie adresowanie Podów jest niepraktyczne. Service rozwiązuje ten problem, dostarczając stały adres IP (ClusterIP) i nazwę DNS, które automatycznie kierują ruch do aktywnych Podów pasujących do selektora.

Mechanizm działania jest prosty: Service używa selektora label do identyfikacji docelowych Podów. Kubernetes utrzymuje obiekt Endpoints (lub EndpointSlice w nowszych wersjach), który dynamicznie aktualizuje listę adresów IP aktywnych Podów spełniających kryteria selektora.

yaml
# api-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: ClusterIP               # internal-only by default
  selector:
    app: api                     # routes to Pods with this label
  ports:
    - name: http
      port: 80                   # Service port (what clients use)
      targetPort: 8080           # Pod port (where container listens)
      protocol: TCP

Pole port: 80 definiuje port, na którym Service nasłuchuje wewnątrz klastra. Pole targetPort: 8080 wskazuje port kontenera, do którego ruch jest przekierowywany. Dzięki temu inne serwisy w klastrze komunikują się z API poprzez http://api-service:80, niezależnie od tego, ile Podów aktualnie działa i jakie mają adresy IP.

Typy Services w Kubernetes i ich zastosowania

Kubernetes oferuje cztery typy Services, każdy z innym zakresem dostępności. Wybór odpowiedniego typu jest częścią pytań na rozmowach kwalifikacyjnych dotyczących architektury sieciowej Kubernetes.

| Typ | Zakres | Zastosowanie | |-----|--------|--------------| | ClusterIP | Tylko wewnątrz klastra | Komunikacja między serwisami (domyślny) | | NodePort | Zewnętrzny dostęp przez port węzła (30000-32767) | Testowanie, proste wdrożenia | | LoadBalancer | Zewnętrzny load balancer (chmura) | Produkcja w AWS, GCP, Azure | | ExternalName | Alias DNS do zewnętrznej usługi | Integracja z serwisami poza klastrem |

W środowiskach chmurowych typ LoadBalancer jest standardowym wyborem dla ruchu produkcyjnego. Poniższy manifest tworzy Service z zewnętrznym load balancerem na AWS, używając adnotacji specyficznej dla dostawcy chmury.

yaml
# api-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
  name: api-public
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"  # AWS NLB
spec:
  type: LoadBalancer
  selector:
    app: api
  ports:
    - name: https
      port: 443
      targetPort: 8080
      protocol: TCP
Gateway API jako następca Ingress

Od Kubernetes v1.35 Gateway API jest rekomendowanym sposobem zarządzania ruchem przychodzącym. W przeciwieństwie do klasycznego Ingress, Gateway API oferuje rozdzielenie odpowiedzialności między zespoły platformowe (GatewayClass, Gateway) i zespoły aplikacyjne (HTTPRoute). Na rozmowach kwalifikacyjnych w 2026 roku znajomość Gateway API jest coraz częściej oczekiwana.

Łączenie Deploymentów z Services -- wzorzec canary

Jeden z najczęściej omawianych wzorców na rozmowach kwalifikacyjnych to canary deployment. Mechanizm opiera się na kluczowej właściwości Services: Service kieruje ruch do wszystkich Podów pasujących do selektora, niezależnie od tego, który Deployment nimi zarządza.

Tworząc drugi Deployment z tą samą etykietą app: api, ale inną wersją obrazu i mniejszą liczbą replik, można skierować część ruchu produkcyjnego do nowej wersji. Przy głównym Deploymencie z 3 replikami i canary z 1 repliką, około 25% ruchu trafi do nowej wersji.

yaml
# canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api                   # same label as main Deployment
  template:
    metadata:
      labels:
        app: api                 # Service picks this up automatically
        version: v3-canary
    spec:
      containers:
        - name: api
          image: registry.example.com/api:3.2.0-rc1
          ports:
            - containerPort: 8080

Po weryfikacji poprawności działania nowej wersji (metryki błędów, latencja, logi) można stopniowo zwiększyć liczbę replik canary i zmniejszyć liczbę replik głównego Deploymentu, aż do pełnego przejścia. Jeśli nowa wersja wykazuje problemy, wystarczy usunąć canary Deployment -- Service automatycznie przestanie kierować ruch do usuniętych Podów.

Horizontal Pod Autoscaler -- automatyczne skalowanie

HPA (Horizontal Pod Autoscaler) dynamicznie dostosowuje liczbę replik Deploymentu na podstawie obserwowanych metryk. Wymaga działającego Metrics Server w klastrze. HPA sprawdza metryki w regularnych odstępach czasu (domyślnie co 15 sekund) i podejmuje decyzje o skalowaniu w górę lub w dół.

yaml
# api-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70   # scale up above 70% CPU
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300  # wait 5 min before scaling down

Parametr stabilizationWindowSeconds: 300 w sekcji scaleDown zapobiega szybkim oscylacjom liczby replik (tzw. flapping). Kubernetes czeka 5 minut przed zmniejszeniem liczby Podów, nawet jeśli metryki spadną poniżej progu. Skalowanie w górę działa natychmiast -- priorytetem jest zapewnienie dostępności pod obciążeniem.

Warto zauważyć, że HPA wymaga prawidłowo skonfigurowanych resources.requests w Podach. Bez nich HPA nie jest w stanie obliczyć procentowego wykorzystania zasobów.

Najczęściej zadawane pytania na rozmowach kwalifikacyjnych

Jaka jest różnica między Podem a kontenerem? Pod to jednostka orkiestracji Kubernetes, która opakowuje jeden lub więcej kontenerów. Kontenery w Podzie współdzielą adres IP, przestrzeń portów i wolumeny. Pod nigdy nie jest kontenerem -- to abstrakcja wyższego poziomu zarządzana przez kubelet na węźle.

Dlaczego nie należy tworzyć Podów bezpośrednio? Pody tworzone bezpośrednio (bare Pods) nie są automatycznie odtwarzane po awarii węzła. Deployment (lub StatefulSet, DaemonSet) zapewnia self-healing -- jeśli Pod zostanie usunięty lub węzeł ulegnie awarii, kontroler automatycznie tworzy nowy Pod na dostępnym węźle.

Jak Service odkrywa Pody? Service używa selektora label do znajdowania pasujących Podów. Kubernetes kontroler Endpoints monitoruje Pody i automatycznie aktualizuje listę docelowych adresów IP. Tylko Pody z pozytywną sondą readiness są uwzględniane w routingu.

Czym się różni ClusterIP od NodePort? ClusterIP przydziela wewnętrzny adres IP dostępny tylko z wnętrza klastra. NodePort otwiera statyczny port (30000-32767) na każdym węźle klastra, umożliwiając dostęp zewnętrzny. NodePort tworzy również ClusterIP automatycznie -- jest to rozszerzenie, nie zamiennik.

Jak działa rolling update w Deployment? Kubernetes tworzy nowy ReplicaSet z nową wersją i stopniowo zwiększa jego liczbę replik, jednocześnie zmniejszając stary ReplicaSet. Parametry maxUnavailable i maxSurge kontrolują tempo tego procesu. Dzięki readinessProbe ruch jest kierowany do nowego Poda dopiero po potwierdzeniu jego gotowości.

Kiedy użyć StatefulSet zamiast Deployment? StatefulSet stosuje się, gdy Pody wymagają stałej tożsamości sieciowej (np. db-0, db-1), stałego storage'u (PersistentVolumeClaims) lub gwarantowanej kolejności uruchamiania i wyłączania. Typowe zastosowania to bazy danych (PostgreSQL, MongoDB) i systemy rozproszone (Kafka, Elasticsearch).

Zacznij ćwiczyć!

Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.

Podsumowanie

  • Pod to najmniejsza jednostka wdrożeniowa w Kubernetes, zawierająca jeden lub więcej kontenerów ze wspólnym adresem IP. Zawsze należy definiować resources.requests i resources.limits oraz sondy readiness/liveness.
  • Deployment zarządza Podami deklaratywnie, zapewniając rolling updates, automatyczne odtwarzanie replik i możliwość rollbacku. Bezpośrednie tworzenie Podów w produkcji jest antywzorcem.
  • Service dostarcza stały adres sieciowy (DNS + ClusterIP) dla grupy Podów. Cztery typy (ClusterIP, NodePort, LoadBalancer, ExternalName) pokrywają różne scenariusze dostępu.
  • HPA automatycznie skaluje liczbę replik na podstawie metryk CPU i pamięci. Wymaga prawidłowo skonfigurowanych resource requests i działającego Metrics Server.
  • Wzorzec canary deployment wykorzystuje mechanizm selektorów Services do stopniowego wdrażania nowych wersji bez zmian w konfiguracji sieciowej.
  • Na rozmowie kwalifikacyjnej kluczowe jest wykazanie zrozumienia wzajemnych zależności między tymi obiektami, a nie tylko znajomości poszczególnych manifestów YAML.

Tagi

#kubernetes
#devops
#interview
#pods
#services
#deployments

Udostępnij