# コンテナとは

アプリケーションと稼働に必要なソフトウェア一式を1つに集約し、開発から本番まで同じ中身で稼働させる仕組みです。新規のWebシステムでは有力な選択肢ですが、中身を更新し続ける保守の作業は引き続き発生します。

## コンテナとは

コンテナはアプリケーションと、その稼働に必要なソフトウェアや設定を1つに集約し、他のアプリケーションと互いに影響しにくい区画で実行する[仕組み](https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-container/)です。集約したものをコンテナイメージと呼び、コンテナはこのイメージを元に起動します。開発者のパソコン、検証環境、本番のサーバーやクラウドで同じイメージを実行するため、環境ごとにソフトウェアのバージョンが異なることで発生する不具合を削減できます。

仮想マシンは1台の物理的なコンピューターの中に、ソフトウェアで別のコンピューターを再現する技術です。WindowsやLinuxのようにコンピューター全体の動作を管理するOS（Operating System）も含め、1台分を丸ごと再現します。一方、コンテナはサーバーのOSの中核部分を複数で[共有する](https://kubernetes.io/docs/concepts/overview/)ので、軽量です。その反面、中核部分に欠陥があると同じサーバー上の他のコンテナにも[影響が及びうる](https://csrc.nist.gov/pubs/sp/800/190/final)ため、区画の分離は仮想マシンより限定的です。

![仮想マシンは1台ごとにOSを保有し、コンテナはサーバーのOSの中核を複数で共有することを示す図](https://media.marketing.kdotdev-tunnel.org/glossary-container-b8bf90643bb0830f133eea254505284f51b31c6b3180ed36d3bc2baaf58b084c.png)

住宅を例にすると、仮想マシンは土地ごとに戸建てを1棟ずつ建築する方式で、コンテナは1棟の集合住宅を各戸に区画し、各戸に家具一式を搬入する方式です。建物の基礎や配管を共有するので建築の資材を節約できますが、隣室との仕切りは戸建てほど厚くありません。

## なぜ必要か

サーバーに1つずつソフトウェアを導入し、設定を手作業で調整している環境では、開発者の環境で稼働したアプリケーションが本番では稼働しない、設定の内容を担当者しか把握していないといった問題が発生します。リリースのたびに手順書を参照しながらの作業が数時間に及ぶ場合もあります。

コンテナを利用する構成では本番で稼働させるアプリケーションと依存するソフトウェアの組み合わせを、開発の段階でイメージとして固定します。開発、検証、本番が同じイメージを実行するため、ソフトウェアのバージョンの差による不具合を[削減できます](https://csrc.nist.gov/pubs/sp/800/190/final)。

イメージの形式はコンテナの共通仕様を定める業界団体のOCI（Open Container Initiative）が[標準化](https://opencontainers.org/about/overview/)しています。対応するOSとCPUの実行環境があれば、主要なクラウドやオンプレミスで共通の形式のまま配布できます。

![開発の段階で作成した1つのコンテナイメージを、開発環境・検証環境・本番環境で同じイメージのまま実行することを示す図](https://media.marketing.kdotdev-tunnel.org/glossary-container-54581c2f6e00a9cd4d9198a179a7654e2975e261048ef67c07467d1c4d11d6c8.png)

## 効果

- 開発・検証・本番で同じイメージを稼働させ、ソフトウェアのバージョンの違いによる不具合を削減
- アプリケーション部分のリリースと、問題があったときに前のバージョンへ切り戻す作業が、イメージの差し替えで完結
- イメージの作成手順はファイルとして保存される。担当者の交代後も同じ中身のイメージを再作成するには、元にするイメージと依存するソフトウェアのバージョンの固定も必要
- 1台のサーバーで複数のアプリケーションを、ソフトウェアのバージョンの衝突なく稼働可能
- 負荷に応じて台数を増減する仕組みとの併用が容易

## コストとリスク

- イメージの作成、保管、配置を自動化する仕組みの初期構築に費用が発生
- イメージ内のソフトウェアは自動では更新されず、脆弱性への対応としてイメージの再作成と再配置が[継続的に発生](https://csrc.nist.gov/pubs/sp/800/190/final)
- 自社でサーバーを管理する構成では、サーバーのOSとコンテナの実行基盤の更新作業も別途発生
- 隔離は仮想マシンより限定的で、設定に誤りがあるとコンテナ同士や実行先のサーバーに影響が波及
- CPUやメモリは共有するため、1つのコンテナの使い過ぎが他に影響しないよう上限の設定が必要
- データベースの項目変更や外部サービスの設定変更は、イメージの切り戻しでは復元されない
- 自社で多数のコンテナを管理する場合は、配置と監視を自動化する仕組みが必要になり、運用と学習の負担が増加。サーバー管理不要のサービスでは、配置と監視の自動化にサービスの機能を利用可能
- 障害時にコンテナの仕組みを理解して調査できる人材が必要で、担当者が不在になると保守を継続できない恐れがある
- 開発用ツールのDocker Desktopは、従業員250人以上または年間売上1,000万ドル以上の組織が業務で利用する場合に[有料契約が必要](https://docs.docker.com/subscription-billing/desktop-license/)
- データベースのように記録を保持し続けるものをコンテナで運用する場合、データの保存先とバックアップの別途設計が必要

![サーバー管理不要のサービスでは自社の更新担当はイメージだけで、自社でサーバーを管理する構成では実行基盤とサーバーのOSの更新も自社の担当になることを示す図](https://media.marketing.kdotdev-tunnel.org/glossary-container-d62c5ae5f9f48b7508670d57349898d0f6163ab97eebcf25a7be5ccd4fa40276.png)

## コンテナを採用するかの判断

### どのようなシステムならコンテナを採用すべきか

新規に構築するWebシステムや業務システムで、実行先と、イメージを更新する担当が確定しているなら、採用してかまいません。サーバーの管理をクラウド事業者に一任してコンテナを実行できるサービスとして、[Google CloudのCloud Run](https://docs.cloud.google.com/run/docs/overview/what-is-cloud-run)や[AWSのFargate](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html)があります。これらを実行先にすればサーバーの保守を自社で担当せずに開始できます。

開発・検証・本番など環境が複数あり、次のような症状がすでに発生している場合は、コンテナ化の効果を期待できます。

- 検証環境では稼働したのに本番では稼働しない、という手戻りが繰り返し発生している
- リリースの作業が特定の担当者にしかできない
- 検証環境と本番の状態の統一に毎回時間がかかる

反対に、次の場合はコンテナ化を早急に実施する必要はありません。

- 安定稼働している既存システムを改修の予定なく使い続け、保守と復旧の手順が確立している
- 市販のパッケージ製品やインターネット経由で利用するサービスを導入するだけで、アプリケーションを開発・改修しない

![新規のWebシステムや業務システムでは実行先と更新の担当が確定していれば採用し、未確定なら実行先と更新の担当を決定してから採用し、それ以外では環境差による手戻りなどの症状があれば検討することを示す図](https://media.marketing.kdotdev-tunnel.org/glossary-container-a2c75c98760b3b6e78405d5178d44953e3278b47ab50283b7a165cfa0a5fd3ca.png)

採用する場合は運用を開始する前に、イメージの更新と保守の継続に関する次の4点を自社で決定します。

- イメージの定期的な更新と脆弱性の点検を、誰がどの頻度で実施するか
- 重大な脆弱性が公表されたとき、何日以内にイメージを更新するか
- 実行先をサーバー管理不要のサービスにするか、自社でサーバーを管理する構成にするか
- 担当者が交代しても同じイメージを再作成できるよう、イメージの作成手順と依存するソフトウェアのバージョンをファイルで管理するか

### Kubernetesまで必要か

Kubernetesは多数のコンテナの配置や復旧を自動化する基盤で、設定項目が多く、運用には専門の知識を備えた担当者が必要になります。Cloud RunやFargateのようなクラウドの実行サービスで要件を充足できるなら、Kubernetesを追加する必要はありません。

Kubernetesの検討が必要になるのは、クラウドの実行サービスでは充足できない要件が明確で、その運用費を負担する理由がある場合です。たとえば、多数のサービスの配置を詳細に制御する必要がある、特定のクラウドに依存しない実行基盤を自社で保有する方針がある、といった場合です。要件を説明できないまま導入したKubernetesは、運用の負担だけが発生しやすくなります。

![クラウドのコンテナ実行サービスで要件を充足できるならKubernetesは追加不要で、充足できない要件が明確で運用費を負担する理由がある場合だけ、配置と復旧を自動化する基盤であるKubernetesを検討することを示す図](https://media.marketing.kdotdev-tunnel.org/glossary-container-ea4bcad9340fb785dba0e1e2aecf6a5593cd1e57b4379e62f82db8104f41e8cf.png)

## よくある誤解

### コンテナにすればサーバー費用を削減できる

複数のアプリケーションを1台に集約できれば設備費は減少しますが、小規模なシステムでは自動化の仕組みの構築費と保守費が設備費の削減を上回る場合があります。コンテナ化の価値はサーバー費用の削減より、リリースの確実さとイメージの再現性で評価するほうが現実的です。

### 旧式のシステムもコンテナに格納すれば移行が完了する

旧式のOSや特定のサーバー設定に依存するシステムは、そのままではコンテナで稼働しないことがあり、事前の検証と改修が必要です。改修の費用が少額なら改修してコンテナ化し、多額なら、コンテナ化より仮想マシンへの移管やシステムの刷新と比較して決定します。

![旧式のシステムは稼働を検証して改修の費用を見積もり、少額なら改修してコンテナ化し、多額ならコンテナ化・仮想マシンへの移管・刷新を比較して決定することを示す図](https://media.marketing.kdotdev-tunnel.org/glossary-container-f942bf3b7f27e1ddb6c57e734c1625549d5964102975ad8092515fe1a44e0018.png)
