Lens - Kubernetes IDE
Katacoda - Interaktive k8s kurs
Kubernetes koordinerer et cluster av datamaskiner som er koplet sammen til å jobbe som en enkel enhet. Det er altså et abstraheringslag over VMer. Et kubernetes-kluster er det man kaller en instanse av Kubernetes. Klusteret sin oppgave er å automatisere applikasjons (docker) containere effektivt.
Et kluster består av:
For å deploye en (dockerized) applikasjon i et kluster så må man lage en "Deployment configuration". Denne forteller Kubernetes hvordan man lager og oppdaterer instanser av appen. Når det er laget vil en Kubernetes Deployment Controller kontinuerlig overvåke instansene til denne appen. Dersom en Node går ned vil denne kontrolleren erstatte instansen med en instanse på en annen node i klusteret. Controlleren lever i Control Plane.
Forskjellen fra vanlige startup script er altså at i tillegg til å starte apper så holder Kubernetes Deployments dem oppe på tvers av noder.
Dokumentasjon
Pods er minste mulige computing enhet man kan deploye i Kubernetes. (Kan kalles Kubernetes' atomiske enhet)
Det er en grupper med 1 eller flere containere, og disse deler lagringsplass og nettverksressurser. Tanken er at den skal modellere en applikasjons-spesifikk "logisk host". Applikasjons containerene som befinner seg i en pod skal være tightly coupled (Se Coupling). De deler IP-adresse og port-space og kjører alltid i en delt kontekst på samme node.
Slik ser en konfigurasjonsfil for å kjøre en pod med 1 docker container ut:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Eksempel på en Pod med flere instanser er en Pod som inneholder en Node.js app såvel som en annen container som feeder dataene som Node.js webserveren skal publisere.
Ofte vil man bare kjøre en instanse per pod. De skal bare kjøre i samme dersom de er nødt til å dele ressurser slik som samme diskplass.
Pods som kjører inne i Kubernetes kjører på et privat isolert nettverk. Default-oppførselen er at de kan sees fra ande pods og tjenester i samme kluster, men ikke fra utsiden av dette nettverket. For å kommunisere med applikasjonen vår må vi altså ta i bruk kubectl som igjen bruker et eksponert API endepunkt.
Vha. kubectl kan man lage en proxy som forwarder kommunikasjon inn til det private nettverket for å kunne snakke med APIet direkte.
Servicer er en abstrahering som definerer et logisk sett med Pods og en policy for å kunne nå dem. Man trenger altså en Service (som altså bare er et sett med nettverksregler) for å la pods motta trafikk fra utsiden av kubernetes klusteret. Man definerer en tjeneste med en YAML (eller JSON) fil.
Det finnes ulike måter å eksponere en Servie på. Disse velger man ved å spesifisere "type" i ServiceSpec.
<NodeIP>:<NodePort>
. Man når altså Servicen ved å gå via en Node og en spesiell port, som da proxyer videre inn til servicen. Supersett av ClusterIP, så den har fortsatt egen intern IP, men kan altså også nås via Nodes om man har satt opp disse til å ha ekstern IP adresse f.eks. Da kan man sette opp sin egen loadbalancer konfigurasjon ved å proxye gjennom en node.apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
Servier er som sagt en abstrahering over et sett med Pods. Måten man matcher et POds sett på er ved å bruke labels og selectors. Det er en primitiv som lar deg gjøre logiske operasjoner på Kubernetes objekter. Labels er key-value pairs (app=myappname) som er knyttet til objekter.
Man kan bruke det til å lage egne objekter for dev, test og prod. Man kan lage versjonerings tags, eller man kan klassifisere objekter med tag. Selector er "operasjonen" av å velge objekter basert på labels.
Ingress er ikke det samme som en service, men en måte å eksponere en Service på. Den fungerer som et entry point for clusteret ditt. Den kan eksponere flere Serivcer under samme IP-adresse. F.eks. kan man lage en NGINX ingress som igjen kan mappe forskjellige hostnames til forskjellige Servicer.
En deployment lever i control plane delen av kubernetes. Den deployer en logisk applikasjon. F.eks. vil en webserver bare ha en deployment med én pod. Men når trafikken øker må vi skalere appen vår.
Scaling skjer ved å endre antall replicas i en Deployment.
Når det skjer en Scaling av en Deployment så vli nye Pods bli opprettet til Noder som har ledige ressurser. Podsene kan være på forskjellige Noder, eller samme Node, eller begge deler. Man kan scale både manuelt og automatisk.
I tillegg, når man har flere instanser av en application, så kan man rulle ut oppdateringer uten downtime. Servicer vil automatisk distribuere trafikken mellom alle Pods av en eksponert Deployment.
En deployment vil lage et ReplicaSet. Dette sier noe om hvor mange instanser vi ønsker av deploymenten vår.
Man kan oppdatere Deployments fortløpende med zero downtime ved å inkrementerende erstatte pod instanser med nye. Man lager altså nye pods med oppdatert kode, før man litt etter litt endrer servicen til å peke på de nye Podsene (som nå har nye IP-adresser siden de er nye Pods), før de gamle podsene termineres. Hver update får en versjon og etter man har deployet kan man reversere tilbake til en tidligere versjon dersom noe gikk galt.
En lightweight Kubernetest implementasjon. Lager en VM på lokalmaskinen og deployer et cluster som inneholder 1 node. Kommer med et CLI for å jobbe med clusteret.
Start cluster
minikube start
Cli for å snakke med Kubernetes. Bruker Kubernetes API for å interagere med klusteret.
Formatet er vanligvis: kubectl action resource.
Man kan bruke --help
bak kommandoer.
Se detaljer om kluseret
kubectl cluster-info
List ressurser
kubectl get <resource-type>
# ex resource-type => pods, deployments, services
Viser detaljer informasjon om en ressurs
kubectl describe <resource-type>
# ex resource-type => pods, services
Describe kommandoen skal printe i menneske-leselig format, og bør ikke brukes i scripting sammenheng.
Vis detaljer om spesifikk service
kubectl describe services/kubernetes-bootcamp
Printer loggene fra en kontainer i en pod
kubectl logs <resource>
# ex resource => $POD_NAME
Eksekverer en kommando på en container i en pod
kubectl exec $POD_NAME -- <command>
#ex command => env, bash
Om man har flere containere i en pod må man også spesifisere dette
Starte et interaktivt bash shell
kubectl exec -ti $POD_NAME -- bash
Se nodene i kluseteret
kubectl get nodes
List deployments
kubectl get deployments
List pods
kubectl get pods
List replicasts
kubectl get rs
Lag ny deployment
kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
Gir navnet "kubernetes-bootcamp" til deployment og bruker det gitte dockerbildet. Finner en node som passer, starter appen på noden og konfugurerer klusteret til å starte instansen på ny node når det trengs
Eksponer en deployment til VM IPen
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
(Merk at NODE_PORT ikke er 8080. Dette er en randomly assigned port på VMen som proxyer videre til port 8080 hos containeren).
Scale en deployment til 4 instanser/pods
kubectl scale deployments/kubernetes-bootcamp --replicas=4
Rull ut oppdatering på deployment med nytt docker bilde
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
Sjekk status av utrulling til deployment
kubectl rollout status deployments/kubernetes-bootcamp
Rull tilbake
kubectl rollout undo deployments/kubernetes-bootcamp
Select pods based on labels
kubectl get pods -l app=kubernetes-bootcamp
Labelet app=appnavn blir laget automatisk ved deploy av en app. Man kan også gjør samme selector på en Service som er knyttet til deployen
Legg til nytt label på en pod
kubectl label pods $POD_NAME version=v1
Poden vil da få en ny label: version=v1. Kan da hentes ut med
kubectl get pods -l version=v1
Slett tjeneste baser på label
kubectl delete service -l app=kubernetes-bootcamp
Start proxy for Kubernetes APIet inn til kluster-nettverket
kubectl proxy
Stoppes med control-C, og vil ikke vise noe output når den kjører.
Versjonsinfo
curl http://localhost:8001/version
Hent pod metadata og informasjon
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/
Snakke med APIet til applikasjonen
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/