14-bo‘lim

Resurs cheklovlari

Xotira va CPU chegaralari, OOM killer, PID chegarasi va faqat o'qish uchun fayl tizimi.

🕑 12 daqiqa o‘qish 📄 716 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Chegarasiz holat
  2. Xotira chegarasi
  3. CPU chegarasi
  4. Chegara oshsa nima bo'ladi?
  5. Chegara stats da ham ko'rinadi
  6. PID chegarasi
  7. Faqat o'qish uchun fayl tizimi
  8. Compose da
  9. Qaysi qiymatni tanlash?
  10. Xulosa

13-bobda docker stats chegarasiz konteyner uchun butun host xotirasini ko'rsatganini payqadik. Bu shunchaki ko'rsatuv emas - konteyner haqiqatan hammasini olishi mumkin.

Bitta xato ketgan jarayon butun serverni to'xtatib qo'yishi uchun shu yetarli.

Chegarasiz holat #

Konteyner ichidan cgroup fayllariga qaraymiz:

Terminal
docker run --rm alpine:3.21 sh -c \
    'echo "xotira: $(cat /sys/fs/cgroup/memory.max)"
     echo "CPU   : $(cat /sys/fs/cgroup/cpu.max)"'
Natija
xotira: max
CPU   : max 100000

Ikkalasida ham max - ya'ni chegara yo'q.

Xotira chegarasi #

Terminal
docker run --rm -m 128m alpine:3.21 cat /sys/fs/cgroup/memory.max
Natija
134217728

134217728 bayt - aynan 128 MiB. Chegara yadro darajasida o'rnatildi.

CPU chegarasi #

Terminal
docker run --rm --cpus 0.5 alpine:3.21 cat /sys/fs/cgroup/cpu.max
Natija
50000 100000

Ikki son: har 100000 mikrosekundlik davrda 50000 mikrosekund CPU vaqti. Ya'ni yarim yadro.

Bu haqiqatan sekinlashtiradi. Bir xil hisoblash sikli mening kompyuterimda:

ChegaraVaqt
Chegarasiz6.4 soniya
--cpus 0.2526.5 soniya

To'rt barobardan ko'proq - kutilganidek.

Chegarasiz va chegarali konteyner Chegarasiz ilova baza kesh ilova xotirani yeb qo'ysa - hammasi yiqiladi Chegarali ilova 512m / 1.0 CPU baza 1g / 2.0 CPU kesh 256m / 0.5 CPU ilova chegarani oshsa - faqat o'zi o'ladi Chegara - bu jazolash emas, qo'shnilarni himoya qilish.
Chegara xatoni bitta konteyner ichida ushlab qoladi

Chegara oshsa nima bo'ladi? #

32 MiB chegarali konteynerga 200 MiB yozdiramiz:

Terminal
docker run --name oom -m 32m alpine:3.21 \
    sh -c 'dd if=/dev/zero of=/dev/shm/katta bs=1M count=200' >/dev/null 2>&1
echo "chiqish kodi: $(docker inspect oom -f '{{.State.ExitCode}}')"
echo "OOMKilled   : $(docker inspect oom -f '{{.State.OOMKilled}}')"
Natija
chiqish kodi: 137
OOMKilled   : true

137 yana paydo bo'ldi - lekin bu safar sabab boshqa.

137 ning sababiQanday ajratiladi
docker stop SIGKILL yubordiOOMKilled: false
Yadro xotira uchun o'ldirdiOOMKilled: **true**

137 = 128 + 9, ya'ni SIGKILL. Ikkala holatda ham jarayon majburan o'ldirilgan, lekin sabab butunlay boshqa - va OOMKilled maydonisiz ularni farqlab bo'lmaydi.

Konteyner takror qayta ishga tushayotgan bo'lsa

Birinchi tekshiradigan narsangiz - shu:

Natija
docker inspect <konteyner> -f '{{.State.OOMKilled}}'

true bo'lsa, ilova xotira chegarasiga sig'mayapti. Chegarani oshirish yoki ilovadagi xotira sizishini tuzatish kerak.

Jurnalda odatda hech qanday xato bo'lmaydi: jarayon SIGKILL bilan o'ladi va oxirgi so'zini ayta olmaydi.

Chegara stats da ham ko'rinadi #

Terminal
docker run -d --name cheklangan -m 256m --cpus 0.5 \
    alpine:3.21 sleep 120 >/dev/null
docker inspect cheklangan \
    -f 'Xotira : {{.HostConfig.Memory}} bayt
NanoCPU: {{.HostConfig.NanoCpus}}'
Natija
Xotira : 268435456 bayt
NanoCPU: 500000000

Endi docker stats da limit haqiqiy qiymatni ko'rsatadi - 13-bobdagi kabi butun host xotirasini emas.

PID chegarasi #

Fork bombasi yoki nazoratdan chiqqan sikl minglab jarayon yaratishi mumkin:

