ココだけは押さえておきたい!Docker v0.11 から v1.0 の変更点まとめ

こんにちは、2014年新卒エンジニアの進藤です。

 

Dockerロゴ

 

コンテナ型仮想化の実装として話題を集めていた「Docker」の正式版がリリースしました。このリリースは、企業の運用環境で利用できるだけの品質・機能の完全性・互換性・APIの安全性の基準が満たされていることを意味しています。

 

『 IT’S HERE: DOCKER 1.0 』

http://blog.docker.com/2014/06/its-here-docker-1-0/

 

今回は v0.11.0 から v1.0.0 の変更点についてを記事にしています。

 

v0.11 から v1.0 の変更点について

2014年5月8日に v0.11.0 が発表され、その1ヶ月後の2014年6月9日に待望の v1.0.0 がリリースされました。

 

Docker v0.11.0 から v1.0.0 で多くの機能がコミットがされています。

https://github.com/dotcloud/docker/compare/v0.11.0...v1.0.0

 

目玉機能としては、こんなところです。

- 製品としてのサポート

- Dockerfile のフォーマットに COPY が追加

- Dockerfile のフォーマットの ADD の改善

- Docker コマンド pause / unpause の追加

- Docker イメージをフィルタリングするオプション -f / --filter の追加

- Docker ビルド失敗時に中間コンテナを削除するオプション --force-rm の追加

- ポート番号2375をDocker APIのHTTPトラフィックとして利用

 

目玉機能を1つずつ紹介していきます。

 

製品としてのサポート

Docker のバージョンが 1.0 となり、企業の運用環境で利用するための品質・機能の完全性・互換性・APIの安全性がサポートされました。また、法人向けにサポート、トレーニング、コンサルティングなどの有償サービスを展開することも発表しています。

 

さらに「インフラ版のGithub」ともいえる Docker Hub も下記URLでサービス公開されました。

https://hub.docker.com/

 

Docker Hub によって、ビルド・テスト・デプロイの一連の継続的インテグレーション/継続的デプロイを実現して、物理サーバ・仮想サーバ・クラウドにアプリケーションを配布するワークフローが実現するとのことです。

 

Dockerfile のフォーマットに COPY が追加

COPYは指定したファイル・フォルダーをコンテナ内にコピーします。

https://docs.docker.com/reference/builder/#copy

 

ADD によく似ていますが、COPYは URL を指定できないことと、圧縮ファイルを自動解凍しません。

 

COPY が登場した背景としては、これまでADDが多くの役割を果たしていたので、ADDの機能を分割しようという流れで COPY が登場しました。COPY はホストサーバー側のファイルをコンテナ内に取り込む機能と考えて良いです。

参考) https://github.com/dotcloud/docker/issues/3050

 

書式 : COPY <src> <dest>

<src> : buildするパスからの相対パス

<dest> : コピー先であるコンテナ内の絶対パス

 

Dockerの設定ファイルの ADD の改善

ADDは指定したファイル・フォルダーをコンテナ内にコピーします。

https://docs.docker.com/reference/builder/#add

 

今回のリリースによる改善点としては、次の3つがあります。

<src> が tar archive であるとき、ディレクトリとして解凍されます。

<src> が file であるとき、ファイルのパーミッションはコピー元を引き継ぎます。

<src> が URL のとき、生成されるファイルのパーミッションは 600 となります。

参考) https://github.com/dotcloud/docker/pull/6057

参考) https://github.com/dotcloud/docker/pull/5953

 

書式 : ADD <src> <dest>

<src> : buildするパスからの相対パス or URL

<dest> : コピー先であるコンテナ内の絶対パス

 

 

 

では実際にCOPYとADDを動かしてみましょう。

 

フォルダ構成

$ tree sample/

sample/

├── Dockerfile

├── copy_file_1.tar.gz

├── copy_file_2.tar.gz

├── hoge_1.txt

└── hoge_2.txt

 

$ ls -l

合計 20

-rw-r--r-- 1 shindo shindo 808 6月 11 16:45 2014 Dockerfile

-rw-r--r-- 1 shindo shindo 168 6月 11 16:47 2014 copy_file_1.tar.gz

-rw-r--r-- 1 shindo shindo 163 6月 11 16:47 2014 copy_file_2.tar.gz

-r-x------ 1 shindo shindo 4 6月 11 07:09 2014 hoge_1.txt

-r-x------ 1 shindo shindo 4 6月 11 16:46 2014 hoge_2.txt

Dockerfile

# CentOSをベースに

FROM centos

 

# 作成者

MAINTAINER Taichi Shindo

 

# RUN コマンドを使って、yum コマンドを実行してインストールする

RUN yum update -y && yum -y upgrade

RUN yum install -y sudo

RUN yum install -y passwd

 

# ユーザーを作成

RUN useradd docker

RUN passwd -f -u docker

RUN chown -R docker:docker /home/docker

 

# docker に権限を与える

RUN echo "docker ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

 

# docker ユーザーで実行

USER docker

 

# ADD コマンドを使って、ファイルを取得

ADD ./hoge_1.txt /home/docker/

