ruk·si

🐋 Docker
Networking

Updated at 2019-06-26 14:40

Docker has the following default networks drivers:

  • none: disable all networking
  • host: containers attach to the host network interface
  • bridge: connect containers running on the same host
  • overlay: connect containers running on separate hosts
  • macvlan: containers appear as physical devices with their own MAC address
  • ipvlan l2: containers share MAC address with host but otherwise appear different
  • ipvlan l3: containers use the host machine like a router, but requires routing config

--network=none

The container has no network connections so you can't access anything.

--network=host

host network driver is useful for quick setups where you have a container running on a host and you don't want to isolate the container network from the host network.

This might have security implications e.g. when running on default cloud provider network configurations as the internal private networks have pretty lax restrictions.

All published ports will be accessible through the host machine IP. Notice that host networking has no effect if the container doesn't publish any ports.

--network=bridge

The standard bridge network named bridge is used by containers by default. The default bridge network is inferior to user-defined bridge networks, so always create your own networks if you require Docker networking.

  • User-defined bridge networks provide better isolation as you can have multiple ones.
  • User-defined bridge networks allow DNS resolution by container name, not just IP.
  • User-defined bridge networks allow attaching and detaching containers.
  • User-defined bridge networks have a lot more configuration options.

bridge networks are used to connect containers running on a same host. If the containers are running on separate Docker daemon hosts, you need to use an overlay network or do the routing at the OS level.

docker network ls
# NETWORK ID          NAME                DRIVER              SCOPE
# 19c8ad9562d5        bridge              bridge              local    <- default
# 8216856f8213        host                host                local
# deac008fe9ed        none                null                local

docker network create --driver=bridge mega-net
# 59529347a82e        mega-net            bridge              local

# NOTE: you can also use the "bridge" network, but that won't work on Docker for Mac
#       as that interface is inside a virtual machine

docker run --rm -it --network=mega-net --name db busybox
ping web

docker run --rm -it --network=mega-net --name web busybox
ping db

# leave the pings running, outside the containers...
docker network disconnect mega-net db
# now pings won't work
docker network connect mega-net db
# now they work again

docker network inspect mega-net     # details, containers in network, etc. in JSON
docker network prune -f             # remove unused networks, except the 3 defaults

--network=overlay

You can connect swarm services and standalone containers to overlay networks.

Prerequisites:

  • Host ports: TCP 2377, TCP 7946, UDP 7946, UDP 4789
  • If you want to ping, allow ICMP Echo Reply
  • Host Docker daemons must either 1) be a swarm manager 2) be part of a swarm, even you are not using swarm services.
docker swarm init
# copy and use the given command on the second machine

docker network create -d overlay --attachable hyper-net
# --attachable is only required for standalone networks

All ports are exposed between containers in an overlay network. You only need to publish ports for external access.

# Ubuntu t2.micro subnet 1
# Ubuntu t2.micro subnet 2
ssh ubuntu@52.19.206.250
ssh ubuntu@52.50.76.195
sudo su

apt update && apt upgrade -y  # keep local versions installed if complains
shutdown -r now

# install Docker
# https://docs.docker.com/install/linux/docker-ce/ubuntu/
apt install -y \
    apt-transport-https \
    ca-certificates \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
apt update
# find and choose Docker version you want
apt-cache madison docker-ce     # => 5:18.09.6~3-0~ubuntu-bionic
apt-cache madison docker-ce-cli # => 5:18.09.6~3-0~ubuntu-bionic
apt install -y \
    docker-ce=5:18.09.6~3-0~ubuntu-bionic \
    docker-ce-cli=5:18.09.6~3-0~ubuntu-bionic \
    containerd.io
docker --version
# => 18.09.6

docker network ls
# NETWORK ID          NAME                DRIVER              SCOPE
# 65714236d0ed        bridge              bridge              local
# 2be620b4c47c        host                host                local
# f8f2514a7b31        none                null                local

# 1
docker swarm init
docker network create -d overlay --attachable hyper-net
docker node ls
docker swarm leave -f
docker network prune -f

# 2
docker swarm join \
    --token SWMTKN-1-3a5yre1665tkimibija1ii3fqj0usyb1t7umfa2riwls6ymzzl-cz47u5lcan6dx4zkf5mef8kud 172.31.28.23:2377
docker swarm leave -f
docker network prune -f

# 1
docker run -it --rm --name=node-1 --network=hyper-net busybox
ping node-2

# 2
docker run -it --rm --name=node-2 --network=hyper-net busybox
ping node-1

--network=macvlan

The containers will effectively go even one level up and get a MAC address from the VLAN device. You'll rarely need this.

Might require further configuration as, in usual configurations, a single physical port on hardware devices can be limited to a single MAC address.

--link=<container>

You can link containers but that is unidirectional and deprecated. They will use the default network then. Avoid using links, it's a legacy feature.

docker run -it --rm --name db busybox

# link container named "db" to this container "web"
docker run -it --rm --link db --name web busybox
cat /etc/hosts  # you can see the "db" in there
ping db

# you can also give aliases
docker run -it --rm --link db:my-db --name web busybox
cat /etc/hosts
ping my-db
ping db

# you can list existing links
docker inspect -f "{{ .HostConfig.Links }}" web
# [/db:/web/my-db]

Sources