Top / Docker / EXPOSEまわり

Dockerfile の記述に出てくる EXPOSE 8080 とか、docker run 時にポート指定する-p,-Pなどについて整理。

サーバ起動

まず、通信の送受信確認のための簡易的なWebサーバを 8080で立ち上げます。

root@photon-machine [ ~ ]# docker run -it \
 ubuntu:14.04  \
 /bin/bash -c 'trap exit INT; while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | \
 nc -l 8080; done'

WEBサーバがポート8080で起動しました。ちなみにこの呪文みたいなbashの記述は、 nc コマンドで簡易HTTPサーバ - sonots:blog こちらを参考にさせてもらいました。

さて、このターミナルはリクエスト待ちでプロンプトは返ってこないので、別のターミナルでDockerサーバにログインして、そちらからコンテナのIPを確認し、実際のWEBサーバに繋いでみます。

root@photon-machine [ ~ ]# docker ps
CONTAINER ID        IMAGE              COMMAND                                             
ec9fcb1b8dee        ubuntu:14.04     "/bin/bash -c 'trap e"   

root@photon-machine [ ~ ]# docker exec -it ec9fcb1b8dee cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
172.17.0.8	ec9fcb1b8dee

というわけで繋いでみます

root@photon-machine [ ~ ]# curl 172.17.0.8:8080
Hello World
root@photon-machine [ ~ ]#

つながりました。ただこのコンテナは -p オプションで起動していないので、Dockerサーバ(とその上で動くコンテナたち)以外からは繋がりません。

別のサーバから、

$ curl http://[DockerサーバのIP]:8080

これは返りません。

-p で起動する

さて、初めのコンテナを、-p つきで起動してみます。

root@photon-machine [ ~ ]# docker run -it \
 -p  38080:8080 \
 ubuntu:14.04  \
 /bin/bash -c 'trap exit INT; while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | \
 nc -l 8080; done'

別のターミナルから先ほどとおなじ手順で。

# docker ps
CONTAINER ID        IMAGE                  COMMAND                  PORTS                                                     
88938a296bee        ubuntu:14.04        "/bin/bash -c 'trap e"    0.0.0.0:38080->8080/tcp  
root@photon-machine [ ~ ]# docker exec -it 88938a296bee cat /etc/hosts
172.17.0.8	88938a296bee
root@photon-machine [ ~ ]# curl 172.17.0.8:8080
Hello World
root@photon-machine [ ~ ]#

繋がりました。ここまでは先ほどとおなじですが、今回は -p で 38080->8080 へPort Forwardingされるので、他サーバからはポート38080で繋がるはずです。

$ curl http://[DockerサーバのIP]:38080
Hello World
$

無事返ってきました。

EXPOSEの件

次にDockerfileで EXPOSEを指定したコンテナを作ってまたサーバを立ち上げます

root@photon-machine [ ~ ]# cat Dockerfile
FROM ubuntu:14.04
EXPOSE 8080

root@photon-machine [ ~ ]# docker build -t my-server .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM ubuntu:14.04
 ---> 8cef1fa16c77
Step 2 : EXPOSE 8080
 ---> Running in e79aa6f343b7
 ---> c68bd1ecb1ca
Removing intermediate container e79aa6f343b7
Successfully built c68bd1ecb1ca
#
root@photon-machine [ ~ ]# docker run -it  \
my-server  \
/bin/bash -c 'trap exit INT; while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | \
nc -l 8080; done'

別ターミナルから見てみます

root@photon-machine [ ~ ]# docker ps
CONTAINER ID        IMAGE               COMMAND                   PORTS     
3d64f7d8d425        my-server           "/bin/bash -c 'trap e"    8080/tcp

PORTSになんか出てますが、Port Forwardingしてるわけじゃないので、別サーバからは繋がりませんでした。

-P で起動する

さて、つぎにサーバを -P オプションつきでてちあげます。

# docker run -it  \
 -P \
 my-server  \
 /bin/bash -c 'trap exit INT; while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | \
 nc -l 8080; done'

別ターミナルからみてみます

# docker ps
CONTAINER ID        IMAGE            COMMAND                  CREATED             STATUS              PORTS 
4f26410059bb        my-server       "/bin/bash -c 'trap e"   37 seconds ago      Up 37 seconds       0.0.0.0:32775->8080/tcp

Port Forwarding が勝手に設定されました。EXPOSEは -P オプションで勝手にPort Forwardingを設定してくれるもの、って感じぽいですね。

$ curl http://[DockerサーバのIP]:32775
Hello World
$

つながりました。。

--linkのはなし。

次に --linkのはなしです。

まずサーバを起動します。

root@photon-machine [ ~ ]# docker run -it  \
  --name my-server \
  my-server  \
 /bin/bash -c 'trap exit INT; while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | \
 nc -l 8080; done'

次にこのWEBサーバと通信するコンテナを立ち上げます。

root@photon-machine [ ~ ]# docker run -it --link my-server:s1 centos /bin/bash
[root@f7ba50802906 /]# curl s1:8080
Hello World

 --linkによって、my-server1は s1というサーバ名で名前解決して通信出来るようになりました。

link先のコンテナの環境変数

サーバを立ち上げます。

root@photon-machine [ ~ ]# docker run -it  \
  --name my-server \
  -e userid=u0001 \
  -e password=p0001 \
  my-server  \
 /bin/bash -c 'trap exit INT; while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | \
 nc -l 8080; done'

つぎにそのサーバとlinkしたコンテナを立ち上げます。

root@photon-machine [ ~ ]# docker run -it --link my-server:s1 --name my-client  centos /bin/bash
[root@a89078de181d /]# echo $S1_ENV_userid
u0001
[root@a89078de181d /]# echo $S1_ENV_password
p0001
[root@a89078de181d /]# cat /etc/hosts
172.17.0.8	s1 09d11a2a5e28 my-server
172.17.0.9	a89078de181d
[root@a89078de181d /]# env | grep S1
S1_ENV_userid=u0001
S1_PORT_8080_TCP=tcp://172.17.0.8:8080
S1_NAME=/my-client/s1
S1_ENV_password=p0001
S1_PORT_8080_TCP_ADDR=172.17.0.8
S1_PORT_8080_TCP_PORT=8080
S1_PORT_8080_TCP_PROTO=tcp
S1_PORT=tcp://172.17.0.8:8080

これらで

  • エイリアス名(S1)_ENV_[s1の環境変数名] で、link先の環境変数にアクセス出来ました。
  • hostsにはs1で名前解決できるようIPが定義されています。
  • またEXPOSEされているポート番号はいろいろと環境変数が定義されていました。

という事が分かりました。

よくmysqlコンテナを立ち上げた際にID/PASSを環境変数に渡して、 redmineコンテナがそれらの定義で接続するなんてパタンがありますが、上記の機構を駆使すれば出来そうですね。

関連リンク


この記事は

選択肢 投票
おもしろかった 0  
そうでもない 0  

Top / Docker / EXPOSEまわり

現在のアクセス:1366


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-07-12 (木) 00:49:07 (2108d)