Docker

Docker（ドッカー）は、コンテナ仮想化を用いてアプリケーションを開発・配置・実行するためのオープンプラットフォームであるDocker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. Docker Documentations - Docker overview。

Dockerはコンテナ仮想化を用いたOSレベルの仮想化によりアプリケーションを開発・実行環境から隔離し、アプリケーションの素早い提供を可能にする。かつその環境自体をアプリケーションと同じようにコード（イメージ）として管理可能にするDocker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. Docker Documentations - Docker overview。Dockerを開発・テスト・デプロイに用いることで「コードを書く」と「コードが製品として実行される」間の時間的ギャップを大きく短縮できるBy taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production. Docker Documentations - Docker overview。

 概要 
アプリケーションソフトウェアは開発環境でコーディングされ、テスト環境で動作確認され、ステージング環境にデプロイされ、本番環境でサービス提供をおこない、開発環境でデバッグされる。ソフトウェア開発ではただアプリケーションのコードを書くのではなく、上記すべての環境整備と環境へのアプリケーションデプロイを行う必要がある。かつ複数人による開発では上記すべてを全員で一貫性をもって共有しなければならない。

これらを達成するには様々な状況（動作OS、既存環境）へ同一の環境とアプリケーションをできるだけ低コストで届ける必要がある。動作OS（ホストOS）や既存環境からの隔離手法にはOSレベルの仮想化があり、その一種にカーネルをホストと共有しプロセス・ファイルシステムを隔離するコンテナ仮想化がある。環境をアプリケーションごとコンテナへ隔離しコンテナのイメージファイルを配布することで、ランタイムが用意されたあらゆる状況へ同一環境・同一アプリケーションを配備できる。

Dockerはこのコンテナ仮想化を核としたアプリケーションのためのオープンプラットフォームである。環境およびアプリケーションをDockerイメージとしてバンドルし、DockerエンジンによりDockerコンテナとして配備・実行できる。Linux・Windows・Macすべてに対応したDockerエンジンは開発・テスト・本番・デバッグなど様々な状況で容易かつ高速なアプリケーション配備・実行を可能にする。またDockerイメージのレジストリ登録・Dockerイメージに基づいた派生イメージ生成・差分管理による派生イメージの低容量化により、容易な独自イメージ生成と高速/低負荷なコンテナ生成が可能になる。かつ標準仕様化を含むDockerソフトウェアのコンポーネント化により、コンテナ仮想化レベル自体の制御を含む独自コンテナ仮想化システムが構築可能になっている。このようにDockerは広範なアプリケーション開発のためのプラットフォームとして現在では機能している。

Dockerがもたらす環境/アプリケーション展開の効率化は継続的インテグレーション（CI）・継続的デプロイ（CD）によるサービス提供の高頻度化をさらに加速させた。またクラウドコンピューティングが提供するマネージドサービスと展開コンテナ数調整によってサービスのスケーリングは容易になり、サービスの柔軟性やコスト構造にも影響を及ぼしている。このようにDockerの採用はアプリケーション開発・運用、それが生み出すビジネスまで影響を与えている。

主な利点
資源の効率化
一台のサーバ上に複数の仮想マシンを動作させてそれぞれにオペレーティングシステム (OS) を走らせる仮想化技術は従来から存在していた。例えば、ハイパーバイザ型のVMWareやHyper-Vやホスト型のVirtualBox等である。仮想化の本来の目的は、一台のハードウエア内でなるべく多くのサーバ用アプリケーションを実行する事であるが、上記の方式の仮想化では仮想環境毎にOSの全体をインストールする必要があり、目的のアプリケーションにとっては必要のないサービスやファイルまでが含まれていた。これは資源(resource)の浪費であり、できることならば仮想環境内にはアプリケーションとは無関係のライブラリやデータは置かずに共有にする事が望ましかった。これを実現するのがコンテナ型の仮想化である。実際にDockerは、ホストOSのカーネルを共有する。それぞれの仮想環境はDockerコンテナと呼ばれ、各コンテナは一台のサーバ上で隔離された形で動作し、複数のインスタンスが並行して動く。

アプリ実行環境構築の容易さ
一般にアプリケーションを開発もしくは動作させるまでには、設定ファイルの編集や必要なライブラリのインストール等、本来の目的には関係のない煩雑な作業が必要である。Dockerはアプリケーションとライブラリを同一のコンテナ内に固めてしまう。一度固めたコンテナは軽量であるため移動が容易であり、比較的どの環境でも素早く目的のアプリケーションを動作させる事が可能である。これをDocker社は、Build, Ship, and Run Any App, Anywhere と表現している。Docker DesktopによりコンテナはWindows、MacOSのどちらでも機能し可搬性が高い。

廃棄の容易さ
複雑なシステムでは設定を一度間違えるとその影響が及ぶ範囲の特定と元に戻すことに多くの時間がかかる可能性がある。Dockerではこのような元に戻しがたいシステムのイメージはただちに削除すれば良く、段階的にイメージをバックアップしておけば設定を間違えた前の状態に戻ることが容易である。そのようなことを行う際に、上記の資源効率の良さと構築の容易さが効果を発揮する。

 利用 

 アプリケーション開発環境 
Dockerコンテナはアプリケーション開発環境に利用できる（Developing inside a Container Docker container as a full-featured development environment. ）。

コンテナは外部と隔離されている。ゆえに開発環境のセットアップが既存環境を破壊する、あるいは既存環境が開発環境へ予期せぬ影響を与える可能性がない。このようにアプリケーション開発用のサンドボックスとしてDockerコンテナを利用できる（development container）This container can be used to run an application or to sandbox tools, libraries, or runtimes needed for working with a codebase. 。

またコンテナはイメージから生成されるため配布することが可能である。ゆえに複数の開発者がそれぞれ開発環境を用意せずとも、配布されたイメージからコンテナを生成するだけで開発環境が利用できる。開発環境を破壊した場合でもそのコンテナを破棄し配布イメージから再生成することですみやかな開発環境の修正が可能である。

コンテナがもつ可搬性によりホストに依存しない一貫した開発が可能になる。コンテナはDockerのランタイム上で動作するためホスト側のOSや設定に影響を受けず、同一イメージからWindowsユーザーもLinuxユーザーも開発環境コンテナを利用できるDocker Containers Are Everywhere: Linux, Windows, Data center, Cloud, Serverless, etc. 。

開発コンテナには複数種類の利用方法がある。

 全てをコンテナ内で完結: コンテナ上のターミナルでコンテナ内のコードを編集
 volumeマウントを利用: ホスト上のコードをコンテナのvolumeへマウントし、コード編集はホスト・実行とその環境はコンテナ
 ホスト-コンテナ間連携: コンテナ内のエディタサーバを通じてホストのエディタUIからコンテナ内コードを操作・実行

などがある。すべてをコンテナ内で完結させればホストはDockerのみで動作する。volumeマウントは実行環境の隔離に近い。ホスト-コンテナ連携をした場合、ホストはDockerとエディタのみに依存する。

 コンテナ化されたアプリケーション 
Dockerコンテナはアプリケーションとその実行環境を組み合わせた一体のものとして利用できる（containerized applicationDeploying a containerized web application , Container Deployed ApplicationsContainer Deployed Applications: You deploy your application into one or more containers and would like to work locally in the containerized environment. ）。

Dockerイメージはファイルシステムと実行時設定を併せたものである（参考: Open Container Initiative#OCI Image)。アプリケーションおよび実行に必要なソフトウェアさらに実行時の設定が含まれているDockerイメージを基にしてコンテナを生成すると、コンテナを起動すれば直ちにアプリケーションとして機能する。このことからDockerコンテナはすべてのDocker環境上でそのまま動作するアプリケーションとして配布ができる。

Dockerイメージは配布することができ、かつ環境によらずに機能する可搬性を持つため、アプリケーションをDockerコンテナとして作成すれば、テスト・ステージング・本番のそれぞれの環境に依らない頒布が容易におこなえる。

評価
Dockerがもたらす環境/アプリケーション展開の効率化は開発から運用まで幅広い領域に大きな影響を与えている。

Dockerイメージ生成による環境生成はOS・ミドルウェアレベルのInfrastructure as Code（IaC）であり、高速/低負荷なコンテナ生成/破棄は実利用可能なImmutable Infrastructureとみなせる。これら高効率な環境展開はテスト・ビルド等の継続的インテグレーション（CI）・サービス提供まで含む継続的デプロイ（CD）をより容易にした。クラウドコンピューティングサービスがDockerコンテナ実行マネージドサービスを提供し始めたことで、開発者はローカルに作成したDockerイメージをクラウド上へホストを意識せず展開可能になった。生成/破棄が容易なコンテナをホストを意識せず利用できるマネージドサービスでデプロイすることで、アプリケーション運用者は展開コンテナ数調整による容易かつ柔軟なアプリケーションのスケーリングが可能になった。コンテナ仮想化による運用が広まるにつれてコンテナ連携によるサービス提供、すなわちマイクロサービスアーキテクチャのDockerコンテナ群による実装が構想され、コンテナ連携を指揮するコンテナオーケストレーションソフトウェアおよびそのマネージドサービスが実利用され始めている。このようにDockerはプラットフォームとしてアプリケーション開発とビジネスへ影響を与えている。

Dockerのコンテナー管理の手軽さやインスタンス操作の高速性は、クラウドサービスやビッグデータ基盤などを管理するためのIT基盤として高く評価され、2014年12月日経BP社より「ITインフラテクノロジーAWARD 2015」グランプリに選出されている。

2014年、GoogleはDockerではないが、コンテナ型仮想技術Kubernetesを利用しており、毎週20億個のコンテナを自社サービスのために起動していると発表した。

技術的な特徴

 コンテナ仮想化 
ホストカーネルを直接利用しながらプロセス・ファイルシステムを隔離するコンテナ仮想化を提供する。仮想化はGo言語で実装されたソフトウェア libcontainer によって行われる。古いDocker実装ではLXCが利用されていた。

差分管理
コンテナのファイルシステムはいくつかのドライバによって提供される。現在推奨されるoverlay2overlay2 is the preferred storage driver, for all currently supported Linux distributions, and requires no extra configuration. およびかつて推奨されていたAufsでは、Dockerコンテナ内に作成されたファイルが元のDockerイメージ (雛形) の差分として蓄えられる。差分しかディスク容量を消費しないので、より少ないリソースでコンテナを作成し実行する事が可能である。このことが他の仮想化手法と比較して容易かつ高速な仮想化環境の生成/破棄を可能にしている。なお当初はaufsのみのサポートだったが、その後btrfs、Device Mapper、OverlayFS、vfs、ZFSが選択可能となっている。

Dockerfile
DockerではDockerfileからコンテナイメージを生成できる。

DockerではDocker imageがインスタンス化されコンテナとして動作する。imageの実体はJSONファイルおよびファイルシステムの.tarであり（c.f. OCI Image) 手動で記述・生成できる。DockerはDockerfileと呼ばれる設定ファイルからコンテナイメージファイルを作成（build）する機能を提供している。

 標準仕様 
DockerコンテナはOpen Container Initiativeが策定したOCI RuntimeおよびOCI Image Format仕様の下敷きになっており、現在のDockerコンテナはOCIに準拠している。OCIへの準拠によりOCI Runtimeを実装する任意のランタイムを利用することができるため、セキュリティを重視したランタイムや速度を重視したランタイムに切り替えることが可能である。

 永続化 
