はじめてのDocker on EC2
はじめに
JAWS DAYS2014でImmutable Infrastructureトラックが提供されたり、昨日Immutable Infrastructure Conference #1が開催されたり、ここ最近のテクノロジートレンドはImmutable Infrastructureに染まっている感じがあります。
僕自身も色々なBlogを読んだり自分で手を動かしてみたりと色々試行錯誤を繰り返しているのですが、僕がEC2上でDockerについてやってみたことを整理してみました。
Docker自体ここ数年でたくさんの人が試しているし、アウトプットも多いので、今更感は否めないのですが、これから試す人にとって少しでも参考になれば幸いです。
EC2上でのDockerのセットアップ
今回はCentOSをEC2にLaunchしました。使用したAMIは「CentOS 6 (x86_64) - with Updates(ami-31e86030)」です。
まずはyum updateで最新化します。またDockerのインストールで使うwgetをインストールしておきます。
# yum -y update # yum -y install wget
SELinuxを無効化しておきます。これはコンテナ上でユーザにパスワードを設定する場合など、SELinuxで制限がかかってしまうものがある為です。
# echo "SELINUX=disabled" > /etc/selinux/config
EPELリポジトリを追加し、docker-ioパッケージをインストールします。
# wget http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm # rpm -ivh epel-release-6-8.noarch.rpm # yum -y --enablerepo=epel install docker-io
インストールしたDockerをサービス起動します。
# chkconfig docker on # service docker start
Dockerコマンドを色々試してみる
まずは実行してみる
docker runコマンドで、CentOSのコンテナイメージでコンテナを起動し、echoコマンド実行してみます。初回はコンテナイメージのダウンロードが入りますので少し時間がかかります。
# docker run -t centos /bin/echo "hello docker" hello docker
echoコマンドが実行されました。そしてこのコンテナはコマンドを実行するとそのまま停止されてしまいます。
インタラクティブに実行してみる
インタラクティブに実行するには-iオプションを付けてコンテナを起動します。
# docker run -i -t centos /bin/bash bash-4.1# echo "hello docker" hello docker bash-4.1# exit exit
こちらもexitすることでコンテナが停止します。
コンテナを一覧表示する
docker psコマンドでコンテナが一覧表示されます。
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
何も表示されません。これは先ほど実行したdockerコンテナが既に停止状態にある為です。停止状態にあるコンテナも含め全て表示するには-aオプションを付けます。
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2561af2b236c centos:6.4 /bin/bash 29 seconds ago Exit 0 dreamy_einstein a41a2a8174f2 centos:6.4 /bin/echo hello dock 36 seconds ago Exit 0 agitated_turing
最初に実行した2つのコンテナが表示されました。
コンテナを削除する
不要になったコンテナを削除するのはdocker rmコマンドを実行します。
# docker rm 2561af2b236c 2561af2b236c # docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a41a2a8174f2 centos:6.4 /bin/echo hello dock 2 minutes ago Exit 0 agitated_turing
2561af2b236cというコンテナIDを持ったコンテナが削除されています。
停止しているコンテナの全削除
試行錯誤してコンテナをポコポコ立てているとゴミがどんどん溜まっていきます。一つ一つIDを指定して削除するのはだいぶ面倒だと思ったのですが、@znzさんが素晴らしいTipsを書かれていました。
まずはコンテナを足して、2つにしてみます。
# docker run -t centos /bin/echo "hello docker 2" hello docker 2 # docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b68343c6822a centos:6.4 /bin/echo hello dock 37 seconds ago Exit 0 elegant_hawking a41a2a8174f2 centos:6.4 /bin/echo hello dock 2 minutes ago Exit 0 agitated_turing
以下のように、コンテナIDをコマンド結果から入力します。
# docker rm `sudo docker ps -a -q` b68343c6822a a41a2a8174f2 # docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
コマンド一回でコンテナが全部消えていますね!素晴らしい!
コンテナからイメージを作成する
上記の作業はCentOSのオフィシャルコンテナイメージを使っていたのですが、自分で作ったコンテナをイメージ化して使い回すことが出来ます。
例えばCentOSのオフィシャルコンテナイメージをベースに、yum updateで現時点で最新のパッケージが適用されたイメージを作ってみます。インタラクティブにコンテナを起動し、yum updateして停止してみます。
# docker run -i -t centos /bin/bash bash-4.1# yum update -y --snip-- Complete! bash-4.1# exit # docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 35369a096a54 centos:6.4 /bin/bash 5 minutes ago Exit 127 dreamy_brattain
このコンテナをベースに、updateというタグ名を付与したイメージを作成します。
# docker commit 35369a096a54 centos:update 062217fc2fa069117695a2093145c1a2f1bc59d85877a6fe768af1e350fb2347
docker imagesコマンドでローカルに保存されているコンテナイメージの一覧を表示します。
# docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos update 062217fc2fa0 50 seconds ago 602.8 MB centos 6.4 539c0211cd76 11 months ago 300.6 MB centos latest 539c0211cd76 11 months ago 300.6 MB
TAGがupdateになっているコンテナイメージが出来ていますね!
イメージのタグからコンテナ起動
では作成したupdateイメージからコンテナを起動してみます。最新のパッケージが適用されているので、yum updateしても何も適用されません。
$ sudo docker run -i -t centos:update /bin/bash bash-4.1# yum update -y No Packages marked for Update
イメージを削除する
作成したコンテナイメージを削除するのはdocker rmiコマンドを実行します。なおそのイメージを使用したコンテナが存在する場合は削除できませんので、先にコンテナを削除した後にイメージを削除します。次の例ではコンテナ:86ad0ef5a87fを削除した後、コンテナイメージ:062217fc2fa0を削除しています。
$ sudo docker rm 86ad0ef5a87f 86ad0ef5a87f $ sudo docker rmi 062217fc2fa0 Deleted: 062217fc2fa069117695a2093145c1a2f1bc59d85877a6fe768af1e350fb2347 $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos 6.4 539c0211cd76 11 months ago 300.6 MB centos latest 539c0211cd76 11 months ago 300.6 MB
コンテナイメージ:062217fc2fa0が削除されていますね!
DockerにホストOSからSSHで接続してみる
それでは実用的な使い方として、コンテナをバックグラウンドで実行し、ホストからコンテナにSSH接続をしてみます。
Dockerfileを使ってイメージを作成する
先ほどは手作業したコンテナからイメージを作成しましたが、今度はDockerfileを使ってイメージを作成してみます。
Dockerfileを配置するディレクトリを作成し、Dockerfileを作成します。なお、今回はSSHで接続するために、Dockerfileと同一ディレクトリ内にauthorized_keysファイルを配置し、イメージ作成時に組み込んでいます。
$ mkdir ~/docker $ cp ~/authorized_keys ~/docker ※authorized_keysは事前に用意しておいて下さい。 $ cd ~/docker $ vi Dockerfile FROM centos # Install SSH RUN yum update -y RUN yum install -y sudo RUN yum install -y passwd RUN yum install -y openssh-server RUN yum install -y openssh-clients RUN /usr/bin/ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -C '' -N '' RUN /usr/bin/ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -C '' -N '' RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config RUN sed -ri 's/#UsePAM no/UsePAM no/g' /etc/ssh/sshd_config # Create User RUN useradd worker RUN passwd -f -u worker RUN mkdir -p /home/worker/.ssh RUN chmod 700 /home/worker/.ssh ADD ./authorized_keys /home/worker/.ssh/authorized_keys RUN chmod 600 /home/worker/.ssh/authorized_keys RUN chown -R worker /home/worker/ # Add sudoers RUN echo "worker ALL=(ALL) ALL" >> /etc/sudoers.d/worker EXPOSE 22
このDockerfileからイメージを作成します。イメージ作成はdocker buildコマンドを使います。ここではsshdというタグを付与しました。
# docker build -t centos:sshd . --snip-- Successfully built 40625ead6983
コンテナイメージが作成されたことを確認します。
# docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos sshd 40625ead6983 9 seconds ago 643.3 MB centos 6.4 539c0211cd76 11 months ago 300.6 MB centos latest 539c0211cd76 11 months ago 300.6 MB
では作成したコンテナイメージから、sshdを起動した状態でコンテナを立ち上げてみましょう!-dオプションを付けてバックグラウンド起動しています。また-pオプションをつけてポートフォワーディングするようにしています。
# docker run -d -p 22 centos:sshd /usr/sbin/sshd -D 2ae8a06038de1efc3e3325be9c3be49368ff422b8a6e3abb6dea5d25524fcc26
起動したコンテナを確認します。
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2ae8a06038de centos:sshd /usr/sbin/sshd -D 10 seconds ago Up 10 seconds 0.0.0.0:49158->22/tcp jolly_pare
sshdのコンテナイメージを使ったコンテナがバックグラウンド起動していることが分かります。また「0.0.0.0:49158->22/tcp」という表示から、49158番ポートが22番ポートにフォワーディングされていることも分かりますね。
それでは接続...するのですが、まずDockerコンテナのIPアドレスを確認します。
# ifconfig docker0 Link encap:Ethernet HWaddr FE:9A:75:95:42:A1 inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::d811:45ff:fee8:5b27/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:20857 errors:0 dropped:0 overruns:0 frame:0 TX packets:43674 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1155152 (1.1 MiB) TX bytes:65358408 (62.3 MiB)
では接続!
# ssh -i ~/.ssh/mykey.pem -l worker 172.17.42.1 -p 49158 The authenticity of host '[172.17.42.1]:49158 ([172.17.42.1]:49158)' can't be established. RSA key fingerprint is e7:f1:8e:96:59:7c:a5:fe:7b:64:b8:7c:d1:ee:86:6b. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[172.17.42.1]:49158' (RSA) to the list of known hosts. Last login: Wed Mar 26 02:07:00 2014 from ip-172-17-42-1.ap-northeast-1.compute.internal $
ちゃんとSSHログインできました!sudoも使えてます!
$ sudo ls / bin boot dev etc home lib lib64 media mnt opt proc root sbin selinux srv sys tmp usr var
わーい出来たー!
まとめ
何が「わーい出来たー!」だ。すんなり出来ているように見えますが、僕の知識不足もあり、非常に難航しました。SSHで接続するためのDockerfileなんかは試行錯誤して試行錯誤してやっと出来たものです。2日くらいかかってしまいました。だいぶ情報が出そろっているとはいえ、環境によって細かいチューニングやコツがいるなぁと思いました。
とにかく「とりあえず使う」ことは出来るようになったので、次は活用を考えたいと思います!