Reputation: 6772
For a testing situation, I've created a docker-compose file which stands up two containers:
version: "3.8"
services:
foo:
ports:
- 5000:5000/tcp
networks:
- default
...
bar:
networks:
- default
...
networks:
default:
ipam:
driver: internal
config:
- subnet: 172.100.0.0/16
For the purposes of my tests, I need bar
to be unreachable from the host. Unfortunately, when I run docker-compose up
, ip addr
shows that my host is on that network at 172.100.0.1
.
How do I change my YAML file to accomplish this?
Upvotes: 1
Views: 122
Reputation: 312630
Caveat The address range you've selected (172.100.0.0/16) is a routeable address range that apparently belongs to charter communications. This means that attempts to reach addresses in that range -- if there's not a specific route to your containers -- will get routed via your default gateway and potentially to actual machines somewhere on the internet.
Anyway, to your question:
I don't believe this is going to be possible using only Docker. For a bridged network, Docker will (a) always create a host bridge and (b) always assign an ip address to that bridge, which means containers will always be routable from the host.
You can create containers that have no network connectivity by using the none
network:
version: "3.8"
services:
foo:
network_mode: none
image: docker.io/alpinelinux/darkhttpd
bar:
network_mode: none
image: docker.io/alpinelinux/darkhttpd
And then manually wire them up to a bridge using ip
commands:
ip link add br-internal type bridge
ip link set br-internal up
foo_pid="$(docker inspect project_foo_1 --format '{{ .State.Pid }}')"
bar_pid="$(docker inspect project_bar_1 --format '{{ .State.Pid }}')"
ln -s /proc/$foo_pid/ns/net /run/netns/foo
ln -s /proc/$bar_pid/ns/net /run/netns/bar
ip link add foo-ext type veth peer name foo-int netns foo
ip -n foo addr add 172.100.0.10/26 dev foo-int
ip -n foo link set foo-int up
ip link set foo-ext up master br-internal
ip link add bar-ext type veth peer name bar-int netns bar
ip -n bar addr add 172.100.0.11/26 dev bar-int
ip -n bar link set bar-int up
ip link set bar-ext up master br-internal
Now we can ping bar
from foo
:
$ docker compose exec foo ping -c1 172.100.0.11
PING 172.100.0.11 (172.100.0.11): 56 data bytes
64 bytes from 172.100.0.11: seq=0 ttl=42 time=0.080 ms
--- 172.100.0.11 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.080/0.080/0.080 ms
And foo
from bar
:
$ docker compose exec bar ping -c1 172.100.0.10
PING 172.100.0.10 (172.100.0.10): 56 data bytes
64 bytes from 172.100.0.10: seq=0 ttl=42 time=0.047 ms
--- 172.100.0.10 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.047/0.047/0.047 ms
But our host doesn't have a route to either of these addresses:
$ ip route get 172.100.0.10
172.100.0.10 via 192.168.1.1 dev eth0 src 192.168.1.175 uid 1000
cache
That shows that attempts to reach addresses on this network will get routed via our default gateway, rather than to the containers.
Upvotes: 2