埋め込みレジストリミラー

バージョンゲート

埋め込みレジストリミラーは、2024年1月のリリース(v1.26.13+rke2r1、v1.27.10+rke2r1、v1.28.6+rke2r1、v1.29.1+rke2r1)から実験的な機能として利用可能であり、2024年12月のリリース(v1.29.12+rke2r1、v1.30.8+rke2r1、v1.31.4+rke2r1)からGAとして利用可能です。

RKE2は、Kubernetesクラスター内のノード間でコンテナイメージをピアツーピアで共有できる、ステートレスな分散型OCIレジストリミラーである Spegelを埋め込んでいます。分散レジストリミラーは、デフォルトで無効になっています。RKE2がこれを活用するには、以下のサブセクションで説明されているように、分散OCIレジストリミラーレジストリミラーリングの両方を有効にする必要があります。

分散OCIレジストリミラーの有効化

埋め込みレジストリミラーを有効にするには、サーバーノードを`embedded-registry: true`で構成する必要があります。このオプションは、クラスター内のすべてのノードで埋め込みミラーを使用できるようにします。

クラスター全体で有効にすると、すべてのノードはポート6443でローカルOCIレジストリをホストし、ポート5001でピアツーピアネットワークを介して利用可能なイメージのリストを公開します。任意のノードのcontainerdイメージストアにあるイメージは、外部レジストリにアクセスせずに、他のクラスターのメンバーがプルできます。エアギャップイメージtarファイルまたは事前インポートされたイメージは、containerdで固定され、利用可能な状態が維持され、Kubeletのガーベジコレクションによって削除されないように保護されます。

要件

埋め込みレジストリミラーが有効な場合、すべてのノードは内部IPアドレスを介して互いに接続可能であり、TCPポート5001および9345を使用する必要があります。ノードが互いに到達できない場合、イメージをプルするのに時間がかかることがあります。これは、containerdが最初に分散レジストリを試み、その後他のエンドポイントにフォールバックするためです。

Metrics

Spegelは、その活動を追跡するのに役立ついくつかのメトリクスを提供し、スーパーバイザーでクエリ可能です。ただし、スーパーバイザーのメトリクスはデフォルトで無効になっています。これらを有効にするには、サーバーノードを設定ファイル内で`supervisor-metrics: true`とともに起動する必要があります。

有効になったら、次のクエリを実行してください:

kubectl get --server https://$SERVER_NAME:9345 --raw /metrics | grep spegel

レジストリミラーリングの有効化

レジストリのミラーリングを有効にすると、ノードは他のノードからそのレジストリのイメージをプルし、他のノードとレジストリのイメージを共有することができます。あるノードでミラーリングのためにレジストリが有効になっている場合でも、他のノードでは無効になっている場合、そのレジストリが有効になっているノードのみがそのレジストリからイメージを交換します。

アップストリームのコンテナレジストリからのイメージのミラーリングを有効にするには、そのレジストリのために`mirrors`の`registries.yaml`セクションにエントリが必要です。レジストリにはエンドポイントがリストされている必要はなく、存在するだけで構いません。例えば、`docker.io`と`registry.k8s.io`からのイメージの分散ミラーリングを有効にするには、すべてのクラスターのノードで`registries.yaml`に次の内容を設定します:

mirrors:
  docker.io:
  registry.k8s.io:

レジストリミラーのエンドポイントも通常通り追加できます。次の構成では、イメージのプル試行は最初に埋め込まれたミラーを試し、次に`mirror.example.com`、最後に`docker.io`を試みます:

mirrors:
  docker.io:
    endpoint:
      - https://mirror.example.com

アップストリームレジストリのミラーとしてではなく、プライベートレジストリを直接使用している場合は、パブリックレジストリを有効にするのと同じ方法、すなわちミラーセクションにリストすることで分散ミラーリングを有効にできます。

mirrors:
  mirror.example.com:
バージョンゲート

ワイルドカードサポートは、2024年3月のリリース(v1.26.15+rke2r1、v1.27.12+rke2r1、v1.28.8+rke2r1、v1.29.3+rke2r1)から利用可能です。

`"*"`のワイルドカードミラーエントリを使用して、すべてのレジストリの分散ミラーリングを有効にできます。アスタリスクは必ず引用符で囲む必要があります:

mirrors:
  "*":

ノードでミラーリングのためにレジストリが有効になっていない場合、そのノードは分散レジストリにいかなる形でも参加しません。

`registries.yaml`ファイルの構造に関する詳細は、プライベートレジストリ設定を参照してください。

デフォルトエンドポイントフォールバック

デフォルトでは、containerdはミラーエンドポイントが設定されたレジストリからプルする際にデフォルトエンドポイントにフォールバックします。これを無効にして、設定されたミラーや組み込みミラーからのみイメージをプルしたい場合は、プライベートレジストリ設定ドキュメントのデフォルトエンドポイントフォールバックのセクションを参照してください。

`disable-default-endpoint`オプションを使用していて、特定のレジストリからのみ直接プルを許可し、他のレジストリからは許可しない場合は、イメージプルがそのレジストリ自体にフォールバックできるように、エンドポイントを明示的に指定できます。

mirrors:
  docker.io:           # no default endpoint, pulls will fail if not available on a node
  registry.k8s.io:     # no default endpoint, pulls will fail if not available on a node
  mirror.example.com:  # explicit default endpoint, can pull from upstream if not available on a node
    endpoint:
      - https://mirror.example.com

最新のタグ

コンテナイメージにタグが指定されていない場合、暗黙のデフォルトタグは`latest`です。このタグは、イメージの最新バージョンを指すように頻繁に更新されます。このタグは、プルされるタイミングによって異なるイメージのリビジョンを指すため、分散レジストリは**他のノードから`latest`タグをプルしません。これにより、containerdは、`latest`タグが何を指しているかの一貫したビューを確保するために、アップストリームレジストリまたはレジストリミラーにアクセスする必要があります。

これは、Kubernetesがコンテナイメージの`latest`タグを使用する際に観察する、 特別な`imagePullPolicy`デフォルト動作と一致します。

セキュリティ

認証

埋め込まれたミラーのレジストリAPIへのアクセスには、クラスターのクライアント証明書機関によって署名された有効なクライアント証明書が必要です。

分散ハッシュテーブルのピアツーピアネットワークへのアクセスには、サーバーノードによって制御される事前共有キーが必要です。ノードは、事前共有キーとクラスター証明書機関によって署名された証明書の両方を使用して互いに認証します。

潜在的な懸念

分散レジストリはピアツーピアの原則に基づいて構築されており、すべてのクラスターのメンバー間で同等の特権と信頼のレベルを前提としています。これがクラスターのセキュリティポスチャーと一致しない場合、埋め込まれた分散レジストリを有効にすべきではありません。

埋め込まれたレジストリは、ノードが通常アクセスできないイメージを提供する可能性があります。たとえば、いくつかのイメージがKubernetesイメージプルシークレットを介して認証を必要とするレジストリ、プロジェクト、またはリポジトリからプルされる場合、または`registries.yaml`の資格情報が必要な場合、分散レジストリは他のノードがアップストリームレジストリに資格情報を提供することなくそれらのイメージを共有できるようにします。

containerdのイメージストアにイメージをプッシュする権限を持つユーザーは、これを利用して他のクラスターのノードに対してイメージを『汚染』する可能性があります。なぜなら、他のノードはそのノードが広告するタグを信頼し、アップストリームレジストリに確認することなく使用するからです。イメージの整合性が重要な場合、タグの代わりにイメージダイジェストを使用すべきです。なぜなら、ダイジェストはこの方法で毒されることがないからです。

エアギャップまたは手動でロードされたイメージの共有

イメージの共有は、ソースレジストリに基づいて制御されます。エアギャップtarball事前インポートされた、または`ctr`コマンドラインツールを使用してcontainerdのイメージストアに直接ロードされたイメージは、ミラーリングが有効なレジストリからのものであるとタグ付けされている場合、ノード間で共有されます。

イメージがアップストリームのレジストリから来ているように見える場合、そのレジストリが実際に存在する必要や到達可能である必要はありません。たとえば、イメージを架空のアップストリームレジストリからのものであるとタグ付けし、それらのイメージをcontainerdのイメージストアにインポートすることができます。そのレジストリが`registries.yaml`にリストされている限り、すべてのクラスターのメンバーからそれらのイメージをプルできるようになります。

画像をプッシュする

埋め込まれたレジストリは読み取り専用であり、`docker push`やOCIレジストリと対話する他の一般的なツールを使用して直接プッシュすることはできません。

画像は、`ctr -n k8s.io image pull`を実行して画像をプルすることによって、または`docker save`によって作成された画像アーカイブを`ctr -n k8s.io image import`コマンドまたはプレインポート機能を使用してロードすることによって、埋め込まれたレジストリを介して手動で利用可能にすることができます。画像を`ctr`を介して管理する際には、`k8s.io`ネームスペースを指定する必要があり、そうすることでkubeletに表示されるようになります。