簡體   English   中英

如何在Docker容器中設置靜態IP地址?

[英]How can I set a static IP address in a Docker container?

我非常滿意176.17.xx默認給我的IP范圍176.17.xx ,所以我不需要創建一個新橋,我只想給我的容器一個靜態地址這個范圍內所以我可以指向客戶端直接瀏覽器。 我試過用

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

我已經在這里回答了這個問題https://stackoverflow.com/a/35359185/4094678但我現在看到這個問題實際上比上面提到的要早,所以我也會復制答案:

使用Docker 1.10.1版,輕松構建9e83765。

首先,您需要創建自己的docker網絡(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/

我用寫的方法在這里從官方泊塢窗文件和我已經證實了它的工作原理:

# 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地址。

實際上,盡管我最初的失敗,@ MarkO'Connor的回答是正確的。 我在我的主機/ etc / network / interfaces文件中創建了一個新接口(docker0),在主機上運行了sudo ifup docker0, 然后運行

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

它獲取靜態IP並將其分配給容器中的docker0。

謝謝!

默認情況下,Docker容器沒有足夠的權限來操作網絡堆棧。 您可以嘗試將--cap-add=NET_ADMIN到run命令以允許此特定功能。 或者您可以嘗試使用--privileged=true (授予所有權限)進行測試。

另一種選擇是使用來自主機的管道

&使用管道 (下面的192.168.1.1default gateway IP地址):

pipework br0 container-name 192.168.1.10/24@192.168.1.1

編輯:不要以--net=none開頭:這會關閉容器端口。

見附注

這對我有用:

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. “導體容器”

使用此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. 運行具有不同角色的容器。

首先(非絕對必要)向/etc/hosts添加條目以通過ip或name定位伙伴(選項--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"

我知道在這個階段你並沒有考慮容器的多主機網絡,但我相信你很快就會需要它。 Weave允許您首先在一個主機上定義多個容器網絡,然后可能將一些容器移動到另一個主機,而不會丟失您分配給它的靜態IP。

管道也很棒,但是如果你可以使用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中找到具有附加功能的腳本

我發現--net=host可能並不總是最好的選擇,因為它可能允許用戶從容器中關閉主機! 無論如何,事實證明我無法從內部正確地執行此操作的原因是因為網絡配置被設計為僅限於以--privileged=true參數--privileged=true會話。

為了完整性:在Docker論壇上提出了另一種方法。 (編輯:並通過АндрейСердюк的回答提及)。

主機系統上添加靜態IP地址,然后將端口發布到該IP,例如docker run -p 192.0.2.1:80:80 -d mywebserver

當然,這種語法不適用於IPv6,文檔也沒有提到......

這對我來說聽起來不對:主機上通常的通配符綁定(*:80)理論上與容器沖突。 在實踐中,Docker端口優先且不沖突,因為它是如何使用iptables實現的。 但是您的公共容器IP仍將響應所有沖突端口,例如ssh。

您可以使用服務發現工具設置SkyDns - https://github.com/crosbymichael/skydock

或者:只需創建網絡接口並在其中發布docker容器端口,如https://gist.github.com/andreyserdjuk/bd92b5beba2719054dfe

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM