9-bo‘lim
Konteynerlar tarmog'i
Standart bridge va o'z tarmog'ingiz farqi, konteyner DNS, port chiqarish hamda EXPOSE nima qilmasligi.
Ushbu bo‘lim mundarijasi
Ikkita konteyner - veb server va baza - bir-birini qanday topadi? Javob ko'pchilik o'ylagandan boshqacha va u yerda bitta muhim tuzoq bor.
Standart tarmoqlar #
docker network ls --format 'table {{.Name}}\t{{.Driver}}\t{{.Scope}}'
NAME DRIVER SCOPE
bridge bridge local
host host local
none null local
| Tarmoq | Nima qiladi |
|---|---|
bridge | Standart - konteyner o'z IP sini oladi |
host | Konteyner host tarmog'ini to'g'ridan-to'g'ri ishlatadi |
none | Tarmoq umuman yo'q |
Boshqa bayroq bermasangiz, konteyner bridge ga ulanadi.
Tuzoq: standart bridge da DNS ishlamaydi #
Ikkita konteyner ochamiz va biri ikkinchisini nomi bilan chaqirmoqchi bo'ladi:
docker run -d --name veb1 alpine:3.21 sleep 120 >/dev/null
docker run -d --name veb2 alpine:3.21 sleep 120 >/dev/null
docker exec veb1 ping -c1 -W2 veb2 2>&1 | head -1
ping: bad address 'veb2'
Topa olmadi. Ikkalasi ham bir tarmoqda, lekin nom ishlamaydi.
IP bo'yicha esa ishlaydi:
IP2=$(docker inspect veb2 \
-f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}')
docker exec veb1 ping -c1 -W2 "$IP2" 2>&1 | head -2
PING 172.18.0.3 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.071 ms
Ulanish bor, faqat nom yechilmaydi. IP esa har qayta ishga tushirishda o'zgaradi - demak unga tayanib bo'lmaydi.
bridge ni ishlatmangBu Docker ning eng eski tarmog'i va u orqaga moslik uchun saqlanadi.
Unda:
- Konteyner nomlari yechilmaydi
- Barcha konteynerlar bir-birini ko'radi (ajratish yo'q)
Har doim o'z tarmog'ingizni yarating. Compose buni sizning o'rningizga qiladi - 11-bobda ko'ramiz.
O'z tarmog'ingiz #
docker rm -f veb1 veb2 >/dev/null
docker network create dokon-net >/dev/null
docker run -d --name baza --network dokon-net alpine:3.21 sleep 120 >/dev/null
docker run -d --name ilova --network dokon-net \
alpine:3.21 sleep 120 >/dev/null
docker exec ilova ping -c1 -W2 baza 2>&1 | head -2
PING baza (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.087 ms
Endi ishladi. Docker o'z tarmoqlarida ichki DNS server ishlatadi va konteyner nomlarini yechadi.
docker exec ilova nslookup baza 2>&1 | grep -A1 '^Name:'
Name: baza
Address: 172.19.0.2
Tarmoq a'zolarini ko'rish:
docker network inspect dokon-net \
-f '{{range .Containers}}{{printf "%s %s\n" .Name .IPv4Address}}{{end}}' \
| sort
baza 172.19.0.2/16
ilova 172.19.0.3/16
Tarmoq - ajratish chegarasi #
Boshqa tarmoqdagi konteyner biznikini ko'rmaydi:
docker run -d --name begona alpine:3.21 sleep 120 >/dev/null
docker exec begona ping -c1 -W2 baza 2>&1 | head -1
ping: bad address 'baza'
Uni tarmoqqa qo'shsak - ko'radi:
docker network connect dokon-net begona
docker exec begona ping -c1 -W2 baza 2>&1 | head -2
PING baza (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.084 ms
Bitta konteyner bir nechta tarmoqqa a'zo bo'lishi mumkin. Bu "ilova ham veb tarmog'ida, ham baza tarmog'ida, lekin veb server bazani ko'rmaydi" degan tuzilmani qurish imkonini beradi.
Portni tashqariga chiqarish #
Konteyner ichidagi port hostdan avtomatik ko'rinmaydi. Uni ataylab chiqarish kerak:
docker rm -f baza ilova begona >/dev/null
docker run -d --name vebsrv --network dokon-net -p 8099:80 \
nginx:alpine >/dev/null
sleep 3
curl -s -o /dev/null -w 'hostdan: HTTP %{http_code}\n' http://127.0.0.1:8099/
hostdan: HTTP 200
-p 8099:80 - chapda host porti, o'ngda konteyner porti. Ularni
adashtirish eng ko'p uchraydigan xatolardan biri.
docker port vebsrv
80/tcp -> 0.0.0.0:8099
80/tcp -> [::]:8099
Chiqarilmagan port - ichkaridan ko'rinadi #
docker run -d --name ichki --network dokon-net nginx:alpine >/dev/null
sleep 2
docker run --rm --network dokon-net alpine:3.21 sh -c \
'apk add --no-cache curl >/dev/null 2>&1
curl -s -o /dev/null -w "ichkaridan: HTTP %{http_code}\n" http://ichki/'
ichkaridan: HTTP 200
ichki konteyneri hech qanday portni chiqarmagan, lekin bir
tarmoqdagi boshqa konteyner unga bemalol kiradi.
docker ps --filter name=ichki --format '{{.Names}}\t{{.Ports}}'
ichki 80/tcp
0.0.0.0:...-> yo'q - demak hostdan kirib bo'lmaydi.
Ilova va baza bir tarmoqda bo'lsa, baza porti chiqarilishi shart emas.
-p 5432:5432 # KERAK EMAS va xavfli
Ko'p jamoada baza porti "tekshirish uchun" chiqariladi va shu holicha ishlab chiqarishga ketadi. 6-bobdagi tarmoq xavfsizligi qoidasi shu yerda ham amal qiladi: kerak bo'lmagan port yopiq bo'lsin.
EXPOSE nima qiladi? #
docker inspect nginx:alpine -f '{{.Config.ExposedPorts}}'
map[80/tcp:{}]
Nginx obrazida EXPOSE 80 bor. Lekin buni ko'rdingizmi - port
hostga chiqmadi. Yuqoridagi ichki konteyneri buni isbotladi.
EXPOSE - faqat hujjat: "bu obraz 80-portni tinglaydi" degan
eslatma. Portni chiqarish uchun baribir -p kerak.
| Ko'rsatma | Nima qiladi |
|---|---|
EXPOSE 80 | Hujjatlaydi; hech narsani ochmaydi |
-p 8099:80 | Host portini konteyner portiga bog'laydi |
-P | Barcha EXPOSE portlarini tasodifiy host portiga |
--network none #
docker run --rm --network none alpine:3.21 ip addr show 2>&1 \
| grep -E '^[0-9]+:'
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
Faqat lo - ya'ni o'ziga o'zi. Tarmoqqa umuman chiqa olmaydi.
Bu ishonchsiz kodni ishga tushirish uchun foydali: ma'lumotni ishlaydi, lekin uni hech qayerga yubora olmaydi.
--network host va rootless rejim--network host konteynerga host tarmog'ini to'g'ridan-to'g'ri
beradi - ajratish yo'qoladi.
Rootless Docker da u boshqacha ishlaydi: konteyner sizning foydalanuvchi tarmoq ilingizga kiradi, hostning haqiqiy interfeyslariga emas.
Shuning uchun rootless rejimda 1024 dan kichik portlarni chiqarish uchun qo'shimcha sozlash kerak bo'ladi.
Tozalash #
docker rm -f vebsrv ichki >/dev/null
docker network rm dokon-net
dokon-net
Xulosa #
- Uchta standart tarmoq:
bridge,host,none. - Standart
bridgeda konteyner nomlari yechilmaydi - faqat IP ishlaydi, IP esa har ishga tushirishda o'zgaradi. - O'z tarmog'ingizni yarating - unda Docker ichki DNS ishlaydi va nom bo'yicha topish ishlaydi.
- Tarmoq - ajratish chegarasi: boshqa tarmoqdagi konteyner siznikini ko'rmaydi.
- Bitta konteyner bir nechta tarmoqqa a'zo bo'lishi mumkin
(
docker network connect). -p 8099:80- chapda host, o'ngda konteyner porti.- Chiqarilmagan port bir tarmoqdagi konteynerlarga baribir
ko'rinadi - shuning uchun bazani
-pbilan chiqarmang. EXPOSEhech narsani ochmaydi, u faqat hujjat.--network nonekonteynerni tarmoqdan butunlay uzadi.- Rootless rejimda
--network hostsizning foydalanuvchi tarmoq ilingizni beradi, hostnikini emas.
- Ikki konteynerni standart
bridgeda ochib, nom bo'yicha ping qiling va xatoni ko'ring. - O'z tarmog'ingizni yaratib, o'sha tajribani takrorlang.
docker network inspectbilan a'zolarni ro'yxatlang.- Uchinchi konteynerni tarmoqdan tashqarida ochib, ulanishni sinang.
- Uni
docker network connectbilan qo'shing. - Nginx ni
-pbilan chiqarib,curlorqali tekshiring. -psiz ishga tushirib, ichki konteynerdan kiring.docker portvadocker pschiqishini solishtiring.EXPOSEbor obrazni-psiz ishga tushirib, hostdan kirib ko'ring.--network nonebilan konteyner ochib,pingqilib ko'ring.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.