「Moby」ベースとなったオープンソース版Dockerの最新状況

2017年4月、Dockerは「Moby Project」と呼ばれる、Dockerのコア部分をコンポーネント化する試みを発表した。オープンソース版のDocker(Docker Community Edition、Docker CE)」もこのMobyをベースとしたものとしてリリースされるようになり、2017年6月にはMobyベースのDockerとなる「Docker 17.06 Community Edition(CE)」がリリースされている。本記事ではこういったDockerの開発体制の変化や、最近Dockerに導入された新機能などを紹介する。

Dockerは有償サポート付き版とオープンソース版の2つがリリースされる状況に

2017年3月、Dockerを開発するDocker社は「サポート付きの商用版」という位置付けの「Docker Enterprise Edition」を発表した。同時に、無償版は「Community Edition」としてリリースされることも発表された。これと前後して、Dockerの開発体制などについても変更が行われている。本記事ではまずこういった変更点についてまとめ、続いて最近のDockerに追加された新機能などについて紹介していく。

商用版の「Docker EE」が登場

今年Dockerで行われた大きな変更点として、「Docker Community Edition」(Docker CE)および「Docker Enterprise Edition」(Docker EE)の登場と、バージョン番号付けルールの変更が挙げられる。

まず新たに発表されたDocker EEだが、こちらはDocker CEの全機能に加えていくつかのサポートが追加で提供される有償の商用版という位置付けの製品となる。Docker EEには現在「Basic」「Standard」「Advanced」という3つのプランが用意されており、Dockerが認証を行った「Docker Certified」なインフラやコンテナ、プラグインが提供されるほか、プランによってはプライベートレジストリや大規模環境向けの管理ツールなども提供される(Dockerの「Docker Pricing」ページ)。サポートについてはWebサイトのほか、メールや電話でも提供される。料金は年間1ノードあたり750ドルからだ。

いっぽうのDocker CEはそれまでのDockerを踏襲するもので、無償で提供され、ソースコードも公開されている。ライセンス等の変更はない。そのため、今までDockerを利用していたユーザーは基本的にはDocker CEにそのまま移行すれば良い。

有償版となるDocker EEのリリースによってオープンソース版に対しなんらかの制限が加わるのではないかとの声もあったが、今のところDocker CEについては以前のDockerと同様に提供されており、利用が制限されるような事態にもなっていない。また、各Linuxディストリビューションが公式に提供するDockerパッケージについても今のところ特に大きな影響はないようだ。

Dockerのバージョン番号やリリースタイミングが変更に

もう1つの大きな変更点であるバージョン番号付けルールの変更だが、Dockerでは今まで「Docker 1.13.1」のような、「1.<メジャーバージョン>.<マイナーバージョン>」という形式のバージョン番号が付けられていた。しかし、2017年3月のリリースからはバージョン表記が「<リリースされた西暦の下2桁>.<リリース月2桁>.<リビジョン>-ce」という形に変更された。このルールに従い、同リリースは「17.03.0-ce」というバージョン表記となっている。最後の「-ce」はオープンソース版(Community Edition)であることを示すものだ。

また、今までDockerでは決まったリリーススケジュールというものはなかったが、今後は4半期毎(3か月おき)に新たなリリース(Stableリリース)を行う方針となっている。これに加えて、「Edge」と呼ばれる、1か月おきに新機能を含むリリースも提供される(図1)。

図1 今後のDockerのリリーススケジュール(Docker Blogより)
図1 今後のDockerのリリーススケジュール(Docker Blogより)

従来は新バージョンがリリースされたら旧バージョンのサポートは終了していたが、Docker CEのStableリリースにおいては最低4か月のサポート期間(セキュリティやバグ修正が提供される期間)が明記された。これによって新バージョンがリリースされても1か月間はサポートが継続されることになる。

なお、このリリース間隔の短縮によって、Dockerが提供しているDocker CEを利用している場合は3~4か月間隔で新版へのアップデートを行う必要が出てくる。また、Edgeリリースについてはサポート期間は1か月で、新たなEdgeリリースが行われたら旧バージョンはその時点でサポート終了となる。

Dockerのリポジトリも変更に

今年に入り、Dockerの開発体制についても大きな変更が行われている。Dockerでは各機能のコンポーネント化が進められており、たとえばコンテナエンジンは「Containerd」としてすでに分離されていた。Dockerはこれらコンポーネントを組み合わせて提供されていたのだが、これをさらに推し進め、各コンポーネントの機能を提供するライブラリや、これらを組み合わせるためのフレームワークやツールなどを提供するプロジェクトである「Moby」が2017年4月に発表された(図2)。