ADD ./copy_file_1.tar.gz /home/docker/

ADD http://cyber-z.co.jp/images/top/logo.png /home/docker/

 

# COPY コマンドを使って、ファイルを取得

COPY ./hoge2.txt /home/docker/

COPY ./copy_file_2.tar.gz /home/docker/

コンテナ生成・起動する。

$ docker build -t centos:sample .

$ docker run -i -t centos:sample /bin/bash

起動したコンテナで、COPYとADDでファイルがコピーされていることが確認できました。

bash-4.1$ ls -l /home/docker/

total 24

drw-r--r-- 2 501 501 4096 Jun 10 22:09 copy_file_1

-rw-r--r-- 1 root root 163 Jun 11 07:47 copy_file_2.tar.gz

-r-x------ 1 root root 4 Jun 10 22:09 hoge_1.txt

-r-x------ 1 root root 4 Jun 11 07:46 hoge_2.txt

-rw------- 1 root root 4445 Jan 1 1970 logo.png

Dockerコマンド pause / unpause の追加

背景としては、OpenStackと連携するために追加された機能のようです。ジョブの一時停止/再開ができることで、システムリソースのスケジューリングが改善されました。

参考) https://github.com/dotcloud/docker/issues/5948

 

paused <コンテナID> : コンテナ内の全てのプロセスを一時停止する

unpause <コンテナID> : 一時停止していたプロセスを再開する

 

paused を使って、コンテナを一時停止させます。

$ docker pause 90907500bb59

2014/06/10 23:45:02 POST /v1.12/containers/90907500bb59/pause

一時停止中のコンテナはSTATUSに (Paused) が表示されます。

$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

90907500bb59 centos:tomcat /bin/sh -c '/etc/ini 18 seconds ago Up 17 seconds (Paused) 0.0.0.0:8080->8080/tcp romantic_franklin

unpause を使って、一時停止していたコンテナを再開します。

$ docker unpause 90907500bb59

2014/06/10 23:46:27 POST /v1.12/containers/90907500bb59/unpause

Dockerのプロセスを調べます。Pausedが表示されなくなったのが確認できます。

$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

90907500bb59 centos:tomcat /bin/sh -c '/etc/ini About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp romantic_franklin

Docker イメージをフィルタリングするオプション -f / --filter の追加

イメージのリストをフィルタリングできるようになりました。`docker rmi ... `と組み合わせて、フィルタリングされたイメージのリストを削除できるようになります。

参考) https://github.com/dotcloud/docker/pull/4430

 

現在使えるフィルタリングは、dangling (boolean - true or false) です。

これは、タグのないイメージをフィルタリングすることができます。

$ docker images --filter "dangling=true"

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

<none> <none> 5d0bcd4751b8 38 hours ago 497.1 MB

<none> <none> dc38931abc8d 38 hours ago 497.1 MB

このフラグを組み合わせることで、タグのないイメージの削除が可能になります。

$ docker rmi $(docker images --filter "dangling=true" -q)

Docker ビルド失敗時に中間コンテナを削除するオプション --force-rm の追加

Dockerfileをビルドしてイメージを作るとき、1つの命令が実行されるごとに中間コンテナが作成されます。デフォルトでは ビルドが成功後に作成された中間コンテナは削除されます。

中間コンテナの削除については "Removing intermediate container ..." で確認できます。

 

$ docker build --no-cache -t centos:test .

2014/06/13 15:17:25 POST /build?nocache=1&rm=1&t=centos%3Atest

 

Sending build context to Docker daemon

[d2ec3d72] +job build()

Step 0 : FROM centos

---> 0b443ba03958

Step 1 : ADD ./hoge_1.txt /home/docker/

---> 28d8923ce60c

Removing intermediate container f33b0b9f3af9

Step 2 : ADD ./copy_file_1.tar.gz /home/docker/

---> f9b107a5c9bc

Removing intermediate container 0b0bec55242f

Step 3 : ADD http://cyber-z.co.jp/images/top/logo.png /home/docker/

---> 03a81a004708

Removing intermediate container a278cf5fba55

しかし、これまでのバージョンでは、ビルドに失敗時に関して中間コンテナを削除する機能はありませんでした。 v1.0 のリリースで、--force-rm オプションを使うことで、ビルド失敗時に中間コンテナを削除することができるようになりました。

参考) https://github.com/dotcloud/docker/pull/5839

 

実際に試してみましょう。

Dockerfileに以下を記述します。

FROM busybox

RUN true

RUN thiswillfail

3行目の RUN thiswillfail で、「sh には thiswillfail のコマンドはないよ」といわれて、ビルドに失敗します。

ビルド失敗時に中間コンテナが削除されるかどうかを調べてみます。

 

まず、--force-rm オプションを使わずにビルドします。

Step 2 で、ビルド失敗時に中間コンテナを削除している箇所がないことに気付くと思います。

$ docker build --no-cache -t centos:test .

Sending build context to Docker daemon 8.192 kB

Sending build context to Docker daemon

2014/06/13 15:28:54 POST /build?nocache=1&rm=1&t=centos%3Atest

[d2ec3d72] +job build()

Step 0 : FROM busybox

