Pradžia / Programavimas / Kubernetes pradedantiesiems

Kubernetes pradedantiesiems

Kas tas Kubernetes ir kodėl visi apie jį kalba?

Jei bent kiek laiko praleidai IT bendruomenėse, DevOps forumuose ar tiesiog kalbėjaisi su backend kūrėjais – tikrai girdėjai šį žodį. Kubernetes. Arba tiesiog K8s, nes rašyti visą žodį kiekvieną kartą yra per daug vargo (tarp „K” ir „s” yra lygiai 8 raidės – štai iš kur tas pavadinimas).

Bet kas tai iš tikrųjų yra? Paprasčiausiai tariant – tai sistema, kuri padeda valdyti konteinerius. Jei nežinai, kas yra konteineriai – pagalvok apie Docker. Docker leidžia supakuoti programą su visomis jos priklausomybėmis į vieną paketą, kuris veikia vienodai bet kur: tavo nešiojamame kompiuteryje, serveryje ar debesyje. Kubernetes yra tas, kas valdo šiuos paketus – paleidžia juos, stebi, ar veikia, perkelia tarp serverių, keičia jų skaičių pagal apkrovą.

Google sukūrė Kubernetes remdamiesi savo vidiniu projektu Borg, kuriuo valdė milijardus konteinerių. 2014 metais jie atidavė šį projektą atvirojo kodo bendruomenei, ir nuo tada jis tapo de facto standartu konteineriuotų aplikacijų orkestravimui. Šiandien jį naudoja tiek startuoliai, tiek didžiausios pasaulio kompanijos.

Pagrindinės sąvokos – be kurių nieko nesuprasite

Prieš einant toliau, reikia susipažinti su keliais terminais. Kubernetes turi savo žodyną, ir iš pradžių jis gali atrodyti kaip kita kalba. Bet kai supranti logikę – viskas susidėlioja į vietą.

Pod – tai mažiausias Kubernetes vienetas. Vienas pod’as gali turėti vieną ar kelis konteinerius, kurie dalinasi tinklo sąsaja ir saugykla. Dažniausiai pod’e yra vienas konteineris, bet kartais pridedami vadinamieji „sidecar” konteineriai papildomoms funkcijoms – pavyzdžiui, logų rinkimui.

Node – tai fizinis arba virtualus serveris, ant kurio veikia pod’ai. Keli node’ai sudaro klasterį.

Cluster – visas Kubernetes aplinkos rinkinys: valdymo plokštuma (control plane) ir darbo mazgai (worker nodes).

Deployment – tai konfigūracija, kuri nurodo, kiek pod’ų turi veikti, kokį Docker image’ą naudoti ir kaip atnaujinti aplikaciją. Jei vienas pod’as sugenda – Deployment automatiškai paleidžia naują.

Service – tai abstrakcija, kuri suteikia stabilų tinklo adresą pod’ams. Pod’ai gali atsirasti ir dingti, bet Service visada žino, kur jie yra.

Namespace – loginis atskyrimas viename klasteryje. Galima turėti „development”, „staging” ir „production” namespace’us tame pačiame klasteryje.

ConfigMap ir Secret – būdai perduoti konfigūracijos duomenis ir slaptus raktus aplikacijoms, nededant jų tiesiai į Docker image’ą.

Kaip Kubernetes veikia po gaubtu

Kubernetes architektūra susideda iš dviejų pagrindinių dalių: valdymo plokštumos ir darbo mazgų.

Valdymo plokštuma (Control Plane) yra klasterio „smegenys”. Čia veikia keli komponentai:

  • API Server – visi komandos ir užklausos eina per jį. Kai rašai kubectl apply, tu kalbies su API Server.
  • etcd – paskirstyta raktų-reikšmių duomenų bazė, kurioje saugoma visa klasterio būsena. Jei etcd sugenda – sugenda visas klasteris. Todėl jo atsarginės kopijos yra kritiškai svarbios.
  • Scheduler – sprendžia, ant kurio node’o paleisti naują pod’ą, atsižvelgdamas į turimus resursus, apribojimus ir kitas taisykles.
  • Controller Manager – stebi klasterio būseną ir užtikrina, kad tikroji būsena atitiktų norimą. Jei reikia 3 pod’ų, bet veikia tik 2 – Controller Manager paleis trečią.

Darbo mazguose (Worker Nodes) veikia:

  • kubelet – agentas, kuris bendrauja su Control Plane ir valdo pod’us ant konkretaus node’o.
  • kube-proxy – tvarko tinklo taisykles ir leidžia pod’ams bendrauti tarpusavyje bei su išoriniu pasauliu.
  • Container Runtime – dažniausiai containerd arba CRI-O, kuris faktiškai paleidžia konteinerius.

