2-bo‘lim

O'rnatish va konteynerni boshqarish

Docker ni o'rnatish, mijoz va demon qanday gaplashadi, konteynerni ishga tushirish, to'xtatish va o'chirish.

🕑 20 daqiqa o‘qish 📄 1 112 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Docker qanday tuzilgan?
  2. O'rnatish
  3. Birinchi buyruq tuzilishi
  4. Konteynerlar ro'yxati
  5. Nom berish
  6. Fon rejimida ishlatish
  7. Ishlayotgan konteynerga kirish
  8. To'xtatish - va 137 raqami
  9. Qayta ishga tushirish
  10. Asosiy buyruqlar
  11. Chiqish kodi uzatiladi
  12. Ortidan tozalash
  13. Xulosa

Oldingi bobda konteyner nima ekanini ko'rdik. Endi uni boshqarishni o'rganamiz: ishga tushirish, jurnalini o'qish, ichiga kirish, to'xtatish va o'chirish.

Docker qanday tuzilgan? #

docker buyrug'ini yozganingizda, u ishni o'zi bajarmaydi. U mijoz - so'rovni demon ga uzatadi, demon esa haqiqiy ishni qiladi.

Mijoz, demon va registry Mijoz docker run docker ps Demon (dockerd) Obrazlar Konteynerlar Tarmoq va hajmlar Registry Docker Hub yoki xususiy soket pull Mijoz va demon bir kompyuterda bo'lishi shart emas - DOCKER_HOST orqali masofadagi demonga ham ulanish mumkin.
Mijoz buyruq yuboradi, demon bajaradi, registry obraz saqlaydi

O'rnatish #

TizimUsul
LinuxRasmiy skript yoki distributiv paketi
WindowsDocker Desktop (WSL2 bilan ishlaydi)
macOSDocker Desktop
Serverdocker-ce paketi, apt yoki dnf orqali

O'rnatgandan keyin birinchi ish - demon javob berayotganini tekshirish:

Terminal
docker info --format 'Server         : {{.ServerVersion}}
Saqlash        : {{.Driver}}
Cgroup         : {{.CgroupDriver}} v{{.CgroupVersion}}
Ishlayotganlar : {{.ContainersRunning}}'
Natija
Server         : 29.8.0
Saqlash        : overlayfs
Cgroup         : systemd v2
Ishlayotganlar : 0
Root huquqisiz Docker

Odatda docker buyrug'i uchun sudo yoki docker guruhiga a'zolik kerak. Lekin docker guruhiga qo'shish - root berish bilan teng, chunki demon root sifatida ishlaydi.

Xavfsizroq yo'l - rootless rejim: demon sizning oddiy foydalanuvchingiz nomidan ishlaydi.

Bu darslikdagi barcha misollar aynan rootless Docker da bajarilgan. 15-bobda bu rejimning kuchli va zaif tomonlarini batafsil ko'ramiz.

Birinchi buyruq tuzilishi #

Natija
docker run  [bayroqlar]  OBRAZ  [buyruq]  [argumentlar]
            ^            ^      ^
            |            |      +-- obraz ichidagi standart
            |            |          buyruq o'rniga bajariladi
            |            +--------- qaysi obrazdan
            +---------------------- qanday ishlasin

Eng oddiy holat:

Terminal
docker run --rm alpine:3.21 echo "Salom, Husanboy"
Natija
Salom, Husanboy

Shu bitta qatorda to'rt ish bajarildi: obraz topildi, konteyner yaratildi, echo ishga tushdi, so'ng konteyner o'chirildi.

Konteynerlar ro'yxati #

Terminal
docker ps
Natija
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Bo'sh. docker ps faqat ishlayotgan konteynerlarni ko'rsatadi - biznikisi esa vazifasini bajarib, darhol tugadi.

-a bayrog'i tugaganlarni ham ko'rsatadi.

Nom berish #

Nom bermasangiz, Docker tasodifiy nom o'ylab topadi (musing_moore kabi). Buyruqlarda ishlatish uchun nom berganingiz qulayroq:

Terminal
docker run --name salom alpine:3.21 echo birinchi
docker ps -a --filter name=salom --format '{{.Names}}\t{{.State}}'
Natija
birinchi
salom    exited

Nom noyob bo'lishi kerak. O'sha nom bilan yana ishga tushirmoqchi bo'lsangiz:

Xabar uzun, shuning uchun uni fold bilan o'qiladigan kenglikka bo'lib ko'rsatamiz:

Terminal
docker run --name salom alpine:3.21 echo ikkinchi 2>&1 | fold -sw 74
Natija
docker: Error response from daemon: Conflict. The container name "/salom"
is already in use by container
"fd6e3b5708a34064c34cacef46ebc011007ee440afb02259e9c34bf9b00a0209". You
have to remove (or rename) that container to be able to reuse that name.

Run 'docker run --help' for more information

Konteyner tugagan bo'lsa ham, u hali o'chirilmagan - nomi band turibdi. Buni hal qilish uchun eski konteynerni o'chirasiz yoki boshidanoq --rm ishlatasiz.

