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:
- Security group rules blocking outbound HTTP (port 80)
- MTU mismatches between host and container networks
- Proxy settings not being inherited correctly
- 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:
- OpenStack VMs often have MTU set to 1450 (instead of standard 1500)
- Docker bridge networks don't automatically adjust for this
- 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