図2 Moby ProjectのWebサイト
図2 Moby ProjectのWebサイト

Docker社によると、MobyはDockerやコンテナ環境のための研究開発プロジェクトという位置付けで、Mobyプロジェクト上で外部開発者とのコミュニケーションや外部開発者からの貢献を受け、それを元にDockerを開発するという。また、Mobyの成果物はDocker上で単にアプリケーションを動かしたいといった人達に向けたものではなく、Docker自体をカスタマイズしたり、独自のコンテナシステムを開発したいような人向けという位置付けだそうだ。

このMobyプロジェクトのリポジトリは新規に作成されたのではなく、dockerのリポジトリ(GitHub上の「docker/docker」リポジトリ)が改名されて利用された。これにより、Docker(Docker CE)のソースコードが入手できなくなるのではないかという危惧の声も出ていたのだが、その後GitHub上にdocker/docker-ceというリポジトリが作られ、現在はこちらでDocker CEのソースコードが入手できるようになっている。

バイナリの入手先も変更に

Docker CEのソースコードはdocker-ceリポジトリから入手できるが、バイナリについては入手方法が若干変更された。Docker 17.05.0-ce(5月6日リリース)まではget.docker.com経由でLinux(x86_64)やmacOS、Windows向けバイナリが入手できたが、それ以降のリリースとなる17.03.2-ceについてはThe Docker Storeでの提供となっている。単に配布サイトが変更されただけで現状では特にダウンロードに登録などが必要というわけではないが、Linux版については最終的にはDockerのドキュメントのInstall Dockerページに誘導され、そこからリンクを辿る必要があるのでやや煩雑ではある。

なお、DebianやUbuntu、CentOS向けに提供されていたapt-get/yum向けリポジトリはDocker CEでも継続して提供されている。

最近のDockerの新機能

さて、Dockerの現状について説明したところで、続いては2017年1月にリリースされたDocker 1.13以降で導入された新機能について紹介していこう。

前述の通り、Dockerでは2017年3月にリリースされた17.03からリリース頻度が変更され、3か月おきの「Stable」リリースに加えて、基本的に毎月行われる「Edge」リリースが行われるようになった。そのため、新機能や変更点のチェックにはEdge版も含めてリリースノートを確認する必要がある。Docker CEのリリースノートはGitHubのdocker/docker-ecリポジトリのリリースページでも確認できるが、こちらにはリリース候補(rc)版のログも含まれており時系列を追いにくいので、Dockerのドキュメントサイトに掲載されている「Docker CE release notes」を確認すると良いだろう。

コマンド体系の変更

最近のDockerでまず大きな変更点が、dockerコマンドにおけるコマンド体系の整理だ。dockerコマンドは「docker <コマンド> [<サブコマンド>] [オプションや引数など]」という形式で実行する処理を指定するが、過去の歴史的経緯からコマンドによってサブコマンドの体系が異なる状況になっていた。たとえば比較的最近導入されたネットワークの管理を行う「docker network」コマンドでは、サブコマンドとしてネットワークを作成する「create」や一覧表示する「ls」、削除する「rm」といったものが用意されている。いっぽう、イメージの管理では「docker images」コマンドでイメージの一覧表示、「docker rmi」コマンドでイメージの削除、イメージの作成は「docker build」や「docker pull」など、サブコマンドが使われていなかった。

2017年1月29日にリリースされたDocker 1.13ではこのような混沌としたコマンド体系の整理が行われ、多くのコマンドがサブコマンドを取るように再構成された。たとえばイメージ関連の処理は、「docker image <サブコマンド>」にまとめられ、たとえばイメージのリスト表示は「docker image ls」、イメージの削除は「docker image rm」、イメージの作成は「docker image build」といったコマンドで実行できるようになった。また、従来は「docker run」、「docker stop」、「docker start」、「docker rm」といったコマンドで実行していたコンテナの実行/停止/開始/削除などは、「docker container」コマンドのrun/stip/start/rmといったサブコマンドで実行できるようになっている(表1)。

