Introduktion till Kubernetes
Hoppa till
Var vi är
I Docker-serien lämnade vi Lisa och teamet med ett e-handelssystem som startar med ett kommando:
docker compose up. Frontend, API och databas ligger i varsin container, och alla i teamet får
samma miljö.
Det fungerar på en dator. Sedan går applikationen live, kunderna blir fler, och systemet måste spridas över flera servrar. Då dyker en ny sorts frågor upp, och ingen av dem handlar om hur en container byggs.
Den här delen ger överblicken över vad Kubernetes är och vilka fyra begrepp du behöver för att läsa vilken introduktion som helst. Detaljerna kommer i senare delar.
Vad Kubernetes är
Kubernetes är ett system som kör containrar över flera servrar åt dig. Det förkortas ofta K8s — åtta bokstäver mellan K och s.
Du ger Kubernetes en beskrivning av vad som ska köras och i hur många kopior. Kubernetes väljer vilka servrar det ska köras på, startar om det som kraschar, och håller antalet rätt över tid.
Kubernetes bygger inte images. Det kör dem genom en container runtime, ofta containerd. Du kan bygga imagen med Docker eller ett kompatibelt verktyg; här använder vi Docker som den bekanta vägen från föregående serie.
Kubernetes vs Docker
De två ställs ofta mot varandra som alternativ. De är olika lager.
Docker paketerar en applikation till en image och kör den som en container — på en maskin.
Kubernetes tar färdiga images och kör dem som containrar över många maskiner, och håller reda på att rätt antal är igång.
Kubernetes ersätter alltså inte Docker. Docker Compose är fortfarande ett bra verktyg för lokal utveckling på en dator. Kubernetes kan ta över när samma system ska köras över flera maskiner i drift.
Deklarativt vs imperativt
Skillnaden är hela idén bakom Kubernetes, och den är värd att fästa direkt.
Imperativt betyder att du ber Kubernetes göra en konkret ändring: “sätt Deploymenten till tre kopior.” Kubernetes uppdaterar sedan sitt önskade läge och fortsätter hålla det.
Deklarativt betyder att YAML-filen säger hur det ska se ut: “det ska alltid finnas tre kopior av API:et.” Filen blir då den granskbara källan för önskat läge.
I båda fallen arbetar Kubernetes controllers mot det önskade läget. Skillnaden är var teamet beskriver och granskar förändringen.
Det är samma deklarativa idé som i Terraform-serien, med en skillnad: Terraform jämför när du kör
apply, Kubernetes jämför oavbrutet.
Klustret
Ett kluster är de servrar Kubernetes har till sitt förfogande, hanterade som en enhet.
Varje server i klustret kallas en nod. En nod kan vara en fysisk maskin eller en virtuell — Kubernetes bryr sig inte om vilket.
Du pratar aldrig med en enskild nod. Du pratar med klustret, och klustret bestämmer var saker hamnar. Det är därför “vilken server körs den här på” är en fråga du sällan ställer.
Control plane och noder
Klustret har två sorters delar.
Control plane är hjärnan. Den tar emot dina beskrivningar, bestämmer vilken nod som ska köra vad, och bevakar att verkligheten stämmer. Det är hit ditt kommando går.
Noderna är musklerna. De kör de containrar de blir tilldelade och rapporterar tillbaka hur det går.
I ett hanterat kluster hos en molnleverantör sköts control plane åt dig, och du ser bara noderna. Vad control plane består av internt — API-server, schemaläggare, en databas som heter etcd — behöver du inte kunna nu. Det räcker att veta att den finns och att det är den du talar med.
Pod
Den minsta enheten i Kubernetes är inte en container, utan en pod.
En pod är ett skal runt en eller några containrar som alltid ska köras på samma nod. Containrarna
i en pod delar nätverk och lagring, och kan nå varandra på localhost.
I praktiken innehåller de flesta poddar exakt en container. Flera förekommer när en hjälpcontainer hör så tätt ihop med huvudcontainern att de aldrig får hamna isär — en som samlar in loggar, till exempel.
Pod vs container
En container är den körande instansen av en image. Det är samma sak som i Docker.
En pod är Kubernetes omslag runt en eller flera sådana containrar. Controllers schemalägger, ersätter och räknar poddar. Kubelet kan samtidigt starta om en container i samma pod när containerns process kraschar.
Därför heter kommandot kubectl get pods och inte kubectl get containers.
Poddar är tillfälliga
Det viktigaste att förstå med poddar är att de är utbytbara.
En pod startas, kör en stund och försvinner. När processen i en container kraschar kan kubelet starta om containern i samma pod.
När en pod som ägs av en Deployment tas bort eller avslutas skapar Deploymenten en ny pod i dess ställe, med nytt namn och ny IP-adress.
Det låter opraktiskt, men är själva poängen. När ingen enskild pod är viktig kan systemet flytta runt, byta ut och skapa fler av dem fritt. Att poddar är utbytbara är det som gör självläkning, skalning och utrullning utan driftstopp möjliga.
En pod är inte en server. Behandla den aldrig som en plats där något ska sparas.
Deployment
Om poddar är tillfälliga behöver något beskriva vad som alltid ska finnas. Det är en Deployment.
En Deployment säger vilken image som ska köras och i hur många kopior. Kubernetes jämför den beskrivningen med verkligheten, oavbrutet, och rättar skillnaden.
kubectl get pods visar dig ett utsnitt av.Mellan Deployment och pod ligger egentligen ett lager till som heter ReplicaSet. Det är den som räknar kopiorna. Du skapar den aldrig själv och rör den sällan — men namnet dyker upp i utskrifter, så det är värt att känna igen.
Manifestet
En Deployment beskrivs i en YAML-fil, ett manifest.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: registry.example.com/searchapi:v2
ports:
- containerPort: 5000
Lisa känner igen sig: samma image från teamets registry som i Docker-serien, men med ett tillägg
Docker Compose aldrig hade — replicas: 3.
Manifestet är en textfil. Den hör hemma i Git, granskas i en merge request och körs av en pipeline, precis som Terraform-filerna.
Fältet selector matchar etiketten app: api och är det som binder ihop Deployment med rätt
poddar. Etiketter är genomgående hur Kubernetes hittar saker, och de återkommer i nästa begrepp.
Service
Om poddar hela tiden byter IP-adress — hur hittar frontend fram till API:et?
En Service ger en stabil adress framför en grupp poddar så länge Service-objektet finns kvar.
Namnet api används för att nå den, och Servicen fördelar anropen mellan endpoints som Kubernetes
markerat som redo.
Readiness-proben avgör när en pod ska räknas som redo. Servicen gör ingen egen hälsokontroll.
Frontend anropar http://api:5000 och behöver aldrig veta hur många poddar som finns bakom eller
var de kör. En pod som startas läggs till i växeln på egen hand; en som försvinner plockas bort.
Deployment vs Service
Två beskrivningar som ofta blandas ihop, eftersom de nästan alltid skrivs i par.
Deployment svarar på vad som ska köras och i hur många kopior.
Service svarar på hur något annat ska nå det.
Du behöver båda. En Deployment utan Service kör poddar som ingen kan nå på en stabil adress. En Service utan Deployment är en adress som pekar på ingenting.
kubectl
kubectl är kommandoradsverktyget du använder för att prata med klustret. Det uttalas oftast
“kube-control”.
Kommandot skickar din begäran till control plane. Det gör alltså ingenting självt — utan ett kluster att tala med kan det bara läsa sin egen version.
kubectl apply -f api.yaml # skicka in beskrivningen
kubectl get pods # vad kör just nu?
kubectl describe pod api-7f9c # varför startar den?
kubectl logs api-7f9c # vad skriver appen?
apply är deklarativ: du skickar in hur det ska se ut, inte vad som ska göras. Kör du samma fil
igen utan ändringar händer ingenting, eftersom verkligheten redan stämmer.
Självläkning
Kubernetes har ingen förvald HTTP-fråga om din applikations hälsa. Definierar du en probe i manifestet kör kubelet den kontrollen.
Utan probe kan Kubernetes se containerstatus, men inte om just din applikation svarar som du tänkt.
Går en hel nod sönder flyttas dess poddar över till de noder som är kvar. Ingen behöver bli väckt, och ingen behöver skriva skriptet som gör det.
Hur frågan ställs — vilken adress som pingas och hur ofta — konfigureras med probes. Det tar vi i del 1.2. Här räcker det att veta att självläkningen bygger på att någon frågar.
Skalning
Inför rean höjer Lisa replicas från 3 till 10 och kör kubectl apply igen. Kubernetes startar sju
poddar till, fördelade över noderna.
Det går också automatiskt: en regel som säger “kör fler poddar när processorlasten går över 70 procent” skalar upp under toppen och ner igen efteråt.
Samma mekanism kan ge utrullning utan driftstopp. Byter Lisa searchapi:v2 mot v3 rullar
Deploymenten ut nya poddar enligt sin strategi.
Antalet som får saknas eller skapas extra styrs av exempelvis maxUnavailable och maxSurge. Med
en readiness-probe får en ny podd trafik först när den är redo.
När du inte behöver Kubernetes
Den här delen hoppas ofta över, och den är den viktigaste. Kubernetes är inte gratis.
En applikation på en server med jämn trafik — Docker Compose räcker, och du slipper ett helt lager att lära dig.
Ett hobbyprojekt eller en tidig produkt — en hanterad tjänst som Azure Container Apps ger dig utrullning och skalning utan att du driftar ett kluster.
Ett litet team utan driftserfarenhet — ett kluster ingen förstår är en risk, inte en trygghet.
Många tjänster, flera servrar, krav på tillgänglighet — då är Kubernetes rätt verktyg, och svårt att bygga bättre själv.
Signalen att titta efter: du har börjat bygga det själv. Skript som startar om kraschade containrar, fördelar trafik och håller reda på vilken server som har plats.
Då finns problemet på riktigt, och då är komplexiteten värd sitt pris.
Ett kluster innebär nätverk, behörigheter, certifikat, övervakning och uppgraderingar som någon måste förstå och underhålla. Tumregeln: börja med Docker och Compose, gå vidare den dag du märker att du håller på att bygga en sämre version av Kubernetes.
Vad det här betyder i ditt arbete
Som utvecklare kommer du sällan att sätta upp ett kluster. Du kommer att skriva manifest, läsa
kubectl get pods, och felsöka med kubectl logs och kubectl describe.
Det som är värt din tid nu är alltså inte hur control plane fungerar internt. Det är att kunna läsa ett manifest och veta vilket av de fyra begreppen ett felmeddelande handlar om.
Är du på väg mot en driftsroll byter det skepnad. Då blir noder, nätverk, behörigheter och uppgraderingar ditt jobb — men ingen av de sakerna går att förstå innan pod, Deployment och Service sitter.
Vanliga nybörjarförväxlingar
Kubernetes ersätter inte Docker eller Docker Compose. Compose passar fortfarande lokal utveckling; Kubernetes passar när systemet ska köras över flera maskiner. Images kan byggas med Docker eller ett kompatibelt verktyg.
En pod är inte en container. Den är ett skal runt en eller flera, och det är poddar Kubernetes räknar och flyttar.
En pod är inte en server. När en Deployment ersätter podden får ersättaren nytt namn och ny IP.
kubectl är inte Kubernetes. Det är en klient som skickar begäran till ett kluster, och utan
kluster kan den nästan ingenting.
Att köra kubectl apply två gånger gör inte saken två gånger. Beskrivningen jämförs med
verkligheten, och stämmer den redan händer ingenting.
Prova själv
Första steget kräver inget kluster. Kontrollera att klienten finns:
kubectl version --client
Fråga sedan efter poddar:
kubectl get pods
Har du inget kluster får du ett fel om att anslutningen till servern nekades. Det är inte ett fel i installationen — det är hela poängen med avsnittet om kubectl. Det är en klient, och den har ingen control plane att fråga.
Vill du gå vidare: slå på Kubernetes i Docker Desktop under Settings → Kubernetes. Då får du ett kluster med en nod på din egen maskin.
kubectl get nodes
Nu svarar klustret med en nod, ofta med namnet docker-desktop. Spara manifestet ovan som
api.yaml, byt ut image: mot något som faktiskt går att hämta — nginx duger — och kör:
kubectl apply -f api.yaml
kubectl get pods
Tre poddar, med namn som api-6d4cf56db-xk29p. Radera en av dem och fråga igen direkt:
kubectl delete pod api-6d4cf56db-xk29p
kubectl get pods
Det finns fortfarande tre. En av dem har ett nytt namn. Det är självläkningen, och det är det enskilt tydligaste beviset för att beskrivningen — inte kommandot — är det som styr.
Två saker som förvirrar: poddarna står först som ContainerCreating medan imagen hämtas, och
kubectl get pods visar bara det aktuella namnrummet. Vad ett namnrum är tar vi i del 1.3, där det
behövs för att sätta ett tak per team.
- Kubernetes är deklarativt: du beskriver önskat läge, systemet håller det sant — oavbrutet.
- Kubernetes ersätter inte Docker eller Docker Compose. Compose passar lokal utveckling.
- En pod är minsta enheten och är tillfällig. En ersättningspodd får ett nytt namn och kan få en annan IP-adress.
- En Deployment beskriver vad som alltid ska finnas. En Service ger det en fast adress.
- Har du inte problemet många containrar på många servrar är Docker Compose fortfarande rätt svar.
Ersätter Kubernetes Docker?
Du raderar en pod med kubectl delete pod api-7f9c. Vad händer?
Om poddarna hela tiden byter IP-adress — hur hittar frontend till API:et?
http://api:5000 och behöver inte veta hur många poddar som finns bakom.Vad är skillnaden mellan en Deployment och en Service?
Du kör kubectl apply -f api.yaml två gånger utan att ändra filen. Vad händer andra gången?
apply skickar beskrivningen igen. Om det önskade läget redan stämmer behöver Kubernetes normalt inte ändra arbetsbelastningen, men kommandot kan fortfarande rapportera att objektet konfigurerats.När är Kubernetes fel verktyg?
Snabb sammanfattning
- Kubernetes kör images över flera servrar. Det bygger dem inte, och ersätter inte Docker Compose.
- Kubernetes är deklarativt: du beskriver önskat läge, systemet håller det sant, oavbrutet.
- Ett kluster är servrarna hanterade som en enhet. Varje server är en nod.
- Control plane tar emot beskrivningar och bestämmer var saker körs. Noderna kör dem.
- En pod är minsta enheten — ett skal runt en eller några containrar på samma nod.
- Poddar är tillfälliga och utbytbara. En Deployment-ersättare får nytt namn och kan få en annan IP.
- En Deployment beskriver vad som alltid ska finnas och i hur många kopior.
- En Service ger poddarna en stabil adress medan Service-objektet finns och fördelar trafiken mellan redo endpoints.
kubectlär klienten. Utan kluster att fråga kan den nästan ingenting.- Har du inte problemet många containrar på många servrar är Docker Compose fortfarande rätt svar.
Nästa del
En mening lämnades hängande här: att frontend ska nås utifrån. En Service ger en adress inuti klustret — men hur når en besökare på internet ända fram till en pod?