2014年2月13日木曜日

Dockerってなんじゃ?(Dockerfileでビルド)



DockerにはDockerfileというものがあります。
docker buildを行うと、指定したパスからDockerfileを探し、コンテナを新規作成し記述されたステップを実行した後、コミットをしてコンテナイメージの作成までを自動で行います。

たとえば
$ docker build -t hoge/moge /path/to/contxt/
とすると、/path/to/contxt/ディレクトリにあるDockerfileを元にステップ実行したコンテナをhoge/mogeというリポジトリ名で保存するところまでを自動で行ってくれます。

Dockerfileの記述フォーマットは、基本的に
命令 引数
という形式で記載します。



命令



命令には以下のものがあります。

FROM

コンテナの元になるベースイメージの指定をします
FROM <image>

MAINTAINER

生成されるイメージのAuthorフィールドの指定をします
MAINTAINER <name>

RUN

ビルドステップ内で実行されるコマンドです
# /bin/sh -cでのコマンドとして実行されます
RUN <command>
# 実行プログラムを直接指定します
RUN ["executable", "param1", "param2"]

CMD

作成されたコンテナ起動時のデフォルトコマンドです
# 実行プログラムを直接指定します
CMD ["executable","param1","param2"]
# ENTRYPOINTのデフォルトパラメータを定義します
CMD ["param1","param2"]
# シェルとして実行されます
CMD command param1 param

EXPOSE

指定されたポートを開放します。指定するのはコンテナ内部からみたポート番号です
EXPOSE <port> [<port>...]

ENV

環境変数をセットします
ENV <key> <value>

ADD

コンテナ外のファイルをコンテナ内に配置します
ADD <src> <dest>

ENTRYPOINT

作成されたコンテナ起動時のコマンドです
CMDと異なり、docker runで引数が与えられた場合、コマンド自体が上書きされず、パラメータとして扱います
# 実行プログラムを直接指定します
ENTRYPOINT ["executable", "param1", "param2"]
# シェルとして実行されます
ENTRYPOINT command param1 param2

VOLUME

外部からボリュームとしてマウントする際のマウントポイントです
VOLUME ["/data"]

USER

コンテナを起動する際のユーザー名またはUIDです
USER daemon

WORKDIR

CMDが実行される時のワークディレクトリを指定します
WORKDIR /path/to/workdir

ONBUILD

ビルド完了後に実行される命令です
他の命令と同じタイミングではまだ実行できないような命令の場合、全てのビルドが終わってから実行されます
ONBUILD [INSTRUCTION]

以上、これらの命令を組み合わせて、コンテナの中身を組み上げていきます。




Dockerfileの作成



前回の記事でつくったsshdとhttpdをsupervisordで起動するコンテナを、上記の命令を組み合わせてDockerfileを記述して作ってみると以下のようになります。

# centosがベース
FROM centos

# 作成者
MAINTAINER memorycraft

# yumでいろいろインストール
RUN yum install sudo passwd openssh openssh-clients openssh-server httpd vim python-setuptools -y

# sshdの設定
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
# キーの生成
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
# sshでログインするユーザーを用意
RUN useradd memorycraft
RUN echo 'memorycraft:memorycraft_password' | chpasswd
RUN echo 'memorycraft ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/memorycraft

# httpdのトップページ
RUN echo 'moge' > /var/www/html/index.html

# supervisordのインストール
RUN easy_install supervisor
# supervisordの設定
RUN echo_supervisord_conf > /etc/supervisord.conf
RUN echo '[include]' >> /etc/supervisord.conf
RUN echo 'files = supervisord/conf/*.conf' >> /etc/supervisord.conf
RUN mkdir -p  /etc/supervisord/conf/
ADD templates/memorycraft/conf/supervisor.conf /etc/supervisord/conf/service.conf


# ポート開放
EXPOSE 22 80

# 起動時にsupervisordを実行
CMD ["/usr/bin/supervisord"]




ビルドの実行


それでは、このDockerfileをビルドしてコンテナイメージを作成します。 ポイントは--rmです。
デフォルトでは1つの命令が実行されるごとにコミットが行われ、沢山のコンテナが出来てしまいますがこのオプションをつけることで、ビルドが成功した後に中間コンテナを全て消してくれます。
# docker build --no-cache --rm -t memorycraft/centos .
# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
memorycraft/centos   latest              d0c94b943ba2        2 minutes ago       437.9 MB
centos               6.4                 539c0211cd76        10 months ago       300.6 MB
centos               latest              539c0211cd76        10 months ago       300.6 MB

作成には成功しているようです。
続けて、このイメージでコンテナを起動してみます。
# docker run -d -p 22 -p 80 memorycraft/centos /usr/bin/supervisord
CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS                                          NAMES
1d4a403c44c5        memorycraft/centos:latest   /usr/bin/supervisord   44 seconds ago      Up 43 seconds       0.0.0.0:49185->22/tcp, 0.0.0.0:49186->80/tcp   goofy_darwin
c118bcc97b1e        centos:6.4                  /bin/bash              18 hours ago        Exit 0



確認



それでは、このコンテナに前回同様アクセスしてみたいと思います。sshのユーザー/パスワードはDockerfileで指定したものを使います。
# ssh memorycraft@127.0.0.1 -p 49185
The authenticity of host '[127.0.0.1]:49185 ([127.0.0.1]:49185)' can't be established.
RSA key fingerprint is ea:46:dd:dd:07:64:89:6e:b6:e4:38:73:41:82:32:b7.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:49185' (RSA) to the list of known hosts.
memorycraft@127.0.0.1's password:
[memorycraft@1d4a403c44c5 ~]$

無事接続出来ました!

また、ブラウザにもアクセスしてみます。



表示されてます!
これで、Dockerfileのコーディングによるインフラ管理ができるようになります。

今回は以上です。