Multiple static IPs for Docker containers - networking

I have a Docker host that should allow each container to have multiple static IP addresses. The application inside the container should then be able to choose from which address it will send traffic to remote hosts (e.g. ping -I <source-address> example.com).
Imagine a setup like this: IP addresses 10.0.0.10 - 10.0.0.19 are assigned to ContainerA, 10.0.0.20 - 10.0.0.29 to ContainerB and so on. Any traffic to ContainerA's address range is forwarded to ContainerA, while outgoing traffic originates from an address from that range that ContainerA can chose. The same applies to ContainerB.
The default --net=bridgemode does not seem to support this. The closest I could get is that incoming traffic to any of ContainerA's addresses is correctly forwarded to the container, but outgoing traffic always originates from the same single address.
When using --net=host, the first container will attach to all available IP addresses, thus the second container will not be able to open the sockets in its IP range.
The --ip option of the docker run command seems to come close to what I need, as explained in this blog post. Unfortunately, it does not seem to support multiple static IPs per container.
If more convenient, using CIDR subnets instead of IP ranges is fine.
How do I need to configure Docker to achieve this?

I think you can do it by customizing docker0 bridge, or even create your own network bridge

Every docker container has a single IP only. We can set custom IP also, by making a bridge network as,
docker network create net1 --driver=bridge --subnet="192.168.0.1/27"
If you don't mention the driver then by default it is bridge network.
So here using --subnet, you can give a custom IP address to the network and using that network, you can also give custom IP addresses to the containers which are inside that network.
Then run a container as,
docker run -it --network=net1 --ip="192.168.0.3" --name=MyContainer image_name
Now, in this way you can make 32-27=5 i.e., (2^5)-2 docker containers.

Hum I'm wondering if I really get the right meaning of your question.
You say:
"while outgoing traffic originates from an address from that range that ContainerA can chose."
This means that your connection should be in UDP.
Or the TCP connection would be broken without the same IP for inbound and outbound trafic ? right ?
I think you could make a network and assign IP addresses on that network to your containers.
You can do this in command line, but I'd rather go for a docker-compose file.
It could be something like this :
version: '2.1'
services:
containerA:
image: xxx
networks:
local_net:
ipv4_address: 10.0.0.10
ipv4_address: 10.0.0.11
...
containerB:
image: xxx
networks:
local_net:
ipv4_address: 10.0.0.20
ipv4_address: 10.0.0.21
...
networks:
local_net:
ipam:
driver: default
config:
- subnet: 10.0.0.0/24
gateway: 172.16.200.1
If you want to automate the creation of the file, you can script it I think.

Related

APP inside docker can only see client coming from IP 172.17.0.1 how to avoid it?

my app live inside the docker log all in-coming traffic from 172.17.0.1
I believe it's named dock0 bridge hub??
is it possible to avoid it? to let the app inside see ourside client real ip?
I also saw a way name network type as host but the docker container will share the same ip with host?
is that possible to do it like host is 192.168.1.101 docker container is 192.168.1.102?
OK.. I found there is a solution, docker have something named macvlan driver.
basicly it's like the br0 for normal homerouter.
it can plug container into the REAL L2 bridge instead of the fake docker0 NAT ("bridge.")
but I can't use it, macvlan only support on linux host, but im using a mac.

Docker on CentOS with bridge to LAN network

I have a server VLAN of 10.101.10.0/24 and my Docker host is 10.101.10.31. How do I configure a bridge network on my Docker host (VM) so that all the containers can connect directly to my LAN network without having to redirect ports around on the default 172.17.0.0/16? I tried searching but all the howtos I've found so far have resulted in losing SSH session which I had to go into the VM from a console to revert the steps I did.
There's multiple ways this can be done. The two I've had most success with are routing a subnet to a docker bridge and using a custom bridge on the host LAN.
Docker Bridge, Routed Network
This has the benefit of only needing native docker tools to configure docker. It has the down side of needing to add a route to your network, which is outside of dockers remit and usually manual (or relies on the "networking team").
Enable IP forwarding
/etc/sysctl.conf: net.ipv4.ip_forward = 1
sysctl -p /etc/sysctl.conf
Create a docker bridge with new subnet on your VM network, say 10.101.11.0/24
docker network create routed0 --subnet 10.101.11.0/24
Tell the rest of the network that 10.101.11.0/24 should be routed via 10.101.10.X where X is IP of your docker host. This is the external router/gateway/"network guy" config. On a linux gateway you could add a route with:
ip route add 10.101.11.0/24 via 10.101.10.31
Create containers on the bridge with 10.101.11.0/24 addresses.
docker run --net routed0 busybox ping 10.101.10.31
docker run --net routed0 busybox ping 8.8.8.8
Then your done. Containers have routable IP addresses.
If you're ok with the network side, or run something like RIP/OSPF on the network or Calico that takes care of routing then this is the cleanest solution.
Custom Bridge, Existing Network (and interface)
This has the benefit of not requiring any external network setup. The downside is the setup on the docker host is more complex. The main interface requires this bridge at boot time so it's not a native docker network setup. Pipework or manual container setup is required.
Using a VM can make this a little more complicated as you are running extra interfaces with extra MAC addresses over the main VM's interface which will need additional "Promiscuous" config first to allow this to work.
The permanent network config for bridged interfaces varies by distro. The following commands outline how to set the interface up and will disappear after reboot. You are going to need console access or a seperate route into your VM as you are changing the main network interface config.
Create a bridge on the host.
ip link add name shared0 type bridge
ip link set shared0 up
In /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=shared0
TYPE=Bridge
BOOTPROTO=static
DNS1=8.8.8.8
GATEWAY=10.101.10.1
IPADDR=10.101.10.31
NETMASK=255.255.255.0
ONBOOT=yes
Attach the primary interface to the bridge, usually eth0
ip link set eth0 up
ip link set eth0 master shared0
In /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
TYPE=Ethernet
IPV6INIT=no
USERCTL=no
BRIDGE=shared0
Reconfigure your bridge to have eth0's ip config.
ip addr add dev shared0 10.101.10.31/24
ip route add default via 10.101.10.1
Attach containers to bridge with 10.101.10.0/24 addresses.
CONTAINERID=$(docker run -d --net=none busybox sleep 600)
pipework shared1 $CONTAINERID 10.101.10.43/24#10.101.10.Y
Or use a DHCP client inside the container
pipework shared1 $CONTAINERID dhclient
Docker macvlan network
Docker has since added a network driver called macvlan that can make a container appear to be directly connected to the physical network the host is on. The container is attached to a parent interface on the host.
docker network create -d macvlan \
--subnet=10.101.10.0/24 \
--gateway=10.101.10.1 \
-o parent=eth0 pub_net
This will suffer from the same VM/softswitch problems where the network and interface will need be promiscuous with regard mac addresses.

