コンテナの中に入っているシムとは一体何なのか?

コンテナの中に入っているシムとは一体何なのか?

この記事は、Brian Goff 氏が執筆した WeChat パブリック アカウント「Cloud Native Lab」から転載したものです。この記事を転載する場合は、Cloud Native Lab 公式アカウントまでご連絡ください。

Kubernetesバージョン1.20ではdockershimのサポートが廃止され、デフォルトのコンテナランタイムとしてContainerd[1]に置き換えられました。この記事では、Containerd の「shim」インターフェースについて紹介します。

各 Containerd または Docker コンテナには、対応する「shim」デーモンがあり、Containerd がコンテナの基本的なライフサイクル (開始/停止) の管理、コンテナ内での新しいプロセスの実行、TTY のサイズ変更、その他のプラットフォーム固有の操作に使用する API を提供します。 shim のもう 1 つの機能は、コンテナの終了ステータスを Containerd に報告することです。 Shim は、コンテナの終了ステータスが Containerd によって収集されるまで存在します。これはゾンビ プロセスと非常によく似ています。ゾンビ プロセスは親プロセスによってリサイクルされるまで存在し続けます。ただし、ゾンビ プロセスはリソースを占有しませんが、シムはリソースを占有します。

Shim は Containerd プロセスをコンテナのライフサイクルから分離します。具体的には、runc はコンテナを作成して実行した後に終了し、shim をコンテナの親プロセスとして使用します。 Containerd プロセスがクラッシュしたり再起動したりしても、コンテナには影響はありません。これを実行することの利点は明らかです。実行中のコンテナに影響を与えることなく、Containerd をアップグレードまたは再起動できます。 Dockerの--live-restore[2]機能も同様の機能を実装しています。

containerd はどのような shim をサポートしていますか?

Containerd によって現在公式にサポートされている shim のリストは次のとおりです。

io.containerd.runtime.v1.linux

io.containerd.runtime.v1.linux は、Containerd 1.0 より前に設計されたオリジナルの shim API および実装 v1 です。この shim は runc を使用してコンテナを実行し、cgroup v1 のみをサポートします。現在、v1 shim API は非推奨となっており、Containerd 2.0 では削除される予定です。

io.containerd.runc.v1

io.containerd.runc.v1 は実装が io.containerd.runtime.v1.linux に似ていますが、唯一の違いは v2 shim API を使用することです。 shim は依然として cgroup v1 のみをサポートしています。

io.containerd.runc.v2

この shim は実装が v1 と完全に異なり、cgroup v1 と v2 の両方をサポートする v2 shim API を使用します。 shim プロセスは、Kubernetes の CRI 実装で複数のコンテナを実行するために使用され、1 つの Pod で複数のコンテナを実行できます。

io.containerd.runhcs.v1

これは、Windows の HCSv2 API を使用してコンテナーを管理する Windows プラットフォーム用のシムです。

もちろん、公式にサポートされている shim に加えて、誰でも独自の shim を作成し、Containerd にその shim を呼び出させることもできます。 Containerd は、呼び出されると shim の名前をバイナリに解決し、$PATH でバイナリを検索します。たとえば、io.containerd.runc.v2 はバイナリ ファイル containerd-shim-runc-v2 に解析され、io.containerd.runhcs.v1 はバイナリ ファイル containerd-shim-runhcs-v1.exe に解析されます。クライアントは、コンテナを作成するときに使用する shim を指定できます。 shim が指定されていない場合は、デフォルトの shim が使用されます。

使用する shim を指定する例を次に示します。

パッケージメイン

輸入
"コンテクスト"

「github.com/containerd/containerd」
「github.com/containerd/containerd/namespaces」
「github.com/containerd/containerd/oci」
v1opts "github.com/containerd/containerd/pkg/runtimeoptions/v1"


関数main ( ) {
ctx : = namespaces .WithNamespace (コンテキスト.TODO ( ) "default" )

// containerd クライアントを作成する
クライアントエラー: = containerd .New ( "/run/containerd/containerd.sock" )
err != nil の場合{
パニックエラー
}

//コンテナを作成するための画像参照を取得します
img err : = client .GetImage ( ctx "docker.io/library/busybox:latest" )
err != nil の場合{
パニックエラー
}

//シムに渡すオプションを設定します(ここでは実際には何も設定しませんが設定することもできます)
var opts v1opts .オプション

// containerd コンテナオブジェクトを作成する
cntr , err : = client .NewContainer ( ctx , "myContainer" ,
//コンテナを作成するために必要なすべての基本的なもの
containerd .WithSnapshotter ( "overlayfs" )
containerd .WithNewSnapshot ( "myContainer-snapshot" img )
containerd.WithImage ( img )
containerd .WithNewSpec ( oci .WithImageConfig ( img ) )

//必要なシムのオプションを設定します
containerd .WithRuntime ( "io.containerd.runc.v1" & opts )

err != nil の場合{
パニックエラー
}

//掃除
cntr .削除( ctx )
}

⚠️注: WithRuntime は 2 番目のパラメーターとして interface{} を受け取るため、任意の型を shim に渡すことができます。 shim がこのタイプのデータを認識し、タイプが typeurl パッケージに登録されて正しくエンコードされることを確認してください。

各 shim には、コンテナーごとに個別に構成できる、サポートされている構成オプションのセットが独自に用意されています。たとえば、io.containerd.runc.v2 は、コンテナの stdout/stderr を別のプロセスに転送したり、shim を実行するためのカスタム cgroup を設定したりすることができます。コンテナの実行時にカスタム オプションを追加するためのカスタム シムを作成できます。一般に、shim API は、shim を作成/削除するための RPC といくつかのバイナリ呼び出し、および Containerd プロセスへのバックチャネルで構成されます。

独自の shim を実装したい場合は、次のリソースを参照してください。

  • (v2) shim RPC APIの詳細な定義[3]
  • シムバイナリとRPC APIを実装するためのヘルパーツール[4]
  • シムの使い方[5]

インターフェースを実装するだけで、残りの作業は shim.Run が処理します。 shim で注意すべき重要な点はメモリ使用量です。各コンテナには shim プロセスがあり、コンテナの数が増えると shim のメモリ使用量が大幅に増加するためです。 shim APIはprotobufで定義されており、gRPC APIに少し似ていますが、実際にはshimはttrpc[6]と呼ばれるカスタムプロトコルを使用しており、gRPCと互換性がありません。 ttrpc は、メモリ使用量を抑えるために設計された生の RPC プロトコルです。

コンテナを作成するためのRPC呼び出しプロセス

Containerd にはコンテナ オブジェクトがあります。コンテナ オブジェクトを作成すると、コンテナ関連のデータが作成され、そのデータがローカル データベースに保存されるだけで、システム内でコンテナは起動されません。コンテナ オブジェクトが正常に作成された後、クライアントはコンテナ オブジェクトからタスクを作成し、shim API を呼び出します。

RPC 呼び出しの全体的なフローは次のとおりです。

  • クライアントは container.NewTask(…) を呼び出し、containerd は指定されたランタイム名またはデフォルトのランタイム名に基づいて shim バイナリを解決します (例: io.containerd.runc.v2 -> containerd-shim-runc-v2)。
  • Containerd は、start コマンドを使用して shim バイナリを起動し、名前空間、OCI バンドル パス、デバッグ モード、containerd に返される Unix ソケット パスなどを定義するためのいくつかの追加パラメータを追加します。このステップ呼び出しでは、現在の作業ディレクトリが shim の作業パスに設定されます。
  • この時点で、新しく作成された shim プロセスは、接続文字列を stdout に書き込み、containerd が shim に接続して API 呼び出しを行えるようにします。接続文字列が初期化され、shim がリッスンを開始すると、開始コマンドが返されます。
  • containerd は、shim start コマンドによって返された接続文字列を使用して、shim API への接続を開きます。
  • containerd は、OCI バンドル パスとその他のオプションを使用して Create shim RPC を呼び出します。このステップでは、必要なすべてのサンドボックスが作成され、サンドボックス プロセスの pid が返されます。 runc を例にとると、runc create --pid-file= コマンドを使用してコンテナを作成します。 runc は新しいプロセス (runc init) をフォークしてサンドボックスを設定し、runc start が呼び出されるのを待機します。これらすべての準備ができたら、runc create コマンドが結果を返します。 runc create が結果を返す前に、runc は runc-init プロセスの pid を定義された pid ファイルに書き込みます。クライアントはこの pid を使用して、サンドボックス内でのネットワークの設定などの操作を実行できます (ネットワーク名前空間は /proc//ns/net で設定できます)。
  • 作成呼び出しでは、チェックポイント情報を含む、rootfs を構築するためのマウントのリストも提供されます。
  • 次に、クライアントは task.Wait を呼び出し、containerd が shim Wait API を呼び出すようにトリガーします。これは、コンテナが終了するまで返されない永続的な要求です。この時点ではコンテナはまだ起動しません。
  • クライアントは task.Start を呼び出し続け、containerd が Start shim RPC を呼び出すようにトリガーします。このステップでは、実際にコンテナを起動し、コンテナ プロセスの pid を返します。
  • このステップでは、クライアントはタスクに対して追加の呼び出し要求を行うことができます。たとえば、タスクに TTY が含まれている場合は、task.ResizePTY が要求されたり、シグナルを送信するために task.Kill が要求されたりすることがあります。
  • task.Exec は、shim Exec RPC を呼び出すものの、コンテナ内のプロセスを実行しないという点で特殊です。 shim に exec を登録し、exec ID を使用して shim Start RPC を呼び出すだけです。
  • コンテナまたは exec プロセスが終了した後、containerd は shim Delete RPC を呼び出して、exec プロセスまたはコンテナのすべてのリソースをクリーンアップします。たとえば、runc shim の場合、このステップは runc delete を呼び出します。
  • containerd は Shutdown RPC を呼び出し、その時点で shim は終了します。

shim のもう 1 つの重要な部分は、TaskCreateTaskStart、TaskDelete、TaskExit、TaskOOM、TaskExecAdded、TaskExecStarted、TaskPaused、TaskResumed、TaskCheckpointed などのコンテナ ライフサイクル イベントを containerd に返すことです。タスクの詳細な定義については[7]を参照してください。

要約する

Containerd は、shim を通じて、基盤となるコンテナ ランタイムにプラグ可能な機能を提供します。これは Containerd を使用してコンテナを管理する唯一の方法ではありませんが、組み込みの TaskService は現在この方法を使用しており、Kubernetes も shim を使用して CRI を呼び出して Pod を作成します。これは、シム アプローチが非常に人気があることを示しています。 Containerdのスケーラビリティを強化して、より多くのプラットフォームや仮想マシンベースのランタイム(firecracker[8]、kata[9])をサポートできるだけでなく、他のshim実装(systemd[10])を試すことも可能になります。

参考リンク

[1]コンテナド: https://containerd.io/

[2]--ライブリストア: https://docs.docker.com/config/containers/live-restore/

[3](v2) shim RPC APIの詳細な定義: https://github.com/containerd/containerd/blob/v1.5.8/runtime/v2/task/shim.proto

[4] shimバイナリとRPC APIを実装するためのヘルパーツール: https://github.com/containerd/containerd/blob/89370122089d9cba9875f468db525f03eaf61e96/runtime/v2/shim/shim.go#L181-L194

[5] shimの使い方: https://github.com/containerd/containerd/blob/v1.5.8/cmd/containerd-shim-runc-v2/main.go

[6]ttrpc: https://github.com/containerd/ttrpc

[7] タスクの詳細な定義: https://github.com/containerd/containerd/blob/v1.5.6/api/events/task.proto

[8] ファイヤークラッカー: https://github.com/firecracker-microvm/firecracker-containerd/tree/main/runtime

[9]kata: https://github.com/kata-containers/kata-containers/tree/2.3.0/src/runtime

[10]systemd: https://github.com/cpuguy83/containerd-shim-systemd-v1

<<:  三国競争は単なる表面的な現象なのでしょうか?国内パブリッククラウド市場は活況を呈している

>>:  [分散] リソースとトランザクション: 可観測性の基本的な二重性

推薦する

IDC:中国のパブリッククラウドサービス市場規模は2021年下半期に151.3億米ドルに達した

インターナショナル・データ・コーポレーション(IDC)が発表した最新の「中国パブリッククラウドサービ...

JVM 内部キャッシュを選択するにはどうすればいいですか?あなたの疑問に答える記事

[[332941]] JVMの内部キャッシュとは何ですかネイティブJava HashMap のチェー...

数万のIPを持つ独立系ブログがもたらした啓蒙

IT ブログ界の伝説である Moonlight Blog は、単なるシンプルなブログです。どのように...

24クーポンの共同購入の失敗の続報:資本ゲームは運命的な結末になるかもしれない

2012年10月20日、かつては共同購入サイトのトップ5に入っていた、もう一つの大手共同購入サイト「...

LuoBo Data: 労働者の日特別価格、月額 4 ドルの VPS、ネイティブ香港 3 ネットワーク cn2、米国 cn2 高防御大規模ブロードバンド、無制限のトラフィック

LBXU#罗罗データ据は現在、メーデーの爽やかな夏のイベントを推進しており、月払いの場合は20%オフ...

webdock: 7 か月で 1 ユーロ、512M メモリ/1 コア/3g SSD/500g トラフィック、フィンランド/米国

以前、今年リリースされた webdock を紹介しました。LXC 仮想 VPS、大容量メモリ、マルチ...

クラウド コンピューティング サービスは将来どのような脅威に直面するでしょうか?

最近の調査によると、クラウド コンピューティング サービスとクラウド セキュリティの脅威が大幅に増加...

Mituo テンプレート: 運転学校のウェブサイト テンプレートの推奨

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています現代人の車...

Xiaoyun: 優れた SEO プロジェクト マネージャーになるためのヒント

優秀な SEO プロジェクト マネージャーになるのは、依然として非常に困難です。これには、プロジェク...

アリババクラウド、重慶市の「アジアで最もスマートな大都市」建設を支援

8月24日、2018年雲啓会議重慶サミットで、アリババクラウド社長胡暁明氏は、同社がスマート交通、ス...

オリジナルソフト製品は、長期間存続するために明確な目的を持つ必要がある

外部リンク担当者は、もともとフォーラム、ブログ、Baidu 製品にのみ外部リンクを構築していました。...

Alibaba Cloud RDSデータベースは「自動運転」機能を実現するために大幅にアップグレードされました

7月5日、正式に商用化されてから10周年を迎え、Alibaba Cloud RDSデータベースが大幅...

ユーザーエクスペリエンスを冷静に分析することがウェブサイトの成功の鍵です

最近、当社のウェブサイトに問題が発生しています。落ち着いてウェブサイトのデータ分析を行ったところ、ユ...

Dogyun: レイバーデー VPS が 50% オフ、香港、日本、韓国、米国、ドイツ、オランダ、ロシア、CN2、CU2 などのハイエンド ネットワーク

Dogyun は労働者の日のために特別なイベントを開催しました。ラッキーホイールでは、毎日コード、ト...

ウェブサイトはランキングの奇妙な消失をどのように回避できるでしょうか?

2014 年 3 月 20 日、これまで非常に高いランキングを獲得していた多くの Web サイトが突...