この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
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日くらいかかってしまいました。だいぶ情報が出そろっているとはいえ、環境によって細かいチューニングやコツがいるなぁと思いました。
とにかく「とりあえず使う」ことは出来るようになったので、次は活用を考えたいと思います!