表1 1.13で新たに導入されたサブコマンド(抜粋)
従来のコマンド 1.13で導入された対応するサブコマンド
attach container attach
build image build
commit container commit
cp container cp
events system events
exec container exec
images image ls
inspect container inspect
kill container kill
logs container logs
ps container ls
pull image pull
push image push
rm container rm
run container run
start container start
stop container stop

なお、従来のコマンドもまだサポートされている。たとえば「docker images」と「docker image ls」はまったく同じ結果を返す。

# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
elasticsearch         latest              4255fc97fa5f        6 weeks ago         315MB
kibana                latest              03b5ca7f5040        7 weeks ago         382MB
# docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
elasticsearch         latest              4255fc97fa5f        6 weeks ago         315MB
kibana                latest              03b5ca7f5040        7 weeks ago         382MB

ただ、開発者らは新しいコマンドの利用を推奨するとしている。

新たなコマンドの導入

前述のコマンド整理に合わせて、1.13ではコンテナ関係の処理を行うコマンドである「docker container」コマンド(ドキュメント)やイメージ関連の処理を行う「docker image」コマンド(ドキュメント)が導入されたほか、「docker secret」、「docker system」などの新しい機能も追加された。また、17.06では「docker config」というコマンドも追加されている。

Dockerの管理を行う「docker system」コマンド

Docker 1.13で導入された「docker system」コマンドは、Dockerの稼動状況や管理といった機能を提供するものだ。提供されるサブコマンドは表2のとおりだ。

表2 「docker system」コマンドのサブコマンド
コマンド 説明
docker system df Dockerのディスク使用状況を出力する
docker system events Docker内で発生したイベントを表示する
docker system info Dockerのシステム情報を表示する
docker system prune 不要なデータを削除する

このうち、「docker system events」は従来の「docker events」コマンド、「docker system info」は「docker info」コマンドと同様の処理を行うものだ。また、新たに導入された「docker system prune」は使用されていないコンテナやボリューム、ネットワーク、イメージなどをまとめて削除できるコマンドとなっている(ドキュメント)。

たとえばDockerイメージの作成時やテスト時にはイメージの作成やコンテナの実行などを繰り返すことが多いが、そうすると使っていないイメージやコンテナがディスク上に残り、ディスク容量を消費することがある。今までは「docker images」や「docker ps -a」コマンドで不要なイメージやコンテナを手動で見つけ出し、「docker rmi」や「docker rm」コマンドで削除していたが、1.13以降であれば「docker system prune」コマンドを実行することでこれらの作業を実行できる。

# docker system prune
WARNING! This will remove:
        - all stopped containers
        - all networks not used by at least one container
        - all dangling images
        - all build cache
Are you sure you want to continue? [y/N] y
Deleted Containers:
c8872b273165a831e3f0475b7a4ca30d0f63e13358f6750ad73bc17f945b381e
15786ebfdc3ed847475f3165241ca04e549027c51dd4642a3403ff78895ac647

Total reclaimed space: 38B

イメージビルド関連の変更点

Docker 1.13以降ではイメージのビルドにおいても複数の変更が加えられている。大きいものとしては、Docker 17.05で導入された「マルチステージビルド」がある。これは、Dockerfile中に最終成果物となるイメージとは別のイメージを定義し、そのコンテナ内でビルド等を行って生成したものを最終成果物となるイメージ内にコピーできるというものだ(ドキュメントでの解説)。

コンテナイメージ内にビルドが必要なバイナリファイルなどを格納したい場合、その処理をDockerfile中に記述してイメージの構築時にビルドを実行することで対応するのが一般的だった。ただ、そうするとイメージ内に最終的には不要な中間ファイルなどが残ってしまう可能性があるため、Dockerfile中に不要なファイルを削除する処理を記述しておく必要があった。

新たに導入されたマルチステージビルドでは、最終的に作成するイメージとは独立したビルド用のイメージを定義し、ビルドを実行してそこから必要なファイルのみを取り出す、といったことをDockerfileのみで可能にするものだ。

マルチステージビルド機能を利用するには、まずDockerfile中に複数のイメージビルド設定を記述する。これは、必要なイメージごとに「FROM」命令と、ビルドに必要な作業を行う命令を記述すれば良い。Dockerfile内で最後に指定されたイメージが、ビルドで最終的な成果物となる。また、それ以外のコンテナについては「FROM <イメージ名> AS <名前>」で名前を付けることができる。Dockerfile内ではこの名前を利用してほかのコンテナを参照する仕組みだ。

