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の起動に失敗しました
私はすでにこれに答えています https://stackoverflow.com/a/35359185/4094678 が、この質問は実際には前述のものよりも古いことがわかりました1つなので、答えもコピーします。
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/ のドキュメント(およびネットワークを作成する必要がある理由)
私は公式の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アドレスを設定します。
実際、私の最初の失敗にもかかわらず、@ MarkO'Connorの答えは正しかった。 Host/etc/network/interfacesファイルに新しいインターフェイス(docker0)を作成し、ホストでSudo ifup docker0を実行し、then ran
docker run --net=Host -i -t ...
静的IPを取得し、コンテナー内のdocker0に割り当てました。
ありがとう!
デフォルトでは、Dockerコンテナにはネットワークスタックを操作するための十分な権限がありません。 runコマンドに--cap-add=NET_ADMIN
を追加して、この特定の機能を許可してください。または、テストのために--privileged=true
(すべての権利を付与)を試すことができます。
別のオプションは、ホストから pipework を使用することです。
これは私のために働いた:
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アドレスを使用してくださいnowおよび将来的に)。次に、コンテナが自動的に停止しないようにbashを実行します。
ボーナス:
私のターゲットシーン:dist-appで異なる役割を果たしているコンテナーで分散アプリをセットアップします。 「コンダクターコンテナ」は、必要に応じてコンテナを起動および停止するために、ドッカーコマンドを単独で(内部で)実行できます。各コンテナーは、dist-appの特定のロール/コンテナーにアクセスするために接続する場所を知るように構成されています(したがって、各ロールのIPのセットは各パートナーが知っている必要があります)。
これをする:
この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
イメージ構築コマンド:
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
最初に(絶対に必要ではありません)エントリを/etc/hosts
に追加して、IPまたは名前でパートナーを見つけます(オプション--add-Host
)
2番目(明らかに必要)は、実行中のコンテナーに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"
br0
)docker
を開始するには:-b=br0
&with pipework (192.168.1.1
以下はdefault gateway
IPアドレスです):
pipework br0 container-name 192.168.1.10/[email protected]
Edit:--net=none
で始めないでください:これはコンテナポートを閉じます。
詳細 をご覧ください
パイプワークも素晴らしいですが、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ラボを起動するたびにこのコマンドを実行する必要があります。追加機能を備えたスクリプトはこちら dockerip
この段階では、コンテナのマルチホストネットワーキングを検討していないことを理解しましたが、すぐに必要になると思われます。 Weave を使用すると、最初に1つのホストで複数のコンテナーネットワークを定義し、次に割り当てた静的IPを失うことなく、一部のコンテナーを別のホストに移動できる可能性があります。
--net=Host
が常に最適なオプションとは限らないことを発見しました。ユーザーがコンテナからホストをシャットダウンできる可能性があるためです。いずれにせよ、ネットワーク構成が--privileged=true
引数で開始されたセッションに制限されるように設計されているため、内部から適切に実行できなかった理由が判明しました。
完全を期すために、Dockerフォーラムで提案されている別の方法があります。 (編集:АндрейСердюкからの回答を渡す際に言及しました)。
Hostシステムに静的IPアドレスを追加し、そのIPにポートを公開します。 docker run -p 192.0.2.1:80:80 -d mywebserver
。
もちろん、その構文はIPv6では機能せず、ドキュメントにはそれが記載されていません...
間違っているように思えますが、ホスト上の通常のワイルドカードバインド(*:80)は、理論的にはコンテナと競合します。実際には、iptablesを使用して実装されているため、Dockerポートが優先され、競合しません。ただし、パブリックコンテナIPは、すべてのnon-conflictingポートで引き続き応答します。 ssh。
サービス検出ツールでSkyDnsをセットアップできます- https://github.com/crosbymichael/skydock
または:ネットワークインターフェースを作成し、その中にドッカーコンテナーポートを次のように公開します https://Gist.github.com/andreyserdjuk/bd92b5beba2719054dfe