Containerization & cloud

01.07.2026 | Muallif: Jaxongir a.k.a | Kategoriya: Spring Boot | 22 daqiqa o'qish

Containerization & cloud - Spring Boot application’ni lokalda ishlatishdan production Kubernetes/cloud muhitiga olib chiqish mavzusi.

Bu mavzu quyidagilarni qamrab oladi: Buildpacks, multi-stage Dockerfile, Kubernetes readiness/liveness probes, graceful shutdown, ConfigMap/Secret injection, Horizontal Pod Autoscaling considerations.


1. Nima uchun container kerak?

Oddiy deployment:

Serverga Java o‘rnatiladi
↓
JAR copy qilinadi
↓
java -jar app.jar

Muammo:

Dev’da ishlaydi, prod’da ishlamaydi
Java version farq qiladi
Environment config aralashadi
Manual setup ko‘p
Rollback qiyin

Container bilan:

Application + runtime + config expectation
↓
Docker image
↓
Har joyda bir xil ishlaydi

Ya’ni container quyidagini beradi:

Build once → run anywhere

2. Spring Boot app’ni container qilishning 2 asosiy yo‘li

Yo‘l

Qachon yaxshi

Buildpacks

Tez, standart, Dockerfile yozmasdan image olish

Multi-stage Dockerfile

To‘liq control kerak bo‘lsa


3. Buildpacks

Spring Boot Maven plugin build-image goal orqali JAR/WAR’dan OCI image yaratishi mumkin. Spring Boot hujjatlarida bu Cloud Native Buildpacks asosida ishlashi va image’lar security sababli non-root user sifatida build/run qilinishi aytiladi. (Home)

Maven bilan image build qilish

./mvnw spring-boot:build-image

Yoki image nomi bilan:

./mvnw spring-boot:build-image \
  -Dspring-boot.build-image.imageName=registry.uz/order-service:1.0.0

Gradle:

./gradlew bootBuildImage

Buildpacks nima qiladi?

Siz Dockerfile yozmaysiz. Buildpack o‘zi aniqlaydi:

Bu Java app
↓
Kerakli JRE tanlaydi
↓
Layerlar yaratadi
↓
Security-friendly image qiladi
↓
Start command tayyorlaydi

Flow:

Spring Boot JAR
  ↓
Cloud Native Buildpacks
  ↓
OCI Docker image
  ↓
Container registry
  ↓
Kubernetes

Buildpacks afzalligi

[+] Dockerfile kerak emas
[+] Standart layer caching yaxshi
[+] Non-root image
[+] Spring Boot bilan yaxshi integratsiya
[+] CI/CD’da sodda

Kamchiligi

[-] Har bir detail ustidan control kamroq
[-] Debug qilish Dockerfile’dan ko‘ra noaniqroq bo‘lishi mumkin
[-] Maxsus OS package kerak bo‘lsa murakkablashadi

4. Multi-stage Dockerfile

Agar siz image ustidan to‘liq nazorat qilmoqchi bo‘lsangiz, Dockerfile yozasiz.

Yomon Dockerfile

FROM openjdk:21
COPY target/app.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

Muammolar:

- Image katta bo‘lishi mumkin
- Build va runtime ajratilmagan
- Non-root user yo‘q
- Layer caching optimal emas

Yaxshiroq multi-stage Dockerfile

# 1-stage: build
FROM maven:3.9.9-eclipse-temurin-21 AS build
WORKDIR /app

COPY pom.xml .
COPY src ./src

RUN mvn clean package -DskipTests

# 2-stage: runtime
FROM eclipse-temurin:21-jre
WORKDIR /app

RUN useradd -r -u 1001 spring
USER spring

COPY --from=build /app/target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

Bu nima qiladi?

Build uchun Maven image ishlatiladi
Runtime uchun yengilroq JRE image ishlatiladi
Final image ichida source code va Maven cache bo‘lmaydi
App non-root user bilan ishlaydi

5. Spring Boot layered JAR

Spring Boot JAR ichida layerlar bo‘lishi mumkin:

dependencies
spring-boot-loader
snapshot-dependencies
application

Bu Docker caching uchun foydali.

Dependency o‘zgarmasa:

dependencies layer qayta build bo‘lmaydi

Faqat code o‘zgarsa:

application layer yangilanadi

Bu CI/CD’da image build vaqtini kamaytiradi.


6. Docker image naming

Yomon:

order-service:latest

Production’da latest xavfli.

Yaxshi:

registry.company.uz/order-service:1.4.2
registry.company.uz/order-service:git-a8f31c2
registry.company.uz/order-service:2026-05-21-1030

Senior qoida:

Har deploy qilingan image aniq trace qilinadigan bo‘lsin.

7. Kubernetes’da Spring Boot deployment

Minimal Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service
          image: registry.company.uz/order-service:1.0.0
          ports:
            - containerPort: 8080

Service:

apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  selector:
    app: order-service
  ports:
    - port: 80
      targetPort: 8080

Flow:

Deployment → Podlarni yaratadi
Service → Podlarga stable network endpoint beradi
Ingress/Gateway → tashqi trafficni olib kiradi

8. Liveness, readiness, startup probes

Kubernetes’da probe’lar production uchun juda muhim. Kubernetes hujjatlari liveness, readiness va startup probe’larni container holatini tekshirish uchun ishlatishni ko‘rsatadi. (Kubernetes)

Spring Boot Actuator Kubernetes uchun maxsus health probe endpointlarini beradi.

management:
  endpoint:
    health:
      probes:
        enabled: true

Endpointlar:

/actuator/health/liveness
/actuator/health/readiness

Spring blog’da readiness state application client request qabul qilishga tayyormi-yo‘qligini bildirishi, unready bo‘lsa Kubernetes traffic yubormasligi kerakligi tushuntirilgan. (Home)


Liveness probe

Liveness - app tirikmi?

Agar liveness fail bo‘lsa:

Kubernetes podni restart qiladi

Misol:

livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
  failureThreshold: 3

Liveness qachon fail bo‘lishi kerak?

App deadlock bo‘lsa
Event loop butunlay osilib qolsa
Application recover bo‘lolmaydigan holatda bo‘lsa

Liveness’ga DB ulanishini qo‘shish ko‘pincha xato. DB 10 sekund sekinlashsa, Kubernetes hamma podlarni restart qilib, vaziyatni yomonlashtirishi mumkin.


Readiness probe

Readiness - app traffic qabul qilishga tayyormi?

Agar readiness fail bo‘lsa:

Pod restart bo‘lmaydi
Lekin unga traffic yuborilmaydi

Misol:

readinessProbe:
  httpGet:
    path: /actuator/health/readiness
    port: 8080
  initialDelaySeconds: 20
  periodSeconds: 5
  failureThreshold: 3

Readiness qachon fail bo‘lishi mumkin?

App hali start bo‘lyapti
Migration tugamagan
Cache warmup tugamagan
Service overload holatda
Critical dependency unavailable

Startup probe

Startup probe - sekin start bo‘ladigan app’lar uchun.

Agar startup probe bor bo‘lsa, liveness probe startup tugamaguncha appni o‘ldirmaydi.

startupProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  failureThreshold: 30
  periodSeconds: 5

Bu degani:

30 × 5s = 150s gacha startga vaqt beradi

9. Probe’larni noto‘g‘ri sozlash

Xato 1: liveness juda agressiv

Yomon:

livenessProbe:
  periodSeconds: 1
  failureThreshold: 1

Kichik latency bo‘lsa ham pod restart bo‘ladi.


Xato 2: DB check liveness ichida

Yomon:

liveness = app + database + redis + kafka

DB vaqtincha sekinlashsa:

Kubernetes podlarni restart qiladi
DB yanada ko‘proq bosim oladi

Yaxshiroq:

liveness = app process tirikmi
readiness = traffic qabul qila oladimi

10. Graceful shutdown

Muammo

Kubernetes podni o‘chirganda:

SIGTERM yuboradi
↓
Pod endpointdan olib tashlanadi
↓
App to‘xtashi kerak

Agar graceful shutdown bo‘lmasa:

O‘rtadagi request uziladi
Kafka consumer yarim processingda qoladi
DB transaction uziladi
Client error oladi

Spring Boot graceful shutdown

server:
  shutdown: graceful

spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s

Bu nima qiladi?

Yangi requestlar qabul qilinmaydi
Mavjud requestlar tugashiga imkon beriladi
Keyin app to‘xtaydi

Kubernetes terminationGracePeriodSeconds

spec:
  terminationGracePeriodSeconds: 45

