18-bo‘lim

Ishlab chiqarishga tayyorlash

Teskari proksi, qat'iylashtirilgan xizmat, restart siyosati qachon ishlamasligi va yangilashda uzilishni kamaytirish.

🕑 13 daqiqa o‘qish 📄 803 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. To'liq sozlama
  2. Teskari proksi
  3. Sozlamalar haqiqatan amaldami?
  4. Yangilash
  5. restart siyosati - va u qachon ishlamasligi
  6. Ishga tushirishdan oldingi ro'yxat
  7. Xulosa

Oldingi o'n yetti bobdagi qoidalarni bitta to'plamga yig'amiz va har birini tekshiramiz.

To'liq sozlama #

YAML
name: ishlab

services:
  proksi:
    image: nginx:alpine
    ports:
      - "8099:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      ilova:
        condition: service_healthy
    restart: unless-stopped
    logging:
      driver: json-file
      options: { max-size: "10m", max-file: "3" }

  ilova:
    image: nginx:alpine
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://127.0.0.1/"]
      interval: 2s
      timeout: 3s
      retries: 10
      start_period: 3s
    restart: unless-stopped
    read_only: true
    tmpfs:
      - /tmp
      - /var/cache/nginx
      - /var/run
    cap_drop: [ALL]
    cap_add: [CHOWN, SETGID, SETUID, NET_BIND_SERVICE, DAC_OVERRIDE]
    security_opt:
      - no-new-privileges:true
    deploy:
      resources:
        limits: { cpus: "0.5", memory: 128M, pids: 100 }

Har bir qator oldingi boblardan keladi:

SozlamaQaysi bobdan
healthcheck + condition12
logging.options13
limits (cpus, memory, pids)14
read_only, cap_drop, no-new-privileges15
:ro bilan sozlama ulash8
restart12
Terminal
docker compose ps --format '{{.Service}} {{.State}}' | sort
Natija
ilova running
proksi running
Compose v5 da pids_limit va deploy birga ishlamaydi

Avval men shunday yozgan edim:

Natija
pids_limit: 100
deploy:
  resources:
    limits: { cpus: "0.5", memory: 128M }

Natija - xato:

Natija
services.ilova: can't set distinct values on 'pids_limit' and
'deploy.resources.limits.pids': invalid compose project

Ikkalasini aralashtirmang. Yangi loyihalarda hammasini deploy.resources.limits ichida yozing.

Teskari proksi #

Nima uchun ilovani to'g'ridan-to'g'ri chiqarmaymiz? Chunki proksi bir nechta ish qiladi: TLS ni tugatadi, statik fayllarni beradi, so'rovlarni bir nechta nusxaga taqsimlaydi va ilovani to'g'ridan-to'g'ri internetdan yashiradi.

Terminal
curl -s http://127.0.0.1:8099/salomatlik
curl -s -o /dev/null -w 'ilovaga proksi: HTTP %{http_code}\n' \
    http://127.0.0.1:8099/
Natija
proksi tirik
ilovaga proksi: HTTP 200

ilova xizmati hech qanday portni chiqarmaydi - unga faqat proksi orqali kirish mumkin. Bu 9-bobdagi qoidaning amaldagi ko'rinishi.

Ishlab chiqarish to'plami Internet 443 proksi TLS, yo'naltirish ilova #1 port chiqmaydi ilova #2 port chiqmaydi Faqat proksi tashqariga ochiq - ilova va baza ichkarida Ilova nusxalari port chiqarmagani uchun ularni bemalol masshtablash mumkin - 11-bobdagi "portli xizmatni masshtablab bo'lmaydi" muammosi bu yerda yo'q.
Proksi - yagona ochiq nuqta

Sozlamalar haqiqatan amaldami? #

Yozish - bir narsa, amalda ishlashi - boshqa. Tekshiramiz:

Terminal
docker inspect ishlab-ilova-1 -f 'ReadOnly : {{.HostConfig.ReadonlyRootfs}}'
docker inspect ishlab-ilova-1 -f 'CapDrop  : {{.HostConfig.CapDrop}}'
docker inspect ishlab-ilova-1 -f 'PidsLimit: {{.HostConfig.PidsLimit}}'
docker inspect ishlab-ilova-1 -f 'Memory   : {{.HostConfig.Memory}}'
docker inspect ishlab-ilova-1 -f 'SecOpt   : {{.HostConfig.SecurityOpt}}'
docker inspect ishlab-ilova-1 -f 'Health   : {{.State.Health.Status}}'
Natija
ReadOnly : true
CapDrop  : [ALL]
PidsLimit: 100
Memory   : 134217728
SecOpt   : [no-new-privileges:true]
Health   : healthy

Jurnal aylanishi proksida:

Terminal
docker inspect ishlab-proksi-1 -f 'Jurnal: {{.HostConfig.LogConfig.Config}}'
Natija
Jurnal: map[max-file:3 max-size:10m]
Bu tekshiruvni skript qiling

Yetkazishdan keyin avtomatik ishlaydigan kichik skript yozing: u docker inspect orqali har bir sozlamani o'qib, kutilganidan farq qilsa xato qaytarsin.

Aks holda kimdir Compose faylini o'zgartiradi va oylab hech kim sezmaydi.

Yangilash #

Ilovani qayta yaratamiz - bu yangi versiya chiqarishning taqlidi:

Terminal
curl -s -o /dev/null -w 'oldin: HTTP %{http_code}\n' http://127.0.0.1:8099/
docker compose up -d --force-recreate --no-deps ilova >/dev/null 2>&1
sleep 3
curl -s -o /dev/null -w 'keyin: HTTP %{http_code}\n' http://127.0.0.1:8099/
Natija
oldin: HTTP 200
keyin: HTTP 200

--no-deps muhim: usiz Compose proksini ham qayta yaratadi va uzilish uzoqroq bo'ladi.

Compose da "nol uzilish" to'liq bo'lmaydi

--force-recreate eski konteynerni to'xtatib, keyin yangisini ko'taradi. Orada bir necha soniya uzilish bo'ladi.

Haqiqiy nol uzilish uchun kerak:

  1. Bir nechta nusxa (proksi orqali)
  2. Yangisini ko'tarish, sog'lom bo'lishini kutish
  3. Keyin eskisini olib tashlash

Compose buni o'zi qilmaydi - docker rollout kabi qo'shimcha vosita yoki orkestrator (Swarm, Kubernetes) kerak.

Kichik loyihada bir necha soniya uzilish odatda maqbul. Muhimi - buni bilib turish.

restart siyosati - va u qachon ishlamasligi #

Bu bobning eng qiziq qismi. Konteyner o'zi yiqilsa, siyosat ishlaydi:

Terminal
docker rm -f yiqiluvchi >/dev/null 2>&1
docker run -d --name yiqiluvchi --restart on-failure \
    alpine:3.21 sh -c 'exit 1' >/dev/null
sleep 6
docker inspect yiqiluvchi -f 'Holat: {{.State.Status}}'
test "$(docker inspect yiqiluvchi -f '{{.RestartCount}}')" -gt 0 \
    && echo "qayta ishga tushirildi: ha"
Natija
Holat: restarting
qayta ishga tushirildi: ha

Endi xuddi shu konteynerni tashqaridan o'ldiramiz:

Terminal
docker rm -f oldirilgan >/dev/null 2>&1
docker run -d --name oldirilgan --restart always \
    alpine:3.21 sleep 300 >/dev/null
sleep 2
docker kill oldirilgan >/dev/null 2>&1
sleep 6
docker inspect oldirilgan -f 'Holat: {{.State.Status}}'
docker inspect oldirilgan -f 'Qayta ishga tushirishlar: {{.RestartCount}}'
Natija
Holat: exited
Qayta ishga tushirishlar: 0

Qayta ishga tushmadi - hatto --restart always bilan ham.

Sabab: docker kill va docker stop qo'lda aralashuv deb hisoblanadi. Docker "bu odam ataylab qildi" deb tushunadi va siyosatni qo'llamaydi.