---> a9eb17255234

Step 1 : RUN true

---> Running in 7e4208afa06d

[d2ec3d72] +job allocate_interface(7e4208afa06de9268dbc30ab1bfa420d5bade3b9f6c5b463b74663e0c1430a36)

[d2ec3d72] -job allocate_interface(7e4208afa06de9268dbc30ab1bfa420d5bade3b9f6c5b463b74663e0c1430a36) = OK (0)

[d2ec3d72] +job release_interface(7e4208afa06de9268dbc30ab1bfa420d5bade3b9f6c5b463b74663e0c1430a36)

[d2ec3d72] -job release_interface(7e4208afa06de9268dbc30ab1bfa420d5bade3b9f6c5b463b74663e0c1430a36) = OK (0)

---> 1f239b459f49

Removing intermediate container 7e4208afa06d

Step 2 : RUN thiswillfail

---> Running in bd07d83b77db

[d2ec3d72] +job allocate_interface(bd07d83b77db6625394f7c99c5b4fb9cbc67818a21f7578a9e93d3aae355fe00)

[d2ec3d72] -job allocate_interface(bd07d83b77db6625394f7c99c5b4fb9cbc67818a21f7578a9e93d3aae355fe00) = OK (0)

/bin/sh: thiswillfail: not found

[d2ec3d72] +job release_interface(bd07d83b77db6625394f7c99c5b4fb9cbc67818a21f7578a9e93d3aae355fe00)

[d2ec3d72] -job release_interface(bd07d83b77db6625394f7c99c5b4fb9cbc67818a21f7578a9e93d3aae355fe00) = OK (0)

The command [/bin/sh -c thiswillfail] returned a non-zero code: 127

[d2ec3d72] -job build() = ERR (1)

2014/06/13 15:28:58 The command [/bin/sh -c thiswillfail] returned a non-zero code: 127

 

次に、--force-rm オプションを使って、ビルドします。

Step 2 で、中間コンテナを削除されていることが確認できます。

$ docker build --no-cache --force-rm=true -t centos:test .

Sending build context to Docker daemon 8.192 kB

Sending build context to Docker daemon

2014/06/13 15:29:21 POST /build?forcerm=1&nocache=1&rm=1&t=centos%3Atest

[d2ec3d72] +job build()

Step 0 : FROM busybox

---> a9eb17255234

Step 1 : RUN true

---> Running in f272814bdc72

[d2ec3d72] +job allocate_interface(f272814bdc72d2a97c64cd4cf6613a52fcef16483173939b07ebd30b0fbac632)

[d2ec3d72] -job allocate_interface(f272814bdc72d2a97c64cd4cf6613a52fcef16483173939b07ebd30b0fbac632) = OK (0)

[d2ec3d72] +job release_interface(f272814bdc72d2a97c64cd4cf6613a52fcef16483173939b07ebd30b0fbac632)

[d2ec3d72] -job release_interface(f272814bdc72d2a97c64cd4cf6613a52fcef16483173939b07ebd30b0fbac632) = OK (0)

---> b7df2f345cf8

Removing intermediate container f272814bdc72

Step 2 : RUN thiswillfail

---> Running in f693a631ece5

[d2ec3d72] +job allocate_interface(f693a631ece510656a7c82774076ac79516f264a75fa73b579c71e5f8166943e)

[d2ec3d72] -job allocate_interface(f693a631ece510656a7c82774076ac79516f264a75fa73b579c71e5f8166943e) = OK (0)

/bin/sh: thiswillfail: not found

[d2ec3d72] +job release_interface(f693a631ece510656a7c82774076ac79516f264a75fa73b579c71e5f8166943e)

[d2ec3d72] -job release_interface(f693a631ece510656a7c82774076ac79516f264a75fa73b579c71e5f8166943e) = OK (0)

Removing intermediate container f693a631ece5

The command [/bin/sh -c thiswillfail] returned a non-zero code: 127

[d2ec3d72] -job build() = ERR (1)

2014/06/13 15:29:26 The command [/bin/sh -c thiswillfail] returned a non-zero code: 127

ポート番号2375をDocker APIのHTTPトラフィックに利用

Docker が IANA(Internet Assigned Numbers Authority)よりポート番号 2375 と 2376 の付与を受けたことを発表しました。

伴って v1.0 では、2375 はDocker APIのHTTPトラフィックに、2376 はHTTPSトラフィックに利用するように実装がされています。

v1.0 より前は、4243 をDocker APIのHTTPトラフィックに使っていたので、注意が必要です。

参考) https://github.com/dotcloud/docker/pull/6181

 

最後に

製品版がリリースされたということで、多くの企業に注目されています。

CyberZ でも Docker を使った運用を検討しているところです。

 

Dockerを使えば何ができるのか?については、以前もブログに書いていたので、こちらを参考にしてください。

怠惰のすゝめ。Dockerで環境構築・テスト・デプロイを完全自動化

 

 

 

CyberZでは、日々最新の技術を追いかけているエンジニアを募集しています。

興味ある方は是非ご覧ください。

 

CyberZ エンジニア採用サイト

cyber-z.co.jp