如何在Docker容器中设置静态IP地址?

时间:2014-08-27 14:08:44

标签: linux networking docker

我非常满意Docker默认授予我的IP范围176.17.x.x,因此我不需要创建新桥,我只想让我的容器静态地址范围内,以便我可以直接将客户端浏览器指向它。 我尝试使用

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
来自Dockerfile的

,它正确填充了interfaces文件,但界面本身并没有改变。实际上,在容器中运行ifup eth0会出现此错误:

  

RTNETLINK答案:不允许操作无法启动eth0

11 个答案:

答案 0 :(得分:28)

我已经在这里回答了这个问题 https://stackoverflow.com/a/35359185/4094678 但我现在看到这个问题实际上比前面提到的要早,所以我也会复制答案:

使用Docker 1.10.1版轻松编译9e83765。

首先,您需要创建自己的docker network(mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

而不是简单地运行图像(我将以ubuntu为例)

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

然后在ubuntu shell中

ip addr

另外你可以使用
--hostname指定主机名
--add-host将更多条目添加到/etc/hosts

文档(以及您需要创建网络的原因)https://docs.docker.com/engine/reference/commandline/network_create/

答案 1 :(得分:13)

我正在使用官方Docker文档中编写的here方法,我已确认它有效:

# At one shell, start a container and
# leave its shell idle and running

$ sudo docker run -i -t --rm --net=none base /bin/bash
root@63f36fc01b5f:/#

# At another shell, learn the container process ID
# and create its namespace entry in /var/run/netns/
# for the "ip netns" command we will be using below

$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
2778
$ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid

# Check the bridge's IP address and netmask

$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0
...

# Create a pair of "peer" interfaces A and B,
# bind the A end to the bridge, and bring it up

$ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up

# Place B inside the container's network namespace,
# rename to eth0, and activate it with a free IP

$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1

使用这种方法,我总是使用 net = none 运行我的容器,并使用外部脚本设置IP地址。

答案 2 :(得分:6)

实际上,尽管我最初的失败,@ MarkO'Connor的回答是正确的。我在主机/ etc / network / interfaces文件中创建了一个新接口(docker0),在主机上运行了sudo ifup docker0,然后然后运行

docker run --net=host -i -t ... 

获取静态IP并将其分配给容器中的docker0。

谢谢!

答案 3 :(得分:4)

默认情况下,Docker容器没有足够的权限来操作网络堆栈。您可以尝试将--cap-add=NET_ADMIN添加到run命令以允许此特定功能。或者您可以尝试--privileged=true(授予所有权利)进行测试。

另一个选择是使用主机中的pipework

答案 4 :(得分:3)

&安培;使用pipework192.168.1.1以下为default gateway IP地址):

pipework br0 container-name 192.168.1.10/24@192.168.1.1

修改:不要以--net=none开头:这会关闭容器端口。

请参阅further notes

答案 5 :(得分:3)

这对我有用:

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

说明:

  • --cap-add=NET_ADMIN拥有管理网络的权利(即/sbin/ip命令)

  • 容器的
  • myimages/image1图片

  • /bin/sh -c "/sbin/ip addr add 172.17.0.8 dev eth0 ; bash" 在容器内运行ip addr add 172.17.0.8 dev eth0以向该容器添加新的IP地址172.17.0.8(注意:将来使用免费的IP地址 。然后运行bash,只是为了不让容器自动停止。

<强>加成

我的目标场景:设置一个分布式应用程序,其中容器在dist-app中扮演不同的角色。 “导体容器”能够自己(内部)运行docker命令,以便根据需要启动和停止容器。 每个容器都配置为知道在dist-app中访问特定角色/容器的连接位置(因此每个伙伴必须知道每个角色的ip集)。

要做到这一点:

  1. “导体容器”
  2. 使用此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命令:

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

    容器运行命令:

    docker run -v /var/run/docker.sock:/var/run/docker.sock --name=conductor1 -d -it myimages/conductor  bash
    
    1. 运行具有不同角色的容器。
    2. 首先(非绝对必要)向/etc/hosts添加条目,以便通过ip或名称找到合作伙伴(选项--add-host

      第二个(显然需要)将ip分配给正在运行的容器(使用 其中/sbin/ip

      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"
      

答案 6 :(得分:2)

我知道您现阶段并未考虑容器的多主机网络,但我相信您很快就会需要它。 Weave允许您首先在一个主机上定义多个容器网络,然后可能将一些容器移动到另一个主机,而不会丢失您分配给它的静态IP。

答案 7 :(得分:2)

管道工作也很棒,但是如果你可以使用ip以外的主机名,那么你可以尝试这个脚本

#!/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

每次启动docker labs时都需要运行此命令 您可以在dockerip

找到具有附加功能的脚本

答案 8 :(得分:1)

我发现--net=host可能并不总是最佳选择,因为它可能允许用户从容器中关闭主机!无论如何,事实证明我无法从内部正确地执行此操作的原因是因为网络配置被设计为仅限于以--privileged=true参数开头的会话。

答案 9 :(得分:1)

为了完整性:在Docker论坛上建议了另一种方法。 (编辑:并通过АндрейСердюк的回答提及。)

主机系统上添加静态IP地址,然后将端口发布到该IP,例如docker run -p 192.0.2.1:80:80 -d mywebserver

当然,该语法不适用于IPv6,文档也没有提到......

对我来说听起来不对:主机上通常的通配符绑定(*:80)理论上与容器冲突。在实践中,Docker端口优先且不冲突,因为它是如何使用iptables实现的。但是您的公共容器IP仍会响应所有 - 冲突端口,例如: SSH。

答案 10 :(得分:0)

您可以使用服务发现工具https://github.com/crosbymichael/skydock

设置SkyDns

或者:只需创建网络接口并在其中发布docker容器端口,如https://gist.github.com/andreyserdjuk/bd92b5beba2719054dfe

相关问题