Kubernetes Cheatsheet

Verktøy og ressurser

Lens - Kubernetes IDE
Katacoda - Interaktive k8s kurs

Kubernetes Cluster

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:

Control plane oppgaver

Node

Kubrenetes Deployments

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.

Pod

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.

Nettverk

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.

Service

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.

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

Labels og selector

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

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.

Deployment og Scaling

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.

Replica sets

En deployment vil lage et ReplicaSet. Dette sier noe om hvor mange instanser vi ønsker av deploymenten vår.

Rolling updates

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.

Verktøy

Minikube

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.

Cheatsheet

Start cluster

minikube start

Kubectl

Cli for å snakke med Kubernetes. Bruker Kubernetes API for å interagere med klusteret.
Formatet er vanligvis: kubectl action resource. Man kan bruke --help bak kommandoer.

Cheatsheet

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.

Kubernetes API

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/