Terminal
docker run --rm --pids-limit 10 alpine:3.21 sh -c \
    'for i in $(seq 1 30); do sleep 5 & done' 2>&1 | head -1
Natija
sh: can't fork: Resource temporarily unavailable

O'ninchi jarayondan keyin yadro fork ga ruxsat bermadi. Konteyner ichida muammo bor, lekin host butunlay sog'lom.

Faqat o'qish uchun fayl tizimi #

Terminal
docker run --rm --read-only alpine:3.21 sh -c 'touch /yangi' 2>&1 | head -1
Natija
touch: /yangi: Read-only file system

Ilova hech narsa yoza olmaydi. Vaqtinchalik fayl kerak bo'lsa, unga alohida joy beriladi:

Terminal
docker run --rm --read-only --tmpfs /tmp alpine:3.21 \
    sh -c 'touch /tmp/yangi && echo "tmp ga yozildi"'
Natija
tmp ga yozildi
--read-only - arzon va kuchli himoya

Hujumchi kod bajarishga erishsa ham, u:

  • Veb qobiq faylini yoza olmaydi
  • Ikkilik fayllarni almashtira olmaydi
  • Doimiylik uchun skript qoldira olmaydi

Narxi esa deyarli nol - faqat yoziladigan papkalarni aniqlab, ularga tmpfs yoki hajm berish kerak.

15-bobda bu mavzuni davom ettiramiz.

Compose da #

YAML
services:
  ilova:
    image: dokon:1.0
    read_only: true
    tmpfs:
      - /tmp
    pids_limit: 200
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
        reservations:
          memory: 128M

limits - maksimum, reservations esa rejalashtirish uchun minimum.

Qaysi qiymatni tanlash? #

Xizmat turiXotiraCPU
Kichik veb ilova256-512 MB0.5-1.0
Baza (kichik)1-2 GB1.0-2.0
Kesh (Redis)Ma'lumot hajmi + 25%0.25-0.5
Fon ishchisi256-512 MB0.5
Teskari proksi64-128 MB0.25-0.5

Bular boshlang'ich nuqta. To'g'ri yo'l - o'lchash:

  1. Chegarasiz ishga tushiring
  2. Bir necha kun docker stats bilan kuzating
  3. Eng yuqori qiymatga 50% zaxira qo'shib chegara qo'ying
  4. OOM bo'lsa - oshiring, uzoq vaqt bo'sh tursa - kamaytiring
Xotira chegarasi va ilovaning o'z sozlamasi

JVM, Node va PostgreSQL o'z xotira sozlamalariga ega. Konteyner chegarasi ulardan kichik bo'lsa, ilova OOM bilan o'ladi.

Masalan JVM ga -Xmx1g berib, konteynerga -m 512m qo'ysangiz - konteyner albatta o'ladi.

Zamonaviy ish vaqtlari cgroup chegarasini o'zi o'qiydi, lekin buni tekshirib ko'ring: ilova ichida nproc va mavjud xotirani chop etib solishtiring.

Xulosa #

  • Chegarasiz konteyner hostning hamma xotirasi va CPU sini olishi mumkin.
  • Chegara cgroup darajasida o'rnatiladi: /sys/fs/cgroup/memory.max va cpu.max.
  • -m 128mmemory.max 134217728 bayt; --cpus 0.5cpu.max "50000 100000".
  • Xotira chegarasi oshsa, yadro jarayonni SIGKILL bilan o'ldiradi: chiqish kodi 137.
  • Bu docker stop dagi 137 dan OOMKilled: true maydoni bilan ajratiladi - takror qayta ishga tushayotgan konteynerda birinchi navbatda shuni tekshiring.
  • OOM o'limida jurnalda odatda hech qanday xato qolmaydi.
  • --pids-limit fork bombasidan himoya qiladi.
  • --read-only juda arzon va kuchli chora: hujumchi fayl qoldira olmaydi; yoziladigan joy --tmpfs bilan beriladi.
  • Compose da deploy.resources.limits ishlatiladi.
  • Chegarani o'lchab tanlang; ilovaning o'z xotira sozlamasi konteyner chegarasidan kichik bo'lsin.
Amaliy topshiriq
  1. Chegarasiz konteynerda memory.max va cpu.max ni o'qing.
  2. -m 128m bilan qayta o'qib, farqni ko'ring.
  3. --cpus 0.25 bilan hisoblash siklini ishga tushirib, vaqtni o'lchang.
  4. Chegaradan ko'p xotira so'rab, OOM ni keltirib chiqaring.
  5. OOMKilled maydonini tekshiring.
  6. --pids-limit 10 bilan ko'p jarayon ochib ko'ring.
  7. --read-only bilan yozishga urinib, xatoni o'qing.
  8. --tmpfs /tmp qo'shib, muammoni hal qiling.
  9. Compose da resurs chegaralarini yozing.
  10. O'z ilovangizni bir kun kuzatib, mos chegarani hisoblang.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.