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

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

この記事は、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

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

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

推薦する

#推奨# GigsGigsCloud-香港VPS/中国電信CN2+中国聯通グローバルVIP+中国移動直接接続へのアクセス

GigsGigsCloudは、香港VPSの新シリーズ「CLOUDLET V*」を発表しました。KVM...

百度に降格された後の思い

2012 年は Baidu にとって激動の年でした。このような混乱を経験した後、私たち草の根ウェブマ...

SEOを活用してプロジェクトの収益率を向上させる方法

ビジネスを始めることは、インターネット業界で働く多くの人が抱いたことがあるアイデアです。良いプロジェ...

企業にとってスマート名刺のメリットは何ですか?起業家はどのように参加すればよいでしょうか?

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

Tencent Cloudがオンライン教育の進化を支援

[51CTO.com オリジナル記事] 6月7日と8日の「大学入試戦争」が全国を席巻した。候補者は全...

Youdao、検索結果を正確に分類する#タグメカニズムを導入

NetEase Youdao Search は本日改訂されました。社内コード名「Tanggula」の...

maxkvm: 年間 29 ドル、AMD プラットフォーム VPS、KVM/1G メモリ/1 コア/25g NVMe/1T トラフィック

新規事業であるmaxkvm(今年5月設立)は、米国(ロサンゼルス、ダラス、ニューヨーク)、オランダ(...

過去 10 年間の SEO 開発を振り返ると、これが道の終わりなのでしょうか?

2012 年は魔法の数字です。それは世界の終わりと SEOER の終わりが予測されています。 SEO...

Extravm Japan Tokyo VPSの簡単なレビューでExtravmの仕組みを説明します

ExtraVM は、日本 VPS (東京) を含む複数のデータセンターで VPS サービスを提供して...

モバイルローミング中に「ブロックされない」Wi-Fi信号を作成 - Huaweiのアジャイル分散Wi-Fiソリューション

奇妙な停電、私の Wi-Fi に何が起こったのでしょうか?新たな商品が倉庫に到着し、阿珍にとってまた...

エッジコンピューティングの成功または失敗の鍵は何でしょうか?

国が新たなインフラ戦略を継続的に推進するにつれ、国内の5Gネットワ​​ーク構築は急速な発展段階に入っ...

123systems の新しい XEN VPS が初年度半額で販売中

正直に言うと、123systems の openvz はあまり理想的ではありません。 過剰販売などの...

ブランドマーケティングプロモーション:なぜ海底撈は広告を出さないのか?

飲食業界のリーダーとして、海底撈は話題に事欠かない。例えば、先日発表された「2019年胡潤世界長者番...