I am trying to set a static IP address inside a docker container (using a CentOS image with systemctl enabled).
The reason for this is, that I want to run a service inside a container which requires ssh and checks if a NIC with the IP it should listen on is available. The service communicates with other services in the same network so the IP needs to be accessible from outside the container as well.
It potentially could work with --net=host, but I could never figure how I would bind a range of ports to the container with that option. Using -p 10.2.0.253:22:22 does not work. When using e.g. SSH from any physical node on that network, I always end up on the docker host instead inside the container.
The network is 10.2.0.0/24.
The docker host has the IP 10.2.0.100
Container should listen to all ports on 10.2.0.253 and most important, there must be an interface within the container with that IP
The container should be reachable from any physical node or container on the 10.2.0.0/24 network
this is a challenging problem due to the way networking works in general.
the network adapter listens for traffic on its mac address.
a container on the same network would have a different mac address. and the host adapter would not be listening for traffic on the containers mac. you can (technically, but not practically) set the host adapter to promiscuous mode (is some environments) so that the host adapter can listen for traffic on ANY (also ALL) mac addresses… in almost all production environments this is a security violation
if you don’t want DHCP support for the container, its a ‘little’ easier…
select an ip address for the container in the range of the network (using dhcp is a problem)
on docker run set the network, mac and ip address for the container
but, at some point you will need promiscuous mode on the host to make this work.
it works on my physical box with ubuntu
it does NOT work on VMWARE instances on this same host with promiscuous mode on. (used to but haven’t figured it out)
it works on my virtual ubuntu under vmware on windows
it does NOT work on my virtual mac on the same vmware on windows
it does NOT work on docker on windows.
I tried your way, and it partially works. I get a interface in my container with the right IP address. but I can’t ping any node on that network.
Host network:
[root@server40 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.2.50 0.0.0.0 UG 0 0 0 eno1
10.2.0.0 0.0.0.0 255.255.255.0 U 0 0 0 ib0
169.254.0.0 0.0.0.0 255.255.0.0 U 1004 0 0 eno1
169.254.0.0 0.0.0.0 255.255.0.0 U 1007 0 0 ib0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eno1
192.168.110.0 0.0.0.0 255.255.255.0 U 0 0 0 enp131s0f1
Not sure what I shall use as “gateway” on the subnet 10.2.0.0/24 as there is none, so I used the hosts IP 10.2.0.100 (IP forwarding is enabled) or a unused IP address (didn’t make a difference):
arp -s address hw_addr is used to set up a new table entry. The format of the hw_addr parameter is dependent on the hardware class, but for most classes one can assume that the usual presentation can be used. For the Ethernet class, this is 6 bytes in
hexadecimal, separated by colons. When adding proxy arp entries (that is those with the publish flag set) a netmask may be specified to proxy arp for entire subnets. This is not good practice, but is supported by older kernels because it can be useful. If
the temp flag is not supplied entries will be permanent stored into the ARP cache. To simplify setting up entries for one of your own network interfaces, you can use the arp -Ds address ifname form. In that case the hardware address is taken from the
interface with the specified name.