Docker って何?
Docker はアプリケーションの開発、導入、実行を行うためのオープンなプラットフォームです。 Docker を使えば、アプリケーションをインフラストラクチャーから切り離すことができるため、ソフトウエアをすばやく提供することができます。 Docker であれば、アプリケーションを管理する手法をそのまま、インフラストラクチャーの管理にも適用できます。 Docker が採用する方法を最大限利用して、アプリケーションの導入、テスト、コードデプロイを行うことは、つまりコーディングと実稼動の合間を大きく削減できることを意味します。
Docker プラットフォーム
Docker はアプリケーションをパッケージ化して実行するために、ほぼ分離された環境となるコンテナーというものを提供します。 隔離してセキュリティを保つことから、実行するホスト上に複数のコンテナーを同時に実行することができます。 コンテナーは非常に軽量なものであり、アプリケーション実行に必要なものをすべて持っています。 したがって、その時点においてホスト上に何がインストールされていても、それに影響を受けません。 作業中のコンテナーは他の人と共有することができ、共有したコンテナーは誰でも同じようにして動作させることができます。
Docker が提供するのは、コンテナーのライフサイクルを管理するツールとプラットフォームです。
- コンテナーを利用して、アプリケーションとそれをサポートするコンポーネントを開発します。
- コンテナーは、アプリケーションの配布とテストを行う1つの単位となります。
- 準備ができたら本番環境に向けてアプリケーションをデプロイします。デプロイの単位は、1つのコンテナーか、あるいはオーケストレーションされた(orchestrated)1つのサービスです。その本番環境があたかも手元のデータセンター上であったり、クラウドプロバイダー上であったりするのと同様に動作します。
Docker は何に利用できるか?
アプリケーションの配信をすばやく一貫性を保って
Docker は開発のライフサイクルを効率化します。 開発するアプリケーションやサービスがローカルなコンテナー内に実現でき、開発者は標準化された環境により作業が進められるからです。 コンテナーを使った開発は、継続的インテグレーション (continuous integration; CI) や継続的開発 (continuous development; CD) のワークフローに適しています。
以下のようなシナリオ例を考えてみてください。
- 開発者がローカルでコードを書き、仲間とその作業を共有するために Docker コンテナーを使います。
- Docker によりアプリケーションをテスト環境に投入し、自動および手動のテストを実行します。
- 開発者がバグを発見したら、開発環境においてこれを修正して、アプリケーションをテスト環境に再デプロイし、テスト確認を行ないます。
- テストが完了します。この後にユーザーが修正版を利用できるようにすることは、更新済イメージを本番環境へ投入することと同じく容易なことです。
迅速なデプロイとスケーリング
Docker によるコンテナーベースのプラットフォームは、処理負荷の高度な分散を考慮しています。 Docker コンテナーは、開発者のノートパソコン上で実行できるだけでなく、データセンターの物理マシンや仮想マシン、クラウドプロバイダー、そしてさまざまな環境の組み合わせにおいて実行可能です。
Docker の可搬性と軽量な特性は、以下のようなことを容易に実現します。 それは処理負荷を動的に管理できること、ビジネスシーンでの要求に応じてアプリケーションのスケールアップや提供終了を簡単に、しかもほぼリアルタイムで行うことができます。
同一ハードウェア上にて負荷の高い処理を実行
Docker は軽量かつ高速です。 ハイパーバイザーベースの仮想マシンに取って変わる、実用的で費用対効果の高いものです。 したがってコンピューター性能をフルに活用してビジネス目標を達成できます。 Docker は高度に処理集中する環境に適しており、さらには中小規模の、より少ないリソースの中でのシステム構築にも適しています。
Docker アーキテクチャー
Docker はクライアントサーバー型のアーキテクチャーを採用しています。 Docker クライアントは Docker デーモンに処理を依頼します。 このデーモンは、Docker コンテナーの構築、実行、配布という複雑な仕事をこなします。 Docker クライアントとデーモンは同一システム上で動かすことも可能ですが、別のシステム上であっても、Docker クライアントからリモートにある Docker デーモンへのアクセスが可能です。 Docker クライアントとデーモンの間の通信には REST API が利用され、UNIX ソケットまたはネットワークインターフェイスを介して行われます。 もう 1 つの Docker クライアントとなるのが Docker Compose です。 これを使えば複数コンテナーからなるアプリケーションを動作させることができます。
Docker デーモン
Docker デーモン(dockerd
)は Docker API リクエストを受け付け、イメージ、コンテナー、ネットワーク、ボリュームといった Docker オブジェクトを管理します。
また Docker サービスを管理するため、他のデーモンとも通信を行います。
Docker クライアント
Docker クライアント(docker
)は Docker とのやりとりを行うために、たいていのユーザーが利用するものです。
docker run
のようなコマンドが実行されると、Docker クライアントはdockerd
にそのコマンドを伝えます。
そしてdockerd
はその内容を実現します。
docker
コマンドは Docker API を利用しています。
Docker クライアントは複数のデーモンと通信することができます。
Docker Desktop
Docker Desktop は Mac、Windows、Linux の各環境に簡単にインストールできるアプリケーションです。
これを使って、コンテナー化アプリケーションやマイクロサービスをビルドし共有することができます。
Docker Desktop には Docker daemon (dockerd
)、Docker クライアント (docker
)、Docker Compose、Docker Content Trust、Kubernetes、Credential Helper が含まれます。
より詳しくは
Docker Desktop を参照してください。
Docker レジストリ
Docker レジストリは Docker イメージを保管します。 Docker Hub と Docker Cloud は公開レジストリであり、誰でも利用可能です。 また Docker はデフォルトで Docker Hub のイメージを探します。 独自にプライベートレジストリを運用することもできます。
docker pull
やdocker run
コマンドを使うと、設定されたレジストリから必要なイメージを取得します。
docker push
コマンドを使えば、イメージを指定したレジストリに送信します。
Docker オブジェクト
Docker の利用時は、イメージ、コンテナー、ネットワーク、ボリューム、プラグイン、その他のオブジェクトを作成、利用します。 このセクションは各オブジェクトの概要を説明します。
イメージ
イメージとは、Docker コンテナーを作成する命令が入った読み込み専用のテンプレートです。
通常イメージは、他のイメージをベースにしてそれをカスタマイズして利用します。
たとえばubuntu
イメージをベースとするイメージを作ったとします。
そこには Apache ウェブサーバーや自開発したアプリケーションといったものをインストールするかもしれません。
さらにアプリケーション実行に必要となる詳細な設定も加えることにもなるでしょう。
イメージは作ろうと思えば作ることができ、他の方が作ってレジストリに公開されているイメージを使うということもできます。 イメージを自分で作る場合は Dockerfile というファイルを生成します。 このファイルの文法は単純なものであり、そこにはイメージを生成して実行するまでの手順が定義されます。 Dockerfile 内の個々の命令ごとに、イメージ内にはレイヤーというものが生成されます。 Dockerfile の内容を書き換えたことでイメージが再構築されるときには、変更がかかったレイヤーのみが再生成されます。 他の仮想化技術に比べて Dockerイメージというものが軽量、小さい、早いを実現できているのも、そういった部分があるからです。
コンテナー
コンテナーとは、イメージが実行状態となったインスタンスのことです。 コンテナーに対する生成、実行、停止、移動、削除は Docker API や CLI を使って行われます。 コンテナーは、複数のネットワークへの接続、ストレージの追加を行うことができ、さらには現時点の状態にもとづいた新たなイメージを生成することもできます。
デフォルトでは、コンテナーは他のコンテナーやホストマシンとは、程よく分離されています。 コンテナーに属するネットワーク、ストレージ、基盤となるサブシステムなどを、いかにして他のコンテナーやホストマシンから切り離すか、その程度は制御することが可能です。
コンテナーはイメージによって定義されるものです。 またこれを生成、実行するために設定したオプションによっても定義されます。 コンテナーを削除すると、その時点での状態に対して変更がかかっていたとしても、永続的なストレージに保存されていないものは消失します。
docker run
コマンド例
次のコマンドはubuntu
コンテナーを実行し、ローカルのコマンドライン処理のセッションを結びつけます。
そして/bin/bash
を実行します。
$ docker run -i -t ubuntu /bin/bash
このコマンドを実行すると、以下が発生します(レジストリから入手した際のデフォルトの設定を使用しているものとします)。
ubuntu
イメージがローカルになければ、Docker は設定されているレジストリからイメージを取得します。 この動作は手動でdocker pull ubuntu
を実行するのと同じです。Docker は新しいコンテナーを生成します。 これは手動で
docker create
コマンドを実行することと同じです。Docker はコンテナーに対して読み書きが可能なファイルシステムを割り当てます。 これが最終的にレイヤーとなります。 このことによりコンテナーの稼動中に、ローカルなファイルシステム内でのファイルやディレクトリの生成や変更などが実現されます。
Docker はネットワークインターフェースを生成し、コンテナーをデフォルトネットワークに接続します。 ここではネットワークオプションを指定していないものとしているためです。 このときには、コンテナーに対しての IP アドレスの割り当ても行われます。 デフォルトでコンテナーは、ホストマシンのネットワーク接続を利用して、外部ネットワークに接続します。
Docker はコンテナーを起動し、
/bin/bash
を実行します。 (-i
と-t
のフラグにより)対話的に、かつターミナル画面に接続するようにして実行しているため、手元のキーボードを使って入力することができ、ターミナル画面に出力が行われるようになります。exit
を入力すると/bin/bash
コマンドは終了します。 コンテナーは停止状態となりますが、削除はされません。 コンテナーは再起動したり削除することもできます。
基盤とする技術
Docker は Go プログラミング言語 で書かれており、Linux カーネルの機能をうまく活用して、さまざまな機能性を実現しています。 Docker は名前空間という技術を利用してコンテナーと呼ぶ作業空間を分離して提供します。 コンテナーが実行されたとき、Docker はそのコンテナーに対して複数の名前空間を生成します。
名前空間はいくつもの分離状態を作り出します。 コンテナー内のさまざまな処理は、分離された名前空間内にて実行され、それぞれへのアクセスはその名前空間内に限定されます。