PR
連載 :
  

Dockerを理解するための8つの軸

2015年7月29日(水)
高橋 正和

「Docker」というキーワードが、サーバーまわりのキーワードとして定着しつつある。その一方で、触ったことのある人以外からは、「Dockerってよくわからない」「コンテナーって昔からあるのでは?」という声も聞く。

Dockerは、それまでにあった要素技術を組み合わせることで、サーバーアプリケーションを実行する便利な方法を作り出したものだ。そのため、1つの要素技術を見ただけでは、新しさや全体像がわかりにくい。

そこでこの記事では、Dockerを触ったことのない人向けに、Dockerを8つの軸から説明する。なお、ここではDockerそのものを解説するわけではないので、ご了解願いたい。

1. コンテナー

Dockerはまず、コンテナー管理ツールだ。

コンテナーとは、1つのサーバーの上で、複数のサーバー環境をそれぞれ分離して実行する、一種の仮想化技術だ。「OSレベルの仮想化」とも呼ばれる。

複数のサーバー環境を動かす点ではハイパーバイザーによる仮想マシン技術に似ている。ただし、仕組みは大きく異なる。仮想マシンでは、物理マシンをエミュレートし、ゲストOSからはあたかも物理マシンで動いているかのように動作する。一方コンテナーは、1つのOSの中を複数の区画に分離する技術であり、1つのカーネルの上で複数のOS環境が動く。

