開発環境のFTPサーバーをboot2dockerでコンテナとして作ろうとしたらなんかコレジャナイ感じになった
Dockerがローカルの開発環境に使えるのかを検証してみようと思って、ただのFTPサーバーを作ってみました。
コンテナの考え方とboot2dockerのネットワークがよく分かってなかったので、苦労しました。ただ、がんばって環境ができたはいいけど、なんか、全然便利じゃない感じになってDockerの使い道を間違ってる気がしてきたという話です。
Docker初心者脳で素直に考えてみる
Dockerfileはこんな感じ。yumでvsftpdインストールして起動するだけ。
FROM centos:latest MAINTAINER Masato Oshima <qqw75pn9@gmail.com> # proxyあればね ENV http_proxy http://proxyuser:password@proxyhost:port ENV https_proxy http://proxyuser:password@proxyhost:port RUN yum -y update && yum -y install vsftpd EXPOSE 21 CMD ["/etc/init.d/vsftpd","start"]
これでビルド&コンテナ起動
$ docker build -t mpon/vsftpd . $ docker run -d mpon/vsftpd $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
コンテナが起動してない・・・
起動してもすぐにコンテナが終了してしまう。docker ps
してもコンテナが出てこない。
-d
をつければデーモンみたいに動くんじゃないの?docker ps -a
のSTATUS見ると、Exited (0)になってる。0ってことは成功っぽいんだけどな。
じゃあということで、-i -t
をつけて、コマンドの出力内容を見てみると、vsftpdが起動していることが分かる。
$ docker run -i -t mpon/vsftpd Starting vsftpd for vsftpd: [ OK ]
うーん、コマンドは実行されてるっぽいんだけどなー。bashで起動して確認してみるか。
bashでコンテナに入ってからvsftpdを起動してみる
$ docker run -i -t mpon/vsftpd bash bash-4.1# /etc/init.d/vsftpd status vsftpd is stopped
あれ?そもそも、vsftpdは起動してないぞ。よく分からないけど、とりあえずもう一回bash上で/etc/init.d/vsftpd start
で起動する。
ここでコンテナのbashはログインしたまま、ローカルからftpでログインしてみる。 まずは、boot2dockerVMのIPアドレスを調べる。
$ boot2docker ip The VM's Host only interface IP address is: 192.168.59.103
macからftp接続しようとするがConnecition refusedになる。
$ ftp ftp> open 192.168.59.103 ftp: Can't connect to `192.168.59.103': Connection refused ftp: Can't connect to `192.168.59.103'
コンテナ起動時にポートをバインドしてないからかな。ポートをバインドして、起動して同様にbashからコマンド入力してvsftpdを起動する。
$ docker run -i -t -p 21:21 mpon/vsftpd bash
そしたら今度はftpログインできた!
ftp> open 192.168.59.103 Connected to 192.168.59.103. 220 (vsFTPd 2.2.2) Name (192.168.59.103:mpon): ftp 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp>
bashでログインして起動してればOKで、-d
で/etc/init.d/vsftpd start
で、コンテナ起動した場合はコンテナが終了しちゃうということは、コンテナは実行中のコマンドが終了しちゃうと終わっちゃうんじゃないかという気がしてきた。
- bashは実行中だからコンテナも起動状態のまま(当たり前な気がするけど)
/etc/init.d/vsftpd start
というコマンド自体は終了、だからコンテナも終了。
みたいな。
dockerのコンテナはコマンドが終了してはいけないんじゃないか説
ってことで、tail
コマンドとtail -f
で確認してみる。
tail
Dockerfileの以下の部分をtailに書き換える。
CMD ["tail", "/var/log/yum.log"]
ビルドして実行すると、コンテナのSTATUSが予想通りExited(0)になってる。コンテナは終了してる。
$ docker build -t mpon/tail $ docker run -d mpon/tail $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 64d8def11df9 mpon/tail:latest tail /var/log/yum.lo 22 seconds ago Exited (0) 20 seconds ago focused_pasteur
tail -f
DockerfileのCMDを書き換える
CMD ["tail", "-f", "/var/log/yum.log"]
ビルドして実行すると、コンテナのSTATUSがUp になってて、コンテナが終了してない。 -a
をつけなくても出てくる。logsも見れるし。予想はあたってた!
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9a24f8a90fab mpon/tailf:latest tail -f /var/log/yum 3 seconds ago Up 2 seconds 21/tcp prickly_ritchie $ docker logs 9a24f8a90fab Jun 22 03:33:55 Updated: libxml2-2.7.6-14.el6_5.2.x86_64 Jun 22 03:34:04 Installed: 2:ethtool-3.5-1.4.el6_5.x86_64 Jun 22 03:34:04 Installed: upstart-0.6.5-13.el6_5.3.x86_64 Jun 22 03:34:04 Installed: iputils-20071127-17.el6_4.2.x86_64 Jun 22 03:34:05 Installed: iproute-2.6.32-32.el6_5.x86_64 Jun 22 03:34:06 Installed: initscripts-9.03.40-2.el6.centos.1.x86_64 Jun 22 03:34:06 Installed: policycoreutils-2.0.83-19.39.el6.x86_64 Jun 22 03:34:07 Installed: iptables-1.4.7-11.el6.x86_64 Jun 22 03:34:07 Installed: logrotate-3.7.8-17.el6.x86_64 Jun 22 03:34:07 Installed: vsftpd-2.2.2-11.el6_4.1.x86_64
やっぱり、そうだ、最後のコマンドは終了しちゃうようなやつだとダメなんだ。
ってことは、vsftpdをforegroundで起動するようなものにすればいいんだということになる。
なので、vsftpdをforegroundで動かす方法を探ってみる。
vsftpdをforegroundで動かすには?
vsftpd.confでbackground=NOにすればいいみたいなのを見つけた。
background
When enabled, and vsftpd is started in "listen" mode, vsftpd will background the listener process. i.e. control will immediately be returned to the shell which launched vsftpd.
Default: NO
あと、/etc/init.d/vsftpd
経由で動かすと、そのコマンド自体が終了してしまうので、直接 /usr/sbin/vsftpd
をたたくようにする。
そのあたりの変更を加えたDockerfileがこちら。なんか迷走し始めてる気がするけど。。
FROM centos:latest MAINTAINER Masato Oshima <qqw75pn9@gmail.com> RUN yum -y update && yum -y install vsftpd RUN echo "background=NO" >> /etc/vsftpd/vsftpd.conf EXPOSE 21 CMD ["/usr/sbin/vsftpd"]
ビルドして、ポート21をバインドするのは忘れないようにしてコンテナ起動して、ftp接続できるか確認。
$ docker build -t mpon/vsftpd . $ docker run -d -p 21:21 mpon/vsftpd 9d7377fedc502995dbc8c24930a8e7ad6ad6c2423f1091798d8f5258e9265278 $ vsftpd docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9d7377fedc50 mpon/vsftpd:latest /usr/sbin/vsftpd 2 seconds ago Up 2 seconds 21/tcp stupefied_yonath $ ftp ftp> open 192.168.59.103 Connected to 192.168.59.103. 220 (vsFTPd 2.2.2) Name (192.168.59.103:mpon): ftp 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files.
やったーftpでログインできた!
パッシブモード
しかし、このあと、ftpサーバー上で、lsとか打ってみると怒られるので、パッシブモードでftpサーバーを動かそうと、そのやり方を調べた。
色々試行錯誤した結果、以下のvsftpd.confの設定も追加されるように、Dockerfileに書いておく必要があった。
pasv_addressでboot2dockerのip書かなきゃいけないのがいけてない...。あと、起動時にバインドするポートを最小限にしたくて、パッシブに使うのは50000番だけにした。
pasv_address=192.168.59.103 pasv_enable=YES pasv_min_port=50000 pasv_max_port=50000
Dockerfileはこんな感じ
FROM centos:latest MAINTAINER Masato Oshima <qqw75pn9@gmail.com> RUN yum -y update && yum -y install vsftpd RUN echo "background=NO" >> /etc/vsftpd/vsftpd.conf RUN echo "pasv_address=192.168.59.103" >> /etc/vsftpd/vsftpd.conf RUN echo "pasv_enable=YES" >> /etc/vsftpd/vsftpd.conf RUN echo "pasv_min_port=50000" >> /etc/vsftpd/vsftpd.conf RUN echo "pasv_max_port=50000" >> /etc/vsftpd/vsftpd.conf EXPOSE 21 EXPOSE 50000 CMD ["/usr/sbin/vsftpd"]
これで起動するときにパッシブモード用のポートもバインドしないとつながらいので、起動するときは以下のようにする。
$ docker run -d -p 21:21 -p 50000:50000 mpon/vsftpd
まぁ開発環境だし、こんなもんかと思ったけど、今度は、FileZillaで同時に複数ファイルをアップロードしようとしたら、エラーになってコンテナが終了してしまった。
そもそもコンテナが終了してしまうってハードすぎじゃね?とは思ったけど、まぁそこは置いといて。
ubuntu - Make FTP Server on virtualbox work in passive mode - Super User を見ると、パッシブモードで複数のファイルをやりとりしたければ、その分のポートを開けないといけないということか。
となると例えば同時50接続を許すなら、Dockerfileは、こうなった。ヤバい。
FROM centos:latest MAINTAINER Masato Oshima <qqw75pn9@gmail.com> RUN yum -y update && yum -y install vsftpd RUN echo "background=NO" >> /etc/vsftpd/vsftpd.conf RUN echo "pasv_address=192.168.59.103" >> /etc/vsftpd/vsftpd.conf RUN echo "pasv_enable=YES" >> /etc/vsftpd/vsftpd.conf RUN echo "pasv_min_port=50000" >> /etc/vsftpd/vsftpd.conf RUN echo "pasv_max_port=50050" >> /etc/vsftpd/vsftpd.conf EXPOSE 21 EXPOSE 50000 EXPOSE 50001 EXPOSE 50002 EXPOSE 50003 EXPOSE 50004 EXPOSE 50005 EXPOSE 50006 EXPOSE 50007 EXPOSE 50008 EXPOSE 50009 EXPOSE 50010 EXPOSE 50011 EXPOSE 50012 EXPOSE 50013 EXPOSE 50014 EXPOSE 50015 EXPOSE 50016 EXPOSE 50017 EXPOSE 50018 EXPOSE 50019 EXPOSE 50020 EXPOSE 50021 EXPOSE 50022 EXPOSE 50023 EXPOSE 50024 EXPOSE 50025 EXPOSE 50026 EXPOSE 50027 EXPOSE 50028 EXPOSE 50029 EXPOSE 50030 EXPOSE 50031 EXPOSE 50032 EXPOSE 50033 EXPOSE 50034 EXPOSE 50035 EXPOSE 50036 EXPOSE 50037 EXPOSE 50038 EXPOSE 50039 EXPOSE 50040 EXPOSE 50041 EXPOSE 50042 EXPOSE 50043 EXPOSE 50044 EXPOSE 50045 EXPOSE 50046 EXPOSE 50047 EXPOSE 50048 EXPOSE 50049 EXPOSE 50050 CMD ["/usr/sbin/vsftpd"]
起動スクリプトも激ヤバ。ワロタ
docker run -d \ -p 21:21 \ -p 50000:50000 \ -p 50001:50001 \ -p 50002:50002 \ -p 50003:50003 \ -p 50004:50004 \ -p 50005:50005 \ -p 50006:50006 \ -p 50007:50007 \ -p 50008:50008 \ -p 50009:50009 \ -p 50010:50010 \ -p 50011:50011 \ -p 50012:50012 \ -p 50013:50013 \ -p 50014:50014 \ -p 50015:50015 \ -p 50016:50016 \ -p 50017:50017 \ -p 50018:50018 \ -p 50019:50019 \ -p 50020:50020 \ -p 50021:50021 \ -p 50022:50022 \ -p 50023:50023 \ -p 50024:50024 \ -p 50025:50025 \ -p 50026:50026 \ -p 50027:50027 \ -p 50028:50028 \ -p 50029:50029 \ -p 50030:50030 \ -p 50031:50031 \ -p 50032:50032 \ -p 50033:50033 \ -p 50034:50034 \ -p 50035:50035 \ -p 50036:50036 \ -p 50037:50037 \ -p 50038:50038 \ -p 50039:50039 \ -p 50040:50040 \ -p 50041:50041 \ -p 50042:50042 \ -p 50043:50043 \ -p 50044:50044 \ -p 50045:50045 \ -p 50046:50046 \ -p 50047:50047 \ -p 50048:50048 \ -p 50049:50049 \ -p 50050:50050 \ mpon/vsftpd
なんだろう、、このコレジャナイ感は。。
configにboot2dockerのVMのIPアドレスを書かなきゃいけないってのもいけてないし。
なんか、ポートを複数使うようなやつにはこういうのは向いてないのかな。
ってか、AWSとかはどうやってるんだろう。セキュリティグループとか。
iptablesはなんか、あんじょうやってくれるそういう設定が合った気がする。
仮想マシンに向いてること、Dockerが得意なことがあるんだろうな。
プロセスが死ぬとコンテナまで終了するとか、怖すぎる。
まぁ、とりあえず、Dockerのいい勉強にはなった!
Vagrant使ったことなくて、いきなりDocker使ってみようってなったからこうなったんだね。
次はVagrantで同じことをやってみよう。
追記
Vagrant試してみました。コレじゃなくてコッチでした。
開発環境作るのにVagrantを使ったら非常にコレダ感になった話 - まーぽんって誰がつけたの?