Debugging Docker Bridge Network Connectivity Issues Preventing apt-get Update in Containers


5 views

When working with Docker containers in an OpenStack-managed VM environment, you might encounter a puzzling scenario where basic network operations work but package management fails:

docker run -it --rm debian:latest
root@123abc:/# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=117 time=2.637 ms

root@123abc:/# apt update
Err:1 http://deb.debian.org/debian buster InRelease
  Connection failed [IP: 199.232.138.132 80]

The key difference between --network host and bridge mode lies in how network isolation is handled:

  • Host mode: Shares the host's network stack completely
  • Bridge mode: Creates a virtual network interface with NAT

Here's how to systematically troubleshoot the problem:

# First, check DNS resolution
docker run --rm busybox nslookup deb.debian.org

# Verify MTU settings
docker run --rm alpine ip link show eth0

# Test raw HTTP connection
docker run --rm appropriate/curl -v http://deb.debian.org

# Check routing table
docker run --rm debian ip route show

In OpenStack environments, these are frequent offenders:

  1. Security group rules blocking outbound HTTP (port 80)
  2. MTU mismatches between host and container networks
  3. Proxy settings not being inherited correctly
  4. DNS resolution issues within the Neutron network

Here's how to handle MTU issues, which are particularly common in OpenStack:

# On the Docker host
ip link show | grep mtu

# Then in your Dockerfile
RUN echo "Acquire::http::Pipeline-Depth 0;" >> /etc/apt/apt.conf.d/99fixes
RUN echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99fixes
RUN echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99fixes

Creating a dedicated bridge network often resolves these issues:

docker network create --driver bridge \
  --opt "com.docker.network.bridge.name"="mybridge" \
  --opt "com.docker.network.bridge.hairpin_mode"="true" \
  --opt "com.docker.network.bridge.enable_ip_masquerade"="true" \
  custom_bridge

docker run -it --network=custom_bridge debian:latest

For temporary debugging, you can override DNS and use a different mirror:

docker run -it --rm --dns 8.8.8.8 \
  -e DEBIAN_FRONTEND=noninteractive \
  debian:latest bash -c \
  'echo "deb http://ftp.us.debian.org/debian buster main" > /etc/apt/sources.list && apt update'

When working with Docker containers in an OpenStack-managed VM environment, I encountered a puzzling scenario where basic network operations worked but package management failed:

docker run -it --rm debian:latest
# Inside container:
ping 8.8.8.8       # Success
ping google.com    # Success
apt-get update     # Fails with connection timeouts

The problem exhibits these characteristics:

  • Works perfectly with --network host mode
  • Fails on default bridge and custom bridge networks
  • Affects both Debian and Ubuntu base images
  • Only occurs in OpenStack VM environments

Here's how I approached troubleshooting:

# Check DNS resolution inside container:
docker run --rm debian cat /etc/resolv.conf

# Test raw HTTP connection:
docker run --rm debian bash -c "exec 3<>/dev/tcp/deb.debian.org/80; echo -e 'GET / HTTP/1.1\\r\\nhost: deb.debian.org\\r\\n\\r\\n' >&3; cat <&3"

After extensive testing, the issue stems from OpenStack's security groups and MTU settings:

  1. OpenStack VMs often have MTU set to 1450 (instead of standard 1500)
  2. Docker bridge networks don't automatically adjust for this
  3. Large packets from apt-get get fragmented and dropped

Option 1: Adjust Docker daemon settings

# Edit/create /etc/docker/daemon.json
{
  "mtu": 1450,
  "dns": ["8.8.8.8", "1.1.1.1"]
}

# Then restart Docker
systemctl restart docker

Option 2: Custom network with proper MTU

docker network create \
  --driver bridge \
  --opt "com.docker.network.driver.mtu=1450" \
  --subnet 172.28.0.0/16 \
  my-bridge-net

Option 3: Temporary workaround

docker run --rm -it --sysctl net.ipv4.ip_default_ttl=65 debian:latest

To confirm the solution works:

docker run --rm debian apt-get update
docker run --rm debian ping -M do -s 1472 8.8.8.8