Yomiao プラットフォームでの Nydus のコンテナ イメージ アクセラレーションの実践

ここに画像の説明を挿入

テキスト | Xiang Shen
Yuemiao プラットフォームの運用保守エンジニアは、クラウド ネイティブの分野に注目しています。

この記事の単語数は 9574 で、読了時間は 24 分です。

この記事は Xiang Shen によって共有され、K8s 運用環境クラスターに Nydus をデプロイする彼の実践を紹介しています。

Nydus は、Ant Group、Alibaba Cloud、Byte が共同で設立したオープンソースのコンテナ イメージ アクセラレーション プロジェクトです. CNCF Dragonfly のサブプロジェクトです. Nydus は、コンテナを高速化するために、OCI Image Spec に基づいてイメージ フォーマットと基盤となるファイル システムを再設計しました起動速度. 大規模クラスタでのコンテナ起動の成功率を向上させます. 詳細なドキュメントについては、次のアドレスを参照してください。

Nydus公式サイト:https://nydus.dev/
Nydus Github:https://github.com/dragonflyoss/image-service

PART.1
コンテナイメージのコンセプト

  1. コンテナー イメージ

コンテナ イメージには、「生活に共通するコンテナ」という公式のアナロジーがあります。仕様は異なりますが、ボックス自体はイミュータブル (Immutable) ですが、その中身は異なります。

ミラーリングの場合、不変部分には、アプリケーション (MySQL など) を実行するために必要なすべての要素が含まれます。開発者は、いくつかのツール (Dockerfile など) を使用して、独自のコンテナー イメージを構築し、署名してインターネットにアップロードできます。その後、これらのソフトウェアを実行する必要がある人は、名前 (例.com/my-app) これらのコンテナー。

  1. OCI 標準イメージ仕様

OCI 標準イメージ仕様が導入される前は、実際には Appc と Docker v2.2 という 2 つの広く使用されているイメージ仕様がありましたが、徐々に同化されたため、OCI 組織は Docker v2.2 に基づいて OCI Image Format Spec を立ち上げました。これは、仕様に準拠したイメージについて、開発者がコンテナーをパッケージ化して署名することを 1 回許可し、すべてのコンテナー エンジンでコンテナーを実行できることを規定しています。

この仕様は、OCI イメージの定義を示します。

この仕様は、マニフェスト、イメージ インデックス (オプション)、一連のファイル システム レイヤー、および構成で構成される OCI イメージを定義します。

  1. コンテナのワークフロー

ここに画像の説明を挿入

一般的なコンテナー ワークフローは、開発者がコンテナー イメージを作成 (ビルド) し、イメージ ストレージ センターにアップロード (シップ) し、最後にクラスターにデプロイ (実行) することから始まります。

PART.2
OCI画像フォーマット

いわゆるイメージ ファイルは、実際には複数のファイルを含む「パッケージ」を指します。「パッケージ」内のこれらのファイルは、コンテナの起動に必要なすべての情報を提供します。これには、ファイル システム、イメージが適用されるプラットフォームなどの構成ファイル、およびデータの整合性検証情報。Docker プルまたは Nerdctl プルを使用してイメージ センターからイメージをプルする場合、実際にはイメージに含まれるファイルを順番にプルしています。

Nerdctl は、インデックス ファイル、マニフェスト ファイル、構成ファイル、およびいくつかのレイヤー データ ファイルを順番に取得しました。実際、標準の OCI イメージは通常、これらのパーツで構成されています。

その中で、レイヤ ファイルは通常、イメージの特定のデータ ファイルを含む tar パッケージまたは圧縮された tar パッケージです。これらのレイヤー ファイルは一緒になって完全なファイル システムを形成します (つまり、イメージからコンテナーを起動した後にコンテナーに表示されるファイル システム)。

構成ファイルは JSON ファイルです。これには、ミラー時間、変更記録、環境変数、ミラー起動コマンドなど、ミラーの構成情報が含まれています。

マニフェスト ファイルも JSON ファイルです。これは、イメージ ファイルのリスト、つまり、どの Layer ファイルとどの Config ファイルがイメージに含まれているかのリストと見なすことができます。

以下は、マニフェスト ファイルの典型的な例です。

"schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
   "mediaType": "application/vnd.oci.image.config.v1+json",
   "digest": "sha256:0584b370e957bf9d09e10f424859a02ab0fda255103f75b3f8c7d410a4e96ed5",
   "size": 7636
 },
  "layers": [
 {
    "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    "digest": "sha256:214ca5fb90323fe769c63a12af092f2572bf1c6b300263e09883909fc865d260",
    "size": 31379476
 },
 {
    "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    "digest": "sha256:50836501937ff210a4ee8eedcb17b49b3b7627c5b7104397b2a6198c569d9231",
    "size": 25338790
 },
 {
    "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    "digest": "sha256:d838e0361e8efc1fb3ec2b7aed16ba935ee9b62b6631c304256b0326c048a330",
    "size": 600
 },
 {
    "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    "digest": "sha256:fcc7a415e354b2e1a2fcf80005278d0439a2f87556e683bb98891414339f9bee",
    "size": 893
 },
 {
    "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    "digest": "sha256:dc73b4533047ea21262e7d35b3b2598e3d2c00b6d63426f47698fe2adac5b1d6",
    "size": 664
 },
 {
    "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    "digest": "sha256:e8750203e98541223fb970b2b04058aae5ca11833a93b9f3df26bd835f66d223",
    "size": 1394
  }
 ]
}

Index ファイルも JSON ファイルです。これはオプションであり、マニフェストのマニフェストと考えることができます。Docker.io/library/nginx:1.20 などのタグで識別されたイメージには、アーキテクチャ プラットフォーム (Linux/amd、Linux/arm64 など) ごとに異なるイメージ ファイルがあり、各イメージは異なるプラットフォーム すべてのファイルはマニフェスト ファイルによって記述されるため、これらの複数のマニフェスト ファイルにインデックスを付けるには、上位レベルのファイルが必要です。

たとえば、Docker.io/library/nginx:1.20 のインデックス ファイルには、複数の異なるプラットフォームのマニフェストの基本情報を記録するマニフェスト配列が含まれています。

{
 "manifests": [
 {
   "digest": "sha256:a76df3b4f1478766631c794de7ff466aca466f995fd5bb216bb9643a3dd2a6bb",
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "platform": {
     "architecture": "amd64",
     "os": "linux"
  },
   "size": 1570
 },
 {
    "digest": "sha256:f46bffd1049ef89d01841ba45bb02880addbbe6d1587726b9979dbe2f6b556a4",
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "platform": {
      "architecture": "arm",
      "os": "linux",
      "variant": "v5"
   },
   "size": 1570
 },
 {
    "digest": "sha256:d9a32c8a3049313fb16427b6e64a4a1f12b60a4a240bf4fbf9502013fcdf621c",
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "platform": {
       "architecture": "arm",
       "os": "linux",
       "variant": "v7"
   },
   "size": 1570
 },
 {
    "digest": "sha256:acd1b78ac05eedcef5f205406468616e83a6a712f76d068a45cf76803d821d0b",
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "platform": {
       "architecture": "arm64",
       "os": "linux",
       "variant": "v8"
   },
   "size": 1570
 },
 {
    "digest": "sha256:d972eee4f12250a62a8dc076560acc1903fc463ee9cb84f9762b50deed855ed6",
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "platform": {
       "architecture": "386",
       "os": "linux"
   },
   "size": 1570
 },
 {
    "digest": "sha256:b187079b65b3eff95d1ea02acbc0abed172ba8e1433190b97d0acfddd5477640",
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "platform": {
       "architecture": "mips64le",
       "os": "linux"
   },
    "size": 1570
 },
 {
    "digest": "sha256:ae93c7f72dc47dbd984348240c02484b95650b8b328464c62559ef173b64ce0d",
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "platform": {
      "architecture": "ppc64le",
      "os": "linux"
   },
    "size": 1570
 },
 {
    "digest": "sha256:51f45f5871a8d25b65cecf570c6b079995a16c7aef559261d7fd949e32d44822",
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "platform": {
       "architecture": "s390x",
       "os": "linux"
  },
   "size": 1570
  }
 ],
 "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
 "schemaVersion": 2
}

PART.3
OCI ミラーリングが直面する問題

ここに画像の説明を挿入

  1. コンテナの起動が遅い

コンテナーは、すべてのイメージ レイヤーがスタックされた後にのみファイル システム ビュー全体を表示できることに気付きました。そのため、コンテナーは、イメージの各レイヤーがダウンロードされて解凍されるまで待機してから開始する必要があります。イメージのプルがコンテナーの起動時間の約 76% を占めるという FAST 論文 [1] の研究分析がありますが、コンテナーによって読み取られるのはデータの 6.4% のみです。この結果は非常に興味深いものであり、オンデマンドでロードすることでコンテナーの起動速度を改善できる可能性を示唆しています。さらに、多数のレイヤーの場合、実行時にオーバーレイのスタック オーバーヘッドが発生します。

一般的に、コンテナの起動は次の 3 つのステップに分けられます。

イメージをダウンロードし、
イメージを解凍し、
Overlayfs を使用してコンテナーの書き込み可能なレイヤーとイメージ内の読み取り専用レイヤーを集約し、コンテナーの動作環境を提供します。

  1. 高いローカル ストレージ コスト

ミラーリングの各レイヤーはメタデータとデータで構成されているため、許可ビットの変更など、ミラーリングの特定のレイヤーでファイルのメタデータに変更がある限り、レイヤーのハッシュが変更され、その後、ミラーリング レイヤー全体を変更する必要があります。再保存するか、再ダウンロードする必要があります。

  1. 多数の同様のミラーが存在します

ミラーリングではレイヤーを基本的なストレージ ユニットとして使用し、レイヤーのハッシュを使用してデータの重複排除を行うため、データ重複排除の粒度が粗くなります。レジストリ ストレージ全体の観点から見ると、イメージ内のレイヤー間およびイメージ間で大量の重複データが存在し、ストレージと転送のコストを占めています。

PART.4
Nydus ミラーリングソリューション

Nydus イメージ アクセラレーション フレームワークは、Dragonfly[2] (CNCF インキュベーション プロジェクト) のサブプロジェクトです。現在の OCI イメージの構築、配布、およびランタイム エコロジーと互換性があります。Nydus ランタイムは Rust で記述されており、言語レベルの安全性とパフォーマンス、メモリと CPU のオーバーヘッドの点で大きな利点があり、安全で高度にスケーラブルです。

ここに画像の説明を挿入

  1. Nydus インフラストラクチャ

Nydus には、主に新しいイメージ形式と、コンテナー イメージの解析を担当する FUSE ユーザー モード ファイル システム プロセスが含まれています。

ここに画像の説明を挿入

  1. Nydus ワークフロー

ここに画像の説明を挿入

Nydus 画像フォーマットは、OCI 画像フォーマットのアーキテクチャを変更しませんが、主に Layer データ層のデータ構造を最適化します。

Nydus は、本来 Layer 層に格納されていたファイルデータとメタデータ (ファイルシステムのディレクトリ構造、ファイルメタデータなど) を分離し、それぞれ「Blob Layer」と「Bootstrap Layer」に格納します。また、Blob レイヤーに格納されたファイル データをチャンク (チャンク) に分割して、遅延読み込みを容易にします (特定のファイルにアクセスする必要がある場合は、Blob レイヤー全体ではなく、対応するチャンクのみをプルする必要があります)。

同時に、ブートストラップ層のメタデータ層には、ブロブ層の各チャンクの位置情報を含むブロック情報も格納されます。このように、コンテナーが起動すると、Bootstrap Layer レイヤーをプルするだけでよく、コンテナーが特定のファイルにアクセスする場合、Bootstrap Layer のメタ情報に従って、対応する Blob Layer の対応する Chunk をプルすることができます。

  1. ナイダスのメリット

コンテナー イメージはオンデマンドでダウンロードされるため、ユーザーは完全なイメージをダウンロードしてコンテナーを起動する必要がなくなりました。
ブロック レベルでのミラー化されたデータの重複排除により、ユーザーのストレージ リソースが最大限に節約されます。
ミラーには最終的に利用可能なデータのみがあり、期限切れのデータを保存してダウンロードする必要はありません。
エンドツーエンドのデータ整合性検証により、ユーザーはより優れたデータ保護を得ることができます。
OCI ディストリビューション標準およびアーティファクト標準と互換性があり、箱から出してすぐに使用できます。
さまざまなミラー ストレージ バックエンドをサポートしており、ミラー データはミラー ウェアハウスに格納できるだけでなく、NAS や S3 などのオブジェクト ストレージにも配置できます。
Dragonfly との優れた統合。

PART.5
苗木生産におけるNydusの実用化

Yomiao Platform は、中国における主要な疾病予防情報およびサービス プラットフォームとして、ワクチン予約サービスを中核として、専門的かつ包括的な疾病予防情報およびサービスを提供しています。

2023 年 2 月現在、Yeemiao プラットフォームは 3,700 万人以上の登録ユーザーを蓄積しており、中央政府直轄の 28 の省と市、200 以上の県レベルの都市をカバーし、全国の 4,000 以上のコミュニティ公衆衛生サービス機関と連携してワクチンを提供しています。 1 億 1000 万回以上の予約およびサブスクリプション サービス。

Yuemiao のビジネスはすべて Kubernetes に基づいてマイクロ サービスを構築しており、4 年以上にわたって Kubernetes プラットフォーム上でスムーズに動作しており、Kubernetes のバージョンの反復に合わせて更新されています。Yue Miao のクラスター サイズは 60 Node ノードを超えており、現在、関連するサービス コンテナー POD は 1000 以上を超えており、毎日数万の一時的な Cronjob タイプの POD が作成および破棄されています。プラットフォームの運用とメンテナンス リリースの効率性には高い要件があります。

  1. 質問

Kubernetes がイメージをプルするのにかかる時間は非常に遅く、OCI イメージを使用している場合の観察によると、イメージのプルにかかる時間は 30 秒に達することがあります。

  1. コンテナの起動が遅い

オンライン観測では、ノードにキャッシュがない場合でも、POD の作成から準備が整うまでに 30 秒以上かかります。

  1. 反復ブロックを更新する

更新の反復では、複数のサービスが毎回バッチで更新され、反復サイクルは短く頻繁に行われ、ミラー ウェアハウスは複数のサービスを更新するときに大きなプレッシャーにさらされます。

上記の問題が発生したため、さまざまな調査と関連するテストの後、同社はオープンソース プロジェクト Nydus を使用して現在のビジネスを最適化することを決定しました。

PART.6
Nydus 展開の練習

Nydus イメージ アクセラレーションは、OCI イメージに直接接続できます. 同時に、Containerd は、Nydus イメージを識別するために Nydus プラグインもサポートしています. 一般に、マイクロサービス シナリオでは、CICD を使用して、Docker パッケージ化されたイメージに Nydus 変換イメージ サービスを展開する必要があります.画像変換後、Harboar 倉庫にある Nydus の画像を直接生成します ここでは CICD に Jenkins を使用します ここでは Jenkins の物理マシンにサービスを直接デプロイします

  1. 関連コンポーネントのダウンロード

ダウンロードリンク: https://github.com/dragonflyoss/image-service/releases

cd /nydus-static
sudo install -D -m 755 nydusd nydus-image nydusify nydusctl nydus-overlayfs /usr/bin
  1. OCI ミラー変換 Nydus
nydusify convert --source dockerharboar/nginx:1.2 --target dockerharboar/nginx:1.2-nydus

知らせ:

ここでのソースは、ソースの Docker-Harboar リポジトリのイメージを示しており、このイメージはプライベート リポジトリに既に存在している必要があります。
ここでのターゲットとは、ソース ウェアハウス イメージを Nydus イメージに変換することを意味します。

このコマンドを使用すると、ミラー ウェアハウスは、同じディレクトリ レベルで 2 つのミラー (1 つのソース OCI ミラーと 1 つの Nydus ミラー) を生成します。

PART. 7
Nydus ドッキング K8s クラスター

K8s クラスターが使用するランタイムは Containerd であり、Containerd はプラグイン Nydus Snapshotter の使用をサポートして Nydus イメージを識別します.同時に、Nydus 機能を使用する場合、Nydus はネイティブ OCI イメージもサポートしますが、関連する機能をオンデマンドでロードしません。

  1. K8s クラスター ノードに Nydus をデプロイする

公式の説明: https://github.com/dragonflyoss/image-service/blob/master/docs/containerd-env-setup.md

注: Nydus 機能を使用するには、K8s-Master ノードを除き、K8s の各ノード ノードに Nydus Snapshotter をデプロイする必要があります。

インストール パッケージをダウンロードします。

https://github.com/dragonflyoss/image-service/releases
https://github.com/containerd/nydus-snapshotter/releases

tar -xf nydus-snapshotter-v0.5.1-x86_64.tgz
tar -xf nydus-static-v2.1.4-linux-amd64.tgz

関連ソフトウェアをインストールする

sudo install -D -m 755  nydusd nydus-image nydusify nydusctl nydus-overlayfs /usr/bin
sudo install -D -m 755 containerd-nydus-grpc /usr/bin

必要なディレクトリを作成します

mkdir -p /etc/nydus  && mkdir -p /data/nydus/cache  && mkdir -p $HOME/.docker/

nydus 構成ファイルの作成

sudo tee /etc/nydus/nydusd-config.fusedev.json > /dev/null << EOF
{
  "device": {
    "backend": {
      "type": "registry",
      "config": {
        "scheme": "",
        "skip_verify": true,
        "timeout": 5,
        "connect_timeout": 5,
        "retry_limit": 4
      }
    },
    "cache": {
      "type": "blobcache",
      "config": {
        "work_dir": "/data/nydus/cache"
      }
    }
  },
  "mode": "direct",
  "digest_validate": false,
  "iostats_files": false,
  "enable_xattr": true,
  "fs_prefetch": {
    "enable": true,
    "threads_count": 4
  }
}
EOF


增加docker-harboar认证
sudo tee $HOME/.docker/config.json << EOF
{
  "auths": {
    "docker-harboarxxx": {
      "auth": "xxxxxx"
    }
  }
}
EOF
增加docker-harboar认证
sudo tee $HOME/.docker/config.json << EOF
{
  "auths": {
    "docker-harboarxxx": {
      "auth": "xxxxxx"
    }
  }
}
EOF
chmod 600 $HOME/.docker/config.json
docker-harboarxx  #私有仓库地址
auth 里是 base64 编码的 user:pass
  1. Nydus サービスを開始する
cd /data/nydus
nohup /usr/bin/containerd-nydus-grpc --config-path /etc/nydus/nydusd-config.fusedev.json --log-to-stdout &
  1. Containerd が Nydus をサポートしていることを確認する
验证nydus是否支持
ctr -a /run/containerd/containerd.sock plugin ls | grep nydus
  1. Nydus をサポートするように Containerd の構成を変更する
containerd配置文件新增
[proxy_plugins]
  [proxy_plugins.nydus]
    type = "snapshot"
    address = "/run/containerd-nydus/containerd-nydus-grpc.sock"
[plugins."io.containerd.grpc.v1.cri".containerd]
   snapshotter = "nydus"
   disable_snapshot_annotations = false
  1. Containerd を再起動する
sudo systemctl restart containerd

PART.8
最終データ試験結果

ネイティブ OCI イメージを使用

ここに画像の説明を挿入

Nydus ミラーを使用する

ここに画像の説明を挿入

作成から準備完了までの POD: OCI -> 20 秒
作成から準備完了までの POD: Nydus -> 13 秒

現在、ビジネス イメージのサイズは大きくなく、約 200MB ですが、Nydus を使用することで既に効果が向上しています.AI コンピューティングなどの非常に大きなイメージを使用するシナリオでは、Nydus によってもたらされる高速化効果は非常に明白です.

PART.9
まとめと今後の期待

Nydus は CNCF の優れたオープン ソース プロジェクトです. さらに、Yomiao はプロジェクトにより多くの投資を続け、コミュニティと深く協力して Yomiao プラットフォームをより強力で持続可能なものにします. クラウドネイティブ テクノロジーは、特に弾力性とサーバーレスという点で、インフラストラクチャの分野における革命であり、Nydus はクラウドネイティブ エコシステムにおいて重要な役割を果たすことは間違いないと考えています。

関連リンク

[1] 《Lazy Dockerコンテナによる迅速な配布》

https://www.usenix.org/conference/fast16/technical-sessions/presentation/harter
[2] トンボ
https://github.com/dragonflyoss/Dragonfly2

もっと詳しく知る…

ナイダススター✨:
https://github.com/dragonflyoss/image-service

おすすめ

転載: blog.csdn.net/SOFAStack/article/details/129281516