Linuxオペレーティングシステムの世界では、コンテナ技術はかなり前から存在していました。その起源は、ファイルシステムとプロセスに関する名前空間の分離に関する、10年以上前のアイデアにまで遡ることができます。その後、ある時点においてLXCが誕生し、Linuxカーネル内に隠されていたこの強力な分離技術に、Linuユーザがアクセスするための共通の手段になりました。
私たちが今“コンテナ”と呼んでいるものが持つ、さまざまな技術基盤を組み立てることの難しさは、LXCによって部分的には隠されていますが、それでもコンテナはある種の魔法のようでもあり、この最先端技術に精通したごく一部の人々を除けば、広く利用されるには至っていません。
2014年、LXCと同じこのLinuxカーネル技術を、開発者フレンドリな方法で新たにパッケージしたDocker — 実際にDockerの初期バージョンでは、バックでLXCを使用していました — が登場して、これらをすべて変えました。そのシンプルさとコンテナイメージの再利用性、シンプルな実行コマンドによって、Dockerは開発者の注目を集め、コンテナは真に大衆のものになったのです。
当然のことですが、コンテナの市場シェアを獲得しようとしたのはDockerだけではありませんでした。2014年に最初の爆発的関心を集めた以降も、まったく減速の兆しが見えないハイプサイクルの中にあって、その後数年間にわたって、CoreOS (rkt)やIntel Clear Containers、hyper.sh(軽量仮想化とコンテナの結合)、Singularity、さらにはHPC(High Performance Computing)科学研究分野におけるshifterなど、さまざまな代案が現れました。
市場が成長し、成熟を続けるにつれて、Dockerが推めた初期のアイデアをOCI(Open Container Initiative)として標準化する試みが現れました。今日では多くのコンテナランタイムがOCIに準拠するか、あるいはOCIに準拠する方向に進んでおり、ベンダが自社製品の機能や特定目的の能力によって差別化を図るための、公平な競争条件が提供されています。
Kubernetesの人気
コンテナの進化における次のステップは、開発とデプロイメントの短期イテレーション — いわゆるDevOpsの世界における、マイクロサービスを使用した分散コンピューティングとコンテナとの統合でした。これは、Dockerの人気の高まりの中から、突如として生まれたものです。
それまでにもApache Mesosなどのソフトウェアオーケストレーションプラットフォームは存在していましたが、Googleの小さなオープンソースプロジェクトから始まったKubernetesは、Dockerと同じように一躍注目の的になった結果、CNCF(Cloud Native Computing Foundation)の代表的なプロジェクトにまで成長しました。DockerもSwarnという名前で、Docker的なシンプルさとセキュアなクラスタ構成を重視し、Docker自体を組み込んだオーケストレーションプラットフォームを競合製品として発表しましたが、それもKubernetesへの関心の高まりを止めるには至りませんでした。
クラウドネイティブなコミュニティのバブルの外にいる多くの関係者を困惑させたのは、それがKubernete対Dockerなのか、KubernetesプラスDockerなのか、一般ユーザには分からなかったことです。Kubernetesは単なるオーケストレーションプラットフォームであるため、実際に稼働しているコンテナをKubernetesで管理するには、コンテナランタイムを動作させる必要がありました。当初からKubernetesはDockerエンジンを使用しており、オーケストレーションの競合相手としてSwarnとKubernetesが対峙した以降も、Kubernetesクラスタの運用にはDockerが既定のランタイムとして必要でした。
Docker以外に利用可能なコンテナランタイムの少なさから、コンテナランタイムをKubernetesにインターフェースするために、各ランタイム用に特別に記述されたインターフェースあるいはシムが必要であることは明らかでした。コンテナランタイム実装のための明確なインターフェースがないことが、Kubernetesに新たな選択肢としてランタイムを追加する作業を煩雑なものにしていたのです。
コンテナ実行時インタフェース(CRI)
Kubernetesにランタイムの選択機能を取り入れるという難題を解決するため、コミュニティは、Kubernetesのためにコンテナランタイムが実装する機能として、CRI(Container Runtime Interface)というインターフェースを定義しました。これにより、Kubernetesコードベース内においてコンテナランタイムの変更を適用しなければならない場所のリストが拡大する、という問題が修正されると同時に、ランタイムがCRIランタイムであるためにサポートしなければならない機能が明確になりました。
ご推察のとおり、CRIがランタイムに求めるものは比較的単純です。ランタイムはPODの起動と停止、POD内のすべてのコンテナ操作(起動、停止、一時停止、強制終了、削除)が可能である他、コンテナレジストリによるイメージ管理に対応できなければなりません。ログ収集やメトリクス収集などに関わるユーティリティや支援機能も、想像通りに存在します。
Kubernetesに新たな機能が加わって、その機能がコンテナランタイム層に依存性を持つ場合には、CRI APIのバージョンが更新されて、Kubernetesからの新機能依存関係を処理するために、その新機能(最近の例であればユーザネームスペース)をサポートするランタイムの新バージョンがリリースされることになります。
現在のCRIの展望
2018年現在、Kubernetes下のコンテナランタイムにはいくつかの選択肢があります。下の図で示すように、Dockerは依然としてKubernetesの選択肢として有効であり、そのシムはCRI APIを実装しています。事実、現在のほとんどのケースにおいて、Dockerは現在もKubernetesインストールのデフォルトランタイムなのです。
SwarmによるDockerのオーケストレーション戦略とKubernetesコミュニティに関する対立の結果として興味深いのは、Dockerのランタイムのコアを使って、containerdという新たな開発オープンソースプロジェクトを作り出そうという、共同プロジェクトが形成されたことです。containerdはその後、Kubernetesプロジェクトを所有し管理するCNCFに寄贈されています。
CRIを通じてDockerとKubernetes両方の基盤となり、中核的で中立的、かつ純粋なランタイムであるcotainerdは、Dockerを置き換える可能性にあるものとして、多くのKubernetesインストールの注目を集めています。現時点ではIBM CloudとGoogle Cloudが、コンテナベースのクラスタをベータサービスないし早期アクセスモードで提供しています。Microsoft Azureも将来的なcontainerdへの移行を表明しています。Amazonは同社のECSおよびEKSコンテナサービス下でのランタイム選択のオプションを検討中で、当面はDockerの使用を継続するとしています。
RedHatもまた、OCI参照実装であるruncを中心に、CRIの完全な実装であるcri-oを開発することによって、コンテナランタイムの世界に参入しました。Dockerとcontainerdはいずれもrunc実装をベースにしているのに対して、cri-oはKubernetesのランタイムとして“必要十分”なものとして、Kubernetes CRIを実装するために必要な機能のみをruncバイナリに加えている、と同社は説明しています。
軽量な仮想化プロジェクトであるIntel Clear Containersとhyper.shは、OpenStack FoundationのプロジェクトであるKata containersの元に統合され、CRI実装であるfraktiによるアイソレーション用に独自形式の仮想化コンテナを提供しています。cri-oとcontainderdはいずれもKata containersで動作するので、それぞれのOCI準拠ランタイムを、これらのCRI実装のプラグイン可能なランタイムオプションにすることも可能です。
今後の予測
未来を知っていると主張するのは賢明なことではありませんが、コンテナエコシステムが大規模な興奮とハイプというレベルから、その存在のより成熟したフェーズへと以降することによって現れるであろう、いくつかのトレンドを推測することは可能でしょう。
コンテナエコシステムを巡る論争から、コンテナとは何かという点に関して、さまざまなパーティが異なる互換性のない考え方を持つようになるのではないか、という懸念が初期にはありました。OCIの活動と、主要ベンダや参加者によるコミットメントのおかげで、業界全体にわたって、OCI準拠を重視したソフトウェア製品への良識ある投資が見られるようになっています。
HPCなどのように、特有の制約によってDockerの標準的な使用が勢いを失った新たな分野での、現実的なコンテナランタイムにおけるDockerベース以外の試みにおいても、OCIは注目されるようになっています。議論はいまだ進行中で、科学や研究のコミュニティに特有のニーズにもOCIが対応できるようになると期待されています。
CRIによってKubernetesのプラグイン可能なコンテナランタイムが標準化されることで、開発者や運用担当者が自分たちに適したツールやソフトウェアスタックを選択しながらも、コンテナエコシステム全体での相互運用性を期待し、経験することが可能な世界を思い描くことができます。
これを明確にするために、次のような具体例について見てみましょう。
- Docker for Macを使ってMacBook上で自身のアプリを開発した開発者が、内蔵のKubernetesサポート(CRIランタイムとしてDockerを使用)を使用して、自身のアプリのKubernetes Podへのデプロイを試みる。
- runcとOCIイメージをパッケージするベンダ記述コードを使ってCI/CDを実践したアプリケーションを、テストのために企業内のコンテナレジストリにプッシュする。
- CRIランタイムとしてcontainerdを使用するオンプレミスのKubernetesクラスタで、アプリケーションに対するテストスイートを実行する。
- ある企業では、運用環境での特定のワークロードでKata containerの使用を選択した。アプリケーションがデプロイされると、containerdとともにPod内で実行されるが、基盤ランタイムとしてruncではなくKata containerを使用するように構成されている。
これらの例は、いずれもランタイムとイメージのOCI仕様に準拠していることと、CRIが提供するランタイム選択の柔軟性によって、すべて問題なく機能します。
コンテナエコシステムにおけるこのような柔軟性と選択の機会は、私たちにとってまさに理想の場所であると同時に、2014年からほぼ一夜にして浮上したこの業界が成熟する上で、非常に重要な部分となっています。コンテナベースのプラットフォームを開発し使用する人々の未来には、2019年以降も続くイノベーションとフレキシビリティが光り輝いているのです。
私が先日のQCon NYで行った講演 “CRI Runtimes Deep Dive: Who's Running My Kubernetes Pod!?”では、さらに詳しい情報を提供しています。
著者について
Phil Estes氏は、IBMのWatson and Cloud Platform部門のLinux OS Architecture Strategyに関する優秀なエンジニアであり、CTOです。氏は現在、Docker(現在はMoby)エンジンプロジェクト、CNCF containerdプロジェクトのOSSメンテナであり、OCI(Open Container Initiative) Technical Oversight BoardとMoby Technical Steering Committeeのメンバでもあります。氏はまた、Docker Captainsプログラムのメンバでもあり、オープンソースとコンテナエコシステムに幅広い経験を持っています。さらに氏は、世界中の業界および開発者のカンファレンスの他、オープンソースやDocker、Linuxコンテナ技術に関するトピックの会議で講演しています。氏のブログでは、これらのトピックを定期的に取り上げています。Twitterでは@estespで検索可能です。