컨테이너 네트워킹(Container Networking)

컨테이너 네트워킹(Container Networking)

학습 목표

  • Docker 네트워크 드라이버(Network Drivers)와 사용 사례 이해
  • 브리지(Bridge), 호스트(Host), 오버레이(Overlay), 맥브이랜(Macvlan) 네트워크 마스터하기
  • 서브넷(Subnet), 게이트웨이(Gateway), DNS를 사용한 커스텀 네트워크 구성
  • 서비스 디스커버리(Service Discovery)와 컨테이너 간 통신 구현
  • 네트워크 연결성 문제 해결
  • 네트워크 보안 모범 사례 적용

목차

  1. Docker 네트워크 드라이버
  2. 브리지 네트워크 심화
  3. 호스트 및 None 네트워크
  4. 오버레이 네트워크
  5. 네트워크 구성
  6. DNS와 서비스 디스커버리
  7. 고급 포트 매핑
  8. 네트워크 보안
  9. 문제 해결
  10. 연습 문제

난이도: ⭐⭐⭐


1. Docker 네트워크 드라이버

Docker는 다양한 사용 사례를 위한 여러 네트워크 드라이버를 제공합니다.

네트워크 드라이버 개요

┌─────────────────────────────────────────────────────────────┐
│                    Docker Network Drivers                    │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │  bridge  │  │   host   │  │ overlay  │  │ macvlan  │   │
│  │          │  │          │  │          │  │          │   │
│  │ Default  │  │  Native  │  │  Swarm   │  │  Legacy  │   │
│  │ Isolated │  │  Network │  │Multi-host│  │  Bridge  │   │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘   │
│                                                              │
│              ┌──────────┐                                    │
│              │   none   │                                    │
│              │          │                                    │
│              │ Disabled │                                    │
│              └──────────┘                                    │
└─────────────────────────────────────────────────────────────┘

네트워크 나열

# List all networks
docker network ls

# Output:
# NETWORK ID     NAME      DRIVER    SCOPE
# 3c7f2a8b4d91   bridge    bridge    local
# 9f8e3d2c1a45   host      host      local
# 1b5a6c9d3e72   none      null      local

네트워크 검사

# Detailed network information
docker network inspect bridge

# Output (truncated):
# [
#     {
#         "Name": "bridge",
#         "Driver": "bridge",
#         "IPAM": {
#             "Config": [
#                 {
#                     "Subnet": "172.17.0.0/16",
#                     "Gateway": "172.17.0.1"
#                 }
#             ]
#         },
#         "Containers": {...}
#     }
# ]

네트워크 드라이버 사용 사례

드라이버(Driver) 사용 사례 범위(Scope) DNS
bridge 단일 호스트, 격리된 컨테이너 Local Yes (사용자 정의)
host 높은 성능, 격리 없음 Local Host DNS
overlay 다중 호스트, Swarm 서비스 Swarm Yes
macvlan MAC 주소가 필요한 레거시 앱 Local No
none 완전한 격리, 커스텀 네트워킹 Local No

2. 브리지 네트워크 심화

브리지 네트워크(Bridge Network)는 컨테이너에 가장 일반적인 네트워크 유형입니다.

기본 브리지 vs 사용자 정의 브리지

Default Bridge Network              User-Defined Bridge Network
┌──────────────────────┐            ┌──────────────────────┐
│   172.17.0.0/16      │            │   172.20.0.0/16      │
│                      │            │                      │
│  ┌────────────┐      │            │  ┌────────────┐      │
│  │ Container1 │      │            │  │ Container1 │      │
│  │ 172.17.0.2 │      │            │  │ 172.20.0.2 │      │
│  │            │      │            │  │ web        │      │
│  └────────────┘      │            │  └────────────┘      │
│                      │            │         │            │
│  ┌────────────┐      │            │         │ DNS        │
│  │ Container2 │      │            │         ▼            │
│  │ 172.17.0.3 │      │            │  ┌────────────┐      │
│  │            │      │            │  │ Container2 │      │
│  └────────────┘      │            │  │ 172.20.0.3 │      │
│                      │            │  │ db         │      │
│  No automatic DNS    │            │  └────────────┘      │
│  Link by IP only     │            │                      │
└──────────────────────┘            │  Automatic DNS       │
                                    │  Link by name        │
                                    └──────────────────────┘