Bu Kubernetes podga toza yopilish uchun vaqt beradi.

Muhim qoida:

terminationGracePeriodSeconds > spring.lifecycle.timeout-per-shutdown-phase

Masalan:

Spring graceful timeout: 30s
Kubernetes termination grace: 45s

PreStop hook

Ba’zida podni endpointdan olib tashlash va load balancer propagation uchun ozgina kutish kerak bo‘ladi.

lifecycle:
  preStop:
    exec:
      command: ["sh", "-c", "sleep 10"]

Bu yangi requestlar eski podga kelib qolishini kamaytiradi.


11. ConfigMap

Kubernetes ConfigMap non-confidential config uchun ishlatiladi. Kubernetes hujjatlarida ConfigMap key-value ko‘rinishidagi maxfiy bo‘lmagan ma’lumotni saqlashi va Podlar uni environment variable, command-line argument yoki volume file sifatida ishlatishi mumkinligi aytiladi. (Kubernetes)

ConfigMap misol

apiVersion: v1
kind: ConfigMap
metadata:
  name: order-service-config
data:
  SPRING_PROFILES_ACTIVE: prod
  PAYMENT_SERVICE_URL: http://payment-service
  LOGGING_LEVEL_ROOT: INFO

Deployment’da ishlatish:

envFrom:
  - configMapRef:
      name: order-service-config

Spring Boot environment variable’larni property sifatida o‘qiydi.

PAYMENT_SERVICE_URL
↓
payment.service.url

12. Secret

Secret maxfiy ma’lumotlar uchun ishlatiladi. Kubernetes hujjatlarida Secret credential, password, SSH key kabi ma’lumotlarni Podlarga environment variable yoki file sifatida berish uchun ishlatilishi mumkinligi aytiladi. (Kubernetes)

Secret misol

apiVersion: v1
kind: Secret
metadata:
  name: order-service-secret
type: Opaque
stringData:
  DB_USERNAME: order_user
  DB_PASSWORD: strong-password
  JWT_CLIENT_SECRET: very-secret

Deployment’da:

envFrom:
  - secretRef:
      name: order-service-secret

Yoki alohida env:

env:
  - name: SPRING_DATASOURCE_PASSWORD
    valueFrom:
      secretKeyRef:
        name: order-service-secret
        key: DB_PASSWORD

Kubernetes environment variable kiritish uchun env yoki envFrom ishlatilishini rasmiy hujjat ko‘rsatadi. (Kubernetes)


Secret haqida muhim eslatma

Kubernetes Secret oddiy holatda "sehrli xavfsiz vault" emas.

Senior darajada quyidagilar kerak:

- etcd encryption at rest
- RBAC cheklovi
- Secret access audit
- External Secrets Operator / Vault / cloud secret manager
- Secret rotation

13. ConfigMap vs Secret

Ma’lumot

Qayerda saqlanadi

SPRING_PROFILES_ACTIVE

ConfigMap

LOG_LEVEL

ConfigMap

PAYMENT_SERVICE_URL

ConfigMap

DB_USERNAME

Secret

DB_PASSWORD

Secret

JWT_SIGNING_KEY

Secret

OAUTH_CLIENT_SECRET

Secret

Qoida:

Maxfiy bo‘lmagan config → ConfigMap
Maxfiy credential → Secret

14. Resource requests and limits

Kubernetes’da har container uchun CPU/memory request va limit beriladi.

resources:
  requests:
    cpu: "250m"
    memory: "512Mi"
  limits:
    cpu: "1000m"
    memory: "1Gi"

Requests

Scheduler uchun signal:

Bu pod kamida shuncha resursga muhtoj.

Limits

Chegara:

Bundan ortiq ishlatmasin.

Java app uchun memory muhim

Agar container memory limit:

1Gi

bo‘lsa, JVM heap’ni shunga mos sozlash kerak.

Aks holda:

JVM heap + metaspace + thread stacks + native memory
>
container limit

Natija:

OOMKilled

Amaliy yondashuv:

Container memory: 1Gi
Heap: 60-70%
Qolgan: metaspace, threads, direct memory, native

Misol:

env:
  - name: JAVA_TOOL_OPTIONS
    value: "-XX:MaxRAMPercentage=70"

15. Horizontal Pod Autoscaling - HPA