たとえば、次の例は、ビルド用コンテナに「bar」という名前を付け、そこでビルドしたファイルを最終成果物となるコンテナにコピーするという場合のDockerfileだ。

FROM foo AS bar ←ビルド用のコンテナを「bar」という名前で定義

(ここにビルドに必要な処理を記述する)


FROM hoge ←最終成果物となるコンテナを定義

(ここにビルドに必要な処理を記述する)

COPY --from=bar /abc/def/ghi /moge ←ビルド用コンテナ(bar)から指定したファイルをコピーする

ビルド用のコンテナからファイルをコピーするには、このように「COPY」命令に「--from=<コンテナ名>」オプションを付けて実行すれば良い。

また、マルチステージビルドの導入に伴いdocker buildコマンドには指定したコンテナのみをビルドする「--target <名前>」オプションも追加されている。たとえば上記の場合、docker buildコマンドを「--target bar」オプション付きで実行することで、ビルド用のコンテナのみを作成できる。これはDockerfileのテスト/デバッグを行う場合などに有用だ。

ビルド関連では、これ以外にも細かい変更点が多数ある。まずDocker 1.13ではDockerfileの作成者情報を埋め込む命令である「MAINTAINER」命令が廃止扱いとなった。代わりに、次のようにLABEL命令でメンテナ情報を埋め込むことが推奨されている。

LABEL maintainer="<メンテナのメールアドレス>"

また、Docker 17.04ではdocker buildコマンドのオプションで「--add-host=<名前>:<ホスト名/IPアドレス>」が追加された。このオプションを利用することで、たとえばビルド時にネットワーク経由でコンテナ外にアクセスするような処理を実行する場合に動的にアクセス先を変更できる。

Docker 17.05では、Dockerfileを指定する「-f <ファイル名>」オプションで、ファイル名の代わりに「-」が指定可能になった。「-」を指定すると、ファイルではなく標準入力からDockerfileを読み込むようになる。さらに Docker 17.06では、docker buildコマンドに「--iidfile <ファイル>」オプションが追加された。これはビルドの完了後、指定したファイルに作成されたイメージのイメージIDを出力するというものだ。これらの機能はスクリプトファイルなどを利用したコンテナ作成の自動化などに役立つだろう。

そのほか、記事執筆段階ではまだRC(リリース候補)であるDocker 17.09ではDockerfileの「ADD」命令や「COPY」命令に、追加/コピーしたファイルのパーミッションを指定する「--chown」オプションが追加される予定となっている。

コンテナ実行時にマウントを行うための新オプション「--mount」

Docker 17.05では、docker runおよびdocker createコマンドにボリュームやディレクトリ、tmpfsなどをマウントするための新しいオプション「--mount」が追加された。従来もマウントを行うためのオプションとして「-v/--volume」オプションや「--tmpfs」オプションが用意されていたが、--mountオプションはこれらのオプションを整理したうえでいくつかの新機能を追加したものとなっている(ドキュメント)。

--mountオプションでは複数のオプションが指定でき、書式としては次のようになっている。

--mount <オプション1>=<値1>,<オプション2>=<値2>,[...]

指定できる代表的なオプションとしては表3のものがある。

表3 指定できるオプション
オプション名 説明 指定できる値
type マウント対象を指定する volume(ボリューム)、bind(ローカルファイルもしくはディレクトリ)、tmpfs
src/source typeがbindの際にマウントするファイル/ディレクトリを指定する
dst/destination/target マウント先を指定する
readonly/ro リードオンリーにするか否かを指定 1(リードオンリーでマウント)、0(読み書き可能でマウント)
consistency マウントしたファイル/ディレクトリの同期タイミングを指定 default(常に同期)、consistent(defaultと同じ)、cached(キャッシュを行う。ホストでの更新がコンテナ内で反映されるのに遅延が起こる場合がある)、delegated(コンテナ内での更新がホストに反映されるのに遅延が起こる場合がある)

そのほかの主要な変更点

Docker 1.13以降ではこれ以外にも、多くの変更点や新機能導入が行われている。大きなものとしては、17.05でdocker updateコマンドで使用するCPU数を変更する「--cpus」オプションが追加されたことや、17.05では、docker runおよびdocker createコマンドでコンテナのファイルシステムをリードオンリーでマウントする「--read-only」オプションが追加された点などがある。

また、Dockerクラスタ構築機能であるswarmモードでも多数の変更が加えられている。これらについては、記事後編で紹介する。