사용자 정의 브리지 네트워크 생성

# Create custom bridge network
docker network create my-app-network

# Create with custom subnet
docker network create \
  --driver bridge \
  --subnet 172.25.0.0/16 \
  --gateway 172.25.0.1 \
  my-custom-network

# Create with IP range reservation
docker network create \
  --subnet 172.26.0.0/16 \
  --ip-range 172.26.5.0/24 \
  my-reserved-network

브리지 네트워크에 컨테이너 연결

# Run container on custom network
docker run -d \
  --name web \
  --network my-app-network \
  nginx

# Run another container on same network
docker run -d \
  --name db \
  --network my-app-network \
  postgres

# Test DNS resolution
docker exec web ping db
# PING db (172.25.0.3): 56 data bytes
# 64 bytes from 172.25.0.3: seq=0 ttl=64 time=0.123 ms

런타임에 네트워크 연결/연결 해제

# Connect running container to additional network
docker network connect my-app-network my-container

# Disconnect from network
docker network disconnect my-app-network my-container

# Connect with static IP
docker network connect --ip 172.25.0.100 my-app-network my-container

Docker Compose 브리지 네트워크

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    networks:
      - frontend
      - backend

  app:
    image: myapp:latest
    networks:
      backend:
        ipv4_address: 172.28.0.100

  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1

3. 호스트 및 None 네트워크

호스트 네트워크(Host Network)

컨테이너가 호스트의 네트워크 스택을 직접 공유합니다.

┌─────────────────────────────────────────┐
│            Host Network                  │
│  ┌───────────────────────────────────┐  │
│  │         Host OS Network           │  │
│  │                                   │  │
│  │  ┌──────────┐    ┌──────────┐    │  │
│  │  │Container1│    │Container2│    │  │
│  │  │  :80     │    │  :443    │    │  │
│  │  └──────────┘    └──────────┘    │  │
│  │                                   │  │
│  │  No network isolation             │  │
│  │  Direct host network access       │  │
│  └───────────────────────────────────┘  │
└─────────────────────────────────────────┘

사용 사례: - 높은 네트워크 성능 (NAT 오버헤드 없음) - 네트워크 모니터링 도구 - 호스트 네트워크 기능이 필요한 서비스

제한 사항: - 네트워크 격리 없음 - 호스트와의 포트 충돌 - 동일한 포트에서 여러 컨테이너를 실행할 수 없음

# Run container with host network
docker run -d \
  --name nginx-host \
  --network host \
  nginx

# Container listens on host's port 80 directly
# No -p flag needed (ignored if specified)

# Check listening ports
netstat -tlnp | grep 80
# tcp  0  0  0.0.0.0:80  0.0.0.0:*  LISTEN  12345/nginx

성능 비교

# Bridge network (with NAT)
docker run --rm --network bridge alpine ping -c 4 8.8.8.8
# avg RTT: ~0.5ms overhead

# Host network (no NAT)
docker run --rm --network host alpine ping -c 4 8.8.8.8
# avg RTT: native host performance

None 네트워크

완전한 네트워크 격리.

┌─────────────────────────────────────────┐
│           None Network                   │
│                                          │
│        ┌──────────────┐                  │
│        │  Container   │                  │
│        │              │                  │
│        │  No network  │                  │
│        │  interface   │                  │
│        │              │                  │
│        │  Only: lo    │                  │
│        └──────────────┘                  │
│                                          │
└─────────────────────────────────────────┘

사용 사례: - 완전한 네트워크 격리 - 커스텀 네트워크 스택 구현 - 테스트 시나리오

# Run container with no network
docker run -d \
  --name isolated \
  --network none \
  alpine sleep 3600

# Verify no network interfaces (except loopback)
docker exec isolated ip addr
# 1: lo: <LOOPBACK,UP,LOWER_UP>
#     inet 127.0.0.1/8 scope host lo

4. 오버레이 네트워크

오버레이 네트워크(Overlay Network)는 Docker Swarm에서 다중 호스트 컨테이너 통신을 가능하게 합니다.

