対象読者
- Linuxの基礎コマンドを少し知っている方
- 簡単にサーバーを構築したいインフラ技術者、開発者
Dockerとは
Dockerの便利さは、システムを稼働するのに必要なサーバーを短時間で作れることにあります。サーバーに必要なソフトウェアがインストールされた出来合いのDockerイメージ(ダウンロードしてすぐに実行できるパッケージのこと)が多数公開されているので、こうしたものを使えば早ければ5分、複雑なものでも1時間もあればサーバーを構築できます。
これはインフラ技術者にとって便利なばかりか、さほどインフラに詳しくない、例えばいつもはコードを書くのが主業務である開発者にとっても、手軽に自分の開発サーバーが作れるという利点となります。
しかしそのためには、Dockerの基礎知識が必要です。本来Dockerはそれだけで1冊の本が書けるほどの内容があるのですが、ここでは本当に主要な箇所だけをかいつまんで説明します。(もちろんDockerについて、詳しく知るに超したことはありません。より詳しく知りたい人は、市販の書籍を読むことをお勧めします。例えば筆者は、AWSを使ってDockerを学べる『さわって学ぶクラウドインフラ docker基礎からのコンテナ構築』(日経BP)という本を書いています。興味があれば、そちらもご覧ください)。
隔離された実行環境「コンテナ」
Dockerとは、Docker社が開発したコンテナ実行環境のことです。一言で言えば、1台のLinuxコンピュータ上に、隔離された実行環境を構築できるソフトウェアです。隔離された、それぞれの実行環境のことを「コンテナ」と呼びます。
コンテナは、ファイルシステムやネットワークが、それぞれ独立しています。つまり、それぞれのコンテナの中に「/」から始まるファイルシステムがあり、ネットワークには別々のIPアドレスが割り当てられています。こうすることで、1台のコンピュータに複数のシステムが同居できる環境を実現しています。
コンテナで隔離すれば競合が起きなくなる
Dockerを利用しない場合、ファイルシステムは1つなので、複数のシステムをインストールすると、競合が起こりがちです。例えば、システムAとシステムBを1台のコンピュータにインストールするとします。ここで、どちらもライブラリとして、/usr/share/libraryXを利用しているとします。
ここでシステムAの都合で、/usr/share/libraryXをアップデートしたいとしましょう。この話は単純ではありません。なぜならこのライブラリはシステムBも使っており、アップデートすると、システムBに影響が生じるかもしれないからです。
しかしDockerを使ってシステムAとシステムBとを別のシステムにわけているのなら、こうしたことは起きません。互いにファイルシステムが独立しているためです。
上図からわかるように、そもそもそれぞれのコンテナは独立しているので、同じソフトウェアをインストールしたものをたくさん同居することもできます。例えばWebサーバーであるApacheやNginxをインストールしたコンテナを実行し、1台のサーバーで複数のコンテンツを提供することもできます。このとき、あるコンテナはPHPが入っていて、別のコンテナはRuby、さらに別のサーバーはGo言語など、それぞれ環境をわけて運用することもできます。
このように、多くのシステムをコンテナという枠で区切って実行できるのが、コンテナの特徴です。
Dockerの仕組みと仮想化ソフトとの違い
このように「複数の環境を作れる」という観点から見ると、VMWareやVirtualBoxのような仮想ソフトとどこが違うのかという話になるかもしれません。できることは同じに見えるかもしれませんが、仕組みが全く違います。
一言で言えば、コンテナは、ただ実行環境を隔離しているだけです(Unixシステムに詳しい人は、「chroot機能」や「jail機能」を思い浮かべるとしっくりくるかもしれません)。ハードウェアをエミュレートしているわけでもなく、それぞれのコンテナにOSをインストールしているわけでもありません。そのため仮想マシンと比べてオーバーヘッドがなく、とても高速です。
このように隔離して実行するためには、Linuxカーネルのcgroupsやネームスペースなどの機能を使っています。そのためDockerは、基本的にLinux環境でしか動作しません(「基本的に」と断っているのは、Windowsのプログラムを実行するための「Windowsコンテナ」というのもあるためですが、本連載では触れません)。
Dockerでは、カーネルの上に「Docker Engine」という実行エンジンが搭載され、その上でDockerコンテナが実行されています。ここで、それぞれのコンテナにはカーネルが入っておらず、ホストのカーネルを共有しているのがポイントです。いくつコンテナを実行してもカーネルは1つなので、コンテナの数、カーネルの分だけメモリを消費してしまうことがありません。それぞれのコンテナは、あくまでも隔離された実行環境に過ぎません。
コンテナのパッケージ化を可能とするイメージ
コンテナの中身は、1本のファイルに書き出すことができます。これを「Dockerイメージ」と言います(この連載では説明しませんが、docker commit、docker saveというコマンドを使うことでイメージ化できます)。コンテナをイメージ化しておけば、それはコンテナのバックアップになるだけでなく、別のコンピュータにコピーすることもできます。
これは例えば、負荷分散などで同じ構成のコンテナをたくさん作らなければならないときにも重宝します。そのほか、開発リーダーなどが開発に必要なソフトウェアやフレームワークをまとめてセットアップしたDockerイメージを作り、それを開発者が各自の開発コンピュータにインストールして使うといったやり方を行う際にも役立つはずです。
DockerリポジトリとDocker Hub
Dockerでは、こうしたイメージを1カ所に登録しておく「Dockerリポジトリ」という仕組みがあります。DockerリポジトリにDockerイメージを登録しておくと、それをダウンロードして、自分のサーバーやPCで簡単に実行できます。
Dockerリポジトリには、誰もが利用できる公共版があります。それが「Docker Hub」(注1)です。Docker Hubには、公共のDockerイメージ、有志の人たちが便利だと考えて登録したDockerイメージなど、多種多様なものがそろっています。
具体例を挙げると、「Apacheがインストールされたイメージ」「MySQLがインストールされたイメージ」「WordPressがインストールされたイメージ」などがあります。こうしたあらかじめセットアップ済みのイメージを使えば、手早く必要なサーバーを構築できます。
注1:Docker Hubは汎用のDockerリポジトリです。公開するパブリックな用途だけでなく、プライベートに設定して、社内などだけで利用するDockerイメージを登録するのにも使えます。
Dockerを使えば簡単にインフラを作れる
ここまで説明してきたように、Docker Hubには、多くの既存のイメージがあります。これを使えば、インフラに詳しくない人でも簡単に必要なサーバーを作れます。
これはサーバーで使うというだけの話ではありません。あとで紹介しますが、Dockerには「Docker for Desktop」と呼ばれる、WindowsやmacOSで動かせるDocker環境(無償)もあります。そのため開発者が自分のPCを使って、「開発用のサーバーを構築する」という操作も実現できるのです。
破棄が容易で何度でもやり直せる
コンテナは、それぞれ独立しているので破棄ややり直しが容易です。もし必要なくなったらコンテナごと削除してしまえばよいのです。
サーバーの構築経験がある人は、「いろいろとやっていたら、よくわからなくなって動かなくなってしまった」という人もいるでしょう。こうした場合Dockerであれば、単純にコンテナを破棄してやり直してしまえば済みます。こうした「破棄しやすい」というのは、開発者が自分のPCで一時的にサーバーを作る場合に便利です。いらなくなったら削除すれば、なくなってしまうからです。