Fon rejimida ishlatish #

-d (detach) bayrog'i konteynerni fonda qoldiradi va terminalni bo'shatadi:

Terminal
docker run -d --name hisob alpine:3.21 \
    sh -c 'for i in 1 2 3; do echo "qadam $i"; sleep 1; done; echo tugadi'
Natija
9a6d0d7347dfe0793da03e26f62590a1938b56e898b3e9d1eb0931217584b269

Chiqishdagi uzun satr - konteyner identifikatori. Sizda u boshqacha bo'ladi, chunki har bir konteyner yangi ID oladi.

Konteyner fonda ishlayapti. Uning chiqishini docker logs bilan o'qiymiz - lekin avval ishini tugatishini kutamiz, aks holda faqat birinchi qatorni ko'ramiz:

Terminal
sleep 4
docker logs hisob
Natija
qadam 1
qadam 2
qadam 3
tugadi
docker logs nimani ko'rsatadi?

U konteynerdagi 1-jarayonning stdout va stderr oqimini ko'rsatadi.

Agar ilovangiz jurnalni faylga yozsa, docker logs bo'sh bo'ladi. Shuning uchun konteynerdagi ilova jurnalni terminalga yozishi kerak - faylga emas.

Bu 13-bobda batafsil ko'riladi.

Ishlayotgan konteynerga kirish #

docker exec ishlayotgan konteyner ichida yangi buyruq ishga tushiradi:

Terminal
docker run -d --name veb --hostname dokon-veb alpine:3.21 sleep 300
docker exec veb hostname
docker exec veb sh -c 'echo salom > /tmp/x; cat /tmp/x'
Natija
3a7da9984d0013003b7490ef048241ef57a525a06ae5792ce9d69e8587be96b2
dokon-veb
salom
exec bilan tuzatilgan narsa saqlanmaydi

Konteyner ichiga kirib biror narsani o'rnatish yoki sozlash vasvasasi kuchli. Lekin bu o'zgarishlar obrazga tushmaydi.

Konteyner qayta yaratilsa, hammasi yo'qoladi va siz nima qilganingizni eslay olmaysiz.

To'g'ri yo'l - o'zgarishni Dockerfile ga yozish. exec esa faqat tekshirish va tuzatish uchun.

To'xtatish - va 137 raqami #

Endi muhim tafsilot. Konteynerni to'xtatamiz va chiqish kodini ko'ramiz:

Terminal
docker stop -t 2 veb
docker inspect -f '{{.State.ExitCode}}' veb
Natija
veb
137

137 - bu nima? U 128 + 9 ga teng, ya'ni jarayon SIGKILL (9-signal) bilan majburan o'ldirilgan.

Nima bo'ldi? docker stop avval muloyim so'raydi - SIGTERM yuboradi. Konteyner ichidagi 1-jarayon bu signalga javob bermasa, Docker belgilangan vaqtni kutadi va so'ng SIGKILL yuboradi.

docker stop nima qiladi docker stop SIGTERM yuboradi Javob berdi o'zi chiqadi 0 javob bermadi Kutish tugadi SIGKILL yuboriladi 137 toza majburan
137 - "muloyim so'radim, javob bermading" degani

Endi signalni to'g'ri ushlaydigan konteyner bilan solishtiramiz:

Terminal
docker run -d --name toza alpine:3.21 \
    sh -c 'trap "exit 0" TERM; sleep 300 & wait'
docker stop -t 5 toza
docker inspect -f '{{.State.ExitCode}}' toza
Natija
910e4d5d612d27eff3440e7074969e4e838b846e4daea00f82461474d5aa6179
toza
0

Chiqish kodi 0. Konteyner SIGTERM ni ushladi va o'zi toza chiqdi - kutishning ham hojati bo'lmadi.

137 - ishlab chiqarishda jiddiy muammo

Ilovangiz SIGTERM ni ushlamasa, har bir yangilanishda u majburan o'ldiriladi:

  • Yarim yozilgan fayl tugallanmay qoladi
  • Ochiq baza tranzaksiyasi uzilib ketadi
  • Mijozga javob yuborilmay qoladi

Ilova SIGTERM kelganda joriy ishni tugatib, yangi so'rov qabul qilmasligi va so'ng chiqishi kerak. Bunga graceful shutdown deyiladi.

docker stop standart holda 10 soniya kutadi.

Qayta ishga tushirish #

To'xtagan konteyner yo'qolmaydi - uni qayta boshlash mumkin:

Terminal
docker start hisob
sleep 5
docker logs hisob
Natija
hisob
qadam 1
qadam 2
qadam 3
tugadi
qadam 1
qadam 2
qadam 3
tugadi

Jurnalda endi ikkita to'plam bor. Demak konteyner o'z buyrug'ini boshidan bajardi - docker start davom ettirmaydi, qaytadan boshlaydi.

Eski jurnal ham saqlanib qoldi: u konteyner bilan birga yashaydi va faqat konteyner o'chirilganda yo'qoladi.

Asosiy buyruqlar #