오버레이 네트워크 아키텍처

┌─────────────────────────────────────────────────────────────┐
│                    Overlay Network                           │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌─────────────────────┐      ┌─────────────────────┐      │
│  │    Host 1           │      │    Host 2           │      │
│  │  ┌──────────────┐   │      │  ┌──────────────┐   │      │
│  │  │ Container A  │   │◄────►│  │ Container B  │   │      │
│  │  │ 10.0.0.2     │   │VXLAN │  │ 10.0.0.3     │   │      │
│  │  └──────────────┘   │Tunnel│  └──────────────┘   │      │
│  │                     │      │                     │      │
│  │  Physical: 192.168.1.10    │  Physical: 192.168.1.20  │
│  └─────────────────────┘      └─────────────────────┘      │
│                                                              │
│  Overlay subnet: 10.0.0.0/24                                │
│  Underlay network: 192.168.1.0/24                           │
└─────────────────────────────────────────────────────────────┘

오버레이 네트워크 생성

# Initialize Swarm (required for overlay networks)
docker swarm init --advertise-addr 192.168.1.10

# Create overlay network
docker network create \
  --driver overlay \
  --subnet 10.0.9.0/24 \
  my-overlay

# Create with encryption
docker network create \
  --driver overlay \
  --opt encrypted \
  --subnet 10.0.10.0/24 \
  secure-overlay

# Create attachable overlay (for standalone containers)
docker network create \
  --driver overlay \
  --attachable \
  --subnet 10.0.11.0/24 \
  attachable-overlay

오버레이 네트워크에 서비스 배포

# Create service on overlay network
docker service create \
  --name web \
  --network my-overlay \
  --replicas 3 \
  nginx

# Create backend service
docker service create \
  --name api \
  --network my-overlay \
  --replicas 2 \
  myapi:latest

# Services can communicate by name across hosts
docker exec <web-container> curl http://api:8080

Docker Compose와 오버레이 (Swarm Stack)

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    deploy:
      replicas: 3
    networks:
      - frontend

  api:
    image: myapi:latest
    deploy:
      replicas: 2
    networks:
      - frontend
      - backend

  db:
    image: postgres
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
    networks:
      - backend
    volumes:
      - db-data:/var/lib/postgresql/data

networks:
  frontend:
    driver: overlay
  backend:
    driver: overlay
    driver_opts:
      encrypted: "true"

volumes:
  db-data:
# Deploy stack
docker stack deploy -c docker-compose.yml myapp

# List networks
docker network ls
# NETWORK ID     NAME              DRIVER    SCOPE
# abc123def456   myapp_frontend    overlay   swarm
# def789ghi012   myapp_backend     overlay   swarm

오버레이 네트워크 암호화

# Create encrypted overlay
docker network create \
  --driver overlay \
  --opt encrypted=true \
  --subnet 10.0.20.0/24 \
  encrypted-net

# IPsec encrypts VXLAN traffic between nodes
# Performance impact: ~10-20% overhead

5. 네트워크 구성

커스텀 서브넷과 게이트웨이

# Create network with custom IPAM
docker network create \
  --driver bridge \
  --subnet 172.30.0.0/16 \
  --gateway 172.30.0.1 \
  --ip-range 172.30.5.0/24 \
  --aux-address "my-router=172.30.1.1" \
  custom-net

MTU 구성

# Set MTU (Maximum Transmission Unit)
docker network create \
  --driver bridge \
  --opt com.docker.network.driver.mtu=1450 \
  low-mtu-net

# Useful for:
# - VPN/overlay networks (avoid fragmentation)
# - Cloud environments (GCP: 1460, AWS: 9001 for jumbo frames)

IPv6 지원

# Enable IPv6 in daemon.json
# /etc/docker/daemon.json
{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}

# Restart Docker
sudo systemctl restart docker

# Create network with IPv6
docker network create \
  --ipv6 \
  --subnet 172.31.0.0/16 \
  --subnet 2001:db8:2::/64 \
  ipv6-net

네트워크 드라이버 옵션

