オープンソース

Docker〜コンテナ型仮想化〜

Dockerとは

Dockerとは、docker社が開発しているコンテナ型仮想化の実装の1つです。オープンソースソフトウェアとして公開されていて、コンテナ型仮想化としては、事実上のデファクトスタンダードとなっています。

VMWare、KVM、Virtualboxなどで採用されている完全仮想化や凖仮想化などの技術では、ハードウェアをエミュレーションした複数の仮想マシンを動かします。それに対して、Dockerでは、1つのOSの上に完全に独立した複数のネームスペースを作り出します。カーネルは、ホストコンピュータと共有します。

Dockerでは、この空間に自動的に小さなファイルシステムをデプロイし、単独のプロセスを動かします。Dockerではユーザ、プロセス、ネットワークなどもホストコンピュータと独立して管理されます。

DockerとCI/CD

Dockerは、もともとアプリケーション開発者の間で注目され普及が進みました。
Dockerを使うとシステムに対する設定手続きなどが、すべてコード化されるためです。また、Dockerを使うと、アプリケーション開発において近年普及してきたCI/CDの手法をシステムにも取り入れることができます。
CI/CDは、アプリケーション開発のステージに自動化を取り入れて、顧客にアプリケーションを提供する頻度を高める手法です。CIは継続的インテグレーション、CDは継続的な配布および継続的な開発を指しています。
Dockerを利用することで、OSやサーバソフトウェアにも、同じようにCI/CDの考え方を取り入れることができると考えられています。

Dockerのメリット

Dockerでは、アプリケーションの動作に必要な最小限のファイルのアーカイブを使います。これをDockerイメージと呼びます。コンテナは、このDockerイメージとその上で動作するアプリケーションをセットにして起動します。Dockerには、次のようなメリットがあります。

Dockerイメージがすぐに入手でき、すぐに使える

Dockerイメージのリポジトリは、インターネット上で公開されています。最も一般的なリポジトリは、Docker-HUBです。Docker-HUBでは、様々な定義されたDockerイメージが公開されていて、様々なOSSのオフィシャルなイメージも入手できます。

次は、docker searchコマンドで、httpdコンテナのイメージを検索した結果です。

