kubectl — rad sa Kubernetes klasterom

Kroz dosadašnje Kubernetes lekcije objašnjeni su Pod, Deployment, Service i ostali objekti. kubectl je alat kojim se sve to zaista radi — jedini kanal između tebe i klastera.

Svaka komanda ide na API server, koji je onda prosleđuje dalje. Nema drugog puta.

Provera veze

$ kubectl version --client
$ kubectl cluster-info
$ kubectl get nodes
NAME       STATUS   ROLES           AGE   VERSION
master01   Ready    control-plane   42d   v1.30.2
worker01   Ready    <none>          42d   v1.30.2
worker02   Ready    <none>          42d   v1.30.2

Ako ovo radi, klaster te prepoznaje. Ako dobiješ connection refused, problem je u konfiguraciji — o tome pri kraju teksta.

Struktura komande

kubectl [radnja] [tip] [ime] [opcije]
kubectl get pods
kubectl describe pod web-abc123
kubectl delete deployment web

Tipovi objekata imaju kratke oblike, što štedi dosta kucanja:

Pun nazivSkraćeno
podspo
deploymentsdeploy
servicessvc
namespacesns
configmapscm
persistentvolumeclaimspvc
statefulsetssts
replicasetsrs
ingressesing

Ceo spisak, sa skraćenicama:

$ kubectl api-resources

get — šta postoji

$ kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-7d4b9c8f5-2xk9p    1/1     Running   0          3h
web-7d4b9c8f5-8mn4q    1/1     Running   0          3h
baza-0                 1/1     Running   0          12d

Kolona READY pokazuje koliko kontejnera u Podu je spremno. Zapis 0/1 uz status Running znači da kontejner radi ali provera zdravlja ne prolazi.

Korisne opcije:

$ kubectl get pods -o wide          # plus IP i na kom je Node-u
$ kubectl get pods -w               # prati promene uživo
$ kubectl get pods -A               # kroz sve imenske prostore
$ kubectl get pods -l app=web       # filtriranje po labeli
$ kubectl get all                   # najčešći objekti odjednom

Opcija -w je nezamenljiva dok posmatraš rollout — vidiš kako Podovi nastaju i nestaju u realnom vremenu.

Puna definicija objekta:

$ kubectl get pod web-7d4b9c8f5-2xk9p -o yaml

Izvlačenje jednog polja:

$ kubectl get pod web-7d4b9c8f5-2xk9p -o jsonpath='{.status.podIP}'
$ kubectl get nodes -o jsonpath='{.items[*].metadata.name}'

describe — zašto nešto ne radi

Ovo je komanda kojom se rešava većina problema:

$ kubectl describe pod web-7d4b9c8f5-2xk9p

Ispisuje sve o objektu, a na dnu — Events. Tamo je odgovor:

Events:
  Type     Reason     Age                From     Message
  ----     ------     ----               ----     -------
  Normal   Scheduled  2m                 default-scheduler  Successfully assigned default/web to worker01
  Normal   Pulling    2m                 kubelet  Pulling image "moja-app:1.0"
  Warning  Failed     1m (x3 over 2m)    kubelet  Failed to pull image "moja-app:1.0": not found
  Warning  BackOff    30s (x5 over 1m)   kubelet  Back-off pulling image

Kad Pod ne startuje, prvo describe, pa odmah na dno.

Događaji celog imenskog prostora, hronološki:

$ kubectl get events --sort-by='.lastTimestamp'

logs — šta aplikacija govori

$ kubectl logs web-7d4b9c8f5-2xk9p
$ kubectl logs -f web-7d4b9c8f5-2xk9p       # prati uživo
$ kubectl logs --tail=50 web-7d4b9c8f5-2xk9p
$ kubectl logs --since=1h web-7d4b9c8f5-2xk9p

Iz svih Podova jednog Deployment-a odjednom:

$ kubectl logs -l app=web --tail=100
$ kubectl logs deploy/web -f

Kad Pod ima više kontejnera, moraš navesti koji:

$ kubectl logs web-7d4b9c8f5-2xk9p -c nginx

A ovo je opcija koju ljudi najkasnije otkriju, a najviše treba — logovi prethodnog, srušenog kontejnera:

$ kubectl logs web-7d4b9c8f5-2xk9p --previous

Kad je Pod u CrashLoopBackOff, trenutni kontejner nema šta da kaže. Greška je u prethodnom.

exec — ulazak u kontejner

$ kubectl exec -it web-7d4b9c8f5-2xk9p -- /bin/bash
$ kubectl exec -it baza-0 -- psql -U app appdb
$ kubectl exec web-7d4b9c8f5-2xk9p -- env

Dve crtice odvajaju kubectl opcije od komande koja se izvršava unutra. Bez njih kubectl pokušava sam da protumači zastavice.

Ako image nema ni shell — što je slučaj kod minimalnih image-a — pokreni privremeni Pod za dijagnostiku:

$ kubectl run alat --rm -it --image=nicolaka/netshoot -- /bin/bash

Odatle možeš da testiraš mrežu prema servisima: curl, dig, ping. Zastavica --rm briše Pod pri izlasku.

apply — deklarativni rad

Postoji imperativni način:

$ kubectl create deployment web --image=nginx:1.25
$ kubectl scale deployment web --replicas=3
$ kubectl expose deployment web --port=80

Brz je za probe, ali stanje klastera nigde nije zapisano. Ozbiljan rad ide kroz YAML fajlove:

$ kubectl apply -f deployment.yaml
$ kubectl apply -f k8s/
$ kubectl delete -f deployment.yaml

apply pravi objekat ako ne postoji, a menja ga ako postoji. Fajlovi idu u Git i tvoj klaster je opisan kodom.

Kako doći do YAML-a bez pisanja od nule

$ kubectl create deployment web --image=nginx:1.25 \
    --dry-run=client -o yaml > deployment.yaml

Ništa se ne pravi u klasteru — dobijaš gotov nacrt koji doteraš. Ovo je najbrži put od ideje do ispravnog manifesta, i vredi ga zapamtiti.

Provera pre primene

$ kubectl apply -f deployment.yaml --dry-run=server
$ kubectl diff -f deployment.yaml

diff pokazuje šta bi se tačno promenilo. Pre svake izmene na produkciji, ovo.

Imenski prostori

Bez navođenja, kubectl radi u prostoru default:

$ kubectl get pods -n kube-system
$ kubectl get ns

Da ne kucaš -n uz svaku komandu:

$ kubectl config set-context --current --namespace=produkcija

Ovo je čest uzrok zabune — komanda „ne radi", a zapravo gledaš pogrešan imenski prostor. Kad nešto ne nalaziš, proveri sa -A.

Kontekst — koji klaster

Konfiguracija stoji u ~/.kube/config:

$ kubectl config get-contexts
$ kubectl config current-context
$ kubectl config use-context produkcija

Ako radiš sa više klastera, uzmi za naviku da pre svake ozbiljne komande proveriš tekući kontekst. Komanda delete puštena na pogrešnom klasteru je skup način da se to nauči.

Rollout — ažuriranje aplikacije

$ kubectl set image deployment/web nginx=nginx:1.26
$ kubectl rollout status deployment/web
$ kubectl rollout history deployment/web
$ kubectl rollout undo deployment/web
$ kubectl rollout undo deployment/web --to-revision=2
$ kubectl rollout restart deployment/web

rollout undo je Kubernetes ekvivalent onoga što je dnf history undo na sistemu — vraća prethodnu verziju za par sekundi.

rollout restart postepeno menja sve Podove, bez prekida rada. Koristi se kad se promeni ConfigMap ili Secret, jer se te promene ne primenjuju same od sebe.

Skaliranje

$ kubectl scale deployment web --replicas=5
$ kubectl scale deployment web --replicas=0    # gašenje bez brisanja

port-forward — pristup bez Ingress-a

$ kubectl port-forward pod/baza-0 5432:5432
$ kubectl port-forward svc/web 8080:80

Otvara tunel sa tvoje mašine u klaster. Neprocenjivo za dijagnostiku — možeš se lokalnim alatom povezati na bazu koja nigde nije javno izložena. Tunel traje dok komanda radi.

Prenos fajlova

$ kubectl cp web-7d4b9c8f5-2xk9p:/var/log/app.log ./app.log
$ kubectl cp ./config.json web-7d4b9c8f5-2xk9p:/app/config.json

Potrošnja resursa

$ kubectl top nodes
$ kubectl top pods
$ kubectl top pods --sort-by=memory

Zahteva da u klasteru radi metrics-server. Ako dobiješ Metrics API not available, nije instaliran.

Kada Pod ne radi

Pending

Pod nije raspoređen ni na jedan Node. Uzrok je u describe, u Events:

Warning  FailedScheduling  0/3 nodes are available: 3 Insufficient memory.

Najčešće nema dovoljno resursa, ili PVC nije vezan.

ImagePullBackOff

Image se ne može preuzeti. Proveri ime i oznaku, i da li registry traži prijavu — u tom slučaju treba Secret tipa docker-registry.

CrashLoopBackOff

Kontejner se pokreće pa odmah izlazi, u krug. Ovde je važno gledati prethodni kontejner:

$ kubectl logs POD --previous

Uzroci su obično isti kao u Dockeru: proces se ne drži u prvom planu, nedostaje promenljiva okruženja, ili baza nije dostupna. Vredi se podsetiti razlike između CMD i ENTRYPOINT iz lekcije o Dockerfile-u.

Running, ali 0/1 READY

Kontejner radi, ali readiness probe ne prolazi — Service ga zato ne uključuje u saobraćaj. Pogledaj Events i logove aplikacije.

Redosled provere

kubectl get pods                  # kakav je status
kubectl describe pod POD          # Events na dnu
kubectl logs POD --previous       # šta je aplikacija rekla pre pada
kubectl exec -it POD -- sh        # ako uopšte živi, uđi i pogledaj

Podešavanje okruženja

Skraćenica i dopunjavanje tastera Tab:

$ echo 'source <(kubectl completion bash)' >> ~/.bashrc
$ echo 'alias k=kubectl' >> ~/.bashrc
$ echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc

Posle ovoga k get po radi isto što i puna komanda. Ako provodiš sate u klasteru, ovo je najbolji minut koji ćeš uložiti.

Ugrađena dokumentacija za bilo koje polje u manifestu:

$ kubectl explain pod.spec.containers
$ kubectl explain deployment.spec.strategy

Ovo je za Kubernetes ono što je man za Linux — kad ne znaš kako se polje zove ili šta prima, odgovor je ovde.

Kratak podsetnik

kubectl get pods -o wide           # šta radi i gde
kubectl describe pod POD           # zašto ne radi
kubectl logs -f POD                # šta govori
kubectl logs POD --previous        # šta je rekao pre pada
kubectl exec -it POD -- sh         # uđi unutra
kubectl apply -f fajl.yaml         # primeni izmenu
kubectl rollout undo deploy/ime    # vrati prethodnu verziju
kubectl config current-context     # na kom sam klasteru

Vežba

Na klasteru za vežbu:

  • napravi Deployment sa nginx:1.25 i tri replike
  • izvezi njegov YAML sa -o yaml i pročitaj šta je Kubernetes sam dodao
  • izloži ga kao Service i pristupi mu preko port-forward
  • promeni image na nginx:1.26 i posmatraj rollout sa -w
  • vrati prethodnu verziju
  • namerno postavi nepostojeći image i pronađi grešku samo pomoću describe

Povezano: Šta je Pod · Deployment i StatefulSet · Service · Dockerfile · DevOps

Comments

Popular posts from this blog

Konverzija tipova podataka u Pythonu

Početak u Linuxu — šta je i zašto se uči

groupadd