IlmHamroh
Python kursi/Infratuzilma4/14-dars19 daqiqa
Mundarija (22)

28.4-dars: Konteyner optimizatsiyasi

28-QISM — INFRATUZILMA · 4-dars


1. Kirish va motivatsiya

Ishlaydigan konteyner — boshlanish; yaxshi konteyner — maqsad. Optimallashtirilmagan image ulkan bo'ladi (1-2 GB), sekin quriladi, sekin yuklanadi (deploy uzoq), ko'p disk egallaydi va xavfsizlik teshiklari ko'p (keraksiz paketlar). Har deploy sekinlashadi, registry to'ladi, xavfsizlik zaiflashadi. Konteyner optimizatsiyasi — imageni kichik, tez va xavfsiz qilish san'ati: yengil asoslar, multi-stage build, qatlamlarni samarali ishlatish, keraksiz narsalarni olib tashlash. Kichik image — tez deploy, kam xarajat, xavfsizroq.

Konteyner optimizatsiyasi — image hajmini kamaytirish va samaradorlikni oshirish usullari: yengil asosiy image (slim, alpine — to'liq OS emas), multi-stage build (qurish va ishga tushirishni ajratish — build vositalari yakuniy imageda yo'q), qatlam optimizatsiyasi (kam qatlam, RUN birlashtirish, kesh), keraksizni olib tashlash (.dockerignore, pip keshi, dev bog'liqliklar), xavfsizlik (root emas, kam paket). Kichik image afzalliklari: tez build/pull/deploy, kam disk/registry, kam hujum yuzasi (xavfsizlik). Bu Dockerfile 28.2-bob ni professional darajaga ko'taradi. Optimizatsiya — kichik, tez, xavfsiz image.

Real vaziyat. Bir loyihada image 1.8 GB edi: to'liq Ubuntu asos, build vositalari (gcc, make), test kutubxonalari, pip keshi — hammasi yakuniy imageda qoldi. Deploy har safar 3 daqiqa (image pull). Optimizatsiya: python:3.14-slim asos, multi-stage build (build vositalar faqat qurish bosqichida, yakuniyda yo'q), --no-cache-dir, .dockerignore. Image 150 MB bo'ldi (12x kichik). Deploy 15 soniyaga tushdi. Optimizatsiya — deploy tezligi va xarajat.

Bu darsda konteyner optimizatsiyasini o'rganamiz.

Bu darsda:

  • Nega optimizatsiya kerak
  • Yengil asosiy image
  • Multi-stage build
  • Qatlam optimizatsiyasi
  • Keraksizni olib tashlash
  • Xavfsizlik optimizatsiyasi
  • Image hajmini o'lchash
  • Amaliy: optimizatsiya modeli

ℹ Optimizatsiya OS vositasi; misollar Python bilan hajm/qatlam mantiqini modellashtiradi (deterministik).


2. Nazariya — chuqur tushuntirish

2.1. Nega optimizatsiya kerak

Kichik image — ko'p afzallik:

Katta image (1.5 GB):
   sekin build, sekin pull (deploy), ko'p disk
   ko'p paket → ko'p xavfsizlik teshigi

Kichik image (150 MB):
   tez build/deploy, kam disk, xavfsizroq

Nega optimizatsiya — kichik image ko'p afzallik beradi: tez build (kam narsa quriladi), tez pull/deploy (kam yuklanadi — har deploy tezroq), kam disk/registry (xarajat), xavfsizlik (kam paket — kam hujum yuzasi, kam zaiflik), tez ishga tushish. Katta image — sekin deploy (har safar GB yuklash), ko'p xarajat, ko'p xavfsizlik teshigi (keraksiz paketlar). Optimizatsiya — nafaqat estetika, balki tezlik, xarajat, xavfsizlik. Kichik image — professional deploy. Hajm — tezlik va xavfsizlik.

2.2. Yengil asosiy image

To'liq OS emas:

dockerfile
FROM ubuntu           # ~70 MB + Python o'rnatish (og'ir)
FROM python:3.14      # ~350 MB (to'liq)
FROM python:3.14-slim # ~50 MB (minimal — tavsiya)
FROM python:3.14-alpine # ~20 MB (eng kichik, lekin ehtiyot)