$ docker search httpd ⏎
NAME                           DESCRIPTION                                     STARS          OFFICIAL        AUTOMATED
httpd                          The Apache HTTP Server Project                  2505             [OK]       
centos/httpd                                                                     23                              [OK]
centos/httpd-24-centos7        Platform for running Apache httpd 2.4 or bui…    22                                      
armhf/httpd                    The Apache HTTP Server Project                     8                                       
polinux/httpd-php              Apache with PHP in Docker (Supervisor, CentO…     2                              [OK]
lolhens/httpd                  Apache httpd 2 Server                              2                              [OK]
 :

OFFICIALの欄に[OK]と表示されているものが、オフィシャルなイメージです。このように、httpdのコンテナだけでも用途に合わせて、複数のイメージが公開されています。Docker-HUBにはより詳細なドキュメントが公開されていますので、その情報を参考に用途に合ったものを選ぶことができます。

そして、Docker-HUBで公開されているDockerイメージは、あらかじめ設定済みです。そのため、すぐに動作させることができます。

例えば、Webサーバ(Apache)の公式イメージはhttpdという名称で配布されています。docker runコマンドは、このイメージを自動的にダウンロードしてデプロイして、起動します。

$ docker run -d -p 80:80 -v webcontents:/usr/local/apache2/htdocs httpd ⏎

この例では、コンテンツが保存されたボリュームを、コンテンツのディレクトリにマウントしています。また、外部からアクセスできるように、コンテナの80番ポートを、ホストの80番ポートに紐付けて公開しています。このように、オプションやボリュームの指定をするだけで、すぐにコンテナを実行することができるのです。

少ないリソースで効率よく動作する

仮想サーバを一台起動すると、8Gbyte程度のディスク容量が必要になります。しかし、Dockerは、他の仮想環境に比べて少ないディスク容量で動作します。また、Dockerは、起動が早く、仮想化による性能の劣化もほとんどありません。次は、Webサーバ(httpd)のコンテナイメージのサイズを調べた結果です。

$ docker images httpd ⏎
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd               latest              b7cc370ac278        4 weeks ago         132MB

SIZEの欄を見ると、132MBとなっています。従来の仮想サーバと比較すると、約5%のリソースの量で動作するのです。

Dockerでは、イメージサイズを小さくする工夫も行われています。Dockerイメージを作成するのに使われるAlpine Linuxのイメージは、約5MBと非常に小さいのが特徴です。

$ docker images alpine ⏎
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              latest              055936d39205        4 weeks ago         5.53MB

このイメージから派生したコンテナは、さらに少ないリソースで動かすことができます。

$ docker images ventz/bind ⏎
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ventz/bind          latest              d5b9c9b769aa        5 weeks ago         16.2MB

このBINDのコンテナは、たった16.2MBで動作します。

リソースの制限も可能

Dockerの各コンテナに割り当てるCPU時間やメモリも簡単に設定することができます。例えば、WWWサーバのメモリを512Mに限定するには、次のように--memoryオプションでサイズを指定するだけです。

$ docker run -d -p 80:80 --memory 512m httpd ⏎
6143987d654da232386f5db6fc3394958e4be32cf403eb4c581cf29c96c0d04e

バージョン管理が可能

Dockerイメージは、リポジトリ内で階層的に管理されます。どこから作成されたかも明確に管理できるため、バージョン管理が行いやすくなっています。次は、httpdコンテナにコンテンツを入れた独自のコンテナを作成した場合の例です。docker image historyコマンドでイメージを確認すると、これまでに行った変更をコメント付で確認することができます。

$ docker image history httpd-designet:1.0 ⏎
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
4bc4ba5a19cd        3 weeks ago         httpd-foreground                                61.4MB              httpd with www.designet.co.jp
b7cc370ac278        4 weeks ago         /bin/sh -c #(nop)  CMD ["httpd-foreground"]      0B                  
<missing>           4 weeks ago         /bin/sh -c #(nop)  EXPOSE 80                     0B                  
<missing>           4 weeks ago         /bin/sh -c #(nop) COPY file:8b68ac010cb13f58…  133B                
  :

ポータビリティがある

Dockerは、OS環境の制約を受けにくい作りになっています。そのため、ほとんどのLinuxの上で動作します。また、CentOSのDocker環境の上で、Debianのコンテナを動かすということもできます。

Docker-HUBでイメージを共有

Docker-HUBは、Docker社が提供するコンテナレポジトリです。作成したコンテナイメージを、レポジトリに登録しておくことで、どのような環境にもすぐにイメージを運ぶことができます。

Docker-HUBには、docker loginでログインし、docker pushコマンドでイメージをアップロードするだけで、イメージをアップロードすることができます。

$ docker login ⏎
$ docker push tune1111/httpd-dg:1.2 ⏎
The push refers to repository [docker.io/tune1111/httpd-dg]
8eac8bf1da5b: Pushed 
a8eceb11d25e: Pushed 
428d798f86c4: Pushed 
d12cae5562ef: Mounted from library/httpd
d188fb853e8f: Mounted from library/httpd 
320e3241be93: Mounted from library/httpd 
5de0920316a3: Mounted from library/httpd 
6270adb5794c: Mounted from library/httpd 
1.2: digest: sha256:f0531e4cb13ee55bd414d5433d23305d2725147c80f865b5d751852a4eb4369a size: 1993

独自のリポジトリでも管理可能

Dockerで作成したイメージは、ローカルリポジトリでも管理できます。また、GitLabなどで作成した独自のレポジトリサーバでも管理ができます。

GitLabリポジトリ機能画像

同じ環境をすぐに作成できる

Dockerイメージを集中管理することで、様々な環境で同じ状態のシステムを構築することができます。例えば、オンプレミスのサーバとクラウド上のサーバとで、同じイメージを使用できます。そのため、Dockerは、環境に左右されず運用ができます。

最近では、Googleが提供するGKE(Google Kubernetes Engine)、Amazonの提供するEKS(Amazon Elastic Container Service for Kubernetes)など、Dockerコンテナを利用できるクラウド型サービスが提供されています。オンプレミスで動作を検証したコンテナは、こうしたクラウドサービスでも同じように動かすことができます。

ステージング・検証環境への利用に適している

作成したDockerイメージをGitLabなどのレポジトリで管理することで、同じシステムをすぐに別の環境に作成ができるようになります。そのため、Dockerで構築したシステムイメージから、すぐにステージング環境や検証用環境を構築することができます。

バージョン管理

Dockerには、バージョン管理を支援する機能があり、非常に便利です。

Dockerでは、Dockerfileという書式を使って、コンテナイメージを作成します。例えば、次のDockerfileは、httpdコンテナのイメージにコンテンツを同梱して、新しいコンテナを作成しています。

FROM httpd
LABEL maintainer="admin@designet.jp"
COPY www.designet.co.jp /usr/local/apache2/htdocs

もし、元になるhttpdのコンテナのバージョンが上がっても、次のようにdocker buildコマンドでイメージを作り直すだけで、自動的に最新のhttpdコンテナから、新しいコンテナイメージを作成することができます。

$ docker build -f Dockerfile -t httpd-designet:1.2 . ⏎
Sending build context to Docker daemon  60.99MB
Step 1/3 : FROM httpd
 ---> b7cc370ac278
Step 2/3 : LABEL maintainer="admin@designet.jp"
 ---> Running in 38dad19d8ddf
Removing intermediate container 38dad19d8ddf
 ---> 5b7b9e5425df
Step 3/3 : COPY www.designet.co.jp /usr/local/apache2/htdocs
 ---> 50401e525d20
Successfully built 50401e525d20
Successfully tagged httpd-designet:1.2

瞬時にアップデートが可能で、ロールバックもすぐに可能

Dockerのコンテナには、「registory:tag」という規則で名前を付けます。registoryは、コンテナの名称です。そして、tagとしてリリース番号を付与します。さらに、最新のコンテナイメージには、次のようにdocker tagコマンドを使うことで、latestというタグをつけます。

$ docker tag httpd-designet:1.2 httpd-designet:latest ⏎

docker runは、latestというタグの付いた最新のイメージを使いコンテナを起動します。そのため、新しいコンテナイメージを作成したら、次のようにコンテナを再起動するだけでバージョンアップが完了します。

$ docker stop httpd ⏎
$ docker run -d -p 80:80 httpd-designet ⏎

また、コンテナを入れ替えることも簡単にできるため、次のようにリリース番号を指定してコンテナを起動することで、ロールバックも簡単に行うことができます。

$ docker stop httpd ⏎
$ docker run -d -p 80:80 httpd-designet:1.1 ⏎

もし、問題がなければ、古いリリース番号のコンテナイメージを削除することもできます。

$ docker rmi httpd-designet:1.1 ⏎

Docker利用のガイドライン

Dockerの利用においては、Dockerの特徴を生かすため、次のような使い方が推奨されています。

  • コンテナイメージを最小化する

    Dockerコンテナには、必要最小限のソフトウェアだけをインストールします。

  • 1サービス/1コンテナ

    1つのコンテナ上に1つのサービスやプロセスだけを起動するような構成が推奨されています。

  • ステートレス

    コンテナイメージ内の情報は、動的に変更しないことが推奨されています。永続的なデータを保管する場合には、外部ストレージをコンテナにmountして使います。

Dockerのデメリット

Dockerには、次のようなデメリットがあります。

  • 入門のハードルが高い

    Docker利用のガイドラインを守ろうとすると、従来とは異なる考え方や知識を学ぶ必要があります。そのため、入門のハードルが高いと言われています。

  • Docker-HUBのセキュリティ

    DockerコンテナのレジストリであるDocker-HUBのコンテナは、安全とは限りません。バイナリでソフトウェアが置かれているので、ウィルスや悪意あるプログラムが含まれている可能性があります。

  • 他のホスト上のDockerとは通信ができない

    Dockerのすべてのコンテナは、ホストコンピュータのネットワークやストレージを共有して利用します。別のホスト上のコンテナと、リソースを共有することはできません。

  • コンテナの管理が煩雑

    Dockerでは、1サービス/1コンテナで動作させるため、多数のコンテナが乱立します。コンテナが増加すると、一つ一つのコンテナを管理することが難しくなります。

  • Dockerコンテナの連携が煩雑

    Dockerコンテナ同士が連携して動作するので、連携情報を管理する必要があり、非常に面倒です。

こうしたDockerのデメリットを補うために、コンテナの管理を行うオーケストレーションツールが使われることがあります。Kubernetesは、代表的なコンテナ・オーケストレーションツールです。

標準化とDockerのアーキテクチャ

コンテナ型仮想化の技術では、DockerおよびKubernetesが事実上のデファクトスタンダードとなりました。一方で、コンテナ型仮想化が非常に重要な技術となったことから、コンテナに関する標準化が進んでいます。この標準化によって、あらたなコンテナツールが生み出されるなど、様々な変化が起きています。

2015年に、Docker、CoreOS、マイクロソフト、RedHat、VMWareなどが、オープンコンテナイニシアティブ(OCI)を発足し、標準化が始まりました。

2016年には、Kubernetesとコンテナランタイムが通信するための仕様としてCRI(Container Runtime Interface)が規定されています。

2017年に、OCIは次の2つの仕様を作成しました。

  • コンテナのランタイムに関する仕様(Open Container Initiative Runtime Specification)
  • コンテナイメージフォーマットに関する仕様(Open Container Initiative Image Format Specification)

その結果、これまでDockerが担ってきた役割が、次のようないくつかの要素に分割されました。

従来のDockerとKubernetesの関係

【従来のDockerとKubernetesの関係】

分割されたDockerとKubernetesの関係

【分割されたDockerとKubernetesの関係】

低レベルのランタイム

低レベルのランタイムは、カーネルの機能を使ってコンテナに必要な独立した環境を用意し、実際にコンテナを動作させる役割を担っています。

低レベルのランタイムの実装としては、runcgVisorKata Containerなどがあります。

高レベルのランタイム

高レベルのランタイムは、DockerやKubernetesなどのコンテナ管理ツールから、コンテナに関する処理を引き受けます。具体的には、次のような機能を持っています。

  • コンテナの管理
  • コンテナイメージの管理
  • コンテナレジストリからのイメージのダウンロード

高レベルのランタイムの実装としては、containerdCRI-Orktなどがあります。

Dockerとpodman

podmanは、RedHat社が開発したコンテナ管理ツールです。OSSで公開されていて、RedHat Enterprise Linux/CentOS 7.6以降でパッケージが配布されています。また、ubuntuなどでもパッケージで導入することができます。Redhatは、Dockerやcontainerdのようなデーモンプロセスを必ず経由して使うシステムは、これらのプロセス停止により全機能が停止してしまうため危険だと主張しています。

Dockerのアーキテクチャ

それを避けるため、podmanは、UNIXドメインソケットを使わずに動作します。また、systemdとの連携なども簡単に行えるようになっていたり、ユーザ毎のローカルレポジトリが利用できるようになっているなど、Linuxとの親和性がより強化されています。

なお、podmanは、Dockerと互換性を持って作られていて、引数などの指定方法は、すべてDockerと同じです。さらに、podの管理やKubernetesの管理用のYAMLファイルを出力する機能が追加されています。

次は、podmanのアーキテクチャです

podmanのアーキテクチャ

デモのお申込み

もっと使い方が知りたい方へ
操作方法や操作性をデモにてご確認いただけます。使い方のイメージを把握したい、使えるか判断したい場合にご活用下さい。デモをご希望の方は、下記よりお申込みいただけます。


デモをご希望の方

デモの申し込みイメージ


OSS情報「Docker」

Docker〜コンテナ型仮想化〜の先頭へ