Kubernetes (K8s) to otwarty system, który uruchamia i pilnuje kontenerów na wielu serwerach: sam restartuje te, które przestały działać, skaluje ich liczbę i aktualizuje aplikację stopniowo, bez przestoju. Opisujesz w pliku YAML, ile kopii aplikacji ma działać, a Kubernetes stale doprowadza stan klastra do tego opisu. Potrzebujesz go, gdy kontenerów i serwerów jest tyle, że nie da się ich ogarniać ręcznie; przy jednej aplikacji na jednym serwerze zwykle wystarczy Docker Compose.
Kiedy nauczysz się Dockera, pojawia się kolejne pytanie: co zrobić, gdy kontenerów jest kilkadziesiąt, działają na kilku serwerach, a któryś w nocy przestaje odpowiadać? Odpowiedzią jest Kubernetes. Poniżej wyjaśniamy, czym jest, z czego się składa i jak go uruchomić na własnym komputerze. Przykłady wykonaliśmy na prawdziwym klastrze, więc pokazujemy też błędy, na które trafisz w pierwszym tygodniu pracy.
Czym jest Kubernetes i do czego służy?
Kubernetes to otwarty system do orkiestracji kontenerów (container orchestration), czyli automatycznego uruchamiania, łączenia, skalowania i naprawiania aplikacji w kontenerach. Według oficjalnej dokumentacji nazwa pochodzi z greckiego i oznacza sternika, a skrót K8s powstał z policzenia ośmiu liter między „K” a „s”. Projekt otworzył Google w 2014 roku.
Dokumentacja wymienia, co Kubernetes daje w praktyce:
- wykrywanie usług i rozkładanie ruchu, czyli stała nazwa DNS dla grupy kontenerów,
- samonaprawę (self-healing): gdy kontener przestaje działać, system uruchamia nowy,
- stopniowe aktualizacje i wycofywanie zmian bez wyłączania aplikacji,
- skalowanie liczby kopii aplikacji jednym poleceniem lub automatycznie,
- zarządzanie konfiguracją i sekretami oraz podłączanie pamięci masowej.
Docker odpowiada na pytanie „jak spakować i uruchomić aplikację?”, a Kubernetes na pytanie „jak utrzymać dziesiątki takich aplikacji przy życiu na wielu maszynach?”. To narzędzia, które się uzupełniają, a nie konkurują.
Z czego składa się klaster Kubernetes?
Klaster (cluster) to zestaw maszyn, który Kubernetes traktuje jak jeden duży komputer. Dokumentacja opisuje go jako control plane oraz zestaw węzłów (nodes):
| Element | Co robi | Analogia |
|---|---|---|
| Control plane | podejmuje decyzje (np. gdzie uruchomić poda) i reaguje na zdarzenia | kierownik zmiany |
| Węzeł (node) | maszyna, na której działają kontenery | stanowisko pracy |
| Pod | najmniejsza jednostka: jeden lub kilka kontenerów uruchamianych razem | pracownik |
| Deployment | opis, ile kopii poda ma działać i jak je aktualizować | grafik zmian |
| Service | stały adres i nazwa dla grupy podów | recepcja z jednym numerem telefonu |
W produkcji control plane zwykle działa na kilku maszynach, a klaster ma wiele węzłów, żeby przetrwać awarię. Do nauki wystarczy jeden węzeł na laptopie.
Czym różni się Pod od Deploymentu?
Tę parę pojęć myli najwięcej osób. Pod to pojedynczy, uruchomiony kontener (lub kilka ściśle związanych): jeśli go usuniesz, nikt go nie odtworzy. Deployment to „zlecenie”: mówisz „chcę 3 kopie tej aplikacji”, a Kubernetes pilnuje, żeby tyle ich działało. To Deployment tworzy pody i zastępuje te, które zniknęły. Pody są z założenia nietrwałe (ephemeral), więc nie zakładaj, że konkretny pod będzie istniał jutro ani że zachowa swój adres IP.
Jak uruchomić Kubernetes na własnym komputerze?
Do nauki nie potrzebujesz chmury. Dokumentacja Kubernetes poleca dwa narzędzia do lokalnych klastrów: kind (uruchamia klaster w kontenerach Dockera, wymaga Dockera lub Podmana) i minikube (osobny klaster na Twoim komputerze). My użyliśmy kind i kubectl, czyli oficjalnego klienta wiersza poleceń:
kind create cluster --name demo
kubectl get nodes
Wynik na macOS 26 (Apple M2 Pro, kind 0.33.0, Docker w maszynie Colima): klaster był gotowy po około 18 sekundach, a węzeł miał status Ready i wersję v1.37.0.
Jak wygląda pierwsza aplikacja w Kubernetes?
Zbudowaliśmy obraz małego serwera w Node.js, który odpowiada nazwą poda i numerem wersji (budowanie obrazu opisaliśmy w artykule o Dockerze). Obraz załadowaliśmy do klastra poleceniem kind load docker-image demo:1 --name demo, a aplikację opisaliśmy w pliku deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
spec:
replicas: 3
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: demo:1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: demo
spec:
selector:
app: demo
ports:
- port: 80
targetPort: 3000
Plik opisuje stan, którego chcesz: trzy kopie aplikacji i jeden Service, który kieruje ruch do podów z etykietą app: demo. Wysyłasz go do klastra i sprawdzasz efekt:
kubectl apply -f deployment.yaml
kubectl rollout status deployment/demo
kubectl get pods
U nas po niecałej sekundzie działały trzy pody w stanie Running, każdy z własnym adresem IP z puli klastra.
Co robi Kubernetes, gdy pod przestaje działać?
Sprawdziliśmy to, usuwając jednego poda ręcznie:
kubectl delete pod demo-5449cfbbd-842s9
kubectl get pods
Po 3 sekundach lista pokazywała nowego poda w stanie Running, a stary był jeszcze w stanie Terminating. Deployment wykrył, że działają 2 kopie zamiast 3, i dołożył brakującą. To właśnie samonaprawa: nie napisałeś żadnego skryptu, tylko opisałeś stan docelowy.
Liczbę kopii zmienisz jednym poleceniem; u nas kubectl scale deployment/demo --replicas=5 doprowadziło do 5 działających podów.
Jak działa Service i czym różnią się jego typy?
Pody pojawiają się i znikają, więc ich adresów IP nie da się używać na stałe. Service daje grupie podów jedną, stałą nazwę. Z innego poda w klastrze wystarczyło wywołać http://demo, żeby trafić do aplikacji; dziesięć kolejnych zapytań obsłużyło pięć różnych podów, więc ruch był rozkładany między kopie.
Dokumentacja wyróżnia kilka typów Service. Domyślny to ClusterIP, czyli adres widoczny tylko wewnątrz klastra (tak jest w naszym pliku). Do wystawienia aplikacji na zewnątrz służą m.in. NodePort (port otwarty na każdym węźle) i LoadBalancer (zewnętrzny load balancer, o który prosi się u dostawcy chmury). Za wystawianie wielu aplikacji pod jednym adresem odpowiada osobny obiekt, Ingress. W naszych testach uruchomiliśmy tylko ClusterIP; pozostałe typy opisujemy na podstawie dokumentacji.
Uwaga dla początkujących: kubectl port-forward svc/demo 8081:80, czyli tunel z Twojego komputera do usługi, wybiera jednego poda. Sześć kolejnych zapytań przez port-forward trafiło u nas do tego samego poda, więc nie testuj w ten sposób rozkładania ruchu.
Jak zaktualizować aplikację bez przestoju?
Zbudowaliśmy obraz demo:2 (zmienna WERSJA=2), załadowaliśmy go do klastra i podmieniliśmy obraz w Deploymencie:
kubectl set image deployment/demo demo=demo:2
kubectl rollout status deployment/demo
kubectl rollout history deployment/demo
Kubernetes zastępował pody stopniowo (rolling update): nowe startowały, zanim stare zostały wyłączone, a historia pokazała rewizje 1 i 2. Po aktualizacji wszystkie odpowiedzi miały „wersja 2”.
Co się dzieje, gdy aktualizacja się nie uda?
Podmieniliśmy obraz na nieistniejący tag demo:nie-ma. Nowe pody utknęły w stanie ImagePullBackOff, ale pody z poprzednią wersją nadal działały i obsługiwały ruch, więc aplikacja pozostała dostępna. kubectl rollout status zakończył się komunikatem timed out waiting for the condition, a kubectl describe pod pokazał przyczynę. Wycofanie zmiany to jedno polecenie:
kubectl rollout undo deployment/demo
Po nim wróciło 5 podów w stanie Running. To najbezpieczniejszy moment, żeby poznać rollout undo, bo na produkcji przyda się szybciej, niż myślisz.
Jakie błędy w Kubernetes zdarzają się najczęściej?
Status w kubectl get pods | Co zwykle znaczy | Co sprawdzić |
|---|---|---|
ErrImagePull, ImagePullBackOff | klaster nie może pobrać obrazu | nazwa i tag obrazu, dostęp do rejestru, kubectl describe pod |
CrashLoopBackOff | kontener startuje i od razu się kończy, a Kubernetes próbuje ponownie | kubectl logs <pod>, kubectl describe pod (pole Exit Code) |
Terminating | pod jest usuwany | to zwykle stan przejściowy; dokumentacja zaznacza, że to napis w kolumnie Status, a nie osobna faza poda |
Dwa przypadki odtworzyliśmy sami:
- Lokalny obraz, którego klaster nie widzi. Pod z obrazem
demo:latest(którego nigdy nie zbudowaliśmy) dostałErrImagePullz komunikatempull access denied, repository does not exist: klaster szukał go wdocker.io. Obraz zbudowany lokalnie trzeba wgrać do klastra (kind load docker-image) i ustawićimagePullPolicy: IfNotPresent. Gdy ustawiliśmyAlwaysdla obrazu istniejącego tylko lokalnie, pod też dostałErrImagePull. Dokumentacja odradza zresztą używania tagu:latestw produkcji, bo trudno ustalić, która wersja faktycznie działa. - Kontener, który kończy się z błędem. Pod uruchamiający polecenie z kodem wyjścia 1 był restartowany (po około minucie licznik pokazywał 3 restarty), a przyczynę widać w
kubectl describe pod(Exit Code: 1) i wkubectl logs. Gdy pod restartuje się w kółko, dokumentacja przewiduje, że w kolumnie Status może pojawić sięCrashLoopBackOff.
Czy Kubernetes to to samo co Docker Compose?
Nie. Docker Compose opisuje kilka kontenerów uruchamianych razem na jednej maszynie i świetnie nadaje się do pracy lokalnej i małych wdrożeń. Kubernetes zarządza kontenerami na wielu maszynach, sam je zastępuje, skaluje i aktualizuje. Płacisz za to złożonością: więcej pojęć, więcej plików konfiguracyjnych i więcej rzeczy, które mogą pójść nie tak.
Kiedy potrzebujesz Kubernetes, a kiedy wystarczy prostsze rozwiązanie?
To ocena praktyczna, a nie twarda reguła z jednego źródła:
| Sytuacja | Rozsądny wybór |
|---|---|
| Jedna aplikacja i baza na jednym serwerze VPS | Docker Compose |
| Kilka usług, które muszą się skalować i przetrwać awarię węzła | Kubernetes |
| Zespół, który ma już wdrażanie przez CI/CD i potrzebuje aktualizacji bez przestoju | Kubernetes |
| Nie chcesz administrować klastrem | zarządzany Kubernetes u dostawcy chmury |
Jeśli aktualizacja aplikacji wymaga okna serwisowego, a awaria jednego serwera wyłącza całą usługę, to pierwszy moment, w którym Kubernetes zaczyna się opłacać. Wcześniej koszt nauki i utrzymania zwykle przewyższa zysk.
Wielcy dostawcy chmury oferują zarządzane klastry: EKS (AWS), AKS (Azure) i GKE (Google Cloud). Dostawca utrzymuje wtedy control plane, a Ty zajmujesz się aplikacjami; ich zestawienie znajdziesz w porównaniu AWS, Azure i Google Cloud.
Czy junior musi znać Kubernetes?
Na początku nie. W ścieżce DevOps Kubernetes jest jedną z późniejszych umiejętności: najpierw Linux, Git, sieci i Docker. Kiedy poczujesz, że rozumiesz kontenery, Kubernetes zaczyna mieć sens, bo zobaczysz problem, który rozwiązuje. Najpierw zbuduj i zdebuguj jeden kontener, potem jeden Deployment z trzema kopiami, a dopiero potem dokładaj Ingress i Helm. Kto zaczyna od Helm, zwykle nie wie, co dzieje się pod spodem.
Od czego zacząć naukę Kubernetes?
- Zbuduj własny obraz w Dockerze i uruchom go lokalnie.
- Postaw lokalny klaster (kind lub minikube) i uruchom Deployment z trzema kopiami.
- Usuń poda, skaluj Deployment i podmień wersję obrazu, tak jak powyżej.
- Zepsuj coś celowo (zły tag obrazu) i naucz się czytać
kubectl describeorazkubectl logs. - Dopiero potem sięgnij po Ingress, ConfigMap, Secret i Helm.


