24 β Ingress, storage, Helm va GitOps¶
β¬ οΈ Oldingi: 23 β Production Kubernetes Β· π README Β· Keyingi: 25 β Monitoring: Prometheus va Grafana β‘οΈ
Bu bobda: Har bir Service uchun alohida
LoadBalancer(va alohida IP) olish qimmat va boshqarib bo'lmas muammosidan boshlab β Ingress (networking.k8s.io/v1) bilan ko'p Service'ni bitta tashqi kirish nuqtasiga ulashni, domen va path bo'yicha marshrutlashni (rules,host,http.paths,pathType,backend.service) va TLS'ni (tlsbloki, cert-manager bilan avtomatik sertifikat) o'rganamiz, Ingress ishlashi uchun Ingress Controller (nginx-ingress) kerakligini ko'ramiz; Pod ephemeral (vaqtinchalik) ekanini va ma'lumotni saqlash uchun PersistentVolume (PV) / PersistentVolumeClaim (PVC) / StorageClass (dynamic provisioning) bilan haqiqiy diskni Pod'ga ulashni, DB kabi stateful ilovalar uchun StatefulSet (apps/v1, barqaror nom + headless Service +volumeClaimTemplates) ni ko'rib chiqamiz; takroriy YAML'ni shablonlash uchun Helm paket menejerini (Chart.yaml,values.yaml,templates/,helm install/upgrade/rollback/uninstall,--set/-f) o'rganamiz; va nihoyat GitOps (Argo CD / Flux β Git haqiqat manbai, push vs pull deploy) hamda managed Kubernetes (EKS/GKE/AKS) ga kirish darajasida qaraymiz.
Muammo: har bir ilovaga alohida IP olib bo'lmaydi¶
22 va 23-boblarda ilovamizni Kubernetes'da Deployment + Service bilan ishga tushirdik. Tashqi dunyoga ochish uchun type: LoadBalancer Service ishlatdik β cloud unga tashqi IP berdi. Bitta ilova uchun bu yaxshi ishladi.
Endi real loyihani tasavvur qiling: sizda api.example.uz (backend), example.uz (frontend), admin.example.uz (admin panel) bor. Har biriga alohida LoadBalancer Service qilsangiz β cloud sizdan har bir IP uchun alohida to'lov oladi (oyiga $15-20 atrofida), va sizda uchta turli IP bo'ladi. DNS'da uchta yozuv, uchta sertifikat, hammasini qo'lda boshqarish kerak. Ilova soni 10 taga yetganda β bu chidab bo'lmas holatga aylanadi.
π Yana bir muammo: LoadBalancer Service faqat TCP/port darajasida ishlaydi. U "example.uz/api ga kelganni backend'ga, example.uz/ ga kelganni frontend'ga yubor" deya olmaydi β chunki u HTTP yo'lini (path) yoki domen nomini (host) ko'rmaydi. Bizga L7 (HTTP darajasida) marshrutlash kerak.
Yechim β Ingress. Bitta tashqi kirish nuqtasi, bitta IP, va domen/path bo'yicha aqlli marshrutlash. Bu β Kubernetes ichidagi reverse proxy (17-bobda nginx'da ko'rgan reverse proxy g'oyasini eslang). Bu bobda Ingress'dan boshlab, ma'lumotni saqlash (storage), ilovalarni paketlash (Helm) va Git orqali deploy qilish (GitOps) gacha boramiz.
Ingress: bitta eshik, ko'p ilova¶
Ingress (kirish) β klasterga tashqaridan keladigan HTTP/HTTPS trafikni domen va path bo'yicha turli Service'larga taqsimlovchi qoidalar to'plami. U β klaster oldidagi aqlli darvozabon: "api.example.uz so'rovini api-service'ga, example.uz/admin ni admin-service'ga yubor".
β οΈ Eng muhim nozik nuqta: Ingress obyektining o'zi hech narsa qilmaydi. U faqat qoidalar ro'yxati (YAML). Bu qoidalarni bajaradigan dastur kerak β bu Ingress Controller.
Ingress Controller nima va nega kerak¶
Ingress resursi β bu "men shunday marshrutlashni xohlayman" degan deklaratsiya. Lekin uni amalda bajaradigan kimdir bo'lishi kerak. Bu vazifani Ingress Controller bajaradi β klasterda ishlaydigan haqiqiy reverse proxy (odatda nginx). Eng mashhuri β nginx-ingress (ingress-nginx).
Ingress Controller:
- Klasterdagi barcha
Ingressobyektlarini kuzatib turadi. - Ulardagi qoidalarni o'qib, ichki nginx config'iga aylantiradi.
- O'zi bitta
LoadBalancerService orqali tashqi IP oladi β va butun klaster uchun shu bitta IP yetarli bo'ladi.
π Demak mantiq: bitta Ingress Controller (bitta tashqi IP) + ko'p Ingress qoidalari (har ilova uchun). Pulli IP bitta, marshrutlash esa cheksiz. Mana shu LoadBalancer-har-ilova muammosini hal qiladi.
Ingress Controller'ni o'rnatish (illustrativ β real klaster kerak):
# nginx-ingress controller (rasmiy manifest)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
# o'rnatilgach, uning tashqi IP'sini ko'rish
kubectl get service -n ingress-nginx
βΉοΈ Illustrativ: yuqoridagi kubectl apply real klaster (minikube/kind/cloud) talab qiladi va internetdan manifest yuklaydi. Lokalda biz uni bajarmaymiz; quyidagi Ingress YAML'ning strukturasini esa offline tekshirdik.
Ingress manifesti: host va path bo'yicha marshrutlash¶
Mana to'liq Ingress namunasi. Bu uchta holatni ko'rsatadi: domen bo'yicha, path bo'yicha marshrutlash va TLS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
# nginx-ingress'ga maxsus ko'rsatma (controller'ga qarab o'zgaradi)
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
# 1) Domen (host) bo'yicha: api.example.uz -> api-service
- host: api.example.uz
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
# 2) Asosiy domen, path bo'yicha bo'linadi
- host: example.uz
http:
paths:
- path: /admin
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
Asosiy maydonlar:
apiVersion: networking.k8s.io/v1β Ingress'ning barqaror (stable) versiyasi. β Eskiextensions/v1beta1yokinetworking.k8s.io/v1beta1β olib tashlangan, ishlatmang.ingressClassName: nginxβ qaysi Ingress Controller bu qoidani bajarishini aytadi (klasterda bir nechta controller bo'lishi mumkin).rulesβ marshrutlash qoidalari ro'yxati. Har birihost(domen) vahttp.paths(path'lar).pathTypeβ path qanday solishtiriladi:Prefixβ yo'l boshi mos kelsa (/admin->/admin/usersham tushadi). Eng ko'p ishlatiladi.Exactβ aniq mos kelishi shart.backend.service.name+backend.service.port.numberβ so'rov qaysi Service'ga va uning qaysi portiga yuborilishi.
π‘ Tartib muhim: nginx-ingress eng uzun mos keluvchi prefixni tanlaydi. Yuqorida /admin /dan oldin tekshiriladi, shuning uchun example.uz/admin/... admin'ga, qolgani frontend'ga ketadi.
Ingress vs Service (LoadBalancer)¶
Service LoadBalancer |
Ingress | |
|---|---|---|
| Daraja | L4 (TCP/port) | L7 (HTTP: host + path) |
| Tashqi IP | Har Service'ga alohida (pulli) | Bitta controller'ga, hammaga umumiy |
| Marshrutlash | Yo'q (faqat port) | Domen va path bo'yicha |
| TLS | Yo'q (ilova o'zi qiladi) | Markazda, Ingress'da tugatiladi |
| Qachon | Bitta TCP xizmat (DB, gRPC) | Ko'p HTTP ilova, bitta klaster |
π Qoida: HTTP(S) ilovalar uchun β Ingress. LoadBalancer Service'ni faqat HTTP bo'lmagan (masalan tashqaridan ochiq DB yoki maxsus TCP protokol) holatlar uchun yoki Ingress Controller'ning o'zini ochish uchun saqlang.
TLS va cert-manager bilan avtomatik HTTPS¶
Ingress sertifikatni markazda boshqarishga imkon beradi β har ilova o'zi HTTPS qilmaydi, Ingress Controller TLS'ni tugatadi (terminate). spec.tls bloki domen va sertifikat saqlangan Secret'ni bog'laydi:
spec:
tls:
- hosts:
- api.example.uz
- example.uz
secretName: example-tls # TLS sertifikat shu Secret'da
rules:
- host: api.example.uz
# ... (yuqoridagidek)
Sertifikatni qo'lda olish va Secret'ga solish zerikarli (18-bobdagi Certbot'ni eslang). Klasterda buni cert-manager avtomatlashtiradi: u Let's Encrypt'dan ACME orqali sertifikat oladi, Secret'ga yozadi va 90 kunda avtomatik yangilaydi β xuddi 18-bobdagi certbot.timer kabi, lekin Kubernetes ichida.
Shu annotatsiya bilan cert-manager Ingress'dagi tls.hosts domenlari uchun sertifikatni o'zi oladi va secretName'ga joylaydi. (18-bobda Let's Encrypt va ACME'ni batafsil ko'rganmiz β cert-manager o'sha jarayonni klaster ichida bajaradi.)
βΉοΈ Illustrativ: cert-manager o'rnatish va Let's Encrypt'dan real sertifikat olish jonli klaster, real domen va ochiq port talab qiladi β o'z klasteringizda bajaring.
Storage: Pod o'chsa, ma'lumot yo'qoladi¶
Hozirgacha ilovalarimiz stateless edi β ma'lumotni o'zida saqlamasdi. Lekin DB (PostgreSQL), fayl yuklamalari, yoki Redis kabi narsalar ma'lumotni saqlashi kerak.
Muammo: Pod ephemeral (vaqtinchalik). Pod o'chsa, qayta yaratilsa yoki boshqa node'ga ko'chsa β uning ichidagi disk butunlay yo'qoladi. Pod ichiga yozilgan PostgreSQL ma'lumotlari Pod restart bo'lishi bilan yo'q bo'ladi. Bu β falokat.
Yechim: Pod'ning umridan uzoq yashaydigan, alohida disk. Kubernetes'da bu β PersistentVolume tizimi.
PV, PVC va StorageClass¶
Kubernetes storage'ni uch tushuncha bilan boshqaradi:
- PersistentVolume (PV) β klasterdagi haqiqiy disk bo'lagi (cloud disk, NFS, lokal disk). Bu β "ombordagi mavjud hajm".
- PersistentVolumeClaim (PVC) β disk uchun talabnoma: "menga 5 GB,
ReadWriteOncerejimida disk kerak". Pod PV'ni to'g'ridan-to'g'ri emas, PVC orqali so'raydi. Bu β "men shunday hajm istayman" degan ariza. - StorageClass β PVC kelganda PV'ni avtomatik yaratish (dynamic provisioning) qoidasi. Cloud'da odatda standart StorageClass bor: PVC yozsangiz, u o'zi cloud disk yaratib, PV qilib bog'laydi. Qo'lda PV yaratish shart emas.
π Mantiqni o'xshatish bilan: PVC β restoranda buyurtma ("menga 5 GB"), StorageClass β oshpaz (buyurtmaga ko'ra taom tayyorlaydi, ya'ni PV yaratadi), PV β tayyor taom (haqiqiy disk). Pod faqat buyurtma beradi (PVC), qolganini tizim qiladi.
PVC manifesti:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce # bitta node'dan o'qish/yozish
resources:
requests:
storage: 5Gi # 5 gigabayt so'raymiz
storageClassName: standard # qaysi StorageClass (cloud'da odatda standart bor)
accessModes β diskga kirish rejimi:
ReadWriteOnce(RWO) β bitta node disk'ni o'qiydi/yozadi. DB uchun eng ko'p ishlatiladi.ReadOnlyMany(ROX) β ko'p node faqat o'qiydi.ReadWriteMany(RWX) β ko'p node yozadi (NFS kabi maxsus storage kerak).
PVC'ni Pod'ga ulash¶
PVC'ni Pod (yoki Deployment) ichida volumes + volumeMounts bilan ulaymiz:
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:17
env:
- name: POSTGRES_PASSWORD
value: "maxfiy-parol" # haqiqatda Secret'dan oling
volumeMounts:
- name: pgdata
mountPath: /var/lib/postgresql/data
volumes:
- name: pgdata
persistentVolumeClaim:
claimName: postgres-pvc # yuqoridagi PVC
volumesβ Pod'ga qaysi hajmlar ulanishini e'lon qiladi; bu yerdapersistentVolumeClaim.claimNameorqali PVC'ga ishora.volumeMounts.mountPathβ disk konteyner ichida qayerga ulanishi (/var/lib/postgresql/dataβ PostgreSQL ma'lumotlari shu yerda).
Endi Pod o'chsa ham, disk PVC sifatida saqlanib qoladi; yangi Pod o'sha PVC'ni qayta ulaydi va ma'lumot joyida turadi.
β οΈ env'da parolni ochiq yozish β faqat namuna. Production'da 23-bobda ko'rgan Secret'dan valueFrom.secretKeyRef bilan oling.
StatefulSet: DB kabi stateful ilovalar uchun¶
Deployment + PVC oddiy holatda ishlaydi, lekin DB klasteri (bir nechta PostgreSQL/MongoDB replikasi) uchun yetarli emas: har replikaga o'z barqaror nomi va o'z alohida diski kerak. Buni StatefulSet beradi.
StatefulSet Deployment'dan farqi:
- Barqaror, oldindan aytib bo'ladigan nom: Pod'lar
db-0,db-1,db-2deb tartib bilan nomlanadi (Deployment'da tasodifiyapp-7d8f...). Pod o'chib qayta yaratilsa ham o'sha nom qaytadi. - Har Pod'ga alohida storage:
volumeClaimTemplatesorqali har replika uchun alohida PVC avtomatik yaratiladi (db-0-> o'z diski,db-1-> boshqa disk). - Headless Service bilan ishlaydi: har Pod'ga barqaror DNS nom beradi (
db-0.db,db-1.db).
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres # headless Service nomi (barqaror DNS uchun)
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:17
ports:
- containerPort: 5432
volumeMounts:
- name: pgdata
mountPath: /var/lib/postgresql/data
volumeClaimTemplates: # har replikaga alohida PVC
- metadata:
name: pgdata
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
serviceNameβ headless Service nomi; StatefulSet shu orqali Pod'larga barqaror DNS beradi.volumeClaimTemplatesβ PVC shabloni: StatefulSet har Pod uchun (pgdata-postgres-0,pgdata-postgres-1, ...) alohida PVC yaratadi.
π Qoida: oddiy stateless ilova -> Deployment. Saqlanadigan ma'lumotli, identifikatsiyasi muhim ilova (DB, message queue) -> StatefulSet. Boshlovchi uchun ko'p hollarda boshqariladigan cloud DB ishlatish (klaster ichida DB ishlatishdan) osonroq β buni ham yodda tuting.
Helm: Kubernetes'ning paket menejeri¶
Hozirgacha har bir resurs uchun alohida YAML yozdik: Deployment, Service, Ingress, PVC, ConfigMap, Secret... Bitta ilova uchun bu 5-6 fayl. Endi shu ilovani uchta muhitga (dev, staging, prod) deploy qilish kerak β har birida replika soni, domen, resurs limitlari boshqacha.
Variant 1: YAML'larni uch marta nusxalab, qiymatlarni qo'lda o'zgartirish. Natija β nusxalar bir-biridan farq qila boshlaydi, xato kiradi, boshqarib bo'lmaydi.
Variant 2: Helm β Kubernetes'ning paket menejeri (Linux'da apt/npm kabi, lekin K8s manifestlari uchun). Helm YAML'ni shablonlash (template) va versiyalash imkonini beradi.
Chart strukturasi¶
Helm paketi β chart deb ataladi. Bu β quyidagi tuzilishdagi papka:
myapp/
βββ Chart.yaml # chart metadatasi (nom, versiya)
βββ values.yaml # standart qiymatlar (sozlanadi)
βββ templates/
βββ deployment.yaml # {{ }} shabloni bilan
βββ service.yaml
Chart.yaml β chart haqida ma'lumot:
apiVersion: v2
name: myapp
description: Mening ilovam uchun Helm chart
type: application
version: 0.1.0 # chart versiyasi
appVersion: "1.0.0" # ichidagi ilova versiyasi
values.yaml β standart, o'zgartiriladigan qiymatlar:
templates/deployment.yaml β {{ }} shablon ifodalari bilan (qiymatlar values.yaml'dan keladi):
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-myapp
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}-myapp
template:
metadata:
labels:
app: {{ .Release.Name }}-myapp
spec:
containers:
- name: myapp
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
β οΈ Illustrativ shablon: yuqoridagi templates/deployment.yamldagi {{ .Values... }} qatorlari β Helm-specific shablon sintaksisi, sof YAML emas. Helm uni helm install paytida render qilib, haqiqiy YAML'ga aylantiradi. .Release.Name β helm install da bergan release nomi, .Values.X β values.yamldagi qiymat. (Shu sababli bu faylni to'g'ridan-to'g'ri kubectl apply qilib bo'lmaydi β avval Helm render qilishi kerak.)
Helm buyruqlari¶
# 1) Tashqi chart repozitoriyni qo'shish
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 2) Chart'ni klasterga o'rnatish (release nomi = "web")
helm install web ./myapp
# 3) values'ni o'zgartirib o'rnatish
helm install web ./myapp --set replicaCount=5
helm install web ./myapp -f prod-values.yaml
# 4) Mavjud release'ni yangilash (yangi versiya / yangi qiymatlar)
helm upgrade web ./myapp --set image.tag=1.1.0
# 5) Xato bo'lsa β oldingi holatga qaytish
helm rollback web 1 # 1-revizyaga qaytar
# 6) O'chirish
helm uninstall web
# Render natijasini ko'rish (klasterga tegmasdan)
helm template web ./myapp
Asosiy g'oyalar:
- release β chart'ning klasterga o'rnatilgan nusxasi. Bitta chart'ni turli nom bilan ko'p marta o'rnatish mumkin (
web,web-staging). --set key=valueβ bitta qiymatni buyruq qatorida o'zgartirish (tezkor).-f values.yamlβ butun qiymatlar faylini berish (muhit bo'yicha:dev-values.yaml,prod-values.yaml).helm upgrade/helm rollbackβ Helm har o'rnatishni revizya (versiya) sifatida saqlaydi; xato bo'lsa bir buyruq bilan oldingi ishchi holatga qaytasiz.
π Nega Helm: takroriy YAML'ni bir marta shablonlab, qiymatlar bilan ko'p muhitga sozlash; butun ilovani bir buyruq bilan o'rnatish/yangilash/qaytarish; va tayyor chart'lardan (PostgreSQL, Redis, nginx-ingress) foydalanib, g'ildirakni qaytadan ixtiro qilmaslik.
π‘ Tayyor chart'lar ko'p: helm install my-db bitnami/postgresql bilan butun PostgreSQL'ni (PVC, Service, Secret bilan) bir buyruqda o'rnatasiz. Ko'p mashhur dasturlarning rasmiy Helm chart'i bor.
βΉοΈ Illustrativ: helm install/upgrade real klaster talab qiladi. Quyida (verify qismida) chart fayllari va render natijasi YAML strukturasini offline tekshirdik; {{ }} shablon qatorlari esa Helm tomonidan render qilinishini yodda tuting.
GitOps: Git β haqiqat manbai¶
Hozirgacha biz kubectl apply yoki helm upgrade ni qo'lda terminaldan ishga tushirdik. Bu β push model: odam (yoki CI) klasterga o'zgarishni "itaradi". Muammolari:
- Klasterning haqiqiy holati Git'dagi YAML'dan farq qilishi mumkin (kimdir qo'lda
kubectl editqilgan β Git bilmaydi). - Kim, qachon, nimani o'zgartirgani β tarix
kubectlhistory'da emas, hech qayerda aniq qayd etilmaydi. - Rollback β qo'lda, xatoga moyil.
GitOps boshqacha yondashuv: Git repozitoriysi = klasterning yagona haqiqat manbai. Klaster qanday bo'lishi kerakligi (barcha manifestlar/Helm chart) Git'da yotadi. Klaster ichidagi agent Git'ni doimiy kuzatadi va klasterni Git holatiga avtomatik moslashtiradi.
Push vs Pull deploy¶
- Push (an'anaviy): CI quvuri tashqaridan klasterga
kubectl applyqiladi. CI'da klaster kaliti (kubeconfig) saqlanadi β xavfsizlik xavfi. - Pull (GitOps): klaster ichidagi agent (Argo CD / Flux) Git'ni o'zi tortib oladi (pull) va o'zgarishni qo'llaydi. Klaster kaliti tashqariga chiqmaydi; agar kimdir qo'lda o'zgartirsa, agent uni Git holatiga qaytaradi (self-healing, drift correction).
π GitOps qoidasi: klasterga to'g'ridan-to'g'ri kubectl apply qilmaysiz β o'zgarishni Git'ga commit/PR qilasiz, qolganini agent bajaradi. Deploy = git push. Rollback = git revert. Audit = Git tarixi.
Argo CD va Flux¶
Ikki asosiy GitOps vositasi:
- Argo CD β Git'ni kuzatuvchi agent + qulay veb-UI (qaysi ilova Git bilan sinxron, qaysi biri "drift" qilgan β vizual ko'rinadi). Boshlash uchun qulayroq.
- Flux β yengilroq, UI'siz, CLI/Kubernetes-native; GitOps tamoyillariga qattiq amal qiladi.
Ikkalasi ham bir g'oyani amalga oshiradi: Git holatini klasterga doimiy moslashtirish.
βΉοΈ Illustrativ: Argo CD / Flux o'rnatish va ulardan foydalanish jonli klaster talab qiladi β bu bobda faqat g'oyani kirish darajasida beramiz; amaliy qism o'z klasteringizda.
Managed Kubernetes (qisqa)¶
Hozirgacha lokal minikube/kind haqida gapirdik. Production'da Kubernetes'ni o'zingiz boshqarish (control plane, etcd, yangilashlar, zaxira) β juda mehnat talab va xatarli. Shuning uchun ko'pchilik managed Kubernetes ishlatadi:
- EKS (Amazon), GKE (Google), AKS (Azure) β cloud control plane'ni siz uchun boshqaradi.
Nega self-managed o'rniga managed:
- Control plane sizning tashvishingiz emas: apiserver, etcd, scheduler'ni cloud boshqaradi, yangilaydi, zaxira oladi.
- Tugmani bosib node qo'shish (autoscaling), cloud LoadBalancer/disk/IAM bilan integratsiya tayyor.
- Siz faqat ilovangizga (manifestlar, Helm) e'tibor berasiz, infratuzilmani emas.
π‘ Boshlovchi uchun maslahat: production K8s kerak bo'lsa β boshidan managed (GKE/EKS/AKS) ni tanlang. Self-managed klaster (kubeadm bilan) β o'rganish uchun yaxshi, lekin kichik jamoa uchun kunlik boshqaruvga arzimaydi.
24-bob mashqlari¶
Quyidagi mashqlarning ko'pi YAML manifest yozish va tushunchalarni mustahkamlash haqida β bularni lokalda (
kubectl apply --dry-run=client, yaml parse bilan) mashq qilasiz. Jonli klaster talab qiladiganlar (Ingress Controller, cert-manager, Argo CD,helm install) illustrativ β o'z klasteringizda bajaring.
Oson¶
- Ingress va
LoadBalancerService o'rtasidagi asosiy farqni (qaysi darajada ishlaydi, IP soni, marshrutlash imkoni) ayting. - "Ingress obyektining o'zi hech narsa qilmaydi" β bu nima degani? Qoidalarni kim bajaradi?
- Pod "ephemeral" deganda nima nazarda tutiladi? Bu DB uchun nega muammo?
- PV, PVC va StorageClass β uchalasini bir jumladan ta'riflang (restoran o'xshatishidan foydalaning).
- Helm'da
Chart.yaml,values.yamlvatemplates/papkasi har biri nima uchun? - GitOps'da deploy qilish, rollback qilish va audit (kim nima qildi) qanday bajariladi?
O'rta¶
pathType: PrefixvapathType: Exactfarqini misol bilan tushuntiring.example.uz/adminso'rovi/admin(Prefix) qoidasiga tushadimi?- PVC manifestida
accessModesnima?ReadWriteOncevaReadWriteManyqachon ishlatiladi? - Deployment + PVC bilan StatefulSet o'rtasidagi uchta asosiy farqni ayting. DB klasteri uchun qaysi biri to'g'ri va nega?
helm upgradevahelm rollbackqanday ishlaydi? Helm release versiyalarini qanday saqlaydi?- GitOps'da push va pull deploy farqini ayting. Pull (Argo CD/Flux) nega xavfsizlik jihatdan afzal?
Qiyin¶
shop.example.uzuchun Ingress yozing:/api(Prefix) ->api-svc:8080, qolgan barcha yo'l (/, Prefix) ->web-svc:80.ingressClassName: nginxishlating.
Yechim
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shop-ingress
spec:
ingressClassName: nginx
rules:
- host: shop.example.uz
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
/api /dan oldin yozilgan; nginx-ingress eng uzun mos prefix'ni tanlagani uchun /api/... so'rovlari api-svc'ga, qolgani web-svc'ga ketadi. apiVersion: networking.k8s.io/v1 β Ingress'ning barqaror versiyasi. Bu manifest kubectl apply --dry-run=client dan o'tadi.
redis-pvcnomli PVC yozing: 2 GB,ReadWriteOnce,standardStorageClass. Keyin uniredisDeployment'ida/dataga ulang.
Yechim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: standard
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-pvc
PVC 2Gi disk so'raydi (StorageClass uni avtomatik yaratadi). Deployment volumes.persistentVolumeClaim.claimName orqali PVC'ni ulaydi va volumeMounts.mountPath bilan konteyner ichida /data'ga bog'laydi. Redis o'chsa ham disk saqlanadi.
Chart.yamlvavalues.yaml(replicaCount, image.repository, image.tag) yozing, so'ngreplicasvaimagenivalues.yamldan oladigan minimaltemplates/deployment.yamlshablonini yozing.
Yechim
Chart.yaml:
apiVersion: v2
name: todo
description: Todo API uchun chart
type: application
version: 0.1.0
appVersion: "1.0.0"
values.yaml:
templates/deployment.yaml (shablon β Helm render qiladi):
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-todo
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}-todo
template:
metadata:
labels:
app: {{ .Release.Name }}-todo
spec:
containers:
- name: todo
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
{{ .Values.X }} qiymatlar values.yamldan, {{ .Release.Name }} esa helm install <nom> ... dan keladi. helm install todo ./todo --set replicaCount=5 bilan replika sonini bir muhitda o'zgartirish mumkin. (Shablon qatorlari sof YAML emas β Helm render qilgach kubectl apply qilinadi.)
postgresuchun 2 replikali StatefulSet yozing: headlessserviceName: postgres, har replikaga 10 GBReadWriteOncePVC (volumeClaimTemplates),/var/lib/postgresql/dataga ulangan.
Yechim
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 2
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:17
ports:
- containerPort: 5432
volumeMounts:
- name: pgdata
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: pgdata
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
serviceName headless Service'ga bog'laydi (har Pod barqaror DNS oladi: postgres-0.postgres, postgres-1.postgres). volumeClaimTemplates har replika uchun alohida PVC yaratadi (pgdata-postgres-0, pgdata-postgres-1) β har biriga 10 GB. Pod o'chsa, o'sha nom va disk qaytadi. Bu manifest apps/v1 apiVersion bilan, kubectl apply --dry-run=client dan o'tadi.
- Bir hamkasbingiz "GitOps shunchaki CI'da
kubectl applyyozish" deydi. Bu xato β GitOps (pull) bilan an'anaviy CI push deploy orasidagi farqni va GitOps afzalligini tushuntiring.
Yechim
An'anaviy push: CI quvuri tashqaridan klasterga kubectl apply/helm upgrade qiladi. CI'da klaster kaliti (kubeconfig) saqlanadi (xavf), va klasterning haqiqiy holati Git'dan ajralib ketishi mumkin (kimdir qo'lda o'zgartirsa β hech kim bilmaydi).
GitOps (pull): Git = yagona haqiqat manbai. Klaster ichidagi agent (Argo CD/Flux) Git'ni o'zi kuzatadi va klasterni Git holatiga doimiy moslashtiradi. Afzalliklari: (1) klaster kaliti tashqariga chiqmaydi β agent ichkarida; (2) drift tuzatish/self-healing β qo'lda o'zgarish Git holatiga qaytariladi; (3) deploy = git push, rollback = git revert, audit = Git tarixi (kim/qachon/nima β hammasi commit'larda). Demak GitOps faqat "apply'ni boshqa joyga ko'chirish" emas β boshqaruv modelini Git-markazli qiladi.
- Qachon
LoadBalancerService, qachon Ingress ishlatiladi? Ikkita aniq stsenariy bilan tushuntiring.
Yechim
Ingress β ko'p HTTP(S) ilovani bitta tashqi IP orqali ochganda. Masalan example.uz (frontend), api.example.uz (backend), example.uz/admin (admin) β uchalasi bitta Ingress Controller IP'sida, host/path bo'yicha marshrutlanadi, TLS markazda. Bu β odatiy veb-ilova holati.
LoadBalancer Service β HTTP bo'lmagan yoki maxsus TCP xizmat tashqariga ochilganda. Masalan tashqaridan ulanish kerak bo'lgan PostgreSQL (5432-port, sof TCP) yoki gRPC/maxsus protokol β Ingress (L7 HTTP) bularni marshrutlay olmaydi, shuning uchun LoadBalancer (L4) kerak. Shuningdek Ingress Controller'ning o'zi tashqi IP'ni LoadBalancer Service orqali oladi.
Qoida: HTTP(S) -> Ingress; sof TCP/maxsus protokol yoki bitta xizmatga to'g'ridan-to'g'ri IP -> LoadBalancer.
β¬ οΈ Oldingi: 23 β Production Kubernetes Β· π README Β· Keyingi: 25 β Monitoring: Prometheus va Grafana β‘οΈ