Optymalizacja sieci Docker: Bridge vs Host mode w praktyce

· 5min · Pondo
Architektura sieci Docker - porównanie trybów bridge i host

Wprowadzenie

Docker oferuje kilka trybów sieciowych, które mają znaczący wpływ na wydajność i bezpieczeństwo kontenerów. W tym artykule szczegółowo przeanalizujemy dwa najczęściej używane tryby: bridge i host, porównamy ich wydajność i pokażemy, kiedy warto użyć każdego z nich.

Właściwy wybór trybu sieciowego może drastycznie wpłynąć na:

  • Przepustowość (throughput) aplikacji
  • Opóźnienia (latency) połączeń sieciowych
  • Izolację i bezpieczeństwo kontenerów
  • Łatwość konfiguracji i debugowania

Tryby sieciowe w Docker

Docker domyślnie oferuje pięć rodzajów sieci:

TrybOpisTypowe zastosowanie
bridgeDomyślny tryb, izolowana sieć wirtualnaAplikacje wielokontenerowe
hostKontener używa sieci hosta bezpośrednioAplikacje wymagające maksymalnej wydajności
noneBrak interfejsu sieciowegoKontenery wymagające pełnej izolacji
overlaySieć rozproszona między hostamiDocker Swarm, orkiestracja
macvlanKontenery z własnymi adresami MACLegacy applications wymagające L2

W tym artykule skupimy się na dwóch najpopularniejszych: bridge i host.

Bridge Mode - izolacja i elastyczność

Jak działa Bridge Mode?

W trybie bridge Docker tworzy wirtualny most sieciowy (docker0) na hoście i przydziela każdemu kontenerowi prywatny adres IP z podsieci wirtualnej (domyślnie 172.17.0.0/16).

  graph TB
    subgraph "Host System"
        ETH0[eth0<br/>192.168.1.100]
        DOCKER0[docker0 bridge<br/>172.17.0.1]

        subgraph "Container 1"
            C1[nginx<br/>172.17.0.2:80]
        end

        subgraph "Container 2"
            C2[postgres<br/>172.17.0.3:5432]
        end

        ETH0 -->|NAT| DOCKER0
        DOCKER0 --> C1
        DOCKER0 --> C2
    end

    CLIENT[Client<br/>Internet] -->|Port 80| ETH0

Konfiguracja Bridge Network

Tworzenie własnej sieci bridge (zalecane zamiast domyślnej):

# Utwórz niestandardową sieć bridge
docker network create --driver bridge \
  --subnet=172.20.0.0/16 \
  --gateway=172.20.0.1 \
  --opt com.docker.network.bridge.name=br-custom \
  my-bridge-net

# Sprawdź utworzoną sieć
docker network inspect my-bridge-net

# Uruchom kontenery w tej sieci
docker run -d --name web \
  --network my-bridge-net \
  -p 8080:80 \
  nginx:alpine

docker run -d --name db \
  --network my-bridge-net \
  postgres:15
tip
Pro Tip

Używaj niestandardowych sieci bridge zamiast domyślnej sieci bridge. Niestandardowe sieci oferują automatyczne DNS resolution między kontenerami - możesz odwoływać się do kontenerów po nazwach zamiast adresów IP!

Zalety Bridge Mode

  1. Izolacja sieciowa - kontenery są odizolowane od sieci hosta
  2. Port mapping - elastyczne mapowanie portów (-p 8080:80)
  3. Wiele aplikacji - możliwość uruchomienia wielu kontenerów używających tego samego portu
  4. Bezpieczeństwo - NAT zapewnia dodatkową warstwę ochrony

Wady Bridge Mode

  1. Overhead NAT - każde połączenie przechodzi przez translację adresów
  2. Niższa wydajność - dodatkowa warstwa abstrakcji
  3. Złożoność - wymagane mapowanie portów i konfiguracja

Host Mode - maksymalna wydajność

Jak działa Host Mode?

W trybie host kontener współdzieli stos sieciowy z hostem. Nie ma NAT, port mappingu ani wirtualnych interfejsów - kontener korzysta bezpośrednio z interfejsów sieciowych hosta.

  graph TB
    subgraph "Host System & Container"
        ETH0[eth0<br/>192.168.1.100]

        subgraph "Container (Host Network)"
            APP[nginx:80<br/>bezpośrednio na eth0]
        end

        ETH0 -.shared network stack.- APP
    end

    CLIENT[Client<br/>Internet] -->|Port 80| ETH0

