Docker Networking
Docker Networking reprezintă infrastructura prin care containerele comunică între ele și cu lumea exterioară. Înțelegerea modelului de rețea Docker este esențială pentru proiectarea aplicațiilor containerizate sigure și scalabile.
Modelul de rețea Docker (CNM)
Docker folosește modelul Container Network Model (CNM), compus din trei abstracții fundamentale:
| Componentă | Descriere |
|---|---|
| Sandbox | Mediu izolat de rețea al unui container (interfețe, tabele de rutare, DNS) |
| Endpoint | Punct de conectare între un sandbox și o rețea |
| Network | Grup de endpoint-uri care pot comunica direct între ele |
Implementarea de referință a CNM este libnetwork, biblioteca Go folosită intern de Docker.
Tipuri de rețele Docker
1. Bridge (implicit)
Rețeaua de tip bridge este driverul implicit și cel mai frecvent utilizat. Docker creează automat o interfață virtuală docker0 pe host, care acționează ca un switch software.
Cum funcționează:
- Fiecare container primește o interfață virtuală
vethconectată la bridge - Containerele din același bridge pot comunica între ele prin IP
- Traficul spre exterior trece prin NAT (masquerading)
- Porturile se expun explicit cu
-p
Bridge implicit vs. bridge definit de utilizator:
| Caracteristică | Bridge implicit (docker0) | Bridge custom |
|---|---|---|
| Rezoluție DNS între containere | ✗ Nu | ✓ Da (prin nume) |
| Izolare automată | ✗ Nu | ✓ Da |
| Configurare flexibilă | ✗ Limitată | ✓ Completă |
| Recomandat pentru producție | ✗ Nu | ✓ Da |
# Creare rețea bridge custom docker network create --driver bridge \ --subnet 172.20.0.0/16 \ --gateway 172.20.0.1 \ retea-app # Pornire containere în rețeaua custom docker run -d --name backend --network retea-app my-api docker run -d --name frontend --network retea-app my-ui # frontend poate accesa backend prin nume: http://backend:8080
2. Host
Driverul host elimină izolarea de rețea între container și host - containerul folosește direct stiva de rețea a mașinii gazdă.
Caracteristici:
- Containerul partajează interfețele de rețea ale host-ului
- Nu există NAT, nu sunt necesare mapări de porturi
- Performanță maximă (fără overhead de rețea virtualizată)
- Disponibil nativ doar pe Linux (pe macOS/Windows funcționează limitat)
# Rulare container în modul host docker run -d --network host nginx # nginx ascultă direct pe portul 80 al host-ului # Nu este nevoie de -p 80:80
⚠ Atenție: Modul host reduce izolarea containerului. Folosiți-l doar când performanța rețelei este critică (ex: aplicații cu latență ultra-scăzută).
3. Overlay
Driverul overlay creează rețele distribuite care se întind pe mai multe noduri Docker (clustere Swarm sau Kubernetes cu plugin compatibil). Traficul este tunelat prin VXLAN.
Cerințe:
- Docker Swarm inițializat (
docker swarm init) sau un key-value store extern - Porturile
2377/tcp,4789/udp,7946/tcp+udpdeschise între noduri
Cum funcționează:
- Fiecare container primește un IP din subnet-ul overlay
- Pachetele sunt încapsulate VXLAN și trimise prin rețeaua fizică
- Un container de pe nodul A poate comunica cu unul de pe nodul B transparent
# Inițializare Swarm docker swarm init --advertise-addr <IP-MANAGER> # Creare rețea overlay docker network create --driver overlay \ --subnet 10.10.0.0/16 \ retea-swarm # Deployare servicii în rețeaua overlay docker service create --name api \ --network retea-swarm \ --replicas 3 \ my-api-image docker service create --name db \ --network retea-swarm \ --replicas 1 \ postgres:15
4. Macvlan
Driverul macvlan atribuie fiecărui container o adresă MAC unică, făcându-l să apară ca un dispozitiv fizic în rețea. Util pentru aplicații legacy care necesită conectivitate directă la rețeaua fizică.
docker network create -d macvlan \ --subnet=192.168.1.0/24 \ --gateway=192.168.1.1 \ -o parent=eth0 \ retea-macvlan
5. None
Dezactivează complet rețeaua pentru un container. Util pentru procesare izolată (batch jobs, transformări de date fără acces la rețea).
docker run --network none alpine sh
Comunicarea între containere
Comunicare în același host (bridge)
┌─────────────────────────────────────────┐ │ Docker Host │ │ │ │ ┌──────────┐ ┌──────────┐ │ │ │ container│ │ container│ │ │ │ frontend │ │ backend │ │ │ │ 172.20.0.2│◄────►│172.20.0.3│ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ─────┴──────────────────┴───── │ │ bridge: retea-app │ │ 172.20.0.1 │ └─────────────────────────────────────────┘
- Containerele din aceeași rețea bridge custom se descoperă prin nume (DNS intern Docker)
- Nu este necesară expunerea porturilor (
-p) pentru comunicare internă
Comunicare multi-host (overlay)
Nod 1 (Manager) Nod 2 (Worker)
┌──────────────────┐ ┌──────────────────┐
│ ┌────────────┐ │ │ ┌────────────┐ │
│ │ api │ │ │ │ api │ │
│ │ 10.10.0.2 │ │ │ │ 10.10.0.4 │ │
│ └─────┬──────┘ │ │ └─────┬──────┘ │
│ │ VXLAN │◄───────►│ │ VXLAN │
│ ┌─────┴──────┐ │ tunel │ ┌─────┴──────┐ │
│ │ db │ │ │ │ db │ │
│ │ 10.10.0.3 │ │ │ │ 10.10.0.5 │ │
│ └────────────┘ │ │ └────────────┘ │
└──────────────────┘ └──────────────────┘
└───────── overlay: retea-swarm ─────────┘
Conectare la rețele multiple
Un container poate fi conectat simultan la mai multe rețele, util pentru separarea traficului (ex: frontend ↔ backend ↔ baza de date):
docker network create retea-frontend docker network create retea-backend # Containerul "api" bridge între cele două rețele docker run -d --name api \ --network retea-frontend \ my-api docker network connect retea-backend api # Acum "api" are acces la ambele rețele
Inspecție și depanare
# Lista rețelelor existente docker network ls # Inspecție detaliată a unei rețele docker network inspect retea-app # Verificare conectivitate între containere docker exec frontend ping backend # Vizualizare interfețe de rețea din container docker exec frontend ip addr # Urmărire rute docker exec frontend ip route # Eliminare rețele neutilizate docker network prune
Porturi și expunere
| Opțiune | Sintaxă | Descriere |
|---|---|---|
| Expunere completă | -p 8080:80 | Host:8080 → Container:80 |
| Legare la interfață | -p 127.0.0.1:8080:80 | Doar localhost, nu extern |
| Port aleatoriu | -p 80 | Port aleatoriu pe host |
| UDP | -p 5353:53/udp | Protocol UDP explicit |
| EXPOSE (Dockerfile) | EXPOSE 80 | Documentație, nu mapare reală |
💡 Bună practică: Legați porturile la127.0.0.1dacă serviciul nu trebuie să fie accesibil din exterior. Expunerea la0.0.0.0(implicit) poate crea riscuri de securitate.
DNS în Docker
Docker rulează un resolver DNS intern (127.0.0.11) disponibil în fiecare container:
- Rețele bridge custom: rezoluție automată prin numele containerului sau alias
- Swarm overlay: rezoluție prin numele serviciului (cu load balancing VIP)
- Suportă DNS round-robin pentru scalare orizontală
# Adăugare alias DNS pentru un container docker run -d --name cache \ --network retea-app \ --network-alias redis \ redis:7 # Acum alte containere pot accesa cache-ul prin "redis" sau "cache"
Comparație rapidă a driverelor
| Driver | Izolare | Multi-host | Performanță | Caz de utilizare |
|---|---|---|---|---|
| bridge | ✓ | ✗ | Bună | Dezvoltare, single-host |
| host | ✗ | ✗ | Maximă | Performanță critică (Linux) |
| overlay | ✓ | ✓ | Bună | Swarm, microservicii distribuite |
| macvlan | ✓ | ✓ | Maximă | Integrare rețea fizică, legacy |
| none | Total | ✗ | N/A | Izolare completă |
Bune practici
- Folosiți întotdeauna rețele bridge custom în loc de rețeaua implicită
docker0 - Segmentați rețelele pe straturi (frontend / backend / date) pentru principiul least-privilege
- Nu expuneți porturi interne dacă serviciile comunică doar intern
- Folosiți overlay pentru comunicare multi-host în loc de soluții manuale (SSH tunneling etc.)
- Numiți rețelele sugestiv (
retea-prod-frontend) pentru management ușor - Documentați subnet-urile alocate pentru a evita conflicte CIDR