HPA podlar sonini avtomatik oshirib-kamaytiradi. Kubernetes hujjatlarida HorizontalPodAutoscaler workload resource’ni kuzatib, podlar sonini kerakli targetga mos ravishda avtomatik yangilashi tushuntiriladi. (Kubernetes)

Misol:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 3
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

Bu nima qiladi?

CPU o‘rtacha 70%dan oshsa → pod soni oshadi
Traffic kamaysa → pod soni kamayadi

HPA faqat CPU bilan cheklanmasin

Spring Boot microservice’da CPU har doim yaxshi scaling signal emas.

Ko‘rib chiqiladigan metriclar:

CPU usage
Memory usage
HTTP requests per second
p95 latency
Kafka consumer lag
Queue length
Active DB connections
Custom business metric

Masalan Kafka consumer uchun:

consumer lag oshsa → replica oshirish

REST API uchun:

p95 latency yoki request rate asosida scaling

16. HPA’da ehtiyot bo‘ladigan joylar

1. Startup sekin bo‘lsa

Pod start bo‘lishi 60 sekund olsa, HPA traffic spike’ga kech javob beradi.

Yechim:

- startup time optimization
- minReplicas yetarli bo‘lsin
- readiness to‘g‘ri sozlansin

2. DB bottleneck bo‘lsa

Podni ko‘paytirish har doim yordam bermaydi.

3 pod → DB zo‘rg‘a ishlayapti
20 pod → DB yiqiladi

Shuning uchun HPA bilan birga:

DB pool size
DB max connections
query performance
cache strategy
rate limiting

ham ko‘riladi.


3. Kafka consumer partition limit

Agar topic’da 3 partition bo‘lsa:

HPA 10 pod qilsa ham, bir consumer group’da faqat 3 pod faol ishlaydi.

Qoida:

Kafka consumer parallelism ≤ partition soni

17. Readiness + rolling update

Deployment rolling update paytida yangi podlar ishga tushadi.

old podlar bor
↓
new pod start
↓
readiness OK bo‘lsa traffic oladi
↓
old podlar sekin o‘chadi

Agar readiness noto‘g‘ri bo‘lsa:

Pod hali tayyor emas
lekin traffic ola boshlaydi
↓
5xx error

Shuning uchun readiness real tayyorlikni aks ettirishi kerak.


18. Deployment strategy

RollingUpdate

Default va ko‘p holatda yaxshi.

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

Bu:

Bitta ortiqcha pod yaratish mumkin
Lekin mavjud pod kamayib ketmasin

Production API uchun maxUnavailable: 0 ko‘p holatda xavfsizroq.


19. Spring profile cloud’da

Config:

spring:
  profiles:
    active: ${SPRING_PROFILES_ACTIVE:local}

Kubernetes ConfigMap:

data:
  SPRING_PROFILES_ACTIVE: prod

Shu bilan bitta image turli environment’da ishlaydi:

order-service:1.0.0
  ├── dev config
  ├── staging config
  └── prod config

Qoida:

Image immutable bo‘lsin.
Environment farqi config orqali berilsin.

20. Container image security

Senior darajada image security ham muhim.

Checklist:

[ ] Non-root user
[ ] Minimal base image
[ ] Image scan
[ ] CVE monitoring
[ ] No secret in image
[ ] No .env in image
[ ] No SSH key in image
[ ] Fixed tag, no latest
[ ] SBOM kerak bo‘lsa generate qilish

Yomon:

COPY . .

Bu .env, .git, local file’larni image ichiga olib kirishi mumkin.

.dockerignore:

.git
target
.env
*.log
.idea
.vscode

21. CI/CD flow

Typical production flow:

Developer push
↓
CI starts
↓
Unit tests
↓
Integration tests
↓
Build JAR
↓
Build image
↓
Scan image
↓
Push to registry
↓
Deploy to staging
↓
Smoke test
↓
Deploy to production

Image tag:

registry.company.uz/order-service:git-a8f31c2

Kubernetes deploy:

kubectl set image deployment/order-service \
  order-service=registry.company.uz/order-service:git-a8f31c2

22. Observability in cloud

Kubernetes’da faqat pod running bo‘lishi yetarli emas.

Kuzatish kerak:

- pod restart count
- OOMKilled
- CPU throttling
- memory usage
- p95/p99 latency
- HTTP 5xx rate
- readiness failures
- liveness restarts
- HikariCP active/pending connections
- Kafka consumer lag
- GC pause