# Bridge options
docker network create \
  --driver bridge \
  --opt com.docker.network.bridge.name=my-bridge \
  --opt com.docker.network.bridge.enable_icc=true \
  --opt com.docker.network.bridge.enable_ip_masquerade=true \
  my-configured-net

일반 옵션: - com.docker.network.bridge.name: 커스텀 브리지 인터페이스 이름 - com.docker.network.bridge.enable_icc: 컨테이너 간 통신(Inter-Container Communication) (기본값: true) - com.docker.network.bridge.enable_ip_masquerade: 외부 트래픽을 위한 NAT (기본값: true) - com.docker.network.driver.mtu: MTU 크기 (기본값: 1500)


6. DNS와 서비스 디스커버리

임베디드 DNS 서버

Docker는 컨테이너 이름에 대한 자동 DNS 해석을 제공합니다.

┌─────────────────────────────────────────┐
│         User-Defined Network            │
│                                         │
│  ┌──────────┐         ┌──────────┐     │
│  │   web    │         │   db     │     │
│  │          │         │          │     │
│  │          │──DNS───►│          │     │
│  │          │  query  │          │     │
│  │          │  "db"   │          │     │
│  └──────────┘         └──────────┘     │
│       │                                 │
│       │ DNS query                       │
│       ▼                                 │
│  ┌─────────────────────────┐           │
│  │  Embedded DNS Server    │           │
│  │  (127.0.0.11:53)        │           │
│  │                         │           │
│  │  web → 172.20.0.2       │           │
│  │  db  → 172.20.0.3       │           │
│  └─────────────────────────┘           │
└─────────────────────────────────────────┘

DNS 해석 예제

# Create network and containers
docker network create my-net
docker run -d --name web --network my-net nginx
docker run -d --name db --network my-net postgres

# Test DNS resolution
docker exec web nslookup db
# Server:    127.0.0.11
# Address:   127.0.0.11:53
#
# Name:      db
# Address:   172.20.0.3

# Ping by container name
docker exec web ping -c 2 db
# PING db (172.20.0.3): 56 data bytes
# 64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.123 ms

커스텀 DNS 구성

# Run container with custom DNS servers
docker run -d \
  --name custom-dns \
  --dns 8.8.8.8 \
  --dns 8.8.4.4 \
  --dns-search example.com \
  nginx

# Verify DNS configuration
docker exec custom-dns cat /etc/resolv.conf
# nameserver 8.8.8.8
# nameserver 8.8.4.4
# search example.com

Docker Compose에서 서비스 디스커버리

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    networks:
      - app-net

  api:
    image: myapi:latest
    environment:
      # Resolve by service name
      - DATABASE_URL=postgresql://db:5432/mydb
    networks:
      - app-net

  db:
    image: postgres
    networks:
      - app-net

networks:
  app-net:
    driver: bridge

DNS 라운드 로빈 (여러 컨테이너)

# Create multiple containers with same name (using --network-alias)
docker run -d --name api1 --network my-net --network-alias api myapi:latest
docker run -d --name api2 --network my-net --network-alias api myapi:latest
docker run -d --name api3 --network my-net --network-alias api myapi:latest

# DNS query returns all IPs (round-robin)
docker run --rm --network my-net alpine nslookup api
# Name:      api
# Address:   172.20.0.2
# Address:   172.20.0.3
# Address:   172.20.0.4

7. 고급 포트 매핑

포트 퍼블리싱 모드

# Publish to random host port
docker run -d -P nginx
# Maps all EXPOSE ports to random high ports (32768+)

# Publish to specific host port
docker run -d -p 8080:80 nginx

# Publish to specific interface
docker run -d -p 127.0.0.1:8080:80 nginx
# Only accessible from localhost

# Publish UDP port
docker run -d -p 53:53/udp dns-server

# Publish port range
docker run -d -p 5000-5010:5000-5010 multi-port-app

포트 매핑 다이어그램

