埋め込みレジストリミラー
バージョンゲート
埋め込みレジストリミラーは、2024年1月のリリースから実験的な機能として利用可能です:v1.26.13+k3s1、v1.27.10+k3s1、v1.28.6+k3s1、v1.29.1+k3s1 |
K3sは、Kubernetesクラスター内のノード間でコンテナイメージをピアツーピアで共有できる、ステートレスな分散OCIレジストリミラーであるSpegelを埋め込んでいます。 分散レジストリミラーはデフォルトでは無効になっています。
分散OCIレジストリミラーの有効化
埋め込みレジストリミラーを有効にするには、サーバーノードを--embedded-registry
フラグを付けて起動するか、設定ファイルにembedded-registry: true
を追加する必要があります。
このオプションを有効にすると、クラスター内のすべてのノードで埋め込みミラーが使用可能になります。
クラスター全体で有効にすると、すべてのノードはポート6443でローカルOCIレジストリをホストし、ポート5001でピアツーピアネットワークを介して利用可能なイメージのリストを公開します。 任意のノードのcontainerdイメージストアにあるイメージは、外部レジストリにアクセスせずに他のクラスターのメンバーによってプルされることができます。 エアギャップイメージtarファイルを介してインポートされたイメージは、Kubeletのガベージコレクションによって削除されないようにcontainerdに固定されます。
ピアツーピアポートは、K3sサービスの環境変数K3S_P2P_PORT
を設定することで5001から変更できます。ポートはすべてのノードで同じ値に設定する必要があります。
ポートの変更はサポートされておらず、推奨されません。
レジストリミラーリングの有効化
レジストリのミラーリングを有効にすると、ノードは他のノードからそのレジストリのイメージをプルし、そのレジストリのイメージを他のノードと共有できます。 一部のノードでレジストリのミラーリングが有効になっているが、他のノードでは有効になっていない場合、レジストリが有効になっているノードのみがそのレジストリからイメージを交換します。
上流のコンテナレジストリからのイメージのミラーリングを有効にするには、ノードはそのレジストリのregistries.yaml
のmirrors
セクションにエントリを持っている必要があります。
レジストリにはエンドポイントをリストする必要はなく、存在するだけで十分です。
例えば、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+k3s1、v1.27.12+k3s1、v1.28.8+k3s1、v1.29.3+k3s1 |
"*"
ワイルドカードミラーエントリを使用して、すべてのレジストリの分散ミラーリングを有効にできます。アスタリスクは必ず引用符で囲む必要があります:
mirrors:
"*":
ノードでミラーリングが有効になっているレジストリがない場合、そのノードは分散レジストリに一切参加しません。
registries.yaml
ファイルの構造に関する詳細は、プライベートレジストリの設定を参照してください。
デフォルトエンドポイントのフォールバック
デフォルトでは、containerdはミラーエンドポイントが設定されているレジストリからプルする際にデフォルトエンドポイントにフォールバックします。これを無効にし、 設定されたミラーおよび/または埋め込みミラーからのみイメージをプルしたい場合は、プライベートレジストリ設定のデフォルトエンドポイントのフォールバックセクションを参照してください。
--disable-default-endpoint
オプションを使用していて、特定のレジストリから直接プルを許可し、他のレジストリからは許可しない場合は、エンドポイントを明示的に指定してイメージプルがそのレジストリ自体にフォールバックするようにできます:
mirrors:
docker.io: # デフォルトエンドポイントなし、ノードで利用できない場合はプルに失敗
registry.k8s.io: # デフォルトエンドポイントなし、ノードで利用できない場合はプルに失敗
mirror.example.com: # 明示的なデフォルトエンドポイント、ノードで利用できない場合は上流からプル可能
endpoint:
- https://mirror.example.com
最新タグ
コンテナイメージにタグが指定されていない場合、暗黙のデフォルトタグはlatest
です。このタグは頻繁に更新され、最新バージョンのイメージを指します。このタグはプルされるタイミングによって異なるリビジョンのイメージを指すため、分散レジストリは他のノードからlatest
タグをプルしません。これにより、containerdは一貫したビューを確保するために上流レジストリまたはレジストリミラーにアクセスすることを強制されます。
これは、コンテナイメージにlatest
タグを使用する際にKubernetesが観察する特別なimagePullPolicy
のデフォルト設定と一致します。
latest
タグのミラーリングは、K3sサービスの環境変数K3S_P2P_ENABLE_LATEST=true
を設定することで有効にできます。上記の理由から、これはサポートされておらず、推奨されません。
セキュリティ
認証
埋め込みミラーのレジストリAPIへのアクセスには、クラスターのクライアント証明書認証局によって署名された有効なクライアント証明書が必要です。
分散ハッシュテーブルのピアツーピアネットワークへのアクセスには、サーバーノードによって制御される事前共有キーが必要です。 ノードは、事前共有キーとクラスター証明書認証局によって署名された証明書の両方を使用して相互に認証します。
潜在的な懸念
分散レジストリはピアツーピアの原則に基づいて構築されており、すべてのクラスターメンバー間で同等の特権と信頼を前提としています。 これがクラスターのセキュリティポリシーに一致しない場合、埋め込み分散レジストリを有効にすべきではありません。 |
埋め込みレジストリは、ノードが通常アクセスできないイメージを利用可能にする場合があります。
例えば、一部のイメージがKubernetesイメージプルシークレットやregistries.yaml
の資格情報を介して認証が必要なレジストリ、プロジェクト、リポジトリからプルされる場合、分散レジストリは他のノードがこれらのイメージを資格情報なしで共有できるようにします。
あるノードのcontainerdイメージストアにイメージをプッシュする権限を持つユーザーは、他のクラスターノードのイメージを「毒する」ことができるかもしれません。他のノードはそのノードが広告するタグを信頼し、上流レジストリを確認せずに使用します。 イメージの整合性が重要な場合は、タグの代わりにイメージダイジェストを使用するべきです。ダイジェストはこの方法で毒されることはありません。
エアギャップまたは手動でロードされたイメージの共有
イメージの共有は、ソースレジストリに基づいて制御されます。
エアギャップtarボールを介して直接containerdにロードされたイメージ、またはctr
コマンドラインツールを使用してcontainerdのイメージストアに直接ロードされたイメージは、ミラーリングが有効になっているレジストリとしてタグ付けされている場合、ノード間で共有されます。
イメージが実際に存在する必要はなく、到達可能である必要もありません。
例えば、架空の上流レジストリとしてイメージをタグ付けし、そのイメージをcontainerdのイメージストアにインポートすることができます。
そのレジストリがregistries.yaml
にリストされている限り、すべてのクラスターメンバーからそのイメージをプルすることができます。
イメージのプッシュ
埋め込みレジストリは読み取り専用であり、docker push
や他の一般的なOCIレジストリと対話するツールを使用して直接プッシュすることはできません。
イメージは、ctr -n k8s.io image pull
を実行してイメージをプルするか、docker save
で作成されたイメージアーカイブをctr -n k8s.io image import
コマンドを使用してロードすることで、手動で埋め込みレジストリで利用可能にできます。
ctr
を使用してイメージを管理する際には、kubeletに表示されるようにするためにk8s.io
名前空間を指定する必要があることに注意してください。