HolatQayta ishga tushadimi
Ilova o'zi yiqildiHa (siyosatga qarab)
OOM bilan o'ldirildiHa
docker stop / docker killYo'q
Demon qayta ishga tushdialways va unless-stopped uchun ha
Server qayta yuklandialways va unless-stopped uchun ha
Nosozlikni topayotganda buni eslang

Konteynerni docker stop bilan to'xtatib, keyin "nega ko'tarilmayapti?" deb hayron bo'lish - keng tarqalgan holat.

Uni docker start bilan qo'lda ko'taring. Shundan keyin siyosat yana ishlaydi.

unless-stopped va always farqi ham shu yerda: server qayta yuklanganda always siz to'xtatgan konteynerni ham ko'taradi, unless-stopped esa yo'q.

Ishga tushirishdan oldingi ro'yxat #

TekshiruvQayerda
Aniq versiya tegi yoki digestimage:
healthcheck yozilganHar bir xizmatda
depends_on sharti bilanBog'liq xizmatlarda
Jurnal aylanishilogging.options yoki daemon.json
Resurs chegaralarideploy.resources.limits
read_only + tmpfsIlovada
cap_drop: [ALL]Ilovada
Norut foydalanuvchiDockerfile USER
Sirlar muhit fayli yoki sir menejerida.env git da emas
Zaxira: hajmlar ro'yxati va nusxa olishAlohida skript
Monitoring: docker events va jurnal yig'ishTashqi tizim
Zaxira - Docker hal qilmaydigan masala

Nomlangan hajm ma'lumotni saqlaydi, lekin uni zaxiralamaydi.

Eng oddiy usul:

Natija
docker run --rm -v dokon-ma:/ma -v "$PWD":/zaxira alpine:3.21 \
    tar czf /zaxira/dokon-ma-$(date +%F).tar.gz -C /ma .

Baza uchun esa fayl darajasidagi nusxa emas, bazaning o'z vositasi ishlatilsin (pg_dump, mysqldump) - aks holda nusxa buzilgan bo'lishi mumkin.

Xulosa #

  • Ishlab chiqarish sozlamasi - oldingi boblardagi qoidalar yig'indisi; har birini docker inspect bilan tekshiring.
  • Compose v5 da pids_limit va deploy.resources.limits ni aralashtirib bo'lmaydi.
  • Teskari proksi - yagona ochiq nuqta; ilova porti chiqarilmaydi va shuning uchun uni masshtablash mumkin.
  • --force-recreate --no-deps faqat kerakli xizmatni yangilaydi.
  • Compose da to'liq nol uzilish yo'q - bir necha soniya tanaffus bo'ladi; buni bilib turing.
  • restart siyosati ilova o'zi yiqilganda ishlaydi.
  • docker stop va docker kill dan keyin konteyner qayta ishga tushmaydi - bu qo'lda aralashuv deb hisoblanadi.
  • always server qayta yuklanganda siz to'xtatgan konteynerni ham ko'taradi, unless-stopped esa yo'q.
  • Hajm ma'lumotni saqlaydi, lekin zaxiralamaydi - bu alohida ish.
  • Bazani fayl sifatida emas, o'z vositasi bilan zaxiralang.
Amaliy topshiriq
  1. To'liq sozlamani yozing va up -d --wait qiling.
  2. Har bir qat'iylashtirish sozlamasini docker inspect bilan tasdiqlang.
  3. Tekshiruvni skriptga aylantiring.
  4. Proksi orqali ilovaga kiring; ilovani to'g'ridan-to'g'ri ochishga urinib ko'ring.
  5. --force-recreate --no-deps bilan yangilang va uzilishni o'lchang.
  6. O'zi yiqiladigan konteyner yaratib, RestartCount ni kuzating.
  7. docker kill dan keyin qayta ishga tushmasligini tasdiqlang.
  8. always va unless-stopped farqini sinab ko'ring.
  9. Hajmni tar bilan zaxiralang va tiklang.
  10. Ishga tushirish ro'yxatini o'z loyihangiz uchun to'ldiring.

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.