Visa Kubernetes filosofija grindžiama deklaratyviu modeliu. Tu nesakai „paleisk šį konteinerį” – tu sakai „noriu, kad veiktų 3 šio konteinerio kopijos”. Kubernetes pats išsiaiškins, kaip tai padaryti, ir nuolat stebės, ar noras atitinka realybę.

Pirmieji žingsniai – kaip pradėti praktiškai

Teorija yra gerai, bet Kubernetes reikia liesti rankomis. Laimei, yra keli būdai paleisti jį lokaliai, neturint serverių ar debesies paskyros.

Minikube – klasikinis pasirinkimas pradedantiesiems. Paleidžia vieno node’o Kubernetes klasterį virtualios mašinos viduje. Instaliacija paprasta, dokumentacija gera. Pradėk nuo čia:


# Instaliuok minikube (macOS su Homebrew)
brew install minikube

# Paleisk klasterį
minikube start

# Patikrink būseną
minikube status

kind (Kubernetes in Docker) – paleidžia Kubernetes mazgus kaip Docker konteinerius. Greičiau nei Minikube, lengviau kurti kelių mazgų klasterius. Puikus CI/CD aplinkoms.

k3s – lengva Kubernetes versija, sukurta Rancher. Veikia net Raspberry Pi. Jei turi seną kompiuterį ar mini serverį – k3s yra puikus pasirinkimas.

Kai klasteris veikia, reikia kubectl – komandinės eilutės įrankio bendravimui su Kubernetes. Kelios esminės komandos, kurias naudosi kasdien:


# Pamatyk visus pod'us
kubectl get pods

# Pamatyk pod'us visose namespace'uose
kubectl get pods --all-namespaces

# Aprašyk pod'ą (labai naudingas derinant klaidas)
kubectl describe pod 

# Žiūrėk pod'o logus
kubectl logs 

# Prisijunk prie veikiančio konteinerio
kubectl exec -it  -- /bin/bash

# Pritaikyk konfigūracijos failą
kubectl apply -f mano-aplikacija.yaml

YAML failai – Kubernetes kalba

Kubernetes konfigūracija rašoma YAML formatu. Jei dar nepažįsti YAML – tai tekstinis formatas, panašus į JSON, bet žmonėms lengviau skaitomas. Ir labai jautrus tarpams – viena netinkama įtrauka gali sugadinti viską.

Štai paprastas Deployment pavyzdys, kuris paleidžia nginx web serverį:


apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Atkreipk dėmesį į resources sekciją. Čia nurodai, kiek atminties ir CPU konteineris prašo (requests) ir kiek maksimaliai gali naudoti (limits). Tai labai svarbu – be šių parametrų vienas „išprotėjęs” konteineris gali sunaudoti visus node’o resursus ir nužudyti kitus pod’us.

Dabar reikia Service, kad galėtum pasiekti šiuos nginx pod’us:


apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

Service naudoja selector, kad surastų pod’us su etikete app: nginx. Tai labai elegantiškas sprendimas – Service ir Deployment nesusieti tiesiogiai, tik per etiketes.

Praktinis patarimas: laikyk visus YAML failus Git repozitorijoje. Tai vadinama GitOps principu – visa infrastruktūra kaip kodas, su versijų istorija ir galimybe grįžti atgal.

Dažniausios klaidos ir kaip jų išvengti

Kubernetes mokymosi kelias yra grįstas klaidomis. Čia surinktos dažniausios, kurias daro pradedantieji – ir kaip jų išvengti.

1. Nenustatyti resursų limitų. Jau minėta, bet verta pakartoti. Visada nustatyk resources.requests ir resources.limits. Be jų Kubernetes Scheduler negali tinkamai paskirstyti pod’ų, o viena aplikacija gali „praryti” visą serverį.

2. Naudoti „latest” tag’ą Docker image’uose. image: nginx:latest atrodo patogu, bet tai tikras košmaras produkcinėje aplinkoje. Kai nginx išleis naują versiją, tavo pod’ai automatiškai ją naudos po perkrovimo – ir gali sugesti. Visada naudok konkrečią versiją: nginx:1.21.6.

3. Ignoruoti Health Checks. Kubernetes turi du tipus: liveness probe (ar konteineris gyvas?) ir readiness probe (ar konteineris pasiruošęs priimti srautą?). Jei jų nenurodysi, Kubernetes nežinos, kad tavo aplikacija užstrigo, ir toliau siųs srautą į neveikiantį pod’ą.


livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5

4. Saugoti slaptus duomenis ConfigMap’uose. ConfigMap skirtas neslaptiems duomenims – URL adresams, konfigūracijos parametrams. Slaptažodžiams, API raktams ir sertifikatams naudok Secret. Ir net Secret nėra pilnai saugus pagal nutylėjimą (jis tik base64 koduotas, ne užšifruotas) – produkcinėje aplinkoje naudok Sealed Secrets arba HashiCorp Vault.

