O'z tarmog'ingiz — konteynerlar nom bilan topishadi

~12 daq · Docker · Tarmoq

Muammodan boshlaylik

O'tgan dars: standart bridge da konteynerlar faqat IP orqali gaplashadi, IP esa o'zgaradi. Kerak — kodda shunchaki:

host: 'baza'

va API qayerda bo'lmasin, baza konteynerini nomi bo'yicha topsin.


Tarmoq yaratish

docker network create dokon-net

Konteynerlarni unga ulash:

docker run -d --name baza --network dokon-net \
  -e MYSQL_ROOT_PASSWORD=root123 -e MYSQL_DATABASE=dokon \
  -v baza-data:/var/lib/mysql \
  mysql:8.4

docker run -d --name api --network dokon-net \
  -e DB_HOST=baza -e DB_USER=root -e DB_PASSWORD=root123 \
  -p 3000:3000 \
  mening-api:1.0

API ichida DB_HOST=baza — va ishlaydi. Docker ning ichki DNS i baza nomini konteynerning joriy IP siga aylantiradi.

Tekshirish:

docker exec api ping -c 1 baza
# PING baza (172.18.0.2): 56 data bytes

E'tibor bering: baza da -p yo'q. Baza tashqi dunyoga ochiq emas — faqat dokon-net dagi konteynerlar unga yetadi. Bu 9-darsdagi xavfsizlik tamoyili amalda.


Port: konteyner porti, host porti emas

Tarmoq ichida konteynerlar bir-biriga konteyner porti orqali murojaat qiladi:

api → baza:3306        ✅ konteyner porti
api → baza:3307        ❌ hatto -p 3307:3306 bo'lsa ham

-p — faqat tashqaridan (kompyuterdan) kirish uchun. Ichki aloqa unga bog'liq emas.


Mavjud konteynerni ulash / uzish

docker network connect dokon-net adminer
docker network disconnect dokon-net adminer

Konteyner bir vaqtda bir nechta tarmoqda bo'lishi mumkin.


Taxalluslar

docker run -d --name mysql-8-4-asosiy --network dokon-net --network-alias db mysql:8.4

Endi mysql-8-4-asosiy ham, db ham ishlaydi. Bir nechta konteynerga bir xil taxallus — Docker DNS so'rovlarni ular orasida taqsimlaydi (oddiy yuklamani taqsimlash).


Tarmoqlarni ajratish — xavfsizlik

Katta loyihada hamma konteyner bitta tarmoqda bo'lishi shart emas:

          ┌─── frontend-net ────┐   ┌──── backend-net ────┐
Internet ─→  nginx  ──────────── api  ──────────── baza
          └─────────────────────┘   └─────────────────────┘
docker network create frontend-net
docker network create backend-net

docker run -d --name baza  --network backend-net mysql:8.4 ...
docker run -d --name api   --network backend-net mening-api:1.0
docker network connect frontend-net api
docker run -d --name nginx --network frontend-net -p 80:80 nginx
  • Nginx → API ✅ (ikkalasi frontend-net da)
  • API → baza ✅ (ikkalasi backend-net da)
  • Nginx → baza ❌ — umumiy tarmoq yo'q

Nginx buzib kirilsa ham, hujumchi bazaga to'g'ridan-to'g'ri yeta olmaydi.

Ichki tarmoq

docker network create --internal backend-net

--internal — bu tarmoqdagi konteynerlar internetga chiqa olmaydi. Bazaga tashqi aloqa umuman kerak emas.


Boshqarish

docker network ls
docker network inspect dokon-net       # ulangan konteynerlar va ularning IP lari
docker network rm dokon-net            # ulangan konteyner bo'lmasa
docker network prune

Compose avtomatik qiladi

Bularning hammasini qo'lda qilish shart emas. Docker Compose (26-dars) har bir loyiha uchun avtomatik tarmoq yaratadi va barcha xizmatlarni unga ulaydi — xizmat nomi bilan DNS darhol ishlaydi:

services:
  api:
    environment:
      DB_HOST: baza        # xizmat nomi
  baza:
    image: mysql:8.4

Lekin ichida — aynan shu darsdagi mexanizm.


Nima uchun shunday?

Nima uchun nom bo'yicha topish faqat o'z tarmoqlarda ishlaydi, standart bridge da emas?

Tarixiy sabab. Standart bridge Docker ning dastlabki versiyalaridan qolgan; o'sha paytda konteynerlarni bog'lash --link degan noqulay mexanizm bilan qilinardi. Keyinroq o'rnatilgan DNS bilan "user-defined networks" qo'shildi — lekin standart tarmoqning xatti-harakatini o'zgartirish millionlab mavjud tizimlarni buzardi. Shuning uchun qoida: standart bridge ni ishlatmang, o'zingiznikini yarating (yoki Compose dan foydalaning — u buni avtomatik qiladi).


Xulosa

Eslab qoling:

  • docker network create nom + --network nom — konteynerlar nom bilan topishadi
  • Ichki aloqa — konteyner porti orqali; -p — faqat tashqaridan
  • Baza — -p siz, faqat ichki tarmoqda
  • network connect / disconnect — mavjud konteynerni ulash
  • Tarmoqlarni ajrating: frontend va backend; --internal — internetsiz
  • Compose bularni avtomatik qiladi

Keyingi dars

25-dars: Tarmoq izolyatsiyasi — nimani tashqariga ochish kerak