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.jarMuammo:
Dev’da ishlaydi, prod’da ishlamaydi
Java version farq qiladi
Environment config aralashadi
Manual setup ko‘p
Rollback qiyinContainer bilan:
Application + runtime + config expectation
↓
Docker image
↓
Har joyda bir xil ishlaydiYa’ni container quyidagini beradi:
Build once → run anywhere2. 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-imageYoki image nomi bilan:
./mvnw spring-boot:build-image \
-Dspring-boot.build-image.imageName=registry.uz/order-service:1.0.0Gradle:
./gradlew bootBuildImageBuildpacks nima qiladi?
Siz Dockerfile yozmaysiz. Buildpack o‘zi aniqlaydi:
Bu Java app
↓
Kerakli JRE tanlaydi
↓
Layerlar yaratadi
↓
Security-friendly image qiladi
↓
Start command tayyorlaydiFlow:
Spring Boot JAR
↓
Cloud Native Buildpacks
↓
OCI Docker image
↓
Container registry
↓
KubernetesBuildpacks afzalligi
[+] Dockerfile kerak emas
[+] Standart layer caching yaxshi
[+] Non-root image
[+] Spring Boot bilan yaxshi integratsiya
[+] CI/CD’da soddaKamchiligi
[-] Har bir detail ustidan control kamroq
[-] Debug qilish Dockerfile’dan ko‘ra noaniqroq bo‘lishi mumkin
[-] Maxsus OS package kerak bo‘lsa murakkablashadi4. 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 emasYaxshiroq 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 ishlaydi5. Spring Boot layered JAR
Spring Boot JAR ichida layerlar bo‘lishi mumkin:
dependencies
spring-boot-loader
snapshot-dependencies
applicationBu Docker caching uchun foydali.
Dependency o‘zgarmasa:
dependencies layer qayta build bo‘lmaydiFaqat code o‘zgarsa:
application layer yangilanadiBu CI/CD’da image build vaqtini kamaytiradi.
6. Docker image naming
Yomon:
order-service:latestProduction’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-1030Senior 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: 8080Service:
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order-service
ports:
- port: 80
targetPort: 8080Flow:
Deployment → Podlarni yaratadi
Service → Podlarga stable network endpoint beradi
Ingress/Gateway → tashqi trafficni olib kiradi8. 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: trueEndpointlar:
/actuator/health/liveness
/actuator/health/readinessSpring 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 qiladiMisol:
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3Liveness qachon fail bo‘lishi kerak?
App deadlock bo‘lsa
Event loop butunlay osilib qolsa
Application recover bo‘lolmaydigan holatda bo‘lsaLiveness’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 yuborilmaydiMisol:
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 20
periodSeconds: 5
failureThreshold: 3Readiness qachon fail bo‘lishi mumkin?
App hali start bo‘lyapti
Migration tugamagan
Cache warmup tugamagan
Service overload holatda
Critical dependency unavailableStartup 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: 5Bu degani:
30 × 5s = 150s gacha startga vaqt beradi9. Probe’larni noto‘g‘ri sozlash
Xato 1: liveness juda agressiv
Yomon:
livenessProbe:
periodSeconds: 1
failureThreshold: 1Kichik latency bo‘lsa ham pod restart bo‘ladi.
Xato 2: DB check liveness ichida
Yomon:
liveness = app + database + redis + kafkaDB vaqtincha sekinlashsa:
Kubernetes podlarni restart qiladi
DB yanada ko‘proq bosim oladiYaxshiroq:
liveness = app process tirikmi
readiness = traffic qabul qila oladimi10. Graceful shutdown
Muammo
Kubernetes podni o‘chirganda:
SIGTERM yuboradi
↓
Pod endpointdan olib tashlanadi
↓
App to‘xtashi kerakAgar graceful shutdown bo‘lmasa:
O‘rtadagi request uziladi
Kafka consumer yarim processingda qoladi
DB transaction uziladi
Client error oladiSpring Boot graceful shutdown
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30sBu nima qiladi?
Yangi requestlar qabul qilinmaydi
Mavjud requestlar tugashiga imkon beriladi
Keyin app to‘xtaydiKubernetes terminationGracePeriodSeconds
spec:
terminationGracePeriodSeconds: 45Bu Kubernetes podga toza yopilish uchun vaqt beradi.
Muhim qoida:
terminationGracePeriodSeconds > spring.lifecycle.timeout-per-shutdown-phaseMasalan:
Spring graceful timeout: 30s
Kubernetes termination grace: 45sPreStop 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: INFODeployment’da ishlatish:
envFrom:
- configMapRef:
name: order-service-configSpring Boot environment variable’larni property sifatida o‘qiydi.
PAYMENT_SERVICE_URL
↓
payment.service.url12. 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-secretDeployment’da:
envFrom:
- secretRef:
name: order-service-secretYoki alohida env:
env:
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: order-service-secret
key: DB_PASSWORDKubernetes 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 rotation13. ConfigMap vs Secret
Ma’lumot | Qayerda saqlanadi |
|---|---|
| ConfigMap |
| ConfigMap |
| ConfigMap |
| Secret |
| Secret |
| Secret |
| Secret |
Qoida:
Maxfiy bo‘lmagan config → ConfigMap
Maxfiy credential → Secret14. 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:
1Gibo‘lsa, JVM heap’ni shunga mos sozlash kerak.
Aks holda:
JVM heap + metaspace + thread stacks + native memory
>
container limitNatija:
OOMKilledAmaliy yondashuv:
Container memory: 1Gi
Heap: 60-70%
Qolgan: metaspace, threads, direct memory, nativeMisol:
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: 70Bu nima qiladi?
CPU o‘rtacha 70%dan oshsa → pod soni oshadi
Traffic kamaysa → pod soni kamayadiHPA 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 metricMasalan Kafka consumer uchun:
consumer lag oshsa → replica oshirishREST API uchun:
p95 latency yoki request rate asosida scaling16. 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 sozlansin2. DB bottleneck bo‘lsa
Podni ko‘paytirish har doim yordam bermaydi.
3 pod → DB zo‘rg‘a ishlayapti
20 pod → DB yiqiladiShuning uchun HPA bilan birga:
DB pool size
DB max connections
query performance
cache strategy
rate limitingham 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 soni17. 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‘chadiAgar readiness noto‘g‘ri bo‘lsa:
Pod hali tayyor emas
lekin traffic ola boshlaydi
↓
5xx errorShuning uchun readiness real tayyorlikni aks ettirishi kerak.
18. Deployment strategy
RollingUpdate
Default va ko‘p holatda yaxshi.
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0Bu:
Bitta ortiqcha pod yaratish mumkin
Lekin mavjud pod kamayib ketmasinProduction 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: prodShu bilan bitta image turli environment’da ishlaydi:
order-service:1.0.0
├── dev config
├── staging config
└── prod configQoida:
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 qilishYomon:
COPY . .Bu .env, .git, local file’larni image ichiga olib kirishi mumkin.
.dockerignore:
.git
target
.env
*.log
.idea
.vscode21. 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 productionImage tag:
registry.company.uz/order-service:git-a8f31c2Kubernetes deploy:
kubectl set image deployment/order-service \
order-service=registry.company.uz/order-service:git-a8f31c222. 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 pauseSpring Boot Actuator:
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheusPrometheus scrape:
/actuator/prometheus23. 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: 3Spring config:
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
management:
endpoint:
health:
probes:
enabled: true
endpoints:
web:
exposure:
include: health,info,metrics,prometheus24. Common mistakes
1. latest tag ishlatish
Yomon:
image: order-service:latestRollback va debugging qiyinlashadi.
2. Readiness yo‘q
Pod tayyor bo‘lmasdan traffic oladi.
Natija:
Deployment paytida 5xx error3. 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=secretSecret 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 |