Docer事始め - ネットワークについて1の続きです。
コンテナ側で起動したミドルウェアへのアクセスについて記載します。
※前回起動していたコンテナは全てdocker rmコマンドで削除しています。
環境
- OS : CentOS release 6.5 (Final)
- Kernel : 2.6.32-431.17.1.el6.x86_64
- Docker : docker-io-0.11.1-4.el6.x86_64
試す
docker runのhelpを参照するとDockerではコンテナ生成時にポート番号の紐付けが可能のようです。
# docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
<snip>
-p, --publish=[] Publish a container's port to the host
format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
(use 'docker port' to see the actual mapping)
-P, --publish-all=false Publish all exposed ports to the host interfaces
<snip>
apacheを例とするため、以下の内容で試します。
- ホストOS側は8080ポートで受け付けたアクセスをコンテナ側の80ポートに渡す
# 事前にiptablesの内容を確認
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
# Dockerコンテナをポート番号を紐付けて生成
# docker run -p 8080:80 -i -t centos /bin/bash
bash-4.1#
# コンテナを生成したまま抜ける
bash-4.1# Ctrl+p , Ctrl+q
#
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a610057f883b centos:latest /bin/bash 15 seconds ago Up 13 seconds 0.0.0.0:8080->80/tcp grave_morse
# PORTS列にポート設定について確認できる
#
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:http
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
# Chain FORWARDにコンテナへのポリシーが追加されていることが確認できる
#
# コンテナ側にapacheを構築して疎通を確認する
# 先ほど生成したコンテナへアタッチ
# docker attach a610057f883b
bash-4.1#
# 80ポートがListenしていないことを確認
bash-4.1# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
bash-4.1#
# apacheをyumからインストール
bash-4.1# yum install -y httpd
bash-4.1#
# httpdパッケージがインストールしたことを確認
bash-4.1# rpm -q httpd
httpd-2.2.15-30.el6.centos.x86_64
bash-4.1#
# 適当な文字列を返すindex.htmlファイルを作成
bash-4.1# echo "Hello, Docker world." > /var/www/html/index.html
bash-4.1#
# apacheを起動
bash-4.1# service httpd start
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2 for ServerName
[ OK ]
# FQDNでメッセージがでるが検証なので気にしない
bash-4.1#
# 80ポートがListenしていることを確認
bash-4.1# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::80 :::* LISTEN 89/httpd
bash-4.1#
# コンテナ上からのアクセスを確認
bash-4.1# curl 127.0.0.1
Hello, Docker world.
bash-4.1#
# コンテナを生成したまま抜ける
bash-4.1# Ctrl+p , Ctrl+q
#
# ホストOSからコンテナに対して確認
# curl 172.17.0.2
Hello, Docker world.
# ホストOS上からはコンテナのIPアドレスとルーティングがわかるため
#
# ホストOSからホストOSに対して確認
# curl 127.0.0.1:8080
Hello, Docker world.
# ポートマッピングができているので別ホストからはホストOSのポート8080に対してアクセスすると、コンテナ側のapacheが応答を返すという形になる
# 念のため別ホストからも確認
# ssh other-host
[other-host ~]#
[other-host ~]# curl ホストOSのIPアドレス:8080
Hello, Docker world.
[other-host ~]#
[other-host ~]# exit
#
雑感
- コンテナへのポートの紐付けはdocker psコマンドから確認できる
- ポートの紐付けはコンテナ生成時に指定する
- コンテナ生成後でも可能…?
- ポートの紐付けはiptablesで実現してるっぽい
- 特殊なことはやっていないようにみえる
最小構成のイメージから毎回ミドルウェアをインストール+設定となると面倒なので、次回はカスタムDockerイメージの作成とかその辺を追ってみたいと思います。