Dockerは揮発性のコンテナに対して永続化可能なストレージを提供している。そのマウントは実装方法により以下に分類される。

 Volumes: ホストのファイルシステム内でDockerが管理する領域に保存されるVolumes are stored in a part of the host filesystem which is managed by Docker 。推奨されるマウントタイプVolumes are the best way to persist data in Docker. 
 Bind mounts: ホストの任意の場所に保存されるBind mounts may be stored anywhere on the host system. 。Docker以外のホストプロセスも操作しうるNon-Docker processes on the Docker host or a Docker container can modify them at any time.　
 tmpfs mounts: ホストのメモリ上に保存される（ホストで揮発性）tmpfs mounts are stored in the host system’s memory only, and are never written to the host system’s filesystem. 

 ネットワーク 
Dockerはネットワーク隔離されたコンテナ同士を繋ぐネットワーキング機能を持つ。

Dockerコンテナはを利用してコンテナをホストのネットワークから隔離している。そのためネットワーク設定をnoneにした場合、外部からのネットワークアクセスができない。これは隔離環境という意味では理想的だが、コンテナ間の協調による機能提供ができない。そこでDockerエンジンはネットワークドライバーによるネットワークの提供を行っている。

主に用いられるドライバはbridgeである。ユーザー定義bridgeネットワークは所属コンテナへのIPアドレス提供とコンテナ名によるドメイン名解決 (automatic service discovery) を提供するcontainers can not only communicate by IP address, but can also resolve a container name to an IP address. This capability is called automatic service discovery. 。また--alias オプションを利用することで1つのドメイン名に複数のコンテナを紐づけることができCreate a network alias for a container 、DNSラウンドロビンが可能である。

 コンテナ連携 
DockerはCompose (docker-compose) による複数コンテナの実行・連携を提供するCompose is a tool for defining and running multi-container Docker applications. docker docs - Overview of Docker Compose。docker-compose.yml でコンテナセット・ネットワークを定義することで、単一のホストマシン上にコンテナ群をデプロイできるDefine the services that make up your app in docker-compose.yml so they can be run together in an isolated environment. docker docs - Overview of Docker Compose。さらにDocker Swarmを用いることでマルチホスト環境へのデプロイも可能になるDocker Swarm, a Docker-native clustering system, exposes the same API as a single Docker host, which means you can use Compose against a Swarm instance and run your apps across multiple hosts. 。

 ロギング 
Dockerはコンテナで発生したデータログ/サーバログを処理する機能（ロギング機能）を提供している。Docker Daemonはデフォルトでコンテナのstdout/stderrを捕捉しており、docker logs コマンドでログを表示できるBy default, docker logs shows the command’s STDOUT and STDERR. docker docs。ロギングはカスタム可能なlogging driverとして実装されており、logging driver pluginsを用いれば独自実装も可能であるEach Docker daemon has a default logging driver, which each container uses unless you configure it to use a different logging driver. In addition to using the logging drivers included with Docker, you can also implement and use logging driver plugins. docker docs。デフォルトのlogging driverはjson-fileであり、他にはsyslogやfluentd、特定クラウドプロバイダに特化したawslogsやgcplogsなどが存在する。

fluentdlogging driverはコンテナログをデータコレクタであるFluentdへ転送するThe fluentd logging driver sends container logs to the Fluentd collector as structured log data.  docker docs。デフォルトではTCPでlocalhost:24224へ送信するが、オプションにより他のTCPポートあるいはUNIXドメインソケットへ送信が可能であるBy default, the logging driver connects to localhost:24224. Supply the fluentd-address option to connect to a different address. tcp(default) and unix sockets are supported. docker docs。fluentdデーモンはホストマシン上のプロセス、あるいはポートマッピングをおこなったコンテナとして機能させるTo use this logging driver, start the fluentd daemon on a host. We recommend that you use the Fluentd docker image. docker docs。

 欠点 

 ホストLinuxカーネルとの関係 