仮想マシンとコンテナーの違い(出典:What is Docker?

現在のLinuxでは、カーネルに含まれる複数の技術の組み合わせによりコンテナーを実現している。これは、「Linuxコンテナー」(または「広義のLXC」)と呼ばれる。単一の技術によるものではないため、Linuxコンテナーを動かすソフトウェアは、Dockerを含め、「LXC」(「lxc-tools」「狭義のLXC」と呼ばれることもある)やsystemd-nspawn、rkt(旧名Rocket)、LXDなど、複数の実装がある。

Dockerは当初、lxc-toolsを用いたコンテナー管理ツールとして登場した。その後、LinuxカーネルのLinuxコンテナー機構を直接使うようになり、さらにそうしたコンテナー操作をlibcontainer(現在では「runC」プロジェクトに移行)というライブラリーで抽象化した。libcontainerでは複数のコンテナー実装をドライバーとして選択できるようになっている。次期Windows Serverではコンテナー機構を備えてDockerに対応するというのも、libcontainerで抽象化されているおかげだろう。

ちなみに、現在のLinuxコンテナーが登場する以前から、SWsoft社(現Parallels社)が開発したVirtuozzoや、そのオープンソース版であるOpenVZが存在し、VPS事業者に採用されてきた。Parallels社では、Linuxコンテナーは本家Linuxカーネルに統合したOpenVZの技術がベースになっていると主張している。

2. ファイルシステムの差分管理

Dockerのほかにも、以前からlxc-toolsなどLinuxコンテナー管理ツールはあった。そうしたこれまでのコンテナー管理ツールと比べて、Dockerの特徴のひとつといえるのが、ファイルシステムの差分管理の機能だ。

一般にコンテナー環境を動かすには、コンテナーごとにそれぞれディレクトリー階層を用意する必要がある。シンプルな実装では、コンテナーごとに全ディレクトリーとファイルをコピーすることになる。

Dockerでも、元となる雛形(Dockerでは「イメージ」と呼ばれる)に含まれたディレクトリーやファイルからコンテナーが作られる。ただし、雛形をコピーすることはない。Dockerではファイルシステムの差分管理の機能を利用して、雛形のディレクトリーとファイルの上に、書き込み用の領域を“重ねる”形をとる。そして、各コンテナーではイメージに重ねられた書き込み用領域の分、つまりイメージからの差分だけを持つ。

差分管理の機能を持つ(出典:What is Docker?

これにより、新しいコンテナーを一瞬で作れる。Dockerでコンテナーを作りながらコマンドを実行してみると、コンテナーを作るオーバーヘッドが人間の感覚ではわからないぐらいだ。差分しかディスク容量を消費しないことと合わせて、どんどんコンテナーを作って使い捨てにできる。

この特徴から、まっさらの環境を何度も作り、使い捨てにする用途にも使える。たとえば、ソースコードを変更するたびにテストを実行するような継続的インテグレーション(CI)などでもDockerが使われることがある。

Dockerではまた、イメージをDockerfileという設定ファイルから作成できる。Dockerfileでは、元イメージを指定したあと、「コマンドAを実行」「コマンドBを実行」……と処理を順番に記述する。実はこの処理1つごとに差分データが作られる。この差分はキャッシュされるため、Dockerfileの最後に処理を追加してイメージを作ると、(うまくいけば)キャッシュを元に追加した処理だけ実行してイメージが作られる。これらの特徴は、コンテナーのデータに対するgitのようなものといえる。

3. 公開されたイメージのライブラリー

Dockerを使ってみて「便利」や「楽」と思うこととして、既存のイメージを簡単に取得できる点がある。

Dockerのコンテナー管理ツールは、正式には「Docker Engine」という。そして、Dockerブランドの中で、Docker Engineを使うための管理ソフトウェアやサービスがDocker社により提供されている。

Docker Engineでは、1つのコマンドで既存のイメージの検索やダウンロードができる。このイメージが多数登録されているサービスが「Docker Hub」だ。Docker Hubには、公式なもののほか、ユーザーが自分の作ったDockerイメージも登録されている。いわば、DockerにおけるGitHubのようなものといえるだろう。

Dockerクライアントからは、1コマンドでDocker Hubからイメージを取得し、コンテナー作成のベースとすることができる。この感覚は、npmやRubyGemsなどからプログラミング言語用ライブラリーを入手するのに似ている。

ただし、たとえば「node」で検索すると、執筆時点で2000イメージ以上がヒットする。サードパーティ製イメージが多く集まってるため、どのイメージを使ったらいいかがわかりづらいとは言われている。

Docker HubのOfficial Repositoriesの一例(出典:Docker Hub Registry - Repositories of Docker Images

4. アプリケーションのポータビリティ

利用目的から見ると、Dockerは「アプリケーションのポータビリティ」のための仕組みである。

サーバーアプリケーションは一般に、アプリケーション本体だけではなく、ランタイムライブラリーや関連ファイルなどが組み合わさって動作する。そのため、同じアプリケーションを異なる環境で動かそうとすると、ライブラリーの有無やバージョン違い、デフォルト設定の違いなどにより、そのままでは動かないといったことがしばしば起こる。

そこで、アプリケーションといっしょに、必要な動作環境をコンテナーに閉じこめてしまうというのがDockerの解決策だ。これにより、アプリケーションを(原則的には)どこのDocker上でも同じように動かせる。プログラミングでいえば、Node.jsのnpmやRubyのbundler、Goの静的リンクなどに似た考えだ。あるいは、Windows環境に詳しい人は、App-Vを連想するかもしれない。

こうした考えがベースになっているため、Dockerは基本的に、1つのコンテナーで1つのプログラムだけを動かすように作られている。複数のプログラム(たとえばWebアプリケーションとデータベースなど)は、それぞれ別のコンテナーで動かす。このようなコンテナーの使い方は「アプリケーションコンテナー」と呼ばれる。

なお、Dockerのポータビリティと言うときには、2種類の意味がある。同じCPUアーキテクチャで動く同じOS上であれば、Dockerイメージをそのままポータブルに利用できる。一方、異なるCPUやOSの場合でも、OS固有の機能(たとえばパッケージインストールなど)を使わずにDockerファイルをうまく書いてあれば、同じDockerfileで同様のコンテナーを再現できる。

5. ホストOSの新しいモデル

さて、このようにアプリケーションがそれぞれ実行環境を持つというDockerのモデルをつき進めると、ホストOSの役割も変わる。

通常のOS環境では、1台のマシンの上で複数のアプリケーションを動かし、そのために必要なライブラリーやミドルウェアのバージョンを用意する。アプリケーションをアップデートするにはライブラリーの互換性に注意する必要があるし、その逆もいえる。また、インストールしたライブラリーが増えると、セキュリティアップデートなど注意しなくてはならない事項も増える。

そこで、アプリケーションはすべてそれぞれDockerコンテナーで動かすことにすれば、ホストOSでは最小限のシステムだけを管理すればよい。こうした考えのもとに登場したのが「CoreOS」や「RHEL Atomic Host」などだ(CoreOSは現在ではDockerからブランチしたrktを採用)。

CoreOSやRHEL Atomic Hostなどでは、通常のLinuxディストリビューションのように「ソフトをインストールする」という考え方はない。ホスト環境のソフトウェアをアップデートするには、ルートファイルシステムをまるごとアップデートする。CoreOSは「Chrome OS」のオープンソース版である「Chromium OS」が元になっており、そのことからもシステムの考え方がわかるだろう。

6. PaaS

Dockerは、PaaSとも近しい。

Dockerを開発するDocker社(旧名DotCloud社)は、もともとPaaSサービスの会社だ。PaaSの仕組みの一つとして、コンテナーを使った実行環境を開発していた。そのシステムをベースに、再実装してオープンソースとして公開したのが、Dockerの始まりだ。

DotCloudやHerokuなどのPaaSサービスでは、アプリケーションのファイル一式をサーバーに送るたびに、ほかと切り離された専用環境が作られてアプリケーションが実行される。似た環境をすばやく何度も作る仕組みとして、Dockerが開発されたわけだ。

Herokuでも類似の仕組みとして「Warden」を開発している。Pivotal Software社によるPaaS基盤ソフト「Cloud Foundry」では、このWardenをもとにした「Garden」を採用している。また、Cloud Foundryと同様のPaaS基盤ソフトであるRed Hat社の「OpenShift」では、最新の「v3」でDockerを採用した。

Dockerが登場したときにも、Dockerを使ったHeroku風簡易PaaS基盤ソフト「Dokku」がすぐに登場して、一つの利用法を示した。現在では、より発展したDockerベースのPaaS基盤ソフトとして、「Flynn」や「Deis」が開発されている。

7. クラウドネイティブなサーバー構築

Dockerは、クラウドネイティブなサーバー構築の考え方にマッチしたツールでもある。

通常のサーバーの構築運用では、一度構築したサーバーに対し、システムソフトをアップデートしたり、アプリケーションを更新したり、機能を追加したりしていく。それに対してクラウド環境では、同じ役割のサーバーの台数を即座に増やすなど、再現性が重視される。

サーバーを自動的に再現するには、人手や手順書ではなく、プログラムのような形で構築方法を記述する必要がある。ChefやPuppetといった構成管理ツールが利用されるのは、そのためだ。また、テキストファイルによる定義として構築方法を記述することで、プログラムのようにサーバーが構築できることや、プログラムをgitのようなバージョン管理ツールで管理できることなど、アプリケーションプログラマのメンタルモデルに近づく。Dockerも同様の性質を持っている。

クラウド型のサーバー構築の極端な形が、「Blue-Green deployment」と呼ばれる方法だ。サーバーに更新や変更などを加えるときに、既存のサーバーを変更するのではなく、新しいサーバーに新しい環境を作り、その後で新しいサーバーにトラフィックを向け変えるというやりかただ。必要なサーバー台数は倍に増えるが、サーバーの変更にともなうトラブルやダウンタイムを減らし、必要であればロールバック(切り戻し)もできる。

Blue-Green Deploymentでは、一度立てたサーバー環境には変更を加えず、新しいサーバーが正常に始動すれば破棄される。こうした手法を総称して「Immutable Infrastructure」と呼ぶ。言い方を変えれば「使い捨てインフラ」だ。

Dockerも、アプリケーションを終了するとその環境が捨てられ、次に起動するときにはまた新しいベース環境で実行される。また、前述のとおり、どのサーバーでアプリを動かしてもいいポータビリティがある。そのため、Immutable Infrastructureとの親和性が高い。

8. クラスター構築

Dockerの上のレイヤーとして、クラスター構築のシステムに各社が取り組んでいる。

Docker社では前述のように、Docker Engineを中心として、それを複数ノード間で管理するための各種ソフトウェア群まで開発している。同社のSteve Francia氏がLinuxCon Japan 2015で行なった講演では、「昔のOSは1つのマシンのリソースを管理していたが、今は複数のノードにまたがってコンポーネントをスケジュールしたり、ポータビリティを提供したりする必要がある」として、「Linux + DockerがOSの未来」と論じている。

前述したCoreOSも、最初からコンテナーのクラスター実行を想定した設計になっている。RHEL Atomic Hostも、OpenShiftやKubernetesから管理することを想定している。

Kubernetesは、Googleが公開した、Dockerによるクラスター構築ソフトウェアだ。複数(多数)のホストをプール化し、Dockerコンテナーをどこかに割り当てて実行する。Kubernetesについては、GoogleやDockerはもちろん、Microsoft、Red Hat、IBMといったメジャー企業が、呉越同舟といえる形でサポートを表明している。

このように、企業やプロジェクトではいまDockerについて、Dockerコンテナー間や複数ホスト間のオーケストレーションに開発リソースを注ぎ込んでいる。

まとめ

以上、Dockerを8つの軸から紹介した。

見てきてわかるように、Dockerは特定のユースケースに適合するように作られたツールであり、万能ではない。合う用途には合うが、合わない用途はそれ以上に多いといってよい。

Dockerがどのような用途に使え、どのような用途に使えないのかを理解するうえでも、この記事で紹介したようなポイントを押さえておこう。

フリーランスのライター&編集者。IT系の書籍編集、雑誌編集、Web媒体記者などを経てフリーに。現在、「クラウドWatch」などのWeb媒体や雑誌などに幅広く執筆している。なお、同姓同名の方も多いのでご注意。

Think IT会員サービス無料登録受付中

Think ITでは、より付加価値の高いコンテンツを会員サービスとして提供しています。会員登録を済ませてThink ITのWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

他にもこの記事が読まれています