Yengil asosiy image — asosiy imageni tanlash hajmga katta ta'sir qiladi: to'liq (python:3.14 — ~350 MB, ko'p vosita), slim (python:3.14-slim — ~50 MB, minimal Debian, tavsiya etiladi), alpine (python:3.14-alpine — ~20 MB, eng kichik, lekin musl libc — ba'zi paketlar muammo, sekin build). Sabab: asos hajmi butun imagega qo'shiladi (asos katta — image katta). Slim — yaxshi muvozanat (kichik, mos). Alpine — eng kichik, lekin ehtiyot (moslik muammolari). To'liq OS (ubuntu) — ko'pincha ortiqcha. Yengil asos — kichik imagening birinchi qadami. Asos — hajmning poydevori.

2.3. Multi-stage build

Qurish va ishga tushirishni ajratish:

dockerfile
# 1-BOSQICH: qurish (build vositalari bilan)
FROM python:3.14 AS builder
RUN pip install --user -r requirements.txt

# 2-BOSQICH: ishga tushirish (faqat kerakli)
FROM python:3.14-slim
COPY --from=builder /root/.local /root/.local   # faqat natija
COPY . .
CMD ["python", "app.py"]
# build vositalar yakuniy imageda YO'Q (kichik)

Multi-stage build — Dockerfile'ni bir necha bosqich ga bo'lish, faqat kerakli natijani yakuniy imagega ko'chirish: build bosqichi (to'liq image + build vositalari — gcc, kutubxonalarni kompilyatsiya), ishga tushirish bosqichi (yengil image + faqat qurilgan natija — COPY --from=builder). Sabab: build vositalari (kompilyator, dev kutubxonalar) faqat qurish uchun kerak, ishga tushirishda emas — ularni yakuniy imagega qo'shmaslik (kichik). Bu ayniqsa kompilyatsiya kerak tillar/paketlar uchun muhim. Multi-stage — qurish axlatini tashlab, faqat natija. Ajratish — kichik yakuniy image.

2.4. Qatlam optimizatsiyasi

Kam qatlam, samarali kesh:

dockerfile
# YOMON: ko'p qatlam, kesh qoladi
RUN apt update
RUN apt install -y gcc
RUN pip install -r req.txt

