高セキュリティのもとで、
圧倒的なユーザビリティで
マルチクラウドの開発・運用をサポート
Phil Karlton にひとつの名言があります。「コンピュータサイエンスの世界には、たった2つの問題が存在するーーネーミングとキャッシュの無効化だ。」
私達コンテナ仲間から言わせると、「ネーミング」の問題は確かにその通りだと思います。疑いなく熟練開発者を黙らせる、新人開発者を泣かせる問題です。
システムソフトウェアに関する限り、今日ではそれは「Linuxコンテナテクノロジー」の概念と呼ばれることが多く、他にもJail、Zone、Virtual Server、Sandboxなどと呼ばれてきました。同様に、初期の仮想化テクノロジースタックでは、一種の仮想マシンはコンテナとも呼ばれ、この用語自体が、カプセル化、および分離に使用されるオブジェクトを指します。 Wikipediaでは「OS-Level Virtualization」(OSレベルのシステム仮想化)と呼ばれ、「コンテナとは何か」の問題は述べられていません。
2013年のDockerの登場後、不変のインフラストラクチャやクラウドネイティブなどの一連の概念を伴うコンテナの概念は、「パッケージ+構成」の細かい組み合わせに基づくアプリケーションのデプロイメントを次の年に変更しました。シンプルな宣言型ポリシーと不変のコンテナにより、ソフトウェアスタックが明確に定義されました。 アプリケーションをデプロイする方法は、トピックから少し外れますが、ここで強調したいのは次の点です。
「クラウドネイティブ言語環境下のコンテナは、基本的に「アプリケーションコンテナ」—標準のオペレーティングシステム環境(多くの場合Linux ABI)で実行される標準形式でパッケージ化されたアプリケーションのパッケージ—またはこのアプリケーションをパッケージ化するプログラム/技術である。 」
この定義は私が作成したものですが、個人的な意見ではなく、OCI(Open Container Initiative)標準のコンセンサスに基づいて記述されています。この仕様は、コンテナ内のアプリケーションが配置される環境とその実行方法を規定しています。たとえば、コンテナのルートファイルシステムで実行される実行可能ファイル、実行するユーザー、必要なCPUの種類、どのようなメモリーリソースか、外部ストレージ、共有のニーズなど。
したがって、パッケージの標準形式と標準オペレーティングシステム環境が一緒になって、アプリケーションコンテナのパッケージングを形成します。 このコンセンサスに基づいて、セキュアコンテナについて説明できます。
当時、共同創設者である趙鵬氏と私は「仮想化コンテナ」としてテクノロジーを命名しましたが、注目を集めるために「Secure as VM、Fast as Container」などのスローガンを使用しました。コンテナのセキュリティに問題があるのに「Secure Container(セキュアコンテナ」」という用語を使うのは、受け入れられるものではありません。
私達にとって、このテクノロジーは追加した(分離した)レイヤーですが、それはセキュリティの一部にすぎず、ユーザーはそれをセキュアコンテナの名前で呼んでも構わないと思っています。 セキュアコンテナの定義は次のとおりです。セキュアコンテナは、コンテナアプリケーションに完全なオペレーティングシステム実行環境(多くの場合Linux ABI)を提供しますが、アプリケーションの実行をホストオペレーティングシステムから分離して回避するランタイムテクノロジーです。 アプリケーションはホストリソースに直接アクセスします。これにより、コンテナホスト間またはコンテナ間の追加の保護を提供できます。 これが私達のセキュアコンテナです。
セキュアコンテナについて説明するときは、「間接レイヤー」という言葉に言及する必要があります。これは、Linus Torvalds(リーナス・トーバルズ)の2015年 Linux Conから来ています。「セキュリティ問題の唯一の確実な解決策は、それら(セキュリティ問題の原因)の発生を許容しても、追加の分離レイヤーでそれらをブロックする事だ。」セキュリティのために、なぜ間接レイヤーの考え方を導入すべきなのでしょうか?
実際、Linux自体は非常に大きく、プログラムにバグがないことを理論的に検証することは不可能です。一旦バグが使用されてしまうと、セキュリティリスクはすぐにセキュリティ問題として顕在化します。セキュリティフレームワークとパッチは安全を保証しません。そのため、セキュリティーホールとそれによる大きな不具合のリスクを減らすために、いくつかの追加の分離レイヤーを実行する必要があります。これがセキュアコンテナの起源です。
2017年12月、私達はKataコンファレンスでKata Containersのセキュアコンテナプロジェクトをリリースしました。このプロジェクトには、先に開始したrunVとIntelのClear Containerプロジェクトの2つの先行プロジェクトがあります。これらのプロジェクトはどちらも2015年5月に、実際にはLinus(リーナス)がKubeCon 2015で言及したよりも早く開始されました。彼らのアイデアはとてもシンプルです。
オペレーティングシステム自体のコンテナメカニズムはセキュリティの問題を解決できず、分離レイヤーが必要となります。
仮想マシン自体、VMは既製の分離レイヤーです。たとえば、Alibaba CloudとAWSはすべて仮想化テクノロジーを使用しているため、一般に、誰もがユーザーにとって、「セキュアなVM」を実現でき、このセキュリティはパブリッククラウドのニーズを満たすことができます。
仮想マシンにカーネルがある場合、先のOCI定義をサポートします(つまり、Linux ABIオペレーティング環境を提供する)。このオペレーティング環境にLinuxアプリケーションを実装することは難しくありません。
現在問題となっているのは、仮想マシンの速度が不十分であり、コンテナ環境でのアプリケーションの妨げになっていることです。十分な「コンテナの速度」を持っている場合は、仮想マシンを使用して分離したセキュアコンテナテクノロジーができる可能性があります。これは、仮想マシンをKubernetes PodSandboxとして使用するためのKataコンテナのアイデアです。 KataでVMとして使用されているのは、qemu、firecracker、ACRN、cloud-hypervisorなどです。次の図は、Kata ContainersとKubernetesの統合方法を示しています。ここでは、containerdを使用していますが、CRI-Oも同じです。
現在、Kataコンテナは通常、Kubernetesで使用されています。
まず、KubeletはCRIインターフェースを介して、containerdまたはCRI-Oを検出しますが、現時点では、ミラーリングなどの操作は通常、containerdまたはCRI-Oによって実行されます。リクエストに応じて、ランタイム部分の要件をOCI仕様に変換し、OCIランタイムに渡して実行します。たとえば、上の図の上部のkata-runtime、または下部の合理化後のcontainerd-shim-kata-v2。 具体的なプロセスは次のとおりです。
私達のPodSandboxでは、実際には、コンテナ自体のパッケージングおよびコンテナアプリケーションを実行しているゲストカーネルが1つだけであり、完全なオペレーティングシステムが含まれていないことがわかります。つまり、このプロセスは従来の仮想マシンとは異なり、コンテナの場合、コンテナのエンジンのみを備え、必要でないメモリーはなるべく使わず、共有可能なメモリーを共有することで、メモリーのオーバーヘッドをさらに小さくしています。
従来の仮想マシンと比較して、オーバーヘッドは小さく、起動は軽くて高速です。ほとんどのシナリオでは、「安全なVM」で「高速なコンテナ」にすることができます。
同時に、セキュリティテクノロジーに加えて、従来の仮想マシンよりも柔軟性が高く、マシンの物理的な操作が少なくなります。例えば、動的リソースの挿入と削除、virtio-fsなどのテクノロジーの使用が含まれます。これは、ホストの基本的なファイルシステムのコンテンツ(コンテナのrootfsなど)を仮想マシンと共有するために、私達のシナリオやkataのようなシナリオのために特別に設計されたテクノロジーです。
以前は不揮発性ストレージと不揮発性メモリーに使用されていた一部のDAXテクノロジーにより、異なるPodSandbox間、また異なるPodと異なるコンテナ間で、コンテナ間で、共有可能な一部の読み取り専用メモリー部分が共有されます。
これにより、異なるPodSandbox間のメモリーを大幅に節約できます。 同時に、すべてのPod管理は外部からKubernetesコンテナ管理を介して行われ、メトリックスとデバッグ情報を外部から取得するため、仮想マシンにログインするような感覚はありません。
非常にcontainerdされた操作のように見えますが、これは下層から見た場合でも仮想マシンですが、実際にはクラウドネイティブの仮想化です。
gVisor、私達はこれをプロセスレベルの仮想化と呼びます。これは、kataとは別の方法です。2018年5月、GoogleはコペンハーゲンのKubeコンファレンスで、kataコンテナへの対応として、自社開発のgVisorセキュリティコンテナを5年間オープンソース化しました。それは彼らがこれまでとは別のもう一つのセキュアコンテナソリューションを持っていることを示しています。
Kata Containersが既存の分離テクノロジーを組み合わせて変換することにより、コンテナ間に分離レイヤーを構築する場合、gVisorにより明らかにより簡潔な設計になります。
上の図の右側に示すように、ユーザーモードで実行されるのはGoで書き換えられたオペレーティングシステムのカーネルであり、このカーネルの名前はsentryと呼ばれます。
それは仮想化や仮想マシンテクノロジーに依存せず、逆に、プラットフォームと呼ばれる内部機能を使用して、ホストのオペレーティングシステムに操作を実行させます。
アプリケーションがオペレーティングシステムに期待するすべての操作は、sentryにより実行されます。
Sentryが処理後、監視機能はその一部をオペレーティングシステムに渡し、完了を支援します。ほとんどは自己で行います。
gVisorは純粋なアプリケーション指向の分離レイヤーであり、当初から仮想マシンではなく、Linux上でLinuxプログラムを実行するために使用されました。 分離レイヤーとしてのセキュリティは、以下によっています。
gVisorの開発者は、最初に攻撃対象を減らす必要があります。ホストのオペレーティングシステムは、サンドボックス内のアプリケーションにシステムコールの約20%しか提供しません。
Linuxにはおそらく300を超えるSyscallがありますが、実際にはSentryがオペレーティングシステムに送信した最後の呼び出しは、60ほどのSyscallにのみ集中しています。これは、gVisorの開発者がオペレーティングシステムのセキュリティについていくつかの調査をした結果であり、オペレーティングシステムへの攻撃の成功のほとんどは、一般的ではないシステムコールによるものであることがわかりました。
これはとても理解しやすいです。一般的ではないシステムコールのため、その実装パスは一般的に古いパスです。つまり、これらのパーツの開発は一般的にあまり活発ではなく、少数の開発者だけがそれを維持します。これらのコードはより頻繁にレビューされるため、コードはより安全です。したがって、gVisorの設計は一般的に使用されていないsyscallへのアクセスするアプリケーションをオペレーティングシステムレベルへ到達させないことです、そして、それをsentryでのみ処理する事です。
sentryからホストマシンにアクセスするには、検証済みで、比較的成熟していて、ホットなシステムコールのみを使用します。
この場合、セキュリティは以前よりもはるかに良くなります。現在、Syscallは従来の1/5ですが、攻撃される可能性は1/5を下回っています。
2番目に、ファイルを開く操作であるopen() など、頻繁に攻撃されるシステムコールを分離する必要があることがわかりました。
Unixシステムでは、ほとんどのものがファイルであるため、openは多くのことを実行でき、ほとんどの攻撃はopenを介して実行されます。
gVisorの開発者は一つの独立したプロセスでopenを個別に実装させます。 このプロセスはGoferと呼ばれます。独立したプロセスは実際には、seccompによって保護されたコンテナであり、一部のシステムおよび一部の「機能低下」によって制限されています。Goferは実行できる処理が少なく、root以外で実行できるため、システム全体のセキュリティがさらに向上します。
最後に、sentryとGofer両方とも従来のC言語ではなくGo言語で実装されています。
Go言語自体はメモリーセーフな実装であるため、gVisor全体が攻撃される可能性は低く、メモリーの問題が発生する可能性も低くなります。 もちろん、Go言語はまだいくつかの箇所でまだ体系的ではありません。gVisorの開発者は、これを実行するためにGoランタイムに多くの調整を加えたことを認め、Go言語コミュニティにフィードバックしています。
gVisorのアーキテクチャは非常に美しく、多くの開発者が私に、gVisorのアーキテクチャが好きで、これはよりシンプルで純粋でクリーンであると述べています。
もちろん、そのアーキテクチャは非常に美しいのですが、カーネルを再実装することを実行できるのは、Googleなどの巨人だけです。MicrosoftのWSL 1についてもこれと同じ事が言えます。
そして、この設計は先端を行っていますが、実際にはいくつかの問題があります。
したがって、gVisorのようなソリューションは最終的には究極のソリューションになることはできませんが、特定のシナリオに適応できると示唆できます。この示唆は、オペレーティングシステムとCPU命令セットの将来の開発に何らかの一定の効果を与える可能性があると考えています。そして、将来的にはkataであろうとgVisorであろうと、進化があると信じており、アプリケーションの実行問題を統一的に解決するパブリックソリューションとなる事を期待しています。
セキュアコンテナの名前にはセキュア(安全)が入っていますが、その他にも分離性も提供します。 その役割は安全のみに限定されません。セキュアコンテナが分離レイヤーを介する事によるアプリケーションの問題――外部からの悪意のある攻撃であれ、予期しないエラーであれ、ホストに影響を与えることはなく、異なるPod間に影響を与えることもありません。つまり、この追加の分離レイヤー、それがもたらす効果は、安全だけでなく他の利点もあり、システムのスケジューリング、サービス品質、アプリケーション情報の保護に適しています。
従来のオペレーティングシステムコンテナテクノロジーは、カーネルプロセス管理の拡張であると言えます。コンテナプロセス自体は関連プロセスのグループであり、ホストのスケジューリングシステムに完全に表示されます。Pod内のすべてのコンテナまたはプロセスも、ホストによってスケジュールおよび管理されます。 つまり、多数のコンテナがある環境では、ホスト自体のカーネルの負担が非常に大きくなり、この負担によって生じるオーバーヘッドは多くの実際の環境ですでに観測されています。
特にコンピュータテクノロジーの継続的な発展により、オペレーティングシステムには大量のメモリー、大量のCPUが搭載され、数百Gのメモリーが見られるようになりました。この場合、割り当てられたコンテナの数が多いと、システムのオーバーヘッドが非常に大きくなります。ここでセキュアコンテナを採用すれば、完全な情報はホストマシンに表示されなくなります。この分離レイヤーは、分離レイヤーの上のアプリケーションのスケジューリングも行います。したがって、ホストでサンドボックスのみをスケジュールすればよく、ホストのスケジュールオーバーヘッドが削減されます。これがスケジューリング効率向上の理由です。
スケジューリングの効率を向上させながら、コンテナ間、コンテナホスト間の干渉を回避し、サービスの品質を向上させるために、すべてのアプリケーションを互いに分離します。別の見方をすると、セキュアコンテナの本来の目的は、コンテナ内の悪意のあるまたは問題のあるアプリケーションからホストを保護することです。次に、クラウドとして、悪意のある攻撃に直面する可能性があるため、自分自身も保護します。
同時に、ユーザーは私達がユーザーのリソースへアクセスしすぎることを望みません。ユーザーはリソースを使用する必要がありますが、しかし私達はデータを見る必要はありません。セキュアコンテナは、ユーザーがコンテナ内で実行するものを完全にカプセル化できるため、ホストの運用および保守管理操作はアプリケーションデータにアクセスできず、ユーザーデータに触れることなくサンドボックス内のアプリケーションデータを保護できます。クラウドとしてユーザーデータにアクセスする場合は、ユーザーに承認を与える必要があります。現時点では、ユーザーは悪意のある操作かどうかを認識する事はできません。サンドボックスが適切にカプセル化されている場合、追加のユーザー認証要求は必要ありません。これはユーザーのプライバシーを保護するために優れています。
将来に目を向けると、セキュアコンテナは安全に隔離するだけのものではないことがわかります。セキュアコンテナ分離レイヤーのカーネルは、ホストのカーネルから独立しており、アプリケーションサービス専用です。この観点から見ると、ホストとアプリケーション間の機能は、実際には機能割り当て及び最適化の合理化です。将来のセキュアコンテナは、分離パフォーマンスのオーバーヘッドを減少させるだけでなく、アプリケーションのパフォーマンスも向上させる可能性があります。分離テクノロジーにより、クラウドネイティブインフラストラクチャがより完全なものになります。
この記事の主な内容を簡単にまとめます。