CentOS 6.4 で Docker 0.7 を使ってみる
Docker がバージョン 0.7 から RedHat 系 OS に正式に対応した、という事なのでインストールして軽く触ってみました。
Requirements and Installation on Red Hat Enterprise Linux / CentOS - Docker Documentation
http://docs.docker.io/en/latest/installation/rhel/
試した OS は手元にあった CentOS 6.4 x86_64 です。
インストールといっても公式の手順にもある通り EPEL で入れられるようになったので、yum リポジトリを追加して入れるだけです。
まずは EPEL リポジトリを使えるようにします。
# rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6 # yum install -y http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
EPEL が使えるようになったら yum で docker-io パッケージをインストール。
# yum install -y docker-io
これだけで他は特に何もしなくても Docker が使えるようになりました。
以前試した時は CentOS へ入れようとするとかなり大変だったので、大分楽になりましたね。
ありがたい事です。
せっかくインストールしたのでちょっと使ってみます。
インストールしたらまずはデーモンを起動。
# service docker start
取りあえず Redis をインストールする Dockerfile を作ってみました。
- Dockerfile
FROM centos RUN rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6 RUN rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi RUN yum install -y http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm RUN yum install -y http://rpms.famillecollet.com/enterprise/6/remi/x86_64/remi-release-6.4-1.el6.remi.noarch.rpm RUN yum install -y --enablerepo=remi redis RUN echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf RUN /sbin/sysctl -p CMD ["/usr/sbin/redis-server"]
保存したらビルドします。
Dockerfile と同じディレクトリで以下を実行。
# docker build -t akishin/redis .
初回は Docker のリポジトリから CentOS のイメージをダウンロードするのでちょっと時間がかかります。
実行が終わったら docker images を実行すると以下のようにイメージが作成された事が分かります。
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE akishin/redis latest 24584d69487e 22 seconds ago 355.4 MB (virtual 1.11 GB) centos 6.4 539c0211cd76 8 months ago 300.6 MB (virtual 300.6 MB) centos latest 539c0211cd76 8 months ago 300.6 MB (virtual 300.6 MB)
作成したイメージを起動してみます。
# docker run -d akishin/redis
ちょっと冗長ですが、以下のコマンドを実行するとコンテナの IP アドレスが分かります。
# docker inspect $(docker ps -q) | grep IPAddress "IPAddress": "172.17.0.17",
Redis は Telnet で操作できるので、先ほど調べた IPアドレスで接続して試しに使ってみます。
# telnet 172.17.0.17 6379 Trying 172.17.0.17... Connected to 172.17.0.17. Escape character is '^]'. SET foo bar +OK GET foo $3 bar quit +OK Connection closed by foreign host.
問題無さそうですね。
ただ、このままだと Docker を動かしているホストからしか Redis を使用することが出来ません。
他のマシンから接続するためには、コンテナのポートをホストのポートにマッピングする必要があります。
公式ドキュメントでは以下の辺り。
Port redirection - Docker Documentation
http://docs.docker.io/en/latest/use/port_redirection/
まずは先ほどのコンテナを停止します。
# docker stop $(docker ps -q)
今度は docker run 時に -p でポートを指定します。
以下の指定ではコンテナの 6379 ポートをホストの同じポートにマッピングしています。
# docker run -d -p 6379:6379 akishin/redis
netstat で見てみると今度はホスト側でもポート 6379 が LISTEN されていることが分かります。
# netstat -tln | grep 6379 tcp 0 0 :::6379 :::* LISTEN
これで「ホストのIPアドレス:6379」で外部のマシンから接続できるはず・・・と思ったら以下のようなエラーとなってしまい、接続できません。
% telnet 192.0.2.3 6379
Trying 192.0.2.3...
telnet: Unable to connect to remote host: No route to host
どうやらこれはファイアウォールにブロックされてしまっている事が原因のようです。
学習用環境なので iptables を止めてしまえばいいかとも思ったのですが、docker では iptables に以下のように NAT 設定が追加されていました。
# iptables -L -t nat Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16 Chain OUTPUT (policy ACCEPT) target prot opt source destination DOCKER all -- anywhere !loopback/8 ADDRTYPE match dst-type LOCAL Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- anywhere anywhere tcp dpt:6379 to:172.17.0.18:6379
これだと iptables は止めちゃ駄目っぽいですね。
という訳で、FORWARD チェインに以下のようなルールを追加してみます。
# iptables -I FORWARD -p tcp --dport 6379 -j ACCEPT
再度別のマシンからアクセス。
% telnet 192.0.2.3 6379 Trying 192.0.2.3... Connected to 192.0.2.3. Escape character is '^]'. set hoge fuga +OK get hoge $4 fuga quit +OK Connection closed by foreign host.
今度は上手く行きました!
これで開発時に Redis サーバが欲しくなったらイメージからサクッと起動できますね。
普段開発で使っている Ubuntu がまだ 32bit という事もあって Docker は使ってなかったのですが、CentOS でこれだけ簡単に使えるようになると今後は活用していきたいところ。
取りあえずドキュメント読みながら触ってるところですが、いまいち EXPOSE の使いどころがよく分からず・・・。