5. Paleisti pod’us kaip root. Saugumo požiūriu tai bloga praktika. Naudok securityContext, kad apribotum teises:


securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  readOnlyRootFilesystem: true

Kubernetes debesyje – managed sprendimai

Valdyti Kubernetes klasterį pačiam – tai rimtas darbas. Reikia rūpintis etcd atsarginėmis kopijomis, Control Plane atnaujinimais, sertifikatų rotacija ir dar daugybe dalykų. Todėl dauguma kompanijų naudoja valdomas (managed) Kubernetes paslaugas, kur debesies tiekėjas rūpinasi Control Plane.

Google Kubernetes Engine (GKE) – natūralu, kad Google, sukūrę Kubernetes, turi vieną geriausių valdymo paslaugų. GKE Autopilot režimas pats valdo net node’us – tu tik aprašai pod’us, o Google pasirūpina serveriais.

Amazon EKS (Elastic Kubernetes Service) – populiariausias pasirinkimas kompanijoms, jau naudojančioms AWS. Integracija su kitomis AWS paslaugomis (IAM, ELB, EBS) yra puiki, bet konfigūracija sudėtingesnė nei GKE.

Azure AKS (Azure Kubernetes Service) – Microsoft pasiūlymas. Gerai integruojasi su Azure DevOps ir Active Directory. Populiarus .NET ekosistemoje.

DigitalOcean Kubernetes – paprastesnis ir pigesnis variantas mažesnėms kompanijoms ir startuoliams. Puikus santykis kainos ir kokybės.

Praktinė rekomendacija: jei tik pradedate – išbandykite DigitalOcean arba GKE. Jų sąsajos yra intuityvesnės, dokumentacija geresnė pradedantiesiems, o kainos priimtinos eksperimentavimui.

Kai Kubernetes tampa gyvenimo būdu – ką mokytis toliau

Kubernetes yra tik ekosistemos centras. Aplink jį sukasi daugybė įrankių, kurie kartu sudaro modernią „cloud-native” platformą.

Helm – Kubernetes paketų valdytojas. Vietoj to, kad rašytum dešimtis YAML failų, naudoji Helm Chart – šabloną, kurį galima konfigūruoti parametrais. Dauguma populiarių programų (PostgreSQL, Redis, Prometheus) turi paruoštus Helm Charts.

Prometheus + Grafana – stebėsenos standartas. Prometheus renka metrikos duomenis iš pod’ų, Grafana juos vizualizuoja. Kubernetes klasteris be stebėsenos – tai kaip vairuoti automobilį užmerktomis akimis.

Istio arba Linkerd – service mesh sprendimai. Kai turi dešimtis mikroservisų, kurie bendrauja tarpusavyje, reikia valdyti srautą, šifravimą, apkrovos balansavimą ir stebėseną tarp jų. Service mesh tai daro automatiškai.

ArgoCD arba Flux – GitOps įrankiai. Automatiškai sinchronizuoja Kubernetes klasterio būseną su Git repozitorija. Kai atnaujini YAML failą Git – ArgoCD automatiškai pritaiko pakeitimus klasteryje.

Kustomize – alternatyva Helm’ui, integruota į kubectl. Leidžia turėti bazinę konfigūraciją ir ją „perdengti” skirtingoms aplinkoms (dev, staging, prod) be šablonų kalbos.

Mokymosi kelias gali atrodyti begalinis, ir iš dalies taip yra – Kubernetes ekosistema nuolat auga. Bet svarbiausia nepasiduoti. Pradėk nuo pagrindų: Minikube, kubectl, paprasti Deployment ir Service failai. Kai tai taps natūralu – eik prie Helm, paskui prie stebėsenos, paskui prie CI/CD integracijos.

Sertifikavimas taip pat verta paminėti. CKA (Certified Kubernetes Administrator) ir CKAD (Certified Kubernetes Application Developer) yra pramonės pripažinti sertifikatai. CKAD labiau tinka kūrėjams, CKA – administratoriams ir DevOps inžinieriams. Egzaminai yra praktiniai – ne testai su atsakymų variantais, o realios užduotys terminale. Tai reiškia, kad ruošiantis reikia praktikuotis, ne kalti teorijos.

Kubernetes nėra sidabrinė kulka. Jis prideda sudėtingumo, reikalauja laiko ir žinių. Mažai aplikacijai, kurią valdo vienas žmogus, gali pakakti paprastesnių sprendimų. Bet kai aplikacija auga, komanda plečiasi, ir reikia patikimumo, masteliavimo bei automatizavimo – Kubernetes tampa ne pasirinkimu, o būtinybe. Ir tada tos valandos, praleistos mokantis, atsiperka su kaupu.