Konfiguracja Host Network

# Uruchom kontener w trybie host
docker run -d --name nginx-host \
  --network host \
  nginx:alpine

# Sprawdź, że kontener używa portów hosta bezpośrednio
docker exec nginx-host netstat -tlnp
warning
Uwaga

W trybie host nie możesz używać flagi -p do mapowania portów. Kontener automatycznie binduje się do portów hosta. Jeśli aplikacja słucha na porcie 80, zajmie port 80 na hoście!

Zalety Host Mode

  1. Maksymalna wydajność - brak overhead NAT i wirtualizacji sieci
  2. Niska latencja - bezpośredni dostęp do interfejsów sieciowych
  3. Prostota - brak konfiguracji port mappingu
  4. Pełny dostęp - kontener widzi wszystkie interfejsy sieciowe hosta

Wady Host Mode

  1. Brak izolacji - kontener ma pełny dostęp do sieci hosta
  2. Konflikty portów - nie można uruchomić wielu kontenerów na tym samym porcie
  3. Bezpieczeństwo - zwiększone ryzyko w przypadku kompromitacji kontenera
  4. Problemy z przenośnością - zachowanie zależy od konfiguracji hosta

Testy wydajnościowe - Bridge vs Host

Przeprowadziłem testy wydajnościowe porównujące oba tryby sieciowe używając iperf3 do pomiaru przepustowości i wrk do testowania aplikacji HTTP.

Środowisko testowe

# Specyfikacja systemu testowego
CPU: AMD Ryzen 9 5900X (12 cores)
RAM: 32GB DDR4 3600MHz
Network: 10Gbit/s Ethernet
OS: Arch Linux 6.6.x
Docker: 24.0.7

Test 1: Przepustowość TCP (iperf3)

# Server w trybie bridge
docker run -d --name iperf-bridge \
  --network my-bridge-net \
  -p 5201:5201 \
  networkstatic/iperf3 -s

# Server w trybie host
docker run -d --name iperf-host \
  --network host \
  networkstatic/iperf3 -s

# Test bridge mode
iperf3 -c localhost -p 5201 -t 30

# Test host mode
iperf3 -c localhost -p 5201 -t 30

Wyniki przepustowości:

TrybPrzepustowośćCPU Usage (host)Latencja średnia
Bridge8.2 Gbit/s15%0.45ms
Host9.8 Gbit/s8%0.12ms
Różnica+19.5%-47%-73%

Test 2: HTTP Throughput (wrk)

# Nginx w bridge mode
docker run -d --name nginx-bridge \
  --network my-bridge-net \
  -p 8080:80 \
  nginx:alpine

# Nginx w host mode
docker run -d --name nginx-host \
  --network host \
  nginx:alpine

# Test bridge
wrk -t12 -c400 -d30s http://localhost:8080

# Test host
wrk -t12 -c400 -d30s http://localhost:80

Wyniki HTTP:

TrybRequests/secTransfer/secLatencja p99
Bridge145,230117 MB/s8.2ms
Host186,450151 MB/s4.1ms
Różnica+28.3%+29%-50%
success
Wnioski z testów

Host mode oferuje wyraźnie lepszą wydajność:

  • 19-28% wyższa przepustowość
  • 47-73% niższa latencja
  • Niższe zużycie CPU na hoście

Dla aplikacji wymagających maksymalnej wydajności (np. load balancery, reverse proxy, bazy danych) host mode jest zdecydowanie lepszym wyborem.

Kiedy używać którego trybu?

Używaj Bridge Mode gdy:

✅ Potrzebujesz uruchomić wiele instancji tej samej aplikacji na różnych portach ✅ Izolacja sieciowa jest priorytetem (środowiska wielodostępne) ✅ Pracujesz z Docker Compose i chcesz łatwą komunikację między kontenerami ✅ Aplikacja nie jest krytyczna pod względem wydajności ✅ Potrzebujesz elastycznego mapowania portów

Przykłady: mikroservisy, aplikacje webowe, środowiska deweloperskie, CI/CD pipelines

Używaj Host Mode gdy:

✅ Wydajność i latencja są krytyczne ✅ Aplikacja musi obsługiwać bardzo duży ruch (>10k req/s) ✅ Potrzebujesz pełnego dostępu do interfejsów sieciowych ✅ Uruchamiasz jedną instancję aplikacji na hoście ✅ Aplikacja wymaga broadcast/multicast packets

