Kubernetes ga kirish — qachon Docker yetmaydi

~15 daq · Docker · Keyingi qadam

Muammodan boshlaylik

Loyiha o'sdi. Endi:

  • Bitta server yetmaydi — 5 ta server kerak
  • API ning 10 ta nusxasi, yuklamaga qarab 3 tadan 30 tagacha o'zgarishi kerak
  • Server o'chsa — undagi konteynerlar avtomatik boshqa serverga ko'chishi kerak
  • Deploy — nol uzilish bilan, xato bo'lsa avtomatik orqaga qaytish

Docker Compose — bitta server uchun. U konteynerlarni boshqa serverga ko'chirmaydi, nusxalarni yuklamaga qarab o'zgartirmaydi, unhealthy ni qayta ishga tushirmaydi (40-dars). Bular — orkestrator ishi. Eng mashhuri — Kubernetes (K8s).


Orkestrator nima qiladi

Siz istalgan holatni yozasiz: "API ning 5 ta nusxasi ishlasin, har biri 512 MB". Orkestrator doimiy ravishda haqiqiy holatni shunga keltiradi:

   Istalgan holat              Haqiqiy holat
   ┌───────────┐               ┌───────────┐
   │ api × 5   │  ──solishtir──│ api × 4   │  ← bittasi o'ldi
   └───────────┘               └───────────┘
                     │
                     ▼
            yangisini ishga tushir (bo'sh serverda)

Bu "o'zini tiklash" (self-healing) tsikli — K8s ning yuragi.


Asosiy tushunchalar

K8s Docker / Compose dagi o'xshashi Nima
Cluster — Serverlar (node lar) to'plami
Node Docker o'rnatilgan server Konteynerlar ishlaydigan mashina
Pod Konteyner Eng kichik birlik: 1 (ba'zan bir nechta) konteyner
Deployment Compose dagi xizmat + replicas "Shu image dan N ta Pod ishlasin"
Service Xizmat nomi orqali DNS (24-dars) Pod larga barqaror nom va yuklama taqsimoti
Ingress Reverse proxy (37-dars) Tashqi HTTP(S) → Service lar
ConfigMap / Secret environment, secrets Sozlamalar va sirlar
PersistentVolume Volume Doimiy ma'lumotlar
Namespace Compose loyiha nomi Resurslarni guruhlash

Compose dan K8s ga: bitta xizmat

Compose:

services:
  api:
    image: ghcr.io/firdavsdev07/dokon-api:1.4.2
    ports: ["3000:3000"]
    environment:
      REDIS_URL: redis://kesh:6379
    deploy:
      replicas: 3
      resources:
        limits: { memory: 512M }

Kubernetes:

# deployment.yaml
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: ghcr.io/firdavsdev07/dokon-api:1.4.2
          ports:
            - containerPort: 3000
          env:
            - name: REDIS_URL
              value: redis://kesh:6379
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef: { name: dokon-sirlar, key: db-parol }
          resources:
            requests: { memory: 256Mi, cpu: 250m }
            limits: { memory: 512Mi }
          readinessProbe:
            httpGet: { path: /health, port: 3000 }
            periodSeconds: 10
          livenessProbe:
            httpGet: { path: /health, port: 3000 }
            periodSeconds: 15
            failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  selector: { app: api }
  ports:
    - port: 3000
      targetPort: 3000

Ko'proq yozish — lekin har bir qator kuchli imkoniyat beradi:

  • readinessProbe — Pod tayyor bo'lmaguncha unga trafik yuborilmaydi
  • livenessProbe — javob bermasa, K8s Pod ni qayta ishga tushiradi (Compose qila olmaydigan narsa)
  • requests — rejalashtiruvchi Pod ni yetarli resursi bor node ga joylaydi
  • Service api — boshqa Pod lar http://api:3000 ga murojaat qiladi, so'rovlar 3 nusxa orasida taqsimlanadi

kubectl — asosiy buyruqlar

kubectl apply -f deployment.yaml          # istalgan holatni yuborish
kubectl get pods                          # ≈ docker ps
kubectl logs -f deploy/api                # ≈ docker logs -f
kubectl exec -it api-7d9f8-x2k4p -- sh    # ≈ docker exec
kubectl describe pod api-7d9f8-x2k4p      # nega ishga tushmayapti
kubectl scale deploy/api --replicas=10    # ko'paytirish
kubectl set image deploy/api api=ghcr.io/firdavsdev07/dokon-api:1.4.3   # deploy
kubectl rollout status deploy/api
kubectl rollout undo deploy/api           # orqaga qaytish

Docker bilganingiz uchun ko'p narsa tanish: get pods ≈ ps, logs, exec.

Rolling update

set image dan keyin K8s Pod larni birma-bir almashtiradi: yangisi ready bo'lgandagina eskisi o'chiriladi. Foydalanuvchi uzilishni sezmaydi. Yangi versiya readinessProbe dan o'tmasa — yangilash to'xtaydi, eskilar ishlashda davom etadi.


Lokal sinab ko'rish

Vosita Izoh
Docker Desktop Settings → Kubernetes → Enable — bitta tugma
kind Kubernetes Docker konteynerlari ichida — CI uchun ham
minikube Klassik lokal klaster
k3d / k3s Yengil K8s; k3s — kichik serverlar uchun production da ham
kind create cluster
kubectl apply -f deployment.yaml
kubectl port-forward svc/api 3000:3000
curl localhost:3000/health

Qachon Kubernetes kerak — va qachon kerak emas

[!WARNING] Kubernetes — kuchli, lekin murakkab. Ko'p kichik jamoalar uni erta qabul qilib, mahsulot o'rniga infratuzilma bilan shug'ullanib qoladi.

Compose yetarli, agar:

  • 1–2 server, bir necha xizmat
  • Bir necha soniyalik deploy uzilishi maqbul
  • Jamoada alohida DevOps muhandisi yo'q

K8s haqida o'ylang, agar:

  • Ko'p server va ko'p xizmat (mikroservislar)
  • Avtomatik masshtablash va nol uzilishli deploy majburiy
  • Bir nechta jamoa bitta platformada ishlaydi

Oraliq variantlar:

  • Docker Swarm — docker stack deploy -c compose.yaml — Compose fayli bilan ko'p serverli klaster, juda sodda
  • Boshqariladigan platformalar — Railway, Render, Fly.io, Google Cloud Run: image bering, qolganini ular qiladi
  • Boshqariladigan K8s — GKE, EKS, AKS, DigitalOcean: klasterni o'zingiz boshqarmaysiz

Eng muhimi: Docker da o'rgangan hamma narsa — image, Dockerfile, qatlamlar, registry, healthcheck, env, volume, tarmoq — Kubernetes ning poydevori. K8s konteynerlarni yasamaydi — siz yasagan image larni ishga tushiradi.


Nima uchun shunday?

Nima uchun Kubernetes "imperativ" buyruqlar ("ishga tushir", "to'xtat") o'rniga "deklarativ" istalgan holat bilan ishlaydi?

Chunki ko'p serverli dunyoda narsalar doimo buziladi: server o'chadi, tarmoq uziladi, konteyner qulaydi. Imperativ buyruq ("3 ta konteyner ishga tushir") bir marta bajariladi — keyin nima bo'lishi uni qiziqtirmaydi. Deklarativ holat ("3 ta bo'lsin") esa doimiy tekshiriladi va tiklanadi: tunda server o'chsa ham, ertalab yana 3 ta. Siz "qanday" ni emas, "nima" ni aytasiz, va tizim o'zi u yerga yetib boradi. Compose ham shu g'oyaning kichik versiyasi — compose.yaml ham istalgan holat — K8s esa uni klaster miqyosida va uzluksiz qiladi.


Xulosa

Eslab qoling:

  • Compose — bitta server; orkestrator — ko'p server, self-healing, masshtablash, rolling update
  • K8s: Cluster → Node → Pod; Deployment (nusxalar), Service (nom + taqsimot), Ingress (proxy)
  • Deklarativ: istalgan holat → K8s haqiqiy holatni unga keltiradi
  • readinessProbe — trafik; livenessProbe — qayta ishga tushirish
  • kubectl get/logs/exec/apply/scale/rollout undo
  • Lokal: Docker Desktop, kind, minikube, k3d
  • K8s ni erta qabul qilmang: Compose → Swarm / PaaS → boshqariladigan K8s
  • Docker bilimlari — K8s ning poydevori

Keyingi dars

45-dars: Yakuniy loyiha — to'liq stekni Docker bilan production ga chiqarish