How to create docker containers with the same internal IP address?

I have an environment where I need to run some external software into Docker containers. This software is trying to connect to our product by specific IP address - let's say 192.168.255.2 - and this address is fixed and cannot be changed. Moreover, host IP address must be also set to specific IP - let's say 192.168.255.3.
Product supports 2 ethernet interfaces:
first of them has strict restrictions regarding IP addressing - let's call it "first"
second does not have such restrictions and provides similar functionalities - for this example let's assume that the IP address of this interface is set to 10.1.1.2/24 - let's call it "second"
I need to run simultaneously multiple docker containers, each container shall be connected to one product (1 to 1 relationship).
Things that are run inside containers must think that they're reaching connectivity to product by using "first" network interface (one which have static IP assignment and which cannot be changed).
All I want to do is to create containers with the same IP addresses to pretend that application inside container is using "first" ethernet interface of product and then at host level I want to redirect all traffic using IPTables to "second" interface.
Therefore I have one major problem: how to create multiple docker containers with the same IP address?
From the exact phrasing of your question, docker has the option to share the network stack of another container. Simply run:
docker run -d --name containera yourimage
docker run -d --net container:containera anotherimage
And you'll see that the second container has the same IP interfaces and can even see ports being used by the first container.
I'd recommend instead that you install both interfaces on your docker host and bind to the IP on the host that you need, then don't worry about the actual IP of the container. The result will be much simpler to manage. Here's how you bind to a single IP on the host with ports 8080 and 8888 that's mapped to two different container's port 80:
docker run -d -p 192.168.255.2:8080:80 --name nginx8080 nginx
docker run -d -p 192.168.255.2:8888:80 --name nginx8888 nginx

Docker giving IP address at the same level as the host, similar to VM bridged networking

I want to assign IP addresses to my docker containers, at the same level as the physical host. i.e. if the IP adress of the host is 192.168.1.101 I would like to give the docker containers IP addresses of 192.168.1.102,103,104 etc.
Essentially I am looking for a functionality similar to bridged networking in VMWare/Virtualbox etc.
Any ideas how we can go about doing this?
Docker's default bridge network allows you to NAT your containers into the physical network.
To achieve what you want, use Pipework or, if you are cutting edge, you can try the docker macvlan driver which is, for now, experimental.
To quote docker docs:
The host network adds a container on the hosts network stack. You’ll
find the network configuration inside the container is identical to
the host.
When starting the container just say --net=host. Check this link. You can't actually assign a static IP when starting with that parameter, but you can give the container a hostname with --hostname, which is at the very least equally useful as knowing the IP. Also you can add more entries to /etc/hosts with --add-host.

Sharing container ip and port across the hosts

We have a set of docker containers spread across the several hosts. Some containers are part of the same logical group, i.e. network so containers should be able to talk directly, accessing each other IP and Port (which is randomized by docker).
The situation is similar to when you use networks in Docker 1.10 and docker-compose 1.6x on one host, but spread on many hosts.
I know swarm with etcd/zookeeper can manage and connect the cluster of dockers, but I don't know how my app in one container would know about the IP address and port of the other part in other container on the other host.
Your app doesn't need to know the IP address of the container. You can use the service name or some other alias as the hostname. The embedded DNS server will resolve it to the correct IP address.
With this setup you don't need host ports at all, so you'll already know the port because it's a static value.
Multi-host networking for Docker is covered in this tutorial: https://docs.docker.com/engine/userguide/networking/get-started-overlay/

Resources