┌──────────────────────────────────────────────────────────┐
│                    Host (192.168.1.100)                   │
│                                                           │
│  ┌─────────────────────────────────────────────────┐    │
│  │              iptables NAT                        │    │
│  │                                                  │    │
│  │  8080 ──► DNAT ──► 172.17.0.2:80               │    │
│  │  8443 ──► DNAT ──► 172.17.0.2:443              │    │
│  └─────────────────────────────────────────────────┘    │
│                          │                               │
│                          ▼                               │
│  ┌─────────────────────────────────────────────────┐    │
│  │         Docker Bridge (docker0)                 │    │
│  │                                                  │    │
│  │         ┌──────────────────┐                    │    │
│  │         │   nginx          │                    │    │
│  │         │   172.17.0.2     │                    │    │
│  │         │   :80, :443      │                    │    │
│  │         └──────────────────┘                    │    │
│  └─────────────────────────────────────────────────┘    │
└──────────────────────────────────────────────────────────┘

External request: http://192.168.1.100:8080
    ↓
NAT translation: 172.17.0.2:80
    ↓
Container receives request on port 80

Docker Compose 포트 매핑

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    ports:
      # Short syntax
      - "8080:80"
      - "8443:443"

      # Long syntax
      - target: 80
        published: 8080
        protocol: tcp
        mode: host

      # Localhost only
      - "127.0.0.1:9090:9090"

      # Port range
      - "5000-5010:5000-5010"

포트 매핑 검사

# List port mappings
docker port nginx
# 80/tcp -> 0.0.0.0:8080
# 443/tcp -> 0.0.0.0:8443

# Inspect with docker ps
docker ps --format "table {{.Names}}\t{{.Ports}}"
# NAMES    PORTS
# nginx    0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp

8. 네트워크 보안

네트워크 격리

┌─────────────────────────────────────────────────────────┐
│                  Network Isolation                       │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌──────────────────┐        ┌──────────────────┐      │
│  │  frontend-net    │        │  backend-net     │      │
│  │                  │        │                  │      │
│  │  ┌────────┐      │        │  ┌────────┐     │      │
│  │  │  web   │      │        │  │  api   │     │      │
│  │  └────────┘      │        │  └────────┘     │      │
│  │                  │        │        │         │      │
│  └──────────────────┘        │        │         │      │
│                               │  ┌────────┐     │      │
│                               │  │  db    │     │      │
│                               │  └────────┘     │      │
│                               └──────────────────┘      │
│                                                          │
│  web CANNOT communicate with db directly                │
│  api bridges both networks                              │
└─────────────────────────────────────────────────────────┘
# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    networks:
      - frontend

  api:
    image: myapi:latest
    networks:
      - frontend
      - backend

  db:
    image: postgres
    networks:
      - backend
    # db is NOT exposed to frontend network

networks:
  frontend:
  backend:
    internal: true  # No external access

내부 네트워크(Internal Networks)

# Create internal network (no external access)
docker network create \
  --internal \
  --subnet 172.40.0.0/16 \
  internal-net

# Containers on this network cannot reach internet
docker run -d --name isolated-db --network internal-net postgres

컨테이너 간 통신(ICC)

# Disable ICC (containers can't talk to each other by default)
docker network create \
  --driver bridge \
  --opt com.docker.network.bridge.enable_icc=false \
  restricted-net

# Containers must use port publishing to communicate

iptables를 사용한 네트워크 정책

# View Docker iptables rules
sudo iptables -t nat -L -n -v | grep DOCKER

# Block traffic between specific containers (manual iptables)
sudo iptables -I DOCKER-USER -s 172.17.0.2 -d 172.17.0.3 -j DROP

# Allow only specific ports
sudo iptables -I DOCKER-USER -p tcp --dport 5432 -s 172.17.0.2 -j ACCEPT
sudo iptables -I DOCKER-USER -s 172.17.0.2 -j DROP

암호화된 오버레이 네트워크

# All traffic between nodes is encrypted with IPsec
docker network create \
  --driver overlay \
  --opt encrypted=true \
  secure-overlay

9. 문제 해결

네트워크 검사 명령어

# Inspect network details
docker network inspect my-net

# Show containers on network
docker network inspect my-net --format '{{range .Containers}}{{.Name}} {{end}}'

# Show network configuration of container
docker inspect my-container --format '{{json .NetworkSettings.Networks}}'

연결성 테스트

# Ping between containers
docker exec container1 ping container2

# Test DNS resolution
docker exec container1 nslookup container2

# Test port connectivity
docker exec container1 nc -zv container2 80