BuyruqNima qiladi
docker runObrazdan yangi konteyner yaratib ishga tushiradi
docker psIshlayotganlarni ko'rsatadi (-a - hammasini)
docker logs1-jarayonning chiqishini ko'rsatadi
docker execIshlayotgan konteynerda yangi buyruq bajaradi
docker stopSIGTERM, so'ng SIGKILL yuboradi
docker startTo'xtaganni qayta boshlaydi
docker rmKonteynerni o'chiradi (-f - ishlayotganini ham)
docker inspectKonteyner haqida to'liq ma'lumot beradi
run va start farqi

docker run - yangi konteyner yaratadi. docker start - mavjud konteynerni qayta boshlaydi.

Yangi boshlovchilar ko'p qiladigan xato: har safar run yozib, o'nlab to'xtagan konteyner to'plab qo'yish.

docker ps -a bilan tekshirib turing.

Chiqish kodi uzatiladi #

Konteynerdagi buyruqning chiqish kodi sizga qaytadi - bu skript va CI uchun muhim:

Terminal
docker run --rm alpine:3.21 sh -c 'exit 7'
echo "chiqish kodi: $?"
Natija
chiqish kodi: 7

Shuning uchun konteynerda test ishga tushirsangiz, CI muvaffaqiyat yoki muvaffaqiyatsizlikni to'g'ri aniqlaydi.

Ortidan tozalash #

Shu bobda nechta konteyner yaratganimizni ko'ramiz:

Terminal
docker ps -a --format '{{.Names}}\t{{.State}}'
Natija
toza    exited
veb    exited
hisob    exited
salom    exited

To'rttasi ham vazifasini bajarib bo'lgan, lekin hammasi diskda turibdi va nomini band qilib qo'ygan. Haqiqiy ishda bu son bir necha kunda yuzlab bo'lib ketadi.

Yechim - --rm. U konteyner tugashi bilan o'zini o'chiradi:

Terminal
docker run --name qoldi alpine:3.21 true
docker run --rm --name ketdi alpine:3.21 true
docker ps -a --format '{{.Names}}' | head -2
Natija
qoldi
toza

ketdi ro'yxatda yo'q - u o'zini o'chirdi. qoldi esa turibdi.

Yig'ilib qolganlarini bir buyruq bilan tozalash mumkin:

Terminal
docker rm -f qoldi toza veb hisob salom
docker ps -a --format '{{.Names}}' | wc -l
Natija
qoldi
toza
veb
hisob
salom
0
Bir martalik buyruqlar uchun har doim --rm

Test, tekshiruv yoki bir martalik skript uchun --rm ni odat qiling.

Uzoq ishlaydigan xizmatlar uchun esa --rm kerak emas - ularni ataylab saqlab, docker start bilan qayta boshlaysiz.

Yig'ilib qolganini docker container prune bilan ham tozalash mumkin.

Xulosa #

  • docker - bu mijoz; haqiqiy ishni demon (dockerd) bajaradi, obrazlar esa registry da saqlanadi.
  • Buyruq tuzilishi: docker run [bayroqlar] OBRAZ [buyruq].
  • docker ps faqat ishlayotganlarni, docker ps -a hammasini ko'rsatadi.
  • --name bilan nom bering - nom noyob bo'lishi kerak va konteyner o'chirilmaguncha band turadi.
  • -d konteynerni fonda qoldiradi; chiqishini docker logs bilan o'qiysiz.
  • docker logs faqat 1-jarayonning stdout/stderr ini ko'rsatadi - faylga yozilgan jurnalni emas.
  • docker exec tekshirish uchun; u bilan qilingan o'zgarish obrazga tushmaydi.
  • docker stop avval SIGTERM, keyin SIGKILL yuboradi; chiqish kodi 137 - majburan o'ldirilgan degani.
  • Ilova SIGTERM ni ushlab, ishini tugatib chiqishi kerak - aks holda har yangilanishda ma'lumot yo'qolishi mumkin.
  • --rm ishlatmasangiz, tugagan konteynerlar diskda to'planib boraveradi.
Amaliy topshiriq
  1. docker info bilan saqlash drayveri va cgroup versiyasini aniqlang.
  2. --name bilan konteyner yarating va o'sha nom bilan yana ishga tushirib, xatoni o'qing.
  3. -d bilan fonda konteyner ishga tushiring va docker logs bilan chiqishini ko'ring.
  4. docker exec orqali ishlayotgan konteynerda fayl yarating, konteynerni qayta ishga tushirib, fayl qoldimi tekshiring.
  5. SIGTERM ni ushlamaydigan konteynerni docker stop qiling va chiqish kodini docker inspect bilan ko'ring.
  6. trap bilan signalni ushlaydigan variantini yozing va kodni solishtiring.
  7. docker stop -t 1 va -t 30 farqini o'lchang.
  8. exit 3 qaytaradigan konteyner yarating va $? ni tekshiring.
  9. docker ps -a da nechta eski konteyner yig'ilganini sanang va tozalang.
  10. docker inspect chiqishidan konteyner IP manzilini toping.

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.