コンテナ仮想化はコンテナ内部からホストカーネルを直接利用するため、エッジケースではホストカーネルのバージョンとDockerに依存した問題が発生する（以下の内容は他の仮想化手法でも類似した形で存在する）。

Dockerイメージは主としてLinuxディストリビューションイメージ、例えばUbuntuイメージを基にして作成されている。ところでLinuxディストリビューションは特定バージョンのLinuxカーネルを含んでいる。例えばUbuntu 18.04.4LTSはv5.3をUbuntu 18.04.4 ships with a v5.3 based Linux kernel 、Debian 10はv4.19をLinux kernel 4.19 series 含んでいる。ゆえにあるDockerイメージがUbuntu 18.04LTSイメージを基にしている場合一見するとカーネルはv5.3かと思うが、コンテナ仮想化はホストカーネルを利用するためDebian10ホスト上でDockerを動作した場合は動作カーネルはv4.19である。またDockerもkernel v4.19上で動作している。

コンテナ仮想化が持つ上記の特性から、いくつかの注意点・欠点がある。

まず異なるホストOSを利用した際の可搬性である。Dockerコンテナは高い可搬性が特徴だが、異なるホストOS例えばUbuntuホストとDebianホストで同一コンテナを動作させた際、カーネルバージョンに違いに起因するコンテナ間で一貫しない動作のリスクが存在する。例えばDebian 8ホストでは発生したカーネル由来のバグがDebian 9ホスト上では修正されて発生しない可能性がある。

また新しいバージョンのLinuxカーネルに依存したイメージが古いLinuxカーネルのホスト上で動かないという問題がある。Ubuntu 18.04.4LTSイメージ（ディストリビューションのカーネルはv5.3）上に構築したアプリケーションがDebian 10（Kernel v4.19）に存在しないカーネル機能を利用していた場合、Debian10ホスト上でこのコンテナを実行すると存在しないカーネル機能を利用しようとしてエラーを起こしてしまう。Linuxカーネルの非常に高い後方互換性から、逆のパターンすなわち古い機能が新しいカーネルのホスト上で動かないパターンは非常にまれと考えられる。

またホストカーネルバージョンとDockerエンジンバージョンの組み合わせによるバグもある。カーネルパニックをおこすエッジケースも存在  している（あらゆる仮想化はホストと仮想化エンジンの不整合リスクを抱えている）。

エコシステム
オーケストレーション
実際のアプリの動作は複数のコンテナ同士が協調し合う事が多いとされる。このため多数のコンテナを自動的に管理する (オーケストレートする) ソフトウエアが必要となる。KubernetesやDocker Swarmは当該機能を提供する。

Docker社は、2018年1月KubernetesをDockerに統合したバージョンのベータ版を提供し始めた。

 イメージレジストリ 
Docker Imageはレジストリを利用した公開・共有が可能である。公開されたイメージはdocker pullコマンドにより取得されコンテナ化できる。広く利用できるレジストリの存在により、Dockerfileを用いたイメージ生成の際にレジストリへ登録されたイメージをベースイメージとすることが可能となっている。docker pullはURL-likeなイメージ識別子（URLからプロトコル名を除いたもの。例:quay.io/assemblyline/ubuntu）を受け入れるため様々なレジストリを利用できるBy default, docker pull pulls images from Docker Hub. It is also possible to manually specify the path of a registry to pull from. docker docs。

Docker Hub
Docker Hubはdocker pullがデフォルトで利用する公開レジストリである。2014年にDockerコンテナの共有サービスの場として発表された。DockerHubのイメージを利用する際はレジストリアドレスを省略できる（[organization/]image:tag形式。例: fluent/fluentd、ubuntu）。

 Amazon Elastic Container Registry 
