How can I set a static IP address in a Docker cont

2019-01-16 10:03发布

I'm perfectly happy with the IP range that docker is giving me by default 176.17.x.x, so I don't need to create a new bridge, I just want to give my containers a static address within that range so I can point client browsers to it directly. I tried using

RUN echo "auto eth0" >> /etc/network/interfaces
RUN echo "iface eth0 inet static" >> /etc/network/interfaces
RUN echo "address 176.17.0.250" >> /etc/network/interfaces
RUN echo "netmask 255.255.0.0" >> /etc/network/interfaces
RUN ifdown eth0
RUN ifup eth0

from a Dockerfile, and it properly populated the interfaces file, but the interface itself didn't change. In fact, running ifup eth0 within the container gets this error:

RTNETLINK answers: Operation not permitted Failed to bring up eth0

11条回答
Summer. ? 凉城
2楼-- · 2019-01-16 10:33

This worked for me:

docker run --cap-add=NET_ADMIN -d -it myimages/image1  /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0;  bash"

Explained:

  • --cap-add=NET_ADMIN have rights for administering the net (i.e. for the /sbin/ip command)

  • myimages/image1 image for the container

  • /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0 ; bash" Inside the container run ip addr add 172.17.0.8 dev eth0 to add a new ip address 172.17.0.8 to this container (caution: do use a free ip address now and in the future). Then run bash, just to not have the container automatically stopped.

Bonus:

My target scene: setup a distributed app with containers playing different roles in the dist-app. A "conductor container" is able to run docker commands by itself (inside) so to start and stop containers as needed. Each container is configured to know where to connect to access a particular role/container in the dist-app (so the set of ip's for each role must be known by each partner).

To do this:

  1. "conductor container"

image created with this Dockerfile

FROM pin3da/docker-zeromq-node
MAINTAINER Foobar

# install docker software  
RUN apt-get -yqq update && apt-get -yqq install docker.io 

# export /var/run/docker.sock  so we can connect it in the host
VOLUME /var/run/docker.sock

image build command:

docker build --tag=myimages/conductor --file=Dockerfile .

container run command:

docker run -v /var/run/docker.sock:/var/run/docker.sock --name=conductor1 -d -it myimages/conductor  bash
  1. Run containers with different roles.

First (not absolutely necessary) add entries to /etc/hosts to locate partners by ip or name (option --add-host)

Second (obviously required) assign a ip to the running container (use /sbin/ip in it)

docker run --cap-add=NET_ADMIN --add-host worker1:172.17.0.8 --add-host worker2:172.17.0.9 --name=worker1 -h worker1.example.com -d -it myimages/image1  /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0;  bash"
查看更多
放我归山
3楼-- · 2019-01-16 10:34

& with pipework (192.168.1.1 below being the default gateway ip address):

pipework br0 container-name 192.168.1.10/24@192.168.1.1

Edit: do not start with --net=none : this closes container ports.

See further notes

查看更多
淡お忘
4楼-- · 2019-01-16 10:37

I have already answered this here https://stackoverflow.com/a/35359185/4094678 but I see now that this question is actually older then the aforementioned one, so I'll copy the answer as well:

Easy with Docker version 1.10.1, build 9e83765.

First you need to create you own docker network (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

than simply run the image (I'll take ubuntu as example)

docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash

then in ubuntu shell

ip addr

Additionally you could use
--hostname to specify a hostname
--add-host to add more entries to /etc/hosts

Docs (and why you need to create a network) at https://docs.docker.com/engine/reference/commandline/network_create/

查看更多
在下西门庆
5楼-- · 2019-01-16 10:39

I discovered that --net=host might not always be the best option, as it might allow users to shut down the host from the container! In any case, it turns out that the reason I couldn't properly do it from inside was because network configuration was designed to be restricted to sessions that begun with the --privileged=true argument.

查看更多
兄弟一词,经得起流年.
6楼-- · 2019-01-16 10:40

pipework also great, but If you can use hostname other than ip then you can try this script

#!/bin/bash
# This function will list all ip of running containers
function listip {
    for vm in `docker ps|tail -n +2|awk '{print $NF}'`; 
        do
            ip=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $vm`;
            echo "$ip  $vm";
        done    
}

# This function will copy hosts file to all running container /etc/hosts
function updateip {
        for vm in `docker ps|tail -n +2|awk '{print $NF}'`;
                do
                        echo "copy hosts file to  $vm";
                        docker exec -i $vm sh -c 'cat > /etc/hosts' < /tmp/hosts
                done
}

listip > /tmp/hosts
updateip

You just need to run this command everytime you boot up your docker labs You can find my scripts with additional function here dockerip

查看更多
混吃等死
7楼-- · 2019-01-16 10:42

I understood that you are not looking at multi-host networking of containers at this stage, but I believe you are likely to need it soon. Weave would allow you to first define multiple container networks on one host, and then potentially move some containers to another host without loosing the static IP you have assigned to it.

查看更多
登录 后发表回答