Spring Boot Actuator:

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus

Prometheus scrape:

/actuator/prometheus

23. Real Spring Boot Kubernetes manifest

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: order-service
    spec:
      terminationGracePeriodSeconds: 45
      containers:
        - name: order-service
          image: registry.company.uz/order-service:1.0.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080

          envFrom:
            - configMapRef:
                name: order-service-config
            - secretRef:
                name: order-service-secret

          env:
            - name: JAVA_TOOL_OPTIONS
              value: "-XX:MaxRAMPercentage=70"

          resources:
            requests:
              cpu: "250m"
              memory: "512Mi"
            limits:
              cpu: "1000m"
              memory: "1Gi"

          startupProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8080
            failureThreshold: 30
            periodSeconds: 5

          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8080
            periodSeconds: 10
            failureThreshold: 3

          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 8080
            periodSeconds: 5
            failureThreshold: 3

Spring config:

server:
  shutdown: graceful

spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s

management:
  endpoint:
    health:
      probes:
        enabled: true
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus

24. Common mistakes

1. latest tag ishlatish

Yomon:

image: order-service:latest

Rollback va debugging qiyinlashadi.


2. Readiness yo‘q

Pod tayyor bo‘lmasdan traffic oladi.

Natija:

Deployment paytida 5xx error

3. Liveness DB’ga bog‘langan

DB sekinlashsa podlar restart bo‘ladi va incident kattalashadi.


4. Graceful shutdown yo‘q

Rolling update paytida requestlar uziladi.


5. Resource limit yo‘q

Pod node resursini yeb qo‘yishi mumkin.


6. Secret image ichida

Yomon:

ENV DB_PASSWORD=secret

Secret runtime’da berilishi kerak.


7. HPA DB limitni hisobga olmaydi

Pod ko‘payadi, DB yiqiladi.


25. Senior interviewda savol-javob

Suhbatda so‘rasa:

Spring Boot application’ni Kubernetes’da production’ga qanday tayyorlaysiz?

Javob:

Avval application’ni immutable container image qilaman. Buildpacks yoki multi-stage Dockerfile ishlataman, image non-root user bilan ishlaydi, latest tag ishlatmayman.

Kubernetes’da Deployment, Service, ConfigMap va Secret ajrataman. ConfigMap’da non-sensitive config, Secret’da credential saqlanadi. Spring profile environment orqali beriladi.

Actuator orqali liveness va readiness probe yoqaman. Liveness faqat app tirikligini bildiradi, readiness esa traffic qabul qilishga tayyorligini bildiradi. DB dependency’ni liveness’ga qo‘shmayman.

Graceful shutdown yoqaman: server.shutdown=graceful va Kubernetes terminationGracePeriodSeconds Spring timeout’dan kattaroq bo‘ladi.

Resource requests/limits qo‘yaman, JVM memory’ni container limitga moslayman. HPA qo‘shsam, faqat CPU emas, latency, Kafka lag, queue length yoki custom metriclarni ham ko‘rib chiqaman.

Deployment’da rolling update, maxUnavailable=0, readiness probe va observability metrikalarini majburiy qilaman.

26. Qisqa xulosa

Containerization & cloud’ning asosiy maqsadi:

Spring Boot app’ni ishonchli, repeatable, observable va autoscalable qilib production’da ishlatish.

Eng muhim qoida:

Container image application’ni olib yuradi.
Config environment’dan keladi.
Secret hech qachon image ichida bo‘lmaydi.

Asosiy tushunchalar:

Mavzu

Esda qoladigan qoida

Buildpacks

Dockerfile yozmasdan OCI image

Multi-stage Dockerfile

Build va runtime alohida

Non-root user

Container security uchun muhim

Liveness

App tirikmi? Fail bo‘lsa restart

Readiness

Traffic qabul qila oladimi? Fail bo‘lsa traffic yo‘q

Startup probe

Sekin start qiladigan app uchun

Graceful shutdown

Rolling update’da request uzilmasin

ConfigMap

Maxfiy bo‘lmagan config

Secret

Credential va maxfiy data

Resources

Scheduler va limit nazorati

HPA

Pod sonini metric asosida oshirib-kamaytiradi

Observability

Running bo‘lish yetmaydi, metrikalar kerak