# Test with curl
docker exec container1 curl http://container2:8080

패킷 캡처

# Capture traffic on docker0 bridge
sudo tcpdump -i docker0 -n

# Capture traffic for specific container
# Find container's veth interface
docker inspect my-container --format '{{.NetworkSettings.SandboxKey}}'
# /var/run/docker/netns/abc123def456

# Enter network namespace and capture
sudo nsenter --net=/var/run/docker/netns/abc123def456 tcpdump -i eth0 -n

# Or use docker exec with tcpdump
docker exec my-container tcpdump -i eth0 -n

일반적인 네트워크 문제

문제 1: 컨테이너가 인터넷에 접근할 수 없음

# Check DNS configuration
docker exec my-container cat /etc/resolv.conf

# Test DNS resolution
docker exec my-container nslookup google.com

# Test connectivity
docker exec my-container ping 8.8.8.8

# Solution: Check IP masquerading
sudo iptables -t nat -L -n | grep MASQUERADE
# Should see: MASQUERADE  all  --  172.17.0.0/16  0.0.0.0/0

문제 2: 컨테이너가 이름으로 통신할 수 없음

# Only works on user-defined networks, NOT default bridge
# Solution: Create custom network
docker network create my-net
docker network connect my-net container1
docker network connect my-net container2

문제 3: 포트가 이미 사용 중

# Find process using port
sudo lsof -i :8080
# or
sudo netstat -tlnp | grep 8080

# Solution: Stop conflicting process or use different port
docker run -d -p 8081:80 nginx

문제 4: DNS 해석 느림

# Check embedded DNS server
docker exec my-container cat /etc/resolv.conf
# Should see: nameserver 127.0.0.11

# Test DNS performance
docker exec my-container time nslookup container2

# Solution: Add custom DNS servers if needed
docker run --dns 8.8.8.8 --dns 8.8.4.4 my-image

네트워크 디버깅 도구

# Run debugging container with network tools
docker run -it --rm --network my-net nicolaka/netshoot

# Available tools in netshoot:
# - ping, traceroute, mtr
# - nslookup, dig, host
# - curl, wget, httpie
# - netcat, socat
# - tcpdump, tshark
# - iftop, nethogs
# - ip, ss, netstat, iptables

네트워크 로그 보기

# Enable debug logging in Docker daemon
# /etc/docker/daemon.json
{
  "debug": true,
  "log-level": "debug"
}

# Restart Docker
sudo systemctl restart docker

# View logs
sudo journalctl -u docker -f

10. 연습 문제

연습 1: 다계층 애플리케이션 네트워크

격리된 네트워크로 3계층 애플리케이션을 생성합니다.

# docker-compose.yml
version: '3.8'

services:
  nginx:
    image: nginx
    ports:
      - "80:80"
    networks:
      - frontend
    depends_on:
      - app

  app:
    image: node:18
    command: node server.js
    networks:
      - frontend
      - backend
    depends_on:
      - db

  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: secret
    networks:
      - backend

networks:
  frontend:
  backend:
    internal: true

작업: 1. 스택 배포 2. nginx가 app에 접근할 수 있는지 확인 3. app이 db에 접근할 수 있는지 확인 4. nginx가 db에 직접 접근할 수 없는지 확인 5. db가 인터넷 접근이 없는지 확인

연습 2: 정적 IP를 사용한 커스텀 브리지 네트워크

# Create network with specific subnet
docker network create \
  --driver bridge \
  --subnet 172.50.0.0/24 \
  --gateway 172.50.0.1 \
  --ip-range 172.50.0.128/25 \
  static-net

# Run containers with static IPs
docker run -d \
  --name web \
  --network static-net \
  --ip 172.50.0.10 \
  nginx

docker run -d \
  --name api \
  --network static-net \
  --ip 172.50.0.20 \
  myapi:latest

docker run -d \
  --name db \
  --network static-net \
  --ip 172.50.0.30 \
  postgres

작업: 1. 컨테이너가 할당된 IP를 가지는지 확인 2. 컨테이너 간 연결성 테스트 3. IP 할당 체계 문서화

연습 3: DNS 라운드 로빈 로드 밸런싱

