Dlaczego Kubernetes rewolucjonizuje deployment aplikacji?
Zarządzanie kontenerami Docker ręcznie to jak dyrygowanie orkiestrą bez nutów – chaos gwarantowany. Kubernetes wprowadza porządek: automatyczne skalowanie, self-healing, rolling updates i service discovery. To różnica między zarządzaniem jednym serwerem a zarządzaniem całym data center jako jednym zasobem.
Co się nauczysz:
- Podstawowe komponenty Kubernetes: pods, nodes, services
- Różnica między Deployment, ReplicaSet i Pod
- Jak działa networking i service discovery w K8s
- Podstawy kubectl – command line tool dla Kubernetes
- Deployment pierwszej aplikacji na Kubernetes cluster
Czym jest Kubernetes?
Kubernetes (często skracane do K8s) to open-source platforma orkiestracji kontenerów. „Orkiestracja” oznacza automatyczne zarządzanie całym lifecycle aplikacji: od deployment przez skalowanie po monitoring i self-healing.
Kubernetes vs Docker – różnica
Aspekt | Docker | Kubernetes |
---|---|---|
Cel | Konteneryzacja aplikacji | Orkiestracja kontenerów |
Scope | Pojedynczy host | Cluster wielu maszyn |
Networking | Bridge/host networking | Service mesh, ingress |
Scaling | Ręczne | Automatyczne |
Self-healing | Restart policy | Automatic pod replacement |
Architektura Kubernetes – główne komponenty
Master Node (Control Plane)
„Mózg” klastra, który podejmuje decyzje o zarządzaniu:
- API Server: Punkt wejścia dla wszystkich operacji (kubectl komunikuje się z nim)
- etcd: Rozproszona baza danych stanu klastra
- Controller Manager: Monitoruje stan i wprowadza zmiany
- Scheduler: Decyduje na którym node uruchomić pod
Worker Nodes
Maszyny które faktycznie uruchamiają aplikacje:
- kubelet: Agent komunikujący się z master node
- kube-proxy: Zarządza networking i load balancing
- Container Runtime: Docker lub inne środowisko kontenerów
Podstawowe obiekty Kubernetes
Pod – najmniejsza jednostka deployment
Pod to grupa jednego lub więcej kontenerów które:
- Dzielą ten sam network namespace (IP address)
- Dzielą storage volumes
- Są zawsze deployowane razem na tym samym node
# pod.yaml - Definicja pojedynczego pod apiVersion: v1 kind: Pod metadata: name: my-app-pod labels: app: my-app spec: containers: - name: web-server image: nginx:1.12 ports: - containerPort: 80 - name: log-collector image: fluentd:latest # Sidecar container dla logów
Service – networking i service discovery
Service zapewnia stały endpoint dla grup podów:
# service.yaml - Load balancer dla podów apiVersion: v1 kind: Service metadata: name: my-app-service spec: selector: app: my-app # Łączy się z podami mającymi ten label ports: - protocol: TCP port: 80 # Port service targetPort: 8080 # Port w kontenerze type: ClusterIP # Dostępny tylko wewnątrz klastra
Deployment – zarządzanie lifecycle aplikacji
Deployment to high-level obiekt zarządzający ReplicaSet i podami:
# deployment.yaml - Deployment aplikacji apiVersion: apps/v1 kind: Deployment metadata: name: my-app-deployment spec: replicas: 3 # Chcemy 3 instancje selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app image: my-app:v1.0 ports: - containerPort: 8080 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
Deployment zarządza ReplicaSet, które zarządza podami, które zawierają kontenery.
Kubectl – command line interface
Podstawowe komendy kubectl
# Sprawdzanie stanu klastra kubectl cluster-info kubectl get nodes # Zarządzanie podami kubectl get pods # Lista wszystkich podów kubectl get pods -o wide # Szczegółowe informacje kubectl describe pod my-app-pod # Szczegóły konkretnego pod # Deployment operacje kubectl apply -f deployment.yaml # Zastosuj konfigurację kubectl get deployments kubectl scale deployment my-app-deployment --replicas=5 # Debugging i logi kubectl logs my-app-pod # Logi z pod kubectl exec -it my-app-pod -- /bin/bash # Shell do pod kubectl port-forward pod/my-app-pod 8080:80 # Port forwarding
Imperatywne vs Deklaratywne zarządzanie
Podejście | Przykład | Użycie |
---|---|---|
Imperatywne | kubectl run nginx –image=nginx | Szybkie testy, debugging |
Deklaratywne | kubectl apply -f deployment.yaml | Produkcja, GitOps |
Pierwszy deployment – praktyczny przykład
Krok 1: Przygotowanie aplikacji
Załóżmy prostą aplikację Java w Docker:
# Dockerfile FROM openjdk:8-jre-alpine COPY app.jar /app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app.jar"]
Krok 2: Deployment manifest
# java-app.yaml - Kompletny deployment z service apiVersion: apps/v1 kind: Deployment metadata: name: java-app spec: replicas: 2 selector: matchLabels: app: java-app template: metadata: labels: app: java-app spec: containers: - name: java-app image: myregistry/java-app:1.0 ports: - containerPort: 8080 env: - name: DATABASE_URL value: "jdbc:postgresql://db:5432/mydb" livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 --- apiVersion: v1 kind: Service metadata: name: java-app-service spec: selector: app: java-app ports: - port: 80 targetPort: 8080 type: LoadBalancer # Dostępny z zewnątrz
Krok 3: Deployment i weryfikacja
# Deploy aplikacji kubectl apply -f java-app.yaml # Sprawdź status kubectl get deployments kubectl get pods kubectl get services # Sprawdź logi kubectl logs -l app=java-app # Test aplikacji (po otrzymaniu external IP) kubectl get service java-app-service curl http://EXTERNAL-IP/api/health
Skalowanie i aktualizacje
Horizontal scaling
# Ręczne skalowanie kubectl scale deployment java-app --replicas=5 # Automatyczne skalowanie (HPA) kubectl autoscale deployment java-app --cpu-percent=50 --min=1 --max=10
Rolling updates
# Update image version kubectl set image deployment/java-app java-app=myregistry/java-app:1.1 # Monitoruj rollout kubectl rollout status deployment/java-app # Rollback jeśli coś poszło nie tak kubectl rollout undo deployment/java-app
Podstawy networking w Kubernetes
Typy Services
Typ | Dostęp | Use Case |
---|---|---|
ClusterIP | Tylko wewnątrz klastra | Internal microservices |
NodePort | Port na każdym node | Development, debugging |
LoadBalancer | External load balancer | Public-facing applications |
ExternalName | DNS alias | External services integration |
Ingress – advanced routing
Ingress zapewnia HTTP/HTTPS routing z features jak SSL termination:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: java-app-ingress spec: rules: - host: myapp.example.com http: paths: - path: / backend: serviceName: java-app-service servicePort: 80 - host: api.example.com http: paths: - path: /api backend: serviceName: java-app-service servicePort: 80
Dla single-server aplikacji Kubernetes to overkill. K8s ma sens przy multiple services, potrzebie high availability, automatic scaling lub complex deployment requirements. Zacznij od Docker Compose.
Użyj minikube dla local development – daje ci single-node cluster na laptopie. Alternatywnie Docker Desktop ma wbudowany Kubernetes support (beta w 2017).
Kubernetes automatycznie uruchomi nowy pod w jego miejsce (self-healing). ReplicaSet zapewnia że zawsze masz określoną liczbę healthy pods. Service automatycznie przekieruje traffic.
Używaj Kubernetes Secrets objects zamiast hardcodowania w Docker images. Secrets są base64-encoded i mogą być mount jako files lub environment variables.
Nie, to complementary technologies. Docker tworzy kontenery, Kubernetes nimi zarządza. K8s może używać innych container runtime (rkt, containerd), ale Docker jest najpopularniejszy.
Używaj health checks (liveness/readiness probes), centralized logging (fluentd + elasticsearch), metrics (Prometheus), i distributed tracing. Kubernetes Dashboard daje basic monitoring UI.
🚀 Zadanie dla Ciebie
Deploy prostą aplikację Java na Kubernetes:
- Zainstaluj minikube i uruchom local cluster
- Stwórz Deployment z nginx image (replicas: 2)
- Dodaj Service typu NodePort
- Test skalowania: zwiększ replicas do 4
- Rolling update: zmień image tag i obserwuj proces
- Cleanup: usuń wszystkie created resources
Użyj kubectl do wszystkich operacji i monitoruj co się dzieje z podami podczas każdego kroku.
Przydatne zasoby:
Używasz już Kubernetes w projekcie? Jakie największe korzyści i wyzwania napotkałeś podczas wdrażania orkiestracji kontenerów?