# YAXSHI: birlashtirilgan, tozalangan
RUN apt update && apt install -y gcc \
    && pip install --no-cache-dir -r req.txt \
    && apt remove -y gcc && rm -rf /var/lib/apt/lists/*

Qatlam optimizatsiyasi: RUN birlashtirish (&& bilan — kam qatlam, ora natijalar bir qatlamda tozalanadi), kesh tozalash (--no-cache-dir pip, rm -rf /var/lib/apt/lists/* apt — kesh imageda qolmaydi), tartib (28.2 — kam o'zgaradiganlar avval). Muhim: har qatlam qo'shadi (o'chirish keyingi qatlamda — oldingisi qoladi!) — masalan bir qatlamda fayl qo'shib, keyingisida o'chirsangiz, fayl baribir imageda (qatlam tarixida). Shuning uchun qo'shish va tozalash bir qatlamda (&&). Qatlam optimizatsiyasi — imageni ixcham qilish. Bir qatlamda qo'sh va tozala.

2.5. Keraksizni olib tashlash

Keraksizni olib tashlash: .dockerignore (28.2 — .git, __pycache__, .env, test fayllar — imagega kirmaydi); pip/apt keshi (--no-cache-dir, rm -rf — o'rnatish keshi keraksiz); dev bog'liqliklar (test, linter kutubxonalari — ishga tushirishda kerak emas, faqat requirements.txt prod); hujjatlar, misollar (paketlar bilan kelgan keraksiz fayllar); build vositalari (multi-stage bilan). Sabab: har keraksiz narsa — hajm (sekin, xavfsizlik). Prinsip: yakuniy imageda faqat ishga tushirish uchun kerakli narsa (kod + prod kutubxonalar). Keraksizni olib tashlash — minimal image. Faqat kerakli — kichik va xavfsiz.

2.6. Xavfsizlik optimizatsiyasi

Kam paket, root emas:

dockerfile
# root emas (xavfsizlik)
RUN useradd -m appuser
USER appuser

# aniq versiyalar (latest emas)
FROM python:3.14.1-slim

# minimal paket (kam hujum yuzasi)
# skanerlar: docker scout, trivy (zaifliklarni topish)

Xavfsizlik optimizatsiyasi: root emas (USER appuser — konteyner root sifatida ishlasa, buzilganda host xavf ostida); kam paket (har paket — potensial zaiflik; minimal image — kam hujum yuzasi); aniq versiyalar (python:3.14.1-slim — latest emas, bashoratli, ma'lum zaifliklar); zaiflik skanerlash (docker scout, trivy — imageda ma'lum zaifliklarni topish); sirlarsiz (28.2 — imageda parol yo'q); minimal ruxsatlar. Kichik image — tabiiy xavfsizroq (kam narsa buzilishi mumkin). Xavfsizlik va hajm bog'liq (kam paket — kichik va xavfsiz). Xavfsizlik — optimizatsiyaning bir qismi. Kam narsa — kam xavf.

2.7. Image hajmini o'lchash

bash
docker images                    # image hajmlari
docker history myapp:v1          # qatlamlar hajmi (nima og'ir?)
docker image inspect myapp:v1    # tafsilotlar
# dive vositasi — qatlamlarni chuqur tahlil

Image hajmini o'lchash — optimizatsiyani boshlash o'lchashdan (nima og'ir?): docker images (image umumiy hajmi), docker history (har qatlam hajmi — qaysi buyruq og'ir?), dive (vosita — qatlamlarni chuqur tahlil, isrofni topish). Sabab: optimizatsiya ma'lumotga asoslanishi kerak (taxmin emas — nima aslida og'ir?); o'lchamasdan optimallashtirish — ko'r-ko'rona. Odatiy og'ir joylar: asosiy image, o'rnatilgan paketlar, kesh, keraksiz fayllar. Avval o'lcha, keyin optimallashtir (29-qism — profiling bilan bir prinsip). O'lchash — optimizatsiyaning boshi. Ma'lumot — to'g'ri optimizatsiya.

2.8. Optimizatsiya — muvozanat va prinsip

Konteyner optimizatsiyasi muvozanat: eng kichik image doim eng yaxshi emas (alpine — kichik, lekin moslik muammosi, sekin build; slim — biroz kattaroq, lekin muammosiz). Prinsip: yetarlicha kichik (ortiqcha optimizatsiyaga vaqt sarflmasdan) — slim asos + multi-stage + .dockerignore ko'pincha yetarli (80/20 — kam ish, katta natija). Ehtiyot: haddan optimizatsiya (har baytni qisqartirish) — vaqt isrofi (KISS — 27.1). O'lcha (nima og'ir), asosiylarini tuzat (asos, multi-stage), to'xta (yetarli). Bu Dockerfile 28.2-bob, deploy 28.8-bob bilan bog'liq. Optimizatsiya — amaliy muvozanat (kichik, lekin ortiqcha emas). Yetarlicha kichik — professional.


3. Tez ma'lumotnoma

dockerfile
# 1. YENGIL ASOS
FROM python:3.14-slim         # slim (tavsiya), alpine (ehtiyot)

# 2. MULTI-STAGE (build vositalar yakuniyda yo'q)
FROM python:3.14 AS builder
RUN pip install --user -r requirements.txt
FROM python:3.14-slim
COPY --from=builder /root/.local /root/.local

# 3. QATLAM (birlashtir, tozala)
RUN apt update && apt install -y gcc \
    && pip install --no-cache-dir -r req.txt \
    && rm -rf /var/lib/apt/lists/*

# 4. XAVFSIZLIK
RUN useradd -m appuser
USER appuser                  # root emas

# 5. KERAKSIZNI OLIB TASHLA
# .dockerignore (.git, __pycache__, .env, testlar)
# --no-cache-dir (pip), rm -rf (apt kesh)

# O'LCHASH:
# docker images | docker history myapp | dive

Konteyner optimizatsiyasi xulosasi

Yengil asos (slim/alpine) · multi-stage (build alohida)
Qatlam (RUN birlashtir, kesh tozala — bir qatlamda)
Keraksizni olib tashla (.dockerignore, --no-cache-dir)
Xavfsizlik (root emas, kam paket, aniq versiya)
O'lcha (docker history, dive) → tuzat → yetarli (muvozanat)

4. Batafsil misollar

Optimizatsiya OS vositasi; misollar Python bilan hajm/qatlam mantiqini modellashtiradi.

Misol 1 — Asosiy image tanlovi (hajm)

python
"""Asosiy image hajmi: tanlov butun image hajmiga ta'sir qiladi."""


ASOSLAR = {
    "ubuntu": 70,
    "python:3.14": 350,
    "python:3.14-slim": 50,
    "python:3.14-alpine": 20,
}


def image_hajmi(asos: str, kod_mb: int, kutubxona_mb: int) -> int:
    return ASOSLAR[asos] + kod_mb + kutubxona_mb


def main() -> None:
    kod = 5
    kutubxona = 80

    print("=== 1. Asos hajmlari ===")
    for asos, hajm in ASOSLAR.items():
        print(f"  {asos}: {hajm} MB")

    print("\n=== 2. To'liq image (python:3.14) ===")
    toliq = image_hajmi("python:3.14", kod, kutubxona)
    print(f"  jami: {toliq} MB")

    print("\n=== 3. Slim image ===")
    slim = image_hajmi("python:3.14-slim", kod, kutubxona)
    print(f"  jami: {slim} MB")

    print("\n=== 4. Taqqoslash ===")
    print(f"  to'liq: {toliq} MB, slim: {slim} MB")
    print(f"  tejaladi: {toliq - slim} MB")
    print("  asos tanlovi — hajmning poydevori")
    print("  ⭐ Yengil asos — kichik image")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Asos hajmlari ===
  ubuntu: 70 MB
  python:3.14: 350 MB
  python:3.14-slim: 50 MB
  python:3.14-alpine: 20 MB

=== 2. To'liq image (python:3.14) ===
  jami: 435 MB

=== 3. Slim image ===
  jami: 135 MB

=== 4. Taqqoslash ===
  to'liq: 435 MB, slim: 135 MB
  tejaladi: 300 MB
  asos tanlovi — hajmning poydevori
  ⭐ Yengil asos — kichik image

Nima ko'rsatdi: 2.2-bo'lim.

Misol 2 — Multi-stage build (build vositalarni chiqarish)

python
"""Multi-stage: build vositalar faqat qurish bosqichida (yakuniyda yo'q)."""


def bir_bosqich(asos: int, build_vositalar: int, kod: int, kutubxona: int) -> int:
    # hammasi bir imageda (build vositalar ham qoladi)
    return asos + build_vositalar + kod + kutubxona


def multi_stage(asos: int, build_vositalar: int, kod: int, kutubxona: int) -> dict:
    # build bosqichi: hammasi
    build_bosqich = asos + build_vositalar + kutubxona
    # yakuniy: faqat yengil asos + natija (build vositalar YO'Q)
    yakuniy = 50 + kod + kutubxona   # slim asos
    return {"build_bosqich": build_bosqich, "yakuniy": yakuniy}


def main() -> None:
    asos, build_vositalar, kod, kutubxona = 350, 200, 5, 80

    print("=== 1. Bir bosqich (build vositalar qoladi) ===")
    bir = bir_bosqich(asos, build_vositalar, kod, kutubxona)
    print(f"  yakuniy image: {bir} MB")
    print("  gcc, make, dev kutubxonalar — hammasi qoldi")

    print("\n=== 2. Multi-stage ===")
    multi = multi_stage(asos, build_vositalar, kod, kutubxona)
    print(f"  build bosqichi: {multi['build_bosqich']} MB (vaqtinchalik)")
    print(f"  yakuniy image: {multi['yakuniy']} MB")

    print("\n=== 3. Taqqoslash ===")
    print(f"  bir bosqich: {bir} MB, multi-stage: {multi['yakuniy']} MB")
    print(f"  tejaladi: {bir - multi['yakuniy']} MB")

    print("\n=== 4. Sabab ===")
    print("  build vositalar faqat qurishda (COPY --from)")
    print("  yakuniyda faqat kod + kutubxona")
    print("  ⭐ Multi-stage — build axlatini tashlash")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Bir bosqich (build vositalar qoladi) ===
  yakuniy image: 635 MB
  gcc, make, dev kutubxonalar — hammasi qoldi

=== 2. Multi-stage ===
  build bosqichi: 630 MB (vaqtinchalik)
  yakuniy image: 135 MB

=== 3. Taqqoslash ===
  bir bosqich: 635 MB, multi-stage: 135 MB
  tejaladi: 500 MB

=== 4. Sabab ===
  build vositalar faqat qurishda (COPY --from)
  yakuniyda faqat kod + kutubxona
  ⭐ Multi-stage — build axlatini tashlash

Nima ko'rsatdi: 2.3-bo'lim.

Misol 3 — Qatlam optimizatsiyasi (birlashtirish)

python
"""Qatlam: qo'shish va o'chirish alohida qatlamda — fayl qoladi (birlashtir)."""


def alohida_qatlamlar() -> dict:
    # qatlam 1: 100 MB qo'shildi
    # qatlam 2: o'chirildi (lekin qatlam 1 tarixida qoladi!)
    return {"qatlamlar": [100, -100], "haqiqiy_hajm": 100}   # o'chirish qatlamni kamaytirmaydi


def bir_qatlam() -> dict:
    # qo'shish va o'chirish bir qatlamda (natija qoladi)
    return {"qatlamlar": [0], "haqiqiy_hajm": 0}   # ora natija tozalandi


def main() -> None:
    print("=== 1. Alohida qatlamlar (RUN add; RUN remove) ===")
    alohida = alohida_qatlamlar()
    print(f"  qatlamlar: {alohida['qatlamlar']}")
    print(f"  haqiqiy hajm: {alohida['haqiqiy_hajm']} MB")
    print("  o'chirish keyingi qatlamda — fayl tarixda qoladi!")

    print("\n=== 2. Bir qatlam (RUN add && remove) ===")
    bir = bir_qatlam()
    print(f"  haqiqiy hajm: {bir['haqiqiy_hajm']} MB")
    print("  qo'shish va o'chirish bir qatlamda (tozalandi)")

    print("\n=== 3. Taqqoslash ===")
    print(f"  alohida: {alohida['haqiqiy_hajm']} MB, bir: {bir['haqiqiy_hajm']} MB")

    print("\n=== 4. Qoida ===")
    print("  har qatlam qo'shadi (o'chirish oldingini kamaytirmaydi)")
    print("  qo'shish + tozalash BIR qatlamda (&&)")
    print("  ⭐ Qatlam optimizatsiyasi — birlashtirish")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Alohida qatlamlar (RUN add; RUN remove) ===
  qatlamlar: [100, -100]
  haqiqiy hajm: 100 MB
  o'chirish keyingi qatlamda — fayl tarixda qoladi!

=== 2. Bir qatlam (RUN add && remove) ===
  haqiqiy hajm: 0 MB
  qo'shish va o'chirish bir qatlamda (tozalandi)

=== 3. Taqqoslash ===
  alohida: 100 MB, bir: 0 MB

=== 4. Qoida ===
  har qatlam qo'shadi (o'chirish oldingini kamaytirmaydi)
  qo'shish + tozalash BIR qatlamda (&&)
  ⭐ Qatlam optimizatsiyasi — birlashtirish

Nima ko'rsatdi: 2.4-bo'lim.

Misol 4 — Image tahlili (nima og'ir?)

python
"""Image tahlili: qatlamlarni o'lchab, og'ir joyni topish (o'lcha → tuzat)."""


def image_tahlil(qatlamlar: list) -> dict:
    jami = sum(q["hajm"] for q in qatlamlar)
    eng_ogir = max(qatlamlar, key=lambda q: q["hajm"])
    return {"jami": jami, "eng_ogir": eng_ogir, "soni": len(qatlamlar)}


def main() -> None:
    qatlamlar = [
        {"buyruq": "FROM python:3.14", "hajm": 350},
        {"buyruq": "COPY requirements", "hajm": 1},
        {"buyruq": "RUN pip install", "hajm": 120},
        {"buyruq": "COPY . .", "hajm": 5},
        {"buyruq": "RUN apt install gcc", "hajm": 200},
    ]

    tahlil = image_tahlil(qatlamlar)

    print("=== 1. Qatlamlar hajmi ===")
    for q in qatlamlar:
        print(f"  {q['buyruq']}: {q['hajm']} MB")

    print("\n=== 2. Umumiy hajm ===")
    print(f"  jami: {tahlil['jami']} MB ({tahlil['soni']} qatlam)")

    print("\n=== 3. Eng og'ir qatlam ===")
    eng = tahlil["eng_ogir"]
    print(f"  {eng['buyruq']}: {eng['hajm']} MB")
    print("  → bu yerdan boshlash (asos: slim, gcc: multi-stage)")

    print("\n=== 4. Optimizatsiya rejasi ===")
    print("  asos (350) → slim (50): -300 MB")
    print("  gcc (200) → multi-stage: -200 MB")
    print("  o'lcha → eng og'irni tuzat")
    print("  ⭐ Image tahlili — o'lcha, keyin optimallashtir")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Qatlamlar hajmi ===
  FROM python:3.14: 350 MB
  COPY requirements: 1 MB
  RUN pip install: 120 MB
  COPY . .: 5 MB
  RUN apt install gcc: 200 MB

=== 2. Umumiy hajm ===
  jami: 676 MB (5 qatlam)

=== 3. Eng og'ir qatlam ===
  FROM python:3.14: 350 MB
  → bu yerdan boshlash (asos: slim, gcc: multi-stage)

=== 4. Optimizatsiya rejasi ===
  asos (350) → slim (50): -300 MB
  gcc (200) → multi-stage: -200 MB
  o'lcha → eng og'irni tuzat
  ⭐ Image tahlili — o'lcha, keyin optimallashtir

Nima ko'rsatdi: 2.7-bo'lim.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"Ishlaydi — yetarli" Kichik, tez, xavfsiz ham
"To'liq OS asos" Yengil (slim, alpine)
"Build vositalar yakuniyda" Multi-stage (ajrat)
"O'chirish hajmni kamaytiradi" Bir qatlamda (o'chirish yangi qatlam)
"Alpine doim yaxshi" Muvozanat (moslik)
"root normal" root emas (xavfsizlik)
"Taxmin bilan optimallashtir" O'lcha (docker history)
"Har baytni qisqartir" Yetarlicha kichik (KISS)

6. Keng tarqalgan xatolar va yechimlari

1. Og'ir asosiy image

dockerfile
FROM python:3.14              # 350 MB               # ⚠️
FROM python:3.14-slim         # 50 MB                 # ✅

2. Build vositalar yakuniy imageda

dockerfile
RUN apt install gcc; pip install; # gcc qoladi        # ⚠️
# multi-stage (build alohida bosqich)                  # ✅

3. Kesh saqlash

dockerfile
RUN pip install -r req.txt    # kesh qoladi           # ⚠️
RUN pip install --no-cache-dir -r req.txt             # ✅

4. Qo'shish va o'chirish alohida qatlam

dockerfile
RUN wget katta.zip
RUN unzip; rm katta.zip   # zip qatlamda qoladi        # ⚠️
RUN wget katta.zip && unzip && rm katta.zip           # ✅

5. root sifatida

dockerfile
CMD ["python", "app.py"]      # root                   # ⚠️
USER appuser; CMD [...]                                 # ✅

6. O'lchamasdan optimallashtirish

dockerfile
# taxmin bilan har narsani qisqartirish               # ⚠️
docker history myapp   # o'lcha, eng og'irni tuzat     # ✅

7. Haddan optimizatsiya (vaqt isrofi)

dockerfile
# 150 MB ni 145 MB ga tushirishga soatlar             # ⚠️
# yetarlicha kichik (asosiylarini tuzat)               # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 28.2-dars (o'tilgan): Dockerfile — qatlamlar
  • 28.7-8-dars: CI/CD — build tezligi, deploy
  • 28.13-dars: Cloud — registry xarajat
  • 29-qism: Unumdorlik — o'lchash, optimallashtirish
  • 27.1-dars (o'tilgan): Toza kod — muvozanat (KISS)

8. Eng yaxshi amaliyotlar

  1. Yengil asos (slim — muvozanat).

  2. Multi-stage (build vositalar ajrat).

  3. RUN birlashtir + kesh tozala (bir qatlamda).

  4. .dockerignore (keraksiz/sir).

  5. root emas (USER).

  6. Aniq versiya (latest emas).

  7. O'lcha (docker history, dive) → tuzat.

  8. Yetarlicha kichik (haddan emas — KISS).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # nega optimizatsiya kerak?
2.  # katta image kamchiligi?
3.  # slim nima?
4.  # alpine nima (ehtiyot)?
5.  # multi-stage nima?
6.  # multi-stage nega kichik?
7.  # RUN birlashtirish nega?
8.  # o'chirish hajmni kamaytiradimi?
9.  # --no-cache-dir nima?
10. # root emas nega?
11. # docker history nima?
12. # optimizatsiya muvozanati?
Javoblar
  1. Tez deploy, kam xarajat, xavfsizlik
  2. Sekin build/deploy, ko'p disk, xavfsizlik teshigi
  3. Minimal asosiy image (~50 MB)
  4. Eng kichik (~20 MB), lekin moslik muammosi
  5. Qurish va ishga tushirishni ajratish
  6. Build vositalar yakuniyda yo'q
  7. Kam qatlam, ora natija tozalanadi
  8. Yo'q (o'chirish yangi qatlam, oldingi qoladi)
  9. pip keshini saqlamaslik
  10. Xavfsizlik (buzilganda host xavfsiz)
  11. Qatlamlar hajmini ko'rsatadi
  12. Yetarlicha kichik (haddan emas)

Vazifa 2: Xatolarni tuzating

dockerfile
1.  FROM python:3.14           # og'ir

2.  RUN apt install gcc        # multi-stage

3.  RUN pip install -r req     # kesh

4.  RUN wget zip; RUN rm zip   # bir qatlam

5.  CMD [...]  # root
Javoblar
dockerfile
1.  FROM python:3.14-slim

2.  multi-stage (build alohida)

3.  RUN pip install --no-cache-dir -r req

4.  RUN wget zip && ... && rm zip

5.  USER appuser; CMD [...]

Vazifa 3: Asos

Taqqoslang:

  1. To'liq
  2. Slim
  3. Alpine
  4. Hajm

Vazifa 4: Multi-stage

Modellang:

  1. Build bosqich
  2. Ishga tushirish bosqich
  3. COPY --from
  4. Hajm

Vazifa 5: Qatlam

Modellang:

  1. Alohida
  2. Birlashgan
  3. O'chirish
  4. Hajm

Vazifa 6: Tahlil

Modellang:

  1. Qatlamlar
  2. Eng og'ir
  3. Reja
  4. Tuzatish

Vazifa 7: O'ylash

Konteyner optimizatsiyasida "o'lcha, keyin optimallashtir" prinsipi va "yetarlicha kichik" muvozanati — 29-qism (unumdorlik) bilan bir xil tamoyillar. Nima uchun "avval o'lcha" (taxmin qilmaslik) optimizatsiyaning universal qoidasi, va nega "haddan optimizatsiya" (har baytni qisqartirish) toza kod (KISS) ni buzadi — optimizatsiya qachon foydali, qachon zararli?

Javob

Qisqa javob: "Avval o'lcha" universal qoida, chunki: intuitsiya ko'pincha noto'g'ri (nima og'ir/sekin ekanini taxmin qilish adashtiradi — dasturchi bir joyni optimallashtiradi, lekin haqiqiy muammo boshqa joyda); o'lchash haqiqatni ko'rsatadi (docker history — qaysi qatlam og'ir; profiling — qaysi funksiya sekin). Optimallashtirishga vaqt ketadi — o'lchamasdan optimallashtirish bu vaqtni noto'g'ri joyga sarflaydi (kichik ta'sir uchun katta ish). "O'lcha → eng katta ta'sirni topib, uni tuzat" — samarali (80/20: 20% ish, 80% natija). Bu Donald Knuth ning mashhur gapiga bog'liq: "erta optimizatsiya — barcha yomonlikning ildizi" (o'lchamasdan, kerak bo'lmasdan optimallashtirish). "Haddan optimizatsiya" KISS ni buzadi, chunki: optimizatsiya odatda murakkablik qo'shadi (multi-stage — ko'proq Dockerfile, aqlli qatlam hiyla-nayranglari — o'qish qiyin); agar bu murakkablik kichik foyda uchun bo'lsa (150 MB → 145 MB), savdo yomon (ko'p murakkablik, kam natija); toza kod (soddalik) qadrliroq. Optimizatsiya foydali qachonki: o'lchangan muammo bor (aniqlangan — asos 350 MB), ta'sir katta (deploy sekin), yechim sodda (slim asos); zararli qachonki: muammo yo'q (yetarlicha yaxshi), ta'sir kichik (bir necha MB), yechim murakkab (o'qish/saqlash qiyinlashadi). Qoida: o'lcha (muammo bormi, qayerda?), muhimlarini tuzat (katta ta'sir), to'xta (yetarlicha yaxshi — ortiqcha sayqallashtirmaslik). Muhandislik saboqlari: intuitsiya adashtiradi — o'lcha (ma'lumot); optimizatsiya vaqt/murakkablik oladi — faqat kerak bo'lganda; "yetarlicha yaxshi" real maqsad (mukammal emas — 27.12 bilan bog'liq); erta/haddan optimizatsiya — KISS dushmani (soddalik qadrliroq).

1. Nega "avval o'lcha"

Intuitsiya noto'g'ri (taxmin adashtiradi). O'lchash haqiqatni ko'rsatadi (nima og'ir/sekin). Vaqtni to'g'ri joyga.

2. 80/20 prinsipi

O'lcha → eng katta ta'sirni tuzat (20% ish, 80% natija). Erta optimizatsiya — yomonlik ildizi (Knuth).

3. Nega haddan optimizatsiya KISS buzadi

Optimizatsiya Savdo
Katta muammo, sodda yechim Yaxshi (foydali)
Kichik foyda, murakkab yechim Yomon (KISS buziladi)

4. Qachon foydali/zararli

Foydali: o'lchangan muammo, katta ta'sir, sodda yechim. Zararli: muammo yo'q, kichik ta'sir, murakkab yechim.

5. Muhandislik saboqlari

  1. Intuitsiya adashtiradi — o'lcha
  2. Optimizatsiya vaqt/murakkablik oladi
  3. "Yetarlicha yaxshi" real maqsad
  4. Erta/haddan optimizatsiya — KISS dushmani

6. Xulosa

  1. Avval o'lcha (intuitsiya noto'g'ri)
  2. Eng katta ta'sirni tuzat (80/20)
  3. Haddan optimizatsiya — murakkablik (KISS)
  4. O'lcha → muhimini tuzat → to'xta

Nimani mustahkamlaydi: 2.7, 2.8-bo'limlar.


Xulosa

Bu darsda konteyner optimizatsiyasini o'rgandik.

Eng muhim uch fikr:

  1. Nega optimizatsiya va yengil asos. Optimizatsiya kerak, chunki kichik image ko'p afzallik beradi: tez build/pull/deploy (kam yuklanadi), kam disk/registry (xarajat), xavfsizlik (kam paket — kam hujum yuzasi). Yengil asosiy image — asos tanlovi hajmga katta ta'sir qiladi: to'liq (python:3.14 — 350 MB), slim (python:3.14-slim — ~50 MB, tavsiya, muvozanat), alpine (20 MB, eng kichik, lekin musl moslik muammosi — ehtiyot). Asos hajmi butun imagega qo'shiladi — yengil asos kichik imagening birinchi qadami.

  2. Multi-stage va qatlam optimizatsiyasi. Multi-stage build — Dockerfile'ni bosqichlarga bo'lish: build bosqichi (to'liq image + build vositalari — gcc, kompilyatsiya), ishga tushirish bosqichi (yengil image + faqat natija — COPY --from=builder); build vositalari yakuniy imageda yo'q (kichik). Qatlam optimizatsiyasi: RUN birlashtirish (&& — kam qatlam), kesh tozalash (--no-cache-dir, rm -rf) — muhim: har qatlam qo'shadi (o'chirish keyingi qatlamda — oldingisi qoladi!), shuning uchun qo'shish va tozalash bir qatlamda.

  3. Keraksiz, xavfsizlik, muvozanat. Keraksizni olib tashlash: .dockerignore (.git, .env, testlar), pip/apt keshi, dev bog'liqliklar — yakuniy imageda faqat ishga tushirish uchun kerakli. Xavfsizlik: root emas (USER), kam paket (kam zaiflik), aniq versiya (latest emas), zaiflik skanerlash (trivy, docker scout). O'lchash — optimizatsiyani o'lchashdan boshlash (docker history, dive — nima og'ir?), taxmin emas. Optimizatsiya muvozanat: "yetarlicha kichik" (slim + multi-stage + .dockerignore ko'pincha yetarli — 80/20), haddan optimizatsiya (har baytni qisqartirish) — vaqt isrofi (KISS). "Avval o'lcha, keyin optimallashtir" — universal qoida (29-qism, profiling bilan bir prinsip); optimizatsiya foydali qachonki muammo o'lchangan, ta'sir katta, yechim sodda.

Keyingi darsda Kubernetes tushunchasini o'rganamiz: ko'p konteynerni ko'p mashinada avtomatik boshqarish — pod, deployment, service tushunchalari va konteyner orkestratsiyasi nima uchun kerakligi.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!