Docker Container Network Interface Ordering

…it seems kinda random, yeah?

Lately I’ve found myself routinely attaching Docker-based containers to multiple networks. This has led to a couple… interesting surprises.

It doesn’t seem to be well documented (AFAIK), so here’s what I’ve learned. This isn’t a big serious how-to post, just something that irked me. 😄

Tooling (a little background)

Observed behavior

As this is observed behavior rather than documented (AFAICT, at any rate), it may change without warning.

Oh well.

For the purposes of this article, let’s say we’re using the following tools:

Network name determines ordering

What’s the actual network name?

When using Compose, there are really two network “names” for each network.

  1. The name specified in the Compose configuration; and
  2. The name Compose uses when creating the Docker network.

In a compose configuration, we always use #1 to refer to a network; however behind the scenes this will be different from the name of the network as known to Docker.

Networks are attached in alphabetical order. Internal networks are attached last, though still in alphabetical order.

Networks appear to be attached in alphabetical order, further segregated by the internal status. Not-internal networks are attached to the container before internal networks.

Let’s say we have a container with three networks attached:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
version: "3.9"

services:
  container1:
  image: docker.io/containous/whoami
    networks:
      backend: {}
      frontend: {}
      apples: {}
      oranges: {}

networks:
  backend: {}
  frontend: {}
  apples:
    internal: true
  oranges:
    name: lemons

Let’s say this has a project name of services. When container1 is launched, it will see a number of interfaces:

Interface Network (Compose) Network (Docker)
eth0 oranges lemons
eth1 backend services_backend
eth2 frontend services_frontend
eth3 apples services_apples

Why? apples is internal, so it ends up at the end of the list. oranges has an actual name of lemons, so it ends up before the other networks with a services_ prefix.

Default route is always through eth0

If you want a specific network to be the default route, you’re going to need to make sure it’s first – alphabetically.

Routing and macvlan interfaces

This is more of a corner case. If you’re attaching containers directly to a vlan/network using, say, macvlan, and that network ends up being your default route (app_vlan, anyone?), then all traffic for networks you’re not directly connected to will be routed over this vlan.

This may or may not matter, but if you have the (reasonable) expectation that non-local traffic will route through and be masqueraded by the host, this can be surprising.

0%