Skip to content

필사 모드: [containerd] CRI実装:Kubernetesランタイム統合

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

containerd CRI実装:Kubernetesランタイム統合

containerdはKubernetes CRI(Container Runtime Interface)を内蔵プラグインとして実装しています。この記事ではCRI gRPCサービスの実装詳細、Pod Sandbox管理、コンテナスペック変換、ストリーミングAPI、RuntimeClass、NRIを分析します。

1. CRI gRPCサービス

1.1 サービス構造

CRIは2つのgRPCサービスで構成されます:

CRI gRPCサービス:

RuntimeService:

+-- PodSandbox管理

| RunPodSandbox

| StopPodSandbox

| RemovePodSandbox

| PodSandboxStatus

| ListPodSandbox

|

+-- Container管理

| CreateContainer

| StartContainer

| StopContainer

| RemoveContainer

| ListContainers

| ContainerStatus

| UpdateContainerResources

|

+-- ストリーミング

| ExecSync

| Exec

| Attach

| PortForward

|

+-- ランタイム情報

Status

Version

ImageService:

+-- PullImage

+-- ListImages

+-- ImageStatus

+-- RemoveImage

+-- ImageFsInfo

1.2 ソケット構成

CRIソケット:

containerdは同一のgRPCソケットでCRIを提供:

/run/containerd/containerd.sock

kubelet設定:

--container-runtime-endpoint=unix:///run/containerd/containerd.sock

CRIプラグインがcontainerdサーバーにCRIサービスを登録:

プラグインID:io.containerd.grpc.v1.cri

2. Pod Sandbox

2.1 Pod Sandbox概念

Pod SandboxはPodの分離環境を表します:

Pod Sandbox構成:

Pod Sandbox = Pauseコンテナ + 共有ネームスペース

共有リソース:

- ネットワークネームスペース(同じIP、ポート空間)

- IPCネームスペース(プロセス間通信)

- UTSネームスペース(ホスト名)

- PIDネームスペース(オプション)

分離リソース:

- マウントネームスペース(コンテナ別)

- cgroup(コンテナ別リソース制限)

2.2 RunPodSandboxフロー

RunPodSandbox処理:

1. Sandboxメタデータ作成

- ID生成

- ログディレクトリ作成

|

v

2. Pauseイメージプル

- sandbox_image設定からイメージ決定

- デフォルト値:registry.k8s.io/pause:3.9

|

v

3. Pauseコンテナスナップショット準備

|

v

4. OCIスペック生成

- Pauseコンテナ用最小スペック

- ホスト名、DNS設定を含む

|

v

5. ネットワークネームスペース作成

- /var/run/netns/にネームスペースファイル作成

|

v

6. CNIプラグイン呼び出し

- ネットワークインターフェース作成

- IP割り当て

|

v

7. PauseコンテナTask作成と起動

|

v

8. Sandbox状態をSANDBOX_READYに設定

2.3 Pauseコンテナ

Pauseコンテナの役割:

1. ネームスペース保持者:

- ネットワークネームスペースの最初のプロセス

- Appコンテナが終了してもネームスペースを維持

- ネームスペースのライフサイクルをPodにバインド

2. PID 1の役割:

- Pod PIDネームスペースのinitプロセス

- ゾンビプロセス回収(reap)

- 最小リソース使用(約1MB)

3. 動作:

- pause()システムコールで無限待機

- SIGTERM受信で終了

3. コンテナスペック変換

3.1 CRIリクエストからOCIスペックへ

スペック変換過程:

CRI ContainerConfig:

- Image

- Command、Args

- Envs

- Mounts

- Devices

- SecurityContext

- Resources

|

v

containerd CRIプラグインが変換

|

v

OCI Runtime Spec:

- root(イメージスナップショットパス)

- process(コマンド、env、capabilities)

- mounts(ボリューム、特殊ファイルシステム)

- linux.resources(cgroup設定)

- linux.namespaces(Sandboxと共有)

- hooks(OCIフック)

3.2 リソース変換

Kubernetesリソース -> OCIリソース変換:

CPU:

requests.cpu: 250m

-> linux.resources.cpu.shares = 256

(1000m = 1024 shares基準)

limits.cpu: 500m

-> linux.resources.cpu.quota = 50000

linux.resources.cpu.period = 100000

(500m/1000m * 100000us)

Memory:

limits.memory: 512Mi

-> linux.resources.memory.limit = 536870912

(バイト単位)

requests.memory:

-> スケジューリングにのみ使用、OCIスペックには反映しない

Hugepages:

limits.hugepages-2Mi: 100Mi

-> linux.resources.hugepageLimits:

pageSize: "2MB"

limit: 104857600

3.3 セキュリティコンテキスト変換

SecurityContext -> OCIスペック変換:

runAsUser: 1000

-> process.user.uid = 1000

runAsGroup: 1000

-> process.user.gid = 1000

readOnlyRootFilesystem: true

-> root.readonly = true

privileged: true

-> すべてのcapabilitiesを付与

-> すべてのデバイスアクセスを許可

-> AppArmor/SELinux/Seccompを無効化

capabilities:

add: ["NET_ADMIN"]

drop: ["ALL"]

-> process.capabilities設定

seccompProfile:

type: RuntimeDefault

-> linux.seccompプロファイル適用

4. ストリーミングAPI

4.1 ExecSync

ExecSync動作:

同期的にコンテナでコマンド実行:

1. kubeletがExecSync(containerID, cmd, timeout)を呼び出し

|

v

2. containerdがshimにExecリクエスト

|

v

3. shimがrunc execを実行

- コンテナネームスペースに新しいプロセス作成

|

v

4. stdout/stderrをキャプチャ

|

v

5. プロセス終了待機

|

v

6. exit code + stdout + stderrを返す

使用事例:liveness/readiness probe、kubectl exec(同期)

4.2 Exec(非同期ストリーミング)

Execストリーミング動作:

1. kubeletがExec(containerID, cmd, stdin, stdout, stderr)を呼び出し

|

v

2. containerdがストリーミングURLを返す

- ストリーミングサーバーアドレス:https://node:10250/exec/...

|

v

3. kubeletがクライアントにURLを転送

|

v

4. クライアントがWebSocket/SPDYでストリーミングサーバーに接続

|

v

5. ストリーミングサーバーがcontainerdに実際のExecを実行

|

v

6. stdin/stdout/stderr双方向ストリーミング

ストリーミングプロトコル:

- SPDY(レガシー)

- WebSocket(最新)

4.3 Attach

Attach動作:

実行中のコンテナのメインプロセスに接続:

1. ストリーミングURL生成(Execと類似)

|

v

2. コンテナのstdin/stdout/stderrに接続

- 新しいプロセスを作成しない

- 既存プロセスのI/Oに直接接続

|

v

3. 双方向ストリーミング

使用事例:kubectl attach

4.4 PortForward

PortForward動作:

Podのポートにローカルトラフィックを転送:

1. ストリーミングURL生成

|

v

2. Podのネットワークネームスペースでsocat/nsenterを実行

- 指定ポートにTCP接続

|

v

3. ローカルポートとPodポート間の双方向データ転送

実装:

containerdがPodのネットワークネームスペースに参入し

対象ポートにTCP接続を作成します。

使用事例:kubectl port-forward

5. RuntimeClass

5.1 RuntimeClassマッピング

RuntimeClass処理:

1. Kubernetes RuntimeClassリソース:

apiVersion: node.k8s.io/v1

kind: RuntimeClass

metadata:

name: kata

handler: kata

2. kubeletがCRI RunPodSandbox呼び出し時

runtime_handler = "kata"を渡す

3. containerdがhandlerをランタイム設定にマッピング:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]

runtime_type = "io.containerd.kata.v2"

4. 対応するshimバイナリでTask作成:

containerd-shim-kata-v2

5.2 デフォルトランタイム

デフォルトランタイム設定:

[plugins."io.containerd.grpc.v1.cri".containerd]

default_runtime_name = "runc"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]

runtime_type = "io.containerd.runc.v2"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]

SystemdCgroup = true

PodにruntimeClassNameがなければデフォルトランタイム(runc)を使用

5.3 RuntimeClassオーバーヘッド

RuntimeClassリソースオーバーヘッド:

apiVersion: node.k8s.io/v1

kind: RuntimeClass

metadata:

name: kata

handler: kata

overhead:

podFixed:

memory: "160Mi"

cpu: "250m"

オーバーヘッド処理:

- kubeletがPodリソースにオーバーヘッドを追加

- スケジューラーがオーバーヘッドを含めてノード選択

- VMベースランタイムの固定コストを反映

6. NRI(Node Resource Interface)

6.1 NRI概要

NRIはcontainerdのプラグイン拡張メカニズムで、コンテナライフサイクルイベントにフックを登録できます:

NRIアーキテクチャ:

kubelet -> containerd

|

+-- NRI Plugin 1(リソース割り当て)

+-- NRI Plugin 2(トポロジー認識)

+-- NRI Plugin 3(モニタリング)

NRIプラグインはコンテナライフサイクルイベントを受信し

OCIスペックを修正できます。

6.2 NRIフックポイント

NRIフックポイント:

1. RunPodSandbox:

- Pod作成時に呼び出し

- Podレベルリソース割り当て

2. CreateContainer:

- コンテナ作成時に呼び出し

- OCIスペック修正可能

- CPUピンニング、メモリNUMA割り当てなど

3. StartContainer:

- コンテナ起動時に呼び出し

4. UpdateContainer:

- リソース更新時に呼び出し

5. StopContainer:

- コンテナ停止時に呼び出し

- リソース解放

6. RemoveContainer:

- コンテナ削除時に呼び出し

6.3 NRI使用事例

NRI活用事例:

1. CPU/メモリトポロジー認識割り当て:

- NUMA認識CPUピンニング

- メモリを特定NUMAノードに割り当て

- トポロジーマネージャーとの連携

2. デバイスリソース管理:

- GPU割り当て最適化

- RDMAリソース管理

- デバイスプラグイン補完

3. セキュリティポリシー適用:

- 動的Seccompプロファイル

- ランタイムセキュリティルール注入

4. モニタリング/監査:

- コンテナ起動/停止イベントロギング

- リソース使用追跡

7. イメージサービス

7.1 イメージPull

CRI PullImage処理:

1. kubeletがPullImage(imageSpec, authConfig)を呼び出し

|

v

2. containerdがイメージ参照を解決

- タグまたはダイジェスト

- レジストリ認証情報を適用

|

v

3. イメージダウンロード

- Manifest、Config、Layers

- k8s.ioネームスペースに保存

|

v

4. レイヤーアンパッキング

- Snapshotterでスナップショットチェーン作成

|

v

5. イメージ参照(imageRef)を返す

7.2 イメージキャッシング

イメージキャッシング:

containerdのイメージキャッシング:

- Content Storeにレイヤーが既にある場合はダウンロードスキップ

- Snapshotterにスナップショットが既にある場合はアンパッキングスキップ

- ダイジェストベースの正確な重複排除

kubeletのイメージポリシー:

imagePullPolicy: Always

-> 常にレジストリマニフェストを確認(レイヤーはキャッシュ活用)

imagePullPolicy: IfNotPresent

-> ローカルにない場合のみPull

imagePullPolicy: Never

-> ローカルイメージのみ使用

8. モニタリングとデバッグ

8.1 CRIメトリクス

containerd CRI関連メトリクス:

container_runtime_cri_operations_total: CRI操作数

container_runtime_cri_operations_errors_total:CRI操作エラー数

container_runtime_cri_operations_latency_seconds:CRI操作レイテンシ

containerd内部メトリクス:

containerd_task_count: 実行中Task数

containerd_container_count: コンテナ数

containerd_image_pull_duration_seconds: イメージPull所要時間

8.2 デバッグツール

デバッグツール:

1. crictl(CRI CLI):

crictl ps # コンテナ一覧

crictl pods # Pod一覧

crictl images # イメージ一覧

crictl inspect CONTAINER_ID # コンテナ詳細

crictl logs CONTAINER_ID # コンテナログ

crictl exec -it CONTAINER_ID /bin/sh # exec

2. ctr(containerd CLI):

ctr -n k8s.io containers list

ctr -n k8s.io tasks list

ctr -n k8s.io images list

3. containerdログ:

journalctl -u containerd -f

9. まとめ

containerdのCRI実装はKubernetesとコンテナランタイム間の核心インターフェースです。Pod Sandboxを通じたPodレベルの分離、CRIリクエストからOCIスペックへの正確な変換、WebSocket/SPDYベースのストリーミング、RuntimeClassによるマルチランタイムサポート、NRIによる柔軟な拡張が主要な特徴です。この階層化された設計によりcontainerdはKubernetesの安定したコンテナランタイムとしての地位を確立しています。

현재 단락 (1/354)

containerdはKubernetes CRI(Container Runtime Interface)を内蔵プラグインとして実装しています。この記事ではCRI gRPCサービスの実装詳細、Pod...

작성 글자: 0원문 글자: 7,140작성 단락: 0/354