Przykłady: load balancery (nginx, haproxy), bazy danych o wysokiej wydajności, monitoring tools, VPN servers

Zaawansowane techniki optymalizacji

1. Tuning parametrów kernela dla Docker networking

Dla aplikacji o wysokiej przepustowości, dostosuj parametry kernela:

# /etc/sysctl.d/99-docker-network.conf
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_congestion_control = bbr

# Zastosuj zmiany
sudo sysctl -p /etc/sysctl.d/99-docker-network.conf

2. Użycie IPv6 w niestandardowych sieciach

# Włącz IPv6 w Docker daemon
# /etc/docker/daemon.json
{
  "ipv6": true,
  "fixed-cidr-v6": "fd00::/80"
}

# Restart Docker
sudo systemctl restart docker

# Utwórz sieć z IPv6
docker network create --ipv6 \
  --subnet=172.20.0.0/16 \
  --subnet=fd00:20::/64 \
  my-dual-stack

3. Monitoring wydajności sieci

# Zainstaluj narzędzia do monitoringu
docker run -d --name=cadvisor \
  --network=host \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  gcr.io/cadvisor/cadvisor:latest

# Sprawdź statystyki sieci kontenera
docker stats nginx-bridge

# Szczegółowa analiza interfejsów
docker exec nginx-bridge cat /proc/net/dev

Troubleshooting - częste problemy

Problem 1: Kontenery bridge nie mogą się komunikować

danger
Błąd komunikacji

Kontenery w domyślnej sieci bridge nie mają automatycznego DNS resolution.

Rozwiązanie:

# NIE: używanie domyślnej sieci bridge
docker run -d --name app1 nginx
docker run -d --name app2 nginx

# TAK: użyj niestandardowej sieci
docker network create my-app-net
docker run -d --name app1 --network my-app-net nginx
docker run -d --name app2 --network my-app-net nginx

# Teraz app1 może pingować app2 po nazwie
docker exec app1 ping app2

Problem 2: Port już zajęty w host mode

warning
Port conflict

Próba uruchomienia dwóch kontenerów w host mode na tym samym porcie zakończy się błędem.

Rozwiązanie:

# Sprawdź zajęte porty
sudo ss -tlnp | grep :80

# Albo zmień port w aplikacji
docker run -d --network host \
  -e NGINX_PORT=8080 \
  custom-nginx

# Albo użyj bridge mode dla drugiej instancji
docker run -d -p 8080:80 nginx

Problem 3: MTU mismatch powoduje packet loss

# Sprawdź MTU na hoście
ip link show eth0

# Ustaw MTU dla sieci Docker
docker network create --driver bridge \
  --opt com.docker.network.driver.mtu=1450 \
  my-network-mtu

# Lub globalnie w daemon.json
{
  "mtu": 1450
}

Problem 4: Debugowanie połączeń sieciowych

# Zainstaluj narzędzia diagnostyczne w kontenerze
docker exec -it nginx-bridge sh
apk add bind-tools curl tcpdump net-tools

# Test DNS resolution
nslookup google.com

# Test connectivity
curl -v http://other-container:8080

# Capture pakietów (wymaga --cap-add=NET_ADMIN)
tcpdump -i eth0 -n

Podsumowanie

Wybór trybu sieciowego w Docker to kompromis między:

  • Wydajnością (host mode wygrywa)
  • Bezpieczeństwem i izolacją (bridge mode wygrywa)
  • Elastycznością (bridge mode wygrywa)

Szybki decision tree:

Potrzebujesz maksymalnej wydajności?
├─ TAK → Host mode
└─ NIE → Musisz uruchomić wiele instancji na tym samym porcie?
         ├─ TAK → Bridge mode (niestandardowa sieć)
         └─ NIE → Izolacja jest ważniejsza niż wydajność?
                  ├─ TAK → Bridge mode
                  └─ NIE → Host mode

Dla większości aplikacji polecam niestandardowe sieci bridge - oferują dobry balans między wydajnością, bezpieczeństwem i łatwością zarządzania.

Host mode rezerwuj dla aplikacji gdzie:

  • Wydajność jest absolutnie krytyczna
  • Uruchamiasz single-instance services
  • Potrzebujesz każdego miligrama przepustowości

Dodatkowe zasoby

info
Testuj w swoim środowisku

Przedstawione benchmarki są specyficzne dla mojego środowiska testowego. Zawsze przeprowadź własne testy w warunkach zbliżonych do produkcyjnych, aby podjąć świadomą decyzję!