# Create network
docker network create lb-net

# Create multiple backend containers with same alias
for i in 1 2 3; do
  docker run -d \
    --name backend-$i \
    --network lb-net \
    --network-alias backend \
    hashicorp/http-echo -text="Backend $i"
done

# Create client container
docker run -it --rm \
  --network lb-net \
  alpine sh

# Test DNS round-robin
for i in {1..6}; do
  wget -qO- http://backend:5678
done

예상 출력:

Backend 1
Backend 2
Backend 3
Backend 1
Backend 2
Backend 3

연습 4: 네트워크 문제 해결

손상된 네트워크 설정을 식별하고 수정합니다.

# broken-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    ports:
      - "80:80"
    networks:
      - frontend

  api:
    image: myapi:latest
    environment:
      - DB_HOST=db
    networks:
      - frontend  # BUG: Should be on backend too

  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
  backend:

작업: 1. 배포하고 api가 db에 접근할 수 없는 이유 식별 2. 네트워크 구성 수정 3. 모든 서비스가 올바르게 통신할 수 있는지 확인 4. 문제와 해결책 문서화

연습 5: 안전한 다중 호스트 네트워크

# On host1 (manager)
docker swarm init --advertise-addr 192.168.1.10

# Create encrypted overlay network
docker network create \
  --driver overlay \
  --opt encrypted=true \
  --attachable \
  secure-overlay

# Deploy service
docker service create \
  --name web \
  --network secure-overlay \
  --replicas 3 \
  nginx

# On host2 (worker)
docker swarm join --token <token> 192.168.1.10:2377

# Verify service spans both hosts
docker service ps web

작업: 1. 2노드 Swarm 클러스터 설정 2. 암호화된 오버레이 네트워크 생성 3. 노드 간 서비스 배포 4. 트래픽을 캡처하고 암호화 확인 5. 교차 호스트 컨테이너 통신 테스트

연습 6: 네트워크 성능 테스트

# Create test network
docker network create perf-net

# Run iperf3 server
docker run -d \
  --name iperf-server \
  --network perf-net \
  networkstatic/iperf3 -s

# Run iperf3 client (bridge network)
docker run --rm \
  --network perf-net \
  networkstatic/iperf3 -c iperf-server -t 30

# Run iperf3 client (host network)
docker run --rm \
  --network host \
  networkstatic/iperf3 -c <host-ip> -t 30

작업: 1. 브리지 네트워크에서 대역폭 측정 2. 호스트 네트워크에서 대역폭 측정 3. 결과 비교 및 오버헤드 문서화 4. 다양한 MTU 크기로 테스트


요약

이 레슨에서 배운 내용:

  • Docker 네트워크 드라이버: bridge, host, overlay, macvlan, none
  • 자동 DNS 해석을 지원하는 사용자 정의 브리지 네트워크
  • 성능을 위한 호스트 네트워크와 격리를 위한 none 네트워크
  • Swarm에서 다중 호스트 통신을 위한 오버레이 네트워크
  • 커스텀 네트워크 구성: 서브넷, 게이트웨이, IP 범위, MTU
  • 임베디드 DNS 서버를 사용한 DNS 및 서비스 디스커버리
  • 고급 포트 매핑 및 퍼블리싱 옵션
  • 네트워크 보안: 격리, 내부 네트워크, 암호화
  • 네트워크 디버깅을 위한 문제 해결 도구 및 기법

핵심 요점: - 자동 DNS 해석을 위해 항상 사용자 정의 네트워크 사용 - 보안을 위해 여러 네트워크로 서비스 격리 - 다중 호스트 배포를 위해 암호화된 오버레이 네트워크 사용 - 서비스 디스커버리를 위해 임베디드 DNS 활용 - 적절한 도구로 모니터링 및 문제 해결

다음 단계: - 프로덕션 환경을 위한 네트워크 정책 구현 - 고급 네트워킹을 위한 서비스 메시 솔루션 (Istio, Linkerd) 탐색 - Kubernetes용 CNI 플러그인 학습 - 네트워크 성능 최적화 기법 연구


이전: 10_CI_CD_Pipelines | 다음: 12_Security_Best_Practices

to navigate between lessons