compose: The order in which networks are assigned to interfaces does not match the order they are listed in compose file
The following report was produced using Docker version 17.03.0-ce and compose version docker-compose version 1.11.2, build dfed245
.
Given a docker-compose.yml
that looks like this:
version: "2"
services:
server:
image: alpine
command: sleep 999
networks:
- nw0
- nw1
- nw2
- nw3
networks:
nw0:
nw1:
nw2:
nw3:
I would expect the networks to be assigned to interface in order, such that eth0
is attached to nw0
, eth1
is attached to nw1
, etc. This is exactly the behavior I see if I start a container using docker run
and then attach additional networks with docker network connect
.
However, when using docker-compose
and the above compose file, the ordering of networks and interfaces appears to be inconsistent. Assuming that the above compose file is in a directory named nwtest
, this script will demonstrate the problem:
#!/bin/sh
docker-compose up -d
for nw in 0 1 2 3; do
nw_cidr=$(docker network inspect -f '{{ (index .IPAM.Config 0).Subnet }}' \
nwtest_nw${nw})
if_cidr=$(docker exec -it nwtest_server_1 ip addr show eth${nw} |
awk '$1 == "inet" {print $2}')
nw_net=$(ipcalc -n $nw_cidr | cut -f2 -d=)
if_net=$(ipcalc -n $if_cidr | cut -f2 -d=)
echo "nw${nw} $nw_net eth${nw} ${if_net}"
if [ "$if_net" != "$nw_net" ]; then
echo "MISMATCH: nw${nw} = $nw_net, eth${nw} = $if_net" >&2
fi
done
docker-compose stop
On my system, that produces as output:
Starting nwtest_server_1
nw0 192.168.32.0 eth0 192.168.32.0
nw1 192.168.48.0 eth1 192.168.48.0
nw2 192.168.64.0 eth2 192.168.80.0
MISMATCH: nw2 = 192.168.64.0, eth2 = 192.168.80.0
nw3 192.168.80.0 eth3 192.168.64.0
MISMATCH: nw3 = 192.168.80.0, eth3 = 192.168.64.0
Stopping nwtest_server_1 ... done
For comparison, here is a script that performs the same test using docker run
and manual attachment:
#!/bin/sh
docker rm -f nwtest_server_1
docker run -d --name nwtest_server_1 --network nwtest_nw0 \
alpine sleep 999
for nw in 1 2 3; do
docker network connect nwtest_nw${nw} nwtest_server_1
done
for nw in 0 1 2 3; do
nw_cidr=$(docker network inspect -f '{{ (index .IPAM.Config 0).Subnet }}' \
nwtest_nw${nw})
if_cidr=$(docker exec -it nwtest_server_1 ip addr show eth${nw} |
awk '$1 == "inet" {print $2}')
nw_net=$(ipcalc -n $nw_cidr | cut -f2 -d=)
if_net=$(ipcalc -n $if_cidr | cut -f2 -d=)
echo "nw${nw} $nw_net eth${nw} ${if_net}"
if [ "$if_net" != "$nw_net" ]; then
echo "MISMATCH: nw${nw} = $nw_net, eth${nw} = $if_net" >&2
fi
done
docker rm -f nwtest_server_1
This always runs without error.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 8
- Comments: 15
+1 form me as well. Editing my response to add some details. I thought about what @johnharris85 mentioned, so I numbered my network names in the order I want them to be connected and I can get around the issue for now.
For example part of my compose looks like this: networks: – 1firstnw – 2nw – 3nw
Hope this helps someone.
@gentunian after looking at the code, I don’t see any difference in handling network priorities between v2 and v3. See https://github.com/docker/compose/blob/master/compose/network.py#L325, and PR docker/compose#5566 clearly show that v3 is ok since at least jan 2018…
however, a rapid test shows that priorities are currently ignored by docker, would you choose v2 or v3… lexical order of network names seems to be overriding the priorities you set. see https://gist.github.com/jfellus/cfee9efc1e8e1baf9d15314f16a46eca
(the answer to this may also answer https://github.com/docker/cli/issues/1372)