Amazon ECRはAmazon Web Servicesが提供するプライベートレジストリであるAmazon Elastic Container Registry (ECR) は、完全マネージド型の Docker コンテナレジストリです。 Amazon Elastic Container Registry。プライベート、すなわち非公開のレジストリであり、docker loginによる認証情報の読み込みが必須である。レジストリアドレスは<aws_account_id>.dkr.ecr.<region>.amazonaws.comである。

 構成要素 
現在のDockerはコンテナランタイム・デーモン・CLI・GUI・イメージレジストリ等、数多くの（取替え可能な）コンポーネントからなっている。

 Docker Engine : クライアント-サーバ型のアプリケーションパッケージDocker Engine is a client-server application with these major components: 
 server: ホストマシン上で稼働するデーモン A server which is a type of long-running program called a daemon process (the dockerd command). 
 （高レベル）コンテナランタイム
 （低レベル）コンテナランタイム・OCIランタイム
 REST API: デーモンが提供するインタフェースA REST API which specifies interfaces that programs can use to talk to the daemon and instruct it what to do. 
 CLI client: CLIクライアントA command line interface (CLI) client (the docker command). 。内部で上記のDocker REST APIを叩いているThe CLI uses the Docker REST API to control or interact with the Docker daemon through scripting or direct CLI commands. 
 registry: Dockerイメージの保存庫A Docker registry stores Docker images. 

現在のDocker（プラットフォーム）は以下のソフトウェアスタックをデフォルトで使用している。

 Docker Engine: docker-ce(Linux),  Docker Desktop (Windows, MacOS)
 server/deamon: dockerd
 runtime: containerdBy default, the Docker daemon automatically starts containerd. 
 OCI runtime: runc
 cli client: docker
 registry: Docker HubDocker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. 

「Docker」は2013年に登場した際、単一アプリケーションの名称であった。しかし標準化を含む発展に伴って上記のように複数の（取替え可能な）コンポーネントから構成されるようになっており、現在の「Docker」はアプリケーションではなく「プラットフォーム」であるとされているDocker is an open platform for developing, shipping, and running applications. 。一般に「Docker」という単語が指す意味は非常に曖昧である。

Dockerを構成する要素は上記のデフォルト以外のものを利用できる。以下はその一例である。

 OCI runtime
 あらゆるOCIランタイム（c.f. ）
 registry
 Docker Trusted Registry: エンタープライズ向けプライベートレポジトリサービスDocker Trusted Registry (DTR) is the enterprise-grade image storage solution from Docker.

またいわゆる「コンテナオーケストレーション」を行う際はdockerCLIをユーザーが直接利用するのではなく、オーケストレーションツールからdockerd、あるいはより直接的にcontainerdが利用される。

関連項目
LXC
chroot
kubernetes

DevOps
仮想化
ハイパーバイザ

 脚注 

 学習参考書など 
 WINGSプロジェクト 阿佐志保：「プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化」、翔泳社、ISBN 978-4798153223 (2018年4月11日）。
 山田明憲：「Docker/Kubernetes 実践コンテナ開発入門」、技術評論社、ISBN 978-4297100339 (2018年8月25日）。
 青山真也：「Kubernetes完全ガイド」、インプレス、ISBN 978-4295004806（2018年9月21日）。
 阿佐志保、真壁徹：「しくみがわかるKubernetes：Azureで動かしながら学ぶコンセプトと実践知識」、翔泳社（2019年1月23日）。
 古賀政純：「Docker実践ガイド 第2版」、インプレス、ISBN 978-4295005520（2019年2月18日）。
 北山晋吾、早川博：「Kubernetes実践ガイド：クラウドネイティブアプリケーションを支える技術」、インプレス、ISBN 978-4295006633（2019年7月12日）。

 外部リンク 




Category:エミュレーションソフトウェア
Category:オープンソースソフトウェア
Category:仮想化
Category:Linux
Category:Goでプログラムされた自由ソフトウェア
カテゴリ:2013年のソフトウェア