コンテナの開発と運用管理を実現する「Docker」とは

2023年11月8日(水)
田中 智明
第6回の今回は、コンテナ開発に必要な開発・配布・実行の全てを担い、強力に開発作業を効率化する「Docker」について解説します。

はじめに

コンテナは古くからある技術ですが、広く一般に普及したのは2013年の「Docker」の登場がきっかけです。それまでのコンテナは軽量な仮想環境としてレンタルサーバーやバーチャルプライベートサーバーなどのホスティングサービスで使用されていました。しかしDockerの登場以降、コンテナは開発ツールとして普及していきます。一体Dockerの登場によって何が起きたのでしょうか。今回は、Dockerはどのようなツールなのか、また、そのメリット・デメリットについて解説します。

Dockerとは

Dockerはコンテナを簡単に扱うためのツールであり、アプケーションを開発・配布・実行をするためのプラットフォームです。Dockerはアプリケーションの動作環境をコンテナ内に構築しアプリケーションをパッケージ化します。これによりアプリケーションはインフラストラクチャから切り離され、様々な環境へ移動し同じ方法で実行できます。

DockerはLinuxカーネルの機能でコンテナの分離を実現しています。具体的にはホスト上で実行されているプロセスをカーネルの「名前空間(Namespaces)」と呼ばれる機能を使用して、分離された環境で実行しているかのように見せています。Dockerを使用するとプロセスの分離を簡単に実現できます。

以下の例では、ubuntu:22.04のコンテナでsleepコマンドを実行しています。

$ docker run --rm -d ubuntu:22.04 sleep 100
7cb93f83191b833d2a8bd57d0c8640ac626b972b3746fd050f4be9befa0b0ca8

$ docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS         PORTS     NAMES
7cb93f83191b   ubuntu:22.04   "sleep 100"   3 seconds ago   Up 2 seconds             kind_wing

実行中のコンテナでpsコマンドを実行すると、先に実行していたsleepコマンドとpsコマンドの2つが確認できます。

$ docker exec kind_wing ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 11:51 ?        00:00:00 sleep 100
root         7     0  0 11:52 ?        00:00:00 ps -ef

ホスト側からプロセスを確認すると、コンテナで実行しているsleepのプロセスが確認できます。

$ pgrep -a sleep
11522 sleep 100

また、sleepコマンドがコンテナ上ではPID 1で実行されている点にも注目してください。Dockerが扱うコンテナは「アプリケーションコンテナ」と呼ばれ、アプリケーション以外のプロセスが実行されていません。通常のLinuxであればSysVinitやUpstart、systemdなどのinitプロセスが実行され、システムの稼動に必要な様々なプロセスがinitプロセスによって実行されます。アプリケーションコンテナはアプリケーションのプロセスのみを起動するため高速に起動し、オーバーヘッドが少ないとされています。

Dockerアーキテクチャ

Dockerはクライアント・サーバ型のアーキテクチャです。Dockerクライアントは「Dockerデーモン」と「RESTful API」を用いて通信します。Dockerの動きを図で示すと下図のようになります。それぞれのコンポーネントについて簡単に紹介します。

Dockerの構成要素

Dockerデーモン

DockerデーモンはDocker APIリクエストを待ち受け、イメージ・コンテナ・ボリューム・ネットワークなどのDockerオブジェクトを管理します。Dockerデーモンを実行しているホストを「Dockerホスト」と呼びます。

Dockerクライアント

DockerクライアントはDockerデーモンに命令を送るためのフロントエンドです。dockerコマンドを実行すると、DockerデーモンにDocker APIリクエストを送信します。特別な事情がない場合はDockerをインストールしたホスト上でクライアントとデーモンを使用しますが、必ずしも同じホストで動作させる必要はありません。Dockerホストの場所を環境変数でクライアントに通知することでリモートのDockerデーモンと通信できます。

Dockerレジストリ

「Dockerレジストリ」はコンテナイメージを保管します。Dockerのデフォルトのコンテナレジストリは「Docker Hub」です。名前からも分かるようにDocker HubはDocker社が運営しており、コンテナレジストリのデファクトスタンダードとなっています。

Docker Hubには「Docker Official Image」と呼ばれるDocker社が公開しているイメージや「Verified Publisher」と呼ばれるベンダーが公開しているイメージがあります。Docker Official ImageやVerified PublisherのイメージはDocker社やベンダーがセキュリティを担保しています。

Docker Hubの他にも、よく使われるレジストリとして「GitHub Container Registry(ghcr.io)」や主要なパブリッククラウドが提供しているレジストリなどがあります。また、セルフホステッド型のコンテナレジストリも存在します。

レジストリによってはイメージの取得に認証が必要な「プライベートレジストリ」と呼ばれるタイプのレジストリも存在しますので、イメージを外部に公開できない場合はプライベートレジストリを使用します。

Dockerfile

「Dockerfile」はテキストファイルであり、コンテナイメージを作成するための設計図です。Dockerfile特有のフォーマットと命令を使用し、アプリケーションの動作環境を構築するためのすべての手順を記述します。DockerはDockerfileに記述されている命令を元にコンテナイメージの作成を自動化します。

Dockerオブジェクト

Dockerを使用すると、様々なオブジェクトが作成され管理できます。ここで言うオブジェクトとはコンテナイメージであったり、コンテナやボリューム、コンテナが外部との通信に使うネットワークを指します。オブジェクトの管理はdockerコマンドを用いてdocker [オブジェクト] [サブコマンド]のフォーマットで行います。

以下に、簡単な使用例を紹介します。

・コンテナの一覧
$ docker container ls
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
f07a669741ca   ubuntu:22.04   "sleep 100"   35 seconds ago   Up 34 seconds             busy_haslett
・コンテナイメージの削除
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
ubuntu       22.04     9b8dec3bf938   About a minute ago   117MB

$ docker image rm 9b8dec3bf938
Untagged: ubuntu:22.04
Deleted: sha256:9b8dec3bf938bc80fbe758d856e96fdfab5f56c39d44b0cff351e847bb1b01ea
・すべてのオブジェクトを削除
$ docker system prune --all --force --volumes
Deleted Images:
untagged: docker.io/library/ubuntu:22.04
deleted: sha256:9b8dec3bf938bc80fbe758d856e96fdfab5f56c39d44b0cff351e847bb1b01ea
deleted: sha256:b4b521bfcec90b11d2869e00fe1f2380c21cbfcd799ee35df8bd7ac09e6f63ea
deleted: sha256:3565a89d9e81a4cb4cb2b0d947c7c11227a3f358dc216d19fc54bfd77cd5b542
deleted: sha256:37aaf24cf781dcc5b9a4f8aa5a99a40b60ae45d64dcb4f6d5a4b9e5ab7ab0894

Total reclaimed space: 29.54MB

Dockerのメリット・デメリット

Dockerはオンプレミスや仮想マシンなどに比べても、様々なメリットがある反面デメリットも存在します。ここではDockerのメリットとデメリットについて解説します。

メリット

・少ない変更で環境構築が可能
従来の構築方法はまっさらな状態のOSに必要なミドルウェア・プログラミング言語ランタイム・ライブラリなどをインストールし、アプリケーションが動作する環境を構築していました。環境構築にはそのOSを操作する作法や構築するための知識が必要になります。

一方でDockerはDocker Hubからアプリケーションの動作環境に近いイメージを選択し、変更を加えることで環境構築が完了します。Docker HubにはベースとなるOSイメージの他にミドルウェアやプログラミング言語ランタイムが既にインストールされた状態のイメージが存在します。これらのイメージを選択することで構築までの手順を少なくできます。

・アプリケーションやインフラストラクチャをコードで管理
コンテナイメージを構築するための手順はDockerfileにすべて記述されています。Dockerfileはテキストファイルであるため、バージョン管理システムと相性が良く構成のレビューや変更の追跡が容易です。環境構築に際して一切の手作業が不要になるため、どこで誰が実行しても同じイメージが作成できます。

・イメージの共有が容易
Dockerにはイメージを簡単に配布する仕組みがあります。最もポピュラーなのはコンテナレジストリを使う方法です。Dockerはレジストリにイメージをアップロード・ダウンロードする機能があり、難しい手順を踏まなくてもコンテナレジストリを利用できます。他には実行中のコンテナからtar形式のファイルに出力する方法もあります。こちらはイメージを共有するというよりコンテナを保存する目的で使用されます。

デメリット

・学習コスト
Dockerを使用するには、Docker特有の作法やDocker、コンテナについての知識が必要になります。例えばDockerコンテナは1つのコンテナで1つのアプリケーションを実行しますが、複数プロセスを起動したい場合もあるでしょう。この場合、複数のコンテナを連携して実現するのが一般的ですが、Dockerコンテナへの理解が足りないと複数のプロセスを1つのコンテナで起動する方法を模索してしまうかもしれません

Dockerfileの書き方も学ぶ必要があります。Dockerはイメージ作成時に一度実行した命令をキャッシュします。つまり、変更の少ない順にDockerfileを記述することで効率的にキャッシュを使用でき、イメージの作成が高速になります。このようにDockerとDockerfile特有の処理を理解した上でDockerfileを記述しないとイメージのサイズが肥大化したり、セキュリティリスクをイメージに埋め込むことになります。

Dockerを正しく効率的に使用するにはコンテナやOS、Docker特有の作法について理解しておきましょう。今まで実行環境の設定をしてこなかった開発者がアプリケーションの動作環境を構築に当たり、OS上に実行環境を構築するための知識が必須となるのです。

おわりに

Dockerは非常に強力に開発作業を効率化してくれます。複数人で同じDockerfileやイメージを使用することで環境の統一が可能になり、差による問題は解決されます。

Dockerは、イメージを共有するための仕組みを有しており、開発に必要な開発・配布・実行の全てを担ってくれます。コンテナの仕組みについて深く理解していなくても、ある程度の知識でDockerによりコンテナを操作できます。Dockerの学習コストは低くはありませんが、習得して損をすることはないでしょう。

日本仮想化技術株式会社
ソーシャルゲーム業界で10年間インフラエンジニアとして活動し、現在は日本仮想化技術でOpsエンジニアを担当。DevOps支援サービス「かんたんDevOps」では仕組み作りや導入支援、技術調査などを行っている。

連載バックナンバー

設計/手法/テスト技術解説
第25回

AWSの監視サービス「CloudWatch」でサーバー監視を試してみよう

2024/8/9
本連載も今回で最終回となります。今回は、AWSの監視サービス「CloudWatch」を使って、簡単なサーバー監視を試してみましょう。
設計/手法/テスト技術解説
第24回

CI環境を構築して「ESLint」で静的解析を実行してみよう

2024/7/26
実践編第8回の今回は、「Dev Containers」でCI環境を構築し、静的解析ツール「ESLint」で静的解析を実行するまでの流れを解説します。
設計/手法/テスト技術解説
第23回

テストコードを書いて「GitHub Actions」でCIを実行してみよう

2024/7/12
実践編第7回の今回は、Webフロントエンド開発を例に、テストコードを書いて「GitHub Actions」でCIを実行するまでの流れを解説します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

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