[ Node A ] [ Node B ] [ Node C ]
[Lo0:1.1.1.1] [et0] <- Eth -> [et0] lo0:1.1.1.2 [et1] <- Eth -> [et1] [lo0:1.1.1.3]
Note: EtX interface IP addresses are not advertised; packets must be sourced from a loopback interface to make a successful round trip.
#!/bin/sh
usage()
{
echo "Usage: $0 -i INTERFACE -n NAME "
exit 2
}
while getopts "i:n:h" flag; do
case "${flag}" in
i)
interface=${OPTARG}
;;
n)
name=${OPTARG}
;;
h)
usage
;;
*)
echo "Invalid options provided"
usage
;;
esac
done
if [ -z "${interface}" ] || [ -z "${name}" ]; then
usage
fi
bridge=br-${name}
source_address=`ip addr show ${interface} | grep -Po 'inet \K[\d.]+'`
# make sure the source interface has an IP address
if [ -z ${source_address} ]; then
echo "ERROR: Unable to find the IP address for interface ${interface}"
exit 1
fi
# cache sudo creds before continuing
if ! sudo -v; then
echo "EROR: authorization failed, exiting."
exit 1
fi
docker network create --attachable \
--opt "com.docker.network.bridge.name=${bridge}" \
--opt "com.docker.network.bridge.enable_ip_masquerade=false" \
${name}
if [ $? -ne 0 ]; then
echo "ERROR: Failed to create docker network"
exit 1
fi
subnet=`docker network inspect ${name} -f '{{ (index .IPAM.Config 0).Subnet }}'`
if [ $? -ne 0 ]; then
echo "ERROR: Failed to inspect docker network: ${name}"
exit 1
fi
if [ -z ${subnet} ]; then
echo "ERROR: Failed to determine docker network subnet"
exit 1
fi
sudo iptables -t nat -A POSTROUTING -s ${subnet} ! -o ${bridge} -j SNAT --to-source ${source_address}
$ sh create_docker_network.sh -i lo0 -n loopnet
98fe05b4f2047d3ea1f98fa6be1a9a80f7c9c052d4bbf20431a8555d6e1799e6
$
$ docker run --rm --network loopnet alpine:latest ping 1.1.1.3
PING 1.1.1.3 (1.1.1.3) 56(84) bytes of data.
64 bytes from 1.1.1.3: icmp_seq=1 ttl=62 time=6.98 ms
64 bytes from 1.1.1.3: icmp_seq=2 ttl=62 time=7.78 ms
64 bytes from 1.1.1.3: icmp_seq=3 ttl=62 time=6.57 ms
^C
$