原文はこちら。
https://blogs.oracle.com/developers/the-microcontainer-manifesto
コンテナの人気が、ここ数年で劇的に高まっています。コンテナはパッケージマネージャと構成管理の両方を置き換えるために使用されてきました。コンテナの標準的なビルドプロセスは開発者にとっては理想的ですが、残念ながら、結果として得られるコンテナイメージにより、オペレータの仕事がより困難になっています。
これらのビルドの問題の多くは、コンテナシステムをリードすることによって既に解決済みです。マルチステージビルドや--squashオプションを追加すると、コンテナを操作する他の方法が提供されますが、今回さらに一歩すすめました。その内容についてコミュニティからどのようがあるかを知りたいと思っています。
これらの機能を有効にするには、デプロイメント・アーティファクトを、手作業でデプロイするのに十分な小さい読み取り専用コンテナに縮小します。ファイルシステムは読み取り専用なので、ユーザーの名前空間を有効にしてレイヤーやオーバーレイを避けることができます。
これらの原則と規約を実装することで、運用上の頭痛につながる主要なセキュリティと安定性の問題のいくつかを解決することができます。
さらに、既存のDockerコンテナを「microize(訳注:microsizeのtypoだと思われます)」するために使用できるので、開発中はコンテナ構築にあたって開発者にとって便利なDockerのツールを使用し、実稼働環境に合わせてmicrocontainerに変換できます。smithは標準のoci形式でイメージを構築しますが、Dockerリポジトリからイメージをアップロード/ダウンロードすることもできます。
smithは実行可能ファイルのリンクされた依存関係を検出できますが、dlopenで開いたライブラリを自動的に拾い上げませんし、構成ファイルやデータファイルを自動的に取得しません。実際には、他のファイルをどのように含める必要があるかを把握するのは概してかなり簡単です。既存のアプリケーションをmicrocontainerにパッケージ化するのに、通常は1時間以上かかりません。最終的には、イメージがより安全で、他の技法を使って作成されたものよりも10倍も小さくなります。
多くのソフトウェアパッケージは、適切に機能するために基本的なユーティリティに依存しています。他のすべてのユーティリティ(bash、grep、awkなど)をマイクロコンテナに入れないことがベストですが、実行しようとしている実行可能ファイルが、実際には実際のアプリケーションを実行する前に環境設定を行うシェルスクリプトであることがあります。場合によっては、これらの依存関係を取り除くために必要な労力が大きすぎるため、これらのユーティリティのいくつかをコンテナに含めざるを得ないことがあります。一般に、すべてのルールは破られる可能性があります。実用的であることは常に良い考えです。コンテナに含めるすべてのものに正当な理由があることを確認してください。維持する必要があるものになるからです。
microcontainerの利点をすべて享受するには、コンテナを読み取り専用モードで実行します。
https://blogs.oracle.com/developers/the-microcontainer-manifesto
コンテナの人気が、ここ数年で劇的に高まっています。コンテナはパッケージマネージャと構成管理の両方を置き換えるために使用されてきました。コンテナの標準的なビルドプロセスは開発者にとっては理想的ですが、残念ながら、結果として得られるコンテナイメージにより、オペレータの仕事がより困難になっています。
Related Content
- Containers, Containers Everywhere But Not a Drop to Drink!
http://blogs.oracle.com/developers/containers-everywhere - Getting Started with Microservices, Part 2: Containers and Microservices
http://blogs.oracle.com/developers/getting-started-with-microservices-part-two - Put Your Containers on a Diet with Oracle Linux
https://blogs.oracle.com/developers/put-your-containers-on-a-diet-with-oracle-linux
Problems Resulting from Docker Build
問題の多くは、Linux全体をコンテナイメージに入れるという作業から生じます。具体的には以下の通りです。1. Large Images
長きにわたり、イメージ構築の標準的な方法は、 `FROM debian / jesse
`で始まり、その結果、大きなサイズのイメージをダウンロードすることになりました。これは管理性のためだけにレイヤを必要としていました。 これは、alpine linuxへの切り替えによっていくらか改善されましたが、すべてのソフトウェアがalpine linux上に構築するのは簡単ではありません。 今日でも、最も人気のあるイメージの多くは1G以上のサイズです。2. Privilege Escalation
Linuxのユーザー空間全体をアプリケーションデプロイメントアーティファクトにするという習慣は、アプリケーションのセキュリティ侵害は、特権昇格のための他の潜在的な攻撃手段を与えることを意味します。コンテナ内にアプリケーション以外のものを置かないことでよりセキュアになります。3. Vulnerability Management
コンテナの最大のセキュリティ問題の1つは期限切れの依存関係です。コンテナはイミュータブル(不変)であって、パッケージマネージャを介して脆弱なソフトウェアを更新するソリューションはありません。つまり、ビルド時に実行する必要があります。標準ビルドプロセスでは、コンテナ内のどのファイルが実際に使用されているかが不明ゆえに、コンテナのアップデートが必要か否かを判断することが難しくなります。つまり、「アプリケーションがコンテナ内の脆弱なバージョンのOpen SSLを使用しているのか、それとも単に標準インストールの一部として含まれていたのか」が不明なのです。これらのビルドの問題の多くは、コンテナシステムをリードすることによって既に解決済みです。マルチステージビルドや--squashオプションを追加すると、コンテナを操作する他の方法が提供されますが、今回さらに一歩すすめました。その内容についてコミュニティからどのようがあるかを知りたいと思っています。
Other Operational Changes
ビルドの問題に加え、オペレーション上の変更を実施して悩みを最小限にしました。これらはコンテナシステムやその機能の悪い部分というわけではありませんが、以下の点で成功しました。1. No Layers
コンテナを使って数年後、Layerが運用上問題のある仕様であると判断しました。 開発時にあたっては、Layerは素晴らしい仕様です。ビルドプロセスの最後のいくつかのステップをキャッシュし、毎回イメージ全体をダウンロードしなくても新しいバージョンのコードを実行できるという点で素晴らしいものです。問題は、デプロイメント・イメージの複数のLayerが不必要な複雑さを意味する点です。最近追加されたdocker buildコマンドに--squashオプションが追加されたことで、他の人が同じことを発見したことを示しています。2. User Namespaces
ユーザー名前空間は素晴らしいセキュリティ機能です。誰かが名前空間の分離を破って出た場合、ホストに対する権限のないユーザーに割り当てられます。一般に、ファイルシステムのユーザーの所有権が適切にマッピングされないため、ユーザーの名前空間を有効にすることは困難です。Dockerはしばらくこの件について取り組んできました。彼らは最近、すべてのコンテナに対して単一のユーザー名前空間を共有する機能を追加しましたが、設定変更が必要で、しかもその設定変更はほとんど利用されることはありません。各コンテナが独自のユーザー名前空間を持つことが理想的ですが、残念なことに、これには読み込み専用のイメージまたはファイルシステムIDのマッピングのためのカーネルサポートが必要です。3. No Overlayfs
OverlayFS(およびその前身のUnionFS)は、本番環境での数多くの問題の原因となっています。同じイメージから多くのコンテナを起動している場合は、ソースイメージの各コンテナディレクトリへのコピーは膨大な領域を必要とするため、オーバーレイの目的は理にかなっています。私たちは将来的にOverlayFSを使いたいと思っていますが、これまで避けていた運用上の問題にぶつかりました。さらに、ファイルシステムIDをマップできないということは、一意のユーザー名前空間には役立たないことを意味します。4. No Image Repository
イメージのダウンロードは、多くの問題の原因となっています。 ネットワークの問題、不適切なイメージ、Layerの破損で悩まされてきました。私たちは、帯域外でノードに必要なイメージをデプロイするだけで、より多くの運用上の成功を収めました。これにより、セキュリティ上の脆弱性が存在する場合に、すべてのノードが最新バージョンのイメージを持つようにすることもできます。これらの機能を有効にするには、デプロイメント・アーティファクトを、手作業でデプロイするのに十分な小さい読み取り専用コンテナに縮小します。ファイルシステムは読み取り専用なので、ユーザーの名前空間を有効にしてレイヤーやオーバーレイを避けることができます。
The Solution: Microcontainers
本番環境でコンテナを使っている際に目の当たりにしたこうした問題を解決するため、microcotainerと呼ぶ新しいコンセプトを作成しました。注意いただきたいのは、これは新しいコンテナ形式ではなく、単によりよいセキュリティや安定性を可能にする、特定のコンテナ構築方法です。具体的にmicrocontainerとは- 単一の実行可能ファイルとその依存関係のみが含まれています(つまりShellとinitプロセスがありません)
- 読み取り専用のルートファイルシステムで実行されます(書き込みはボリュームマウントによって分離されて処理されます)
- ユーザーとグループのファイルシステムの所有権はありません(すべてが単一のユーザーによって所有され、読み取り可能です)
- ファイルシステムのタイムスタンプや機能はありません
- 再現可能に構築することができ、毎回同じイメージを生成します
これらの原則と規約を実装することで、運用上の頭痛につながる主要なセキュリティと安定性の問題のいくつかを解決することができます。
Building a Microcontainer
静的にリンクされたGoバイナリを構築し、ベースとしてスクラッチ(開発)を使用している場合は、すでにmicrocontainerを構築している可能性があります。他のソフトウェアでは、マイクロコンテナを構築するのが難しい場合があります。そのため、私たちはmicrocontainerを構築するために利用するsmithをオープンソース化しました。このツールを使って、yumリポジトリと(オプションで)rpmファイルからmicrocontainerを構築できます。さらに、既存のDockerコンテナを「microize(訳注:microsizeのtypoだと思われます)」するために使用できるので、開発中はコンテナ構築にあたって開発者にとって便利なDockerのツールを使用し、実稼働環境に合わせてmicrocontainerに変換できます。smithは標準のoci形式でイメージを構築しますが、Dockerリポジトリからイメージをアップロード/ダウンロードすることもできます。
Practical Considerations
様々な方法でconfigファイルを/readに入れたり、出力ファイルを/writeに入れたりすることができます。コマンドラインパラメータで設定することもできますが、簡単な解決策の1つは、予想される場所を適切なディレクトリにシンボリックリンクを貼ることです。たとえば、/var/log/appnameを/write/logにシンボリックリンクを貼ることができます。smithは実行可能ファイルのリンクされた依存関係を検出できますが、dlopenで開いたライブラリを自動的に拾い上げませんし、構成ファイルやデータファイルを自動的に取得しません。実際には、他のファイルをどのように含める必要があるかを把握するのは概してかなり簡単です。既存のアプリケーションをmicrocontainerにパッケージ化するのに、通常は1時間以上かかりません。最終的には、イメージがより安全で、他の技法を使って作成されたものよりも10倍も小さくなります。
多くのソフトウェアパッケージは、適切に機能するために基本的なユーティリティに依存しています。他のすべてのユーティリティ(bash、grep、awkなど)をマイクロコンテナに入れないことがベストですが、実行しようとしている実行可能ファイルが、実際には実際のアプリケーションを実行する前に環境設定を行うシェルスクリプトであることがあります。場合によっては、これらの依存関係を取り除くために必要な労力が大きすぎるため、これらのユーティリティのいくつかをコンテナに含めざるを得ないことがあります。一般に、すべてのルールは破られる可能性があります。実用的であることは常に良い考えです。コンテナに含めるすべてのものに正当な理由があることを確認してください。維持する必要があるものになるからです。
Running a Microcontainer
一意のユーザー名前空間でコンテナを実行するには、runcのようなものを使って手動で設定する必要がありますが、Dockerを直接使用して他のメリットも享受できます。Dockerはociイメージをインポートできないので、smithで構築されたmicrocontainerイメージをDocker HubのようなDockerリポジトリにプッシュしてから実行する必要があります。microcontainerの利点をすべて享受するには、コンテナを読み取り専用モードで実行します。
docker run -ti --read-only --tmpfs /run -v /my/write/directory:/write my-microcontainer
Operations
microcontainerは、システムのセキュリティを向上させる優れた方法です。 smithを使ってビルドしている場合は、アプリケーション自体が変更された場合にのみコンテナのIDが変わります。つまり、自動ビルドを構成してコンテナの再デプロイの必要性を警告することができます。しかし、docker execコマンドを使ってアクセスできるコンテナ内にツールがないため、デバッグが難しいという欠点もあります。このため、デバッグに役立つcrashcartという別のツールもリリースしました。CrashCart: sideload binaries into a running container
https://github.com/oracle/crashcart
Hardcore Container Debugging
https://blogs.oracle.com/developers/hardcore-container-debugging