|Index|SUSE Telco Cloud ドキュメント
SUSE Telco Cloud 3.7

SUSE Telco Cloud ドキュメント

発行日: 2026-05-27

SUSE Telco Cloud 3.7 ドキュメント

SUSE Telco Cloud ドキュメントへようこそ。高レベルのアーキテクチャの概要、クイックスタート、検証済みの設計、コンポーネントの使用方法に関するガイダンス、サードパーティの統合、およびエッジコンピューティングインフラストラクチャとワークロードの管理に関するベスト プラクティスをご覧いただけます。

1 SUSE Telco Cloudとは

SUSE Telco Cloud は、通信事業者や通信ネットワークベンダーがネットワークの近代化を革新し、加速させることを可能にする、通信向けに最適化されたコンピューティングプラットフォームです。

SUSE Telco Cloud は、CNFをホストするための完全な通信事業者向けクラウドネイティブスタックであり、すべての通信ドメインをカバーしています。パケットコア、RAN、OSS、およびBSS。

  • 通信事業者規模での複雑なエッジスタック構成のゼロタッチ展開とライフサイクル管理を自動化します。

  • 通信事業者グレードのハードウェア上で、通信事業者固有の構成とワークロードを使用して、継続的に品質を保証します。

  • エッジ向けに専用設計されたコンポーネントで構成されているため、フットプリントが小さく、ワットあたりのパフォーマンスが高くなっています。

  • ベンダーニュートラルなAPIと100%オープンソースを備えた柔軟なプラットフォーム戦略を維持しています。

2 設計思想

このソリューションは、顧客の要件や期待が大きく異なるため、「万能な」エッジプラットフォームは存在しないという考えに基づいて設計されています。エッジデプロイメントでは、大規模なスケーラビリティ、制限されたネットワーク可用性、物理的なスペースの制約、新たなセキュリティの脅威と攻撃ベクトル、ハードウェアアーキテクチャとシステムリソースの多様性、レガシーインフラストラクチャおよびアプリケーションのデプロイメントとインターフェース接続の要件、そして長寿命の顧客ソリューションなど、最も困難な課題のいくつかを解決し、継続的に進化させることが求められます。これらの課題の多くは、データセンター内やパブリッククラウド内でのインフラストラクチャやアプリケーションのデプロイメントといった従来の考え方とは異なるため、設計をより詳細に検討し、一般的な前提の多くを見直す必要があります。

例えば、私たちはミニマリズム、モジュール性、運用の容易さに価値を見出しています。システムが複雑であればあるほど故障しやすくなるため、エッジ環境ではミニマリズムが重要です。数百から数十万もの拠点に目を向けると、複雑なシステムは複雑な方法で故障します。当社のソリューションにおけるモジュール性により、ユーザーの選択肢が広がり、デプロイされたプラットフォームにおける不要な複雑さが排除されます。また、これらと運用の容易さとのバランスを取る必要もあります。人間はプロセスを何千回も繰り返す際にミスを犯す可能性があるため、プラットフォームは潜在的なミスを確実に復旧できるようにし、現場の技術者による訪問の必要性を排除すると同時に、一貫性と標準化にも努めるべきです。

3 高度なアーキテクチャ

SUSE Telco Cloudの高レベルシステムアーキテクチャは、「管理」クラスターと「ダウンストリーム」クラスターという2つの主要なカテゴリに分類されます。管理クラスターは、1つまたは複数のダウンストリームクラスターのリモート管理を担当します。ただし、エッジサイトに外部接続がなく、独立して動作する必要がある状況など、特定の状況下ではダウンストリームクラスターがリモート管理なしで動作する必要があることも認識されています。SUSE Telco Cloudにおいて、管理クラスターとダウンストリームクラスターの両方の運用に使用される技術コンポーネントは大部分が共通していますが、システム仕様と、その上で実行されるアプリケーションの両面で異なる可能性が高いです。つまり、管理クラスターはシステム管理とライフサイクル運用を可能にするアプリケーションを実行し、ダウンストリームクラスターはユーザーアプリケーションを提供するという要件を満たします。

3.1 SUSE Telco Cloudで使用されるコンポーネント

SUSE Telco Cloudは、既存のSUSEおよびRancherコンポーネントと、エッジコンピューティングで求められる制約や複雑さに対処するためにEdgeチームが構築した追加機能およびコンポーネントで構成されています。管理クラスターとダウンストリームクラスターの両方で使用されるコンポーネントについて、簡略化された高レベルのアーキテクチャ図とともに以下に説明します。なお、これは網羅的なリストではありません。

3.1.1 管理クラスタ

suse edge management cluster
  • 管理:これは、接続されたダウンストリームクラスターのプロビジョニングとライフサイクルを管理するために使用される、SUSE Telco Cloudの中央集権的な部分です。管理クラスターには、通常、以下のコンポーネントが含まれます。

    • Rancher Prime (第6章 「Rancher」)によるマルチクラスター管理。ダウンストリームクラスターのオンボーディングと、インフラストラクチャおよびアプリケーションの継続的なライフサイクル管理のための共通ダッシュボードを実現します。また、包括的なテナント分離と`IDP`(IDプロバイダー)統合、サードパーティ製統合および拡張機能の広範なマーケットプレイス、ベンダーニュートラルなAPIも提供します。

    • SUSE Multi-Linux ManagerによるLinuxシステム管理。ダウンストリームクラスター上で実行される基盤となるLinuxオペレーティングシステム(*SUSE Linux Micro (第10章 「SUSE Linux Micro」))の自動化されたLinuxのパッチおよび設定管理を実現します。このコンポーネントはコンテナ化されていますが、現時点では他の管理コンポーネントとは別のシステム上で実行する必要があるため、上記の図では「Linux管理」とラベル付けされています。

    • 特定のSUSE Telco Cloudリリースへの管理クラスターコンポーネントのアップグレードを処理する専用のライフサイクル管理 (第21章 「Upgrade Controller」)コントローラー。

    • Metal3 (第11章 「Metal3」)、MetalLB (第17章 「MetalLB」)、および`CAPI`(Cluster API)インフラストラクチャプロバイダーによる、オプションのフルベアメタルライフサイクルおよび管理サポート。リモート管理機能を持つベアメタルシステムの完全なエンドツーエンドのプロビジョニングを実現します。

    • ダウンストリームクラスターおよびその上で実行されるアプリケーションのプロビジョニングとライフサイクルを管理するための、Fleet (第9章 「Fleet」)と呼ばれるオプションのGitOpsエンジン。

    • 管理クラスター自体を支える基盤として、ベースオペレーティングシステムにはSUSE Linux Micro (第10章 「SUSE Linux Micro」)が、管理クラスターアプリケーションをサポートするKubernetesディストリビューションにはRKE2 (第14章 「RKE2」)が採用されています。

3.1.2 ダウンストリームクラスタ

suse edge downstream cluster
  • ダウンストリーム:これはSUSE Telco Cloudの分散部分であり、エッジでユーザーワークロードを実行するために使用されます。つまり、エッジロケーション自体で実行されているソフトウェアであり、通常は以下のコンポーネントで構成されています。

    • RKE2は、政府機関や規制の厳しい業界での使用向けに最適化された、強化および認定済みのKubernetesディストリビューションです。

    • SUSE Security (第16章 「SUSE Security」)により、イメージの脆弱性スキャン、ディープパケットインスペクション、リアルタイムの脅威および脆弱性保護などのセキュリティ機能が有効になります。

    • SUSE Storage (第15章 「SUSE Storage」)を使用したソフトウェアブロックストレージにより、軽量で永続的、回復力があり、スケーラブルなブロックストレージが可能になります。

    • SUSE Linux Micro (第10章 「SUSE Linux Micro」)を使用した、軽量でコンテナに最適化された強化済みLinuxオペレーティングシステムであり、エッジでコンテナや仮想マシンを実行するためのイミュータブル(不変)で回復力の高いOSを提供します。SUSE Linux MicroはAArch64アーキテクチャとAMD64/Intel 64アーキテクチャの両方で利用可能であり、遅延に敏感なアプリケーション(通信業界のユースケースなど)向けに`Real-Time Kernel`もサポートしています。

    • 接続されたクラスター(つまり、管理クラスターへの接続性を持つクラスター)の場合、2つのエージェントがデプロイされます。Rancher Primeへの接続を管理するためのRancher System Agentと、Linuxソフトウェアアップデートを適用するためにSUSE Multi-Linux Managerから指示を受けるためのvenv-salt-minionです。切断されたクラスターの管理には、これらのエージェントは不要です。

3.2 [Connectivity (接続]

suse edge connected architecture

上の図は、*接続された*ダウンストリームクラスターと、それらが管理クラスターに接続される仕組みの概要を示しています。管理クラスターは、ダウンストリームクラスターとターゲット管理クラスター間のネットワーク接続状況に応じて、オンプレミスおよびクラウドの両方の環境において、さまざまな基盤インフラストラクチャプラットフォーム上にデプロイできます。これが機能するための唯一の要件は、ダウンストリームクラスターノードと管理インフラストラクチャを接続するネットワーク経由で、APIおよびコールバックURLにアクセスできることです。

この接続が確立されるメカニズムは、ダウンストリームクラスターのデプロイメカニズムとは異なる点に留意することが重要です。これについては次のセクションで詳しく説明しますが、基本的な理解として、接続されたダウンストリームクラスターを「管理対象」クラスターとして確立するための主なメカニズムが3つあります。

  1. ダウンストリームクラスターは、最初は「切断された」状態でデプロイされ(例:Edge Image Builder (第12章 「Edge Image Builder」)を使用)、接続が可能になった時点で管理クラスターにインポートされます。

  2. ダウンストリームクラスターは、ビルトインのオンボーディングメカニズムを使用するように構成されます。 そして、初回起動時に自動的に管理クラスターに登録されるため、クラスター構成のレイトバインディングが可能になります。

  3. ダウンストリームクラスターはベアメタル管理機能(CAPI + Metal3)でプロビジョニングされており、クラスターがデプロイおよび構成されると(Rancher Turtlesオペレーター経由で)、自動的に管理クラスターにインポートされます。

注記
注記

大規模なデプロイメントの規模に対応し、地理的に分散した環境における帯域幅やレイテンシの懸念を最適化し、停止や管理クラスターのアップグレード時の混乱を最小限に抑えるために、複数の管理クラスターを実装することが推奨されます。現在の管理クラスターのスケーラビリティ制限とシステム要件は こちらで確認できます。

4 一般的なエッジデプロイメントパターン

さまざまな動作環境とライフサイクル要件のため、SUSE Telco Cloudが運用されている市場セグメントやユースケースに大まかに適合する、いくつかの異なるデプロイメントパターンへのサポートを実装しました。お客様のニーズに合わせてSUSE Telco Cloudプラットフォームに慣れていただけるよう、これらの各デプロイメントパターンに関するクイックスタートガイドを作成しました。現在サポートしている3つのデプロイメントパターンを以下に説明し、それぞれのクイックスタートページへのリンクを記載します。

4.1 ダイレクトネットワークプロビジョニング

ダイレクトネットワークプロビジョニングとは、デプロイ先のハードウェアの詳細を把握しており、帯域外管理インターフェースに直接アクセスして、プロビジョニングプロセス全体を調整および自動化できる場合を指します。このシナリオでは、お客様は、エッジロケーションでの手動操作を最小限に抑えることで、ブートイメージの作成をはるかに超えて、中央の場所からエッジサイトを完全に自動化してプロビジョニングできるソリューションを期待しています。物理ハードウェアをラックに設置し、電源を入れ、必要なネットワークを接続するだけで、自動化処理が帯域外管理(Redfish APIなどを使用)を介してマシンの電源を入れ、ユーザーの介入なしにインフラストラクチャのプロビジョニング、オンボーディング、デプロイメントを処理します。これが機能するための鍵は、システムが管理者にとって既知であることです。管理者はどのハードウェアがどの場所にあるかを把握しており、デプロイメントは中央で処理されることが想定されています。

このソリューションは、ハードウェアの管理インターフェースと直接やり取りし、既知のハードウェアを扱い、ネットワークの可用性に関する制約が少ないため、最も堅牢です。機能面では、このソリューションはCluster APIとMetal3を広範囲に活用して、ベアメタルからオペレーティングシステム、Kubernetes、階層化されたアプリケーションに至るまで自動プロビジョニングを行い、デプロイメント後にSUSE Telco Cloudの他の一般的なライフサイクル管理機能と連携する機能を提供します。このソリューションのクイックスタートは第4章 「Metal3によるBMC自動デプロイメント」にあります。

4.2 イメージベースのプロビジョニング

スタンドアロン環境、エアギャップ(された)環境、またはネットワークが制限された環境で運用する必要があるお客様向けに、SUSE Telco Cloudは、エッジでのシングルノードおよびマルチノードの高可用性Kubernetesクラスターを実現するために必要なすべてのデプロイメントアーティファクトを含む、完全にカスタマイズ可能なインストールメディアを生成できるソリューションを提供します。これには、必要なワークロードや追加のレイヤーコンポーネントが含まれ、外部へのネットワーク接続や集中管理プラットフォームの介入なしで利用可能です。ユーザーエクスペリエンスは、『phone home』ソリューションと同様に、ターゲットシステムにインストールメディアが提供される点が特徴ですが、ソリューション自体はその場で起動します。このシナリオでは、結果として得られたクラスターを Rancher に接続して継続的に管理すること(つまり、大規模な再構成や再デプロイなしで「切断」モードから「接続」モードへ移行すること)が可能ですが、分離した状態で運用を続けることもできます。どちらの場合も、ライフサイクル操作を自動化するための同じ一貫したメカニズムを適用できることに注意してください。

さらに、このソリューションを使用して、あらゆるタイプのエッジインフラストラクチャをプロビジョニングするための最も迅速かつシンプルな方法となり得るため、「ダイレクトネットワークプロビジョニング」モデルと「phone home ネットワークプロビジョニング」モデルの両方をサポートする集中インフラストラクチャをホストする管理クラスターを迅速に作成できます。このソリューションは、SUSE Telco Cloud Image Builderの機能を最大限に活用して、完全にカスタマイズされた無人インストールメディアを作成します。クイックスタートは第5章 「Edge Image Builderを使用したスタンドアロンクラスター」にあります。

5 SUSE Telco Cloud スタック検証

すべての SUSE Telco Cloud リリースは、緊密に統合され、徹底的に検証されたコンポーネントで構成されており、これらは1つのユニットとしてバージョン管理されています。コンポーネント間の統合をテストするだけでなく、強制的な障害シナリオ下でシステムが期待どおりに動作することを保証する継続的インテグレーションおよびスタック検証の取り組みの一環として、SUSE Telco Cloud チームはすべてのテスト実行とその結果を公開しています。結果とすべての入力パラメータは ci.edge.suse.com で確認できます。

6 コンポーネントの全リスト

コンポーネントの全リストと、それぞれの概要説明および SUSE Telco Cloud での使用方法へのリンクを以下に示します。

パート I コンセプトとアーキテクチャ

SUSE Telco Cloudは、コアからエッジまで、最新のクラウドネイティブな通信アプリケーションを大規模にホストするために設計されたプラットフォームです。

このページでは、SUSE Telco Cloudで使用されるアーキテクチャとコンポーネントについて説明します。

  • 1 SUSE Telco Cloudアーキテクチャ
  • 次の図は、SUSE Telco Cloudのハイレベルアーキテクチャを示しています。

  • 2 コンポーネント
  • 管理スタックとランタイムスタックという2つの異なるブロックがあります。

  • 3 デプロイメントモデル
  • SUSE Telco Cloudは、2段階のデプロイメントモデルに従います。管理クラスターはEdge Image Builder (第12章 「Edge Image Builder」)によって生成されたイメージを使用してデプロイされ、ダウンストリームクラスターはダイレクトネットワークプロビジョニングを介してプロビジョニングされます。この章では、SUSE Telco Cloud環境で推奨され、サポートされているアプローチであるため、このデプロイメントモデルの概要を説明します。

1 SUSE Telco Cloudアーキテクチャ

次の図は、SUSE Telco Cloudのハイレベルアーキテクチャを示しています。

product atip architecture1

2 コンポーネント

管理スタックとランタイムスタックという2つの異なるブロックがあります。

  • 管理スタック:これは、ランタイムスタックのプロビジョニングとライフサイクルを管理するために使用されるSUSE Telco Cloudの一部です。SUSE Linux Enterprise 10には、次のようなコンポーネントが含まれています。

    • Rancher (第6章 「Rancher」)を使用したパブリックおよびプライベートクラウド環境でのマルチクラスター管理

    • Metal3 (第11章 「Metal3」)、MetalLB (第17章 「MetalLB」)、および`CAPI` (Cluster API) インフラストラクチャプロバイダーによるベアメタルサポート

    • 包括的なテナント分離と`IDP` (Identity Provider) 統合

    • サードパーティ製統合および拡張機能の広範なマーケットプレイス

    • ベンダーニュートラルなAPIと豊富なプロバイダーエコシステム

    • SUSE Linux Microのトランザクション更新を管理

    • Fleet (第9章 「Fleet」)を使用したGitリポジトリによるクラスターのライフサイクル管理用GitOpsエンジン

  • ランタイムスタック:これは、ワークロードを実行するために使用されるSUSE Telco Cloudの一部です。

    • RKE2 (第14章 「RKE2」)は、エッジ環境やコンプライアンス重視の通信環境向けに最適化された、セキュリティが強化された軽量なKubernetesディストリビューションとして機能します。

    • (オプション) イメージの脆弱性スキャン、ディープパケットインスペクション、クラスター内トラフィックの自動制御などのセキュリティ機能を有効にするSUSE Security (第16章 「SUSE Security」)

    • (オプション)SUSE Storage (第15章 「SUSE Storage」)を使用したブロックストレージにより、クラウドネイティブなストレージソリューションをシンプルかつ簡単に利用できるようになります。

    • SUSE Linux Micro (第10章 「SUSE Linux Micro」)を使用した最適化されたオペレーティングシステムにより、コンテナを実行するための安全で軽量かつ不変(トランザクションファイルシステム)なOSを実現します。SUSE Linux MicroはAArch64およびAMD64/Intel 64アーキテクチャで利用可能であり、通信事業者やエッジのユースケース向けに`Real-Time Kernel`もサポートしています。

3 デプロイメントモデル

SUSE Telco Cloudは、2段階のデプロイメントモデルに従います。管理クラスターはEdge Image Builder (第12章 「Edge Image Builder」)によって生成されたイメージを使用してデプロイされ、ダウンストリームクラスターはダイレクトネットワークプロビジョニングを介してプロビジョニングされます。この章では、SUSE Telco Cloud環境で推奨され、サポートされているアプローチであるため、このデプロイメントモデルの概要を説明します。

3.1 なぜこのデプロイメントモデルなのか?

管理クラスターは、1回限りの単一サイトデプロイメントです。Image-based Provisioningは、すべてのコンポーネントを単一のブート可能なイメージにバンドルします。このように、管理クラスターは自ら起動するため、運用上の複雑さを最小限に抑えることができます。これが、セットアップして稼働させるための最もシンプルで直接的な方法です。

しかし、ダウンストリームクラスターの場合は事情が異なります。通信事業者環境では、多くのデータセンターやエッジサイトにまたがって大規模に展開されることが多く、現場に技術専門家がいないことも珍しくありません。ダイレクトネットワークプロビジョニングは、このために設計されています。ターゲットサーバーがRedfishなどの帯域外管理インターフェースをサポートしている必要があり、管理クラスターはそれを通じて、現場での介入なしにベアメタルノードの電源投入、検査、プロビジョニングをリモートで実行します。

Image-based Provisioningで必要となるように、クラスター固有のすべての構成をブートイメージに組み込むと、サイトのバリエーションごとに異なるイメージが必要になり、構成を変更するたびにすべてのサイトでイメージを再構築して再配布する必要が生じます。ダイレクトネットワークプロビジョニングは、OSイメージを汎用的なままにし、ネットワーキング、Kubernetes、Telcoプロファイルを含むすべてのクラスター固有の構成を、プロビジョニング時に管理クラスターから実行することで、この問題を解決します。オペレーターはハードウェアをラックに設置し、電源を入れ、接続するだけで、残りの作業は管理クラスターが処理します。

この分離により、完全なGitOps統合も可能になります。ダウンストリームクラスターの定義全体がCluster APIマニフェストとして表現されるため、Gitに保存してすべてのサイトでFleetによって調整できます。これにより、手動介入なしで、プロビジョニング、構成、ライフサイクル操作を完全に監査可能かつ再現可能なものにできます。

3.2 管理クラスターのデプロイメント

Edge Image Builder (第12章 「Edge Image Builder」)を使用して、管理スタックを含む新しい`ISO`イメージを作成します。この`ISO`イメージを使用して、VMまたはベアメタル上に新しい管理クラスターをインストールできます。

product atip architecture2
注記
注記

新しい管理クラスターをデプロイする方法の詳細については、SUSE Telco Cloud Management Cluster guide (パートV「管理クラスタのセットアップ」)を参照してください。

注記
注記

Edge Image Builderの使用方法の詳細については、Edge Image Builder guide (第5章 「Edge Image Builderを使用したスタンドアロンクラスター」)を参照してください。

3.3 Telcoプロファイルを使用したシングルノードダウンストリームクラスターのデプロイメント

管理クラスターが稼働したら、それを使用して、ダイレクトネットワークプロビジョニングワークフローにより、すべてのTelco機能が有効化および構成されたシングルノードダウンストリームクラスターをデプロイできます。

次の図は、それをデプロイするための高レベルのワークフローを示しています。

product atip architecture3
注記
注記

ダウンストリームクラスターをデプロイする方法の詳細については、SUSE Telco Cloud Automated Provisioning guide. (パートVII「完全自動化されたダイレクトネットワークプロビジョニング」)を参照してください。

注記
注記

Telco機能の詳細については、SUSE Telco Cloud Telco Features guide. (パートVI「Telco機能の設定」)を参照してください。

3.4 高可用性ダウンストリームクラスターのデプロイメント

管理クラスターが稼働したら、それを使用して、ダイレクトネットワークプロビジョニングワークフローにより、`MetalLB`をロードバランサーとして使用する高可用性ダウンストリームクラスターをデプロイできます。

次の図は、それをデプロイするための高レベルのワークフローを示しています。

product atip architecture4
注記
注記

ダウンストリームクラスターをデプロイする方法の詳細については、SUSE Telco Cloud Automated Provisioning guide. (パートVII「完全自動化されたダイレクトネットワークプロビジョニング」)を参照してください。

注記
注記

`MetalLB`の詳細については、こちら (第17章 「MetalLB」)を参照してください。

パート II クイックスタート

クイックスタートはこちら

  • 4 Metal3によるBMC自動デプロイメント
  • Metal3は、Kubernetes向けのベアメタルインフラストラクチャ管理機能を提供する CNCFプロジェクトです。

  • 5 Edge Image Builderを使用したスタンドアロンクラスター
  • Edge Image Builder (EIB) は、完全にエアギャップされたシナリオであっても、マシンの起動用にカスタマイズされた起動可能な (CRB) ディスクイメージを生成するプロセスを効率化するツールです。EIBは、SUSE Telco Cloudの3つのデプロイメントフットプリントすべてで使用するデプロイメントイメージを作成するために使用されます。ユーザーの追加やタイムゾーンの設定といった最小限のカスタマイズから、複雑なネットワーク構成の設定、マルチノードKubernetesクラスターのデプロイメント、顧客ワークロードのデプロイメント、Rancher/ElementalおよびSUSE…

4 Metal3によるBMC自動デプロイメント

Metal3は、Kubernetes向けのベアメタルインフラストラクチャ管理機能を提供する CNCFプロジェクトです。

Metal3は、 Redfishなどの帯域外プロトコルを介した管理をサポートするベアメタルサーバーのライフサイクルを管理するための、Kubernetesネイティブなリソースを提供します。

また、広く採用されているベンダー中立のAPIを介して複数のインフラストラクチャプロバイダー間でインフラストラクチャリソースの管理を可能にする Cluster API (CAPI)の成熟したサポートも備えています。

4.1 この方法を使用する理由

この方法は、ターゲットハードウェアが帯域外管理をサポートしており、完全に自動化されたインフラストラクチャ管理フローが望まれるシナリオで役立ちます。

管理クラスタは、自動化されたインスペクション、クリーニング、プロビジョニング/デプロビジョニングを含む、ダウンストリームクラスタのベアメタルサーバーのインベントリおよび状態管理を可能にする宣言型APIを提供するように構成されます。

4.2 上位レベルのアーキテクチャ

quickstart metal3 architecture

4.3 前提条件

ダウンストリームクラスタのサーバーハードウェアおよびネットワークに関連する特定の制約がいくつかあります。

  • 管理クラスタ

    • ターゲットサーバーの管理/BMC APIへのネットワーク接続が必要です

    • ターゲットサーバーのコントロールプレーンネットワークへのネットワーク接続が必要です

    • マルチノード管理クラスタの場合、追加の予約済みIPアドレスが必要です

  • 制御対象のホスト

    • Redfish、iDRAC、またはiLOインターフェイスを介した帯域外管理をサポートしている必要があります

    • 仮想メディアを介したデプロイメントをサポートしている必要があります(PXEは現在サポートされていません)

    • Metal3プロビジョニングAPIにアクセスするために、管理クラスタへのネットワーク接続が必要です

いくつかのツールが必要です。これらは管理クラスタ、または管理クラスタにアクセスできるホストにインストールできます。

4.4 展開

4.4.1 管理クラスタのセットアップ

管理クラスタをインストールし、Metal3 を使用するための基本的な手順は以下の通りです。

  1. RKE2 管理クラスタをインストールします

  2. Rancher をインストールします

  3. ストレージプロバイダーをインストールします (オプション)

  4. Metal3 依存関係をインストールします

  5. CAPI プロバイダーの依存関係をインストールします

  6. ダウンストリームクラスタホスト用の SLEMicro OS イメージをビルドします

  7. ベアメタルインベントリを定義するために BareMetalHost CR を登録します

  8. CAPI リソースを定義してダウンストリームクラスタを作成します

このガイドでは、既存の RKE2 クラスタと Rancher (cert-manager を含む) が、例えば Edge Image Builder (第12章 「Edge Image Builder」) を使用してインストール済みであることを前提としています。

ヒント
ヒント

ここでの手順は、管理クラスタドキュメント (パートV「管理クラスタのセットアップ」) に記載されているように完全に自動化することも可能です。

4.4.2 Metal3 依存関係のインストール

Rancher インストールの一部としてまだインストールされていない場合は、cert-manager をインストールして実行する必要があります。

Metal3 管理サービスに一貫したエンドポイントを提供するために、 MetalLB によって管理される追加の IP が必要です。 この IP はコントロールプレーンサブネットの一部であり、静的構成用に予約されている必要があります (DHCP プールの一部ではないこと)。

ヒント
ヒント

管理クラスタがシングルノードである場合、MetalLB を介して管理される追加のフローティング IP の要件を回避できます。4.7.1項 「シングルノードの設定」 を参照してください。

  1. まず、MetalLB をインストールします。

    helm install \
      metallb oci://registry.suse.com/edge/charts/metallb \
      --namespace metallb-system \
      --create-namespace
  2. 次に、以下のように STATIC_IRONIC_IP として定義された予約済み IP を使用して、IPAddressPool と L2Advertisement を定義します。

    export STATIC_IRONIC_IP=<STATIC_IRONIC_IP>
    
    cat <<-EOF | kubectl apply -f -
    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
      name: ironic-ip-pool
      namespace: metallb-system
    spec:
      addresses:
      - ${STATIC_IRONIC_IP}/32
      serviceAllocation:
        priority: 100
        serviceSelectors:
        - matchExpressions:
          - {key: app.kubernetes.io/name, operator: In, values: [metal3-ironic]}
    EOF
    cat <<-EOF | kubectl apply -f -
    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: ironic-ip-pool-l2-adv
      namespace: metallb-system
    spec:
      ipAddressPools:
      - ironic-ip-pool
    EOF
  3. これで Metal3をインストールできるようになりました:

    helm install \
      metal3 oci://registry.suse.com/edge/charts/metal3 \
      --namespace metal3-system \
      --create-namespace \
      --set global.ironicIP="$STATIC_IRONIC_IP"
  4. このデプロイメントでinitコンテナが実行されるまで約2分かかる場合があるため、続行する前にすべてのポッドが実行されていることを確認してください:

    kubectl get pods -n metal3-system
    NAME                                                    READY   STATUS    RESTARTS   AGE
    baremetal-operator-controller-manager-85756794b-fz98d   2/2     Running   0          15m
    metal3-metal3-ironic-677bc5c8cc-55shd                   4/4     Running   0          15m
    metal3-metal3-mariadb-7c7d6fdbd8-64c7l                  1/1     Running   0          15m
警告
警告

`metal3-system`ネームスペース内のすべてのポッドが実行されるまで、次のステップに進まないでください。

4.4.3 クラスターAPIプロバイダーの依存関係のインストール

クラスターAPIプロバイダーの依存関係は、Rancher Turtles Providers Helmチャートを介して管理されます:

helm install \
  rancher-turtles oci://registry.suse.com/edge/charts/rancher-turtles-providers \
  --namespace cattle-turtles-system \
  --create-namespace

しばらくすると、コントローラーポッドが`cattle-capi-system`、capm3-system、rke2-bootstrap-system、および`rke2-control-plane-system`名前空間で実行されるはずです。

4.4.4 ダウンストリームクラスタイメージの準備

Kiwi (第65章 「Kiwiを使用して更新されたSUSE Linux Microイメージを構築する」)とEdge Image Builder (第12章 「Edge Image Builder」)を使用して、ダウンストリームクラスタホストにプロビジョニングされる変更済みのSLEMicroベースイメージを準備します。

このガイドでは、ダウンストリームクラスタをデプロイするために必要な最小限の設定について説明します。

4.4.4.1 イメージ設定

注記
注記

クラスターを作成するために必要な最初のステップとして、まず第65章 「Kiwiを使用して更新されたSUSE Linux Microイメージを構築する」に従って新しいイメージをビルドしてください。

Edge Image Builderを実行する際、ホストからディレクトリがマウントされるため、ターゲットイメージの定義に使用する設定ファイルを保存するディレクトリ構造を作成する必要があります。

├── downstream-cluster-config.yaml
├── base-images/
│   └ SL-Micro.x86_64-6.2-Base-GM.raw
├── network/
|   └ configure-network.sh
└── custom/
    └ scripts/
        └ 01-fix-growfs.sh
4.4.4.1.1 ダウンストリームクラスターのイメージ定義ファイル

`downstream-cluster-config.yaml`ファイルは、ダウンストリームクラスターイメージのメイン設定ファイルです。Metal3を介したデプロイメントの最小限の例を次に示します。

apiVersion: 1.3
image:
  imageType: raw
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.2-Base-GM.raw
  outputImageName: SLE-Micro-eib-output.raw
operatingSystem:
  time:
    timezone: Europe/London
    ntp:
      forceWait: true
      pools:
        - 2.suse.pool.ntp.org
      servers:
        - 10.0.0.1
        - 10.0.0.2
  kernelArgs:
    - ignition.platform.id=openstack
  systemd:
    disable:
      - rebootmgr
      - transactional-update.timer
      - transactional-update-cleanup.timer
  users:
    - username: root
      encryptedPassword: $ROOT_PASSWORD
      sshKeys:
      - $USERKEY1
      createHomeDir: true
  packages:
    packageList:
      - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE

`$SCC_REGISTRATION_CODE`は SUSE Customer Centerからコピーした登録コードであり、パッケージリストには必要な`jq`が含まれています。

$ROOT_PASSWORD はルートユーザの暗号化されたパスワードであり、テストやデバッグに役立ちます。これは openssl passwd -6 PASSWORD コマンドで生成できます。

本番環境では、$USERKEY1 を実際の SSH キーに置き換えて users ブロックに追加できる SSH キーを使用することをお勧めします。

注記
注記

ignition.platform.id=openstack は必須であることに注意してください。この引数がないと、Metal3 自動フローでの ignition を介した SUSE Linux Micro の設定は失敗します。

time セクションはオプションですが、証明書やクロックスキューに関する潜在的な問題を回避するために構成することを強くお勧めします。この例で提供されている値は、説明のみを目的としています。特定の要件に合わせて調整してください。

4.4.4.1.2 Growfs スクリプト

現在、プロビジョニング後の初回起動時にディスクサイズに合わせてファイルシステムを拡張するには、カスタムスクリプト(custom/scripts/01-fix-growfs.sh)が必要です。01-fix-growfs.sh スクリプトには、次の情報が含まれています。

#!/bin/bash
growfs() {
  mnt="$1"
  dev="$(findmnt --fstab --target ${mnt} --evaluate --real --output SOURCE --noheadings)"
  # /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1
  parent_dev="/dev/$(lsblk --nodeps -rno PKNAME "${dev}")"
  # Last number in the device name: /dev/nvme0n1p42 -> 42
  partnum="$(echo "${dev}" | sed 's/^.*[^0-9]\([0-9]\+\)$/\1/')"
  ret=0
  growpart "$parent_dev" "$partnum" || ret=$?
  [ $ret -eq 0 ] || [ $ret -eq 1 ] || exit 1
  /usr/lib/systemd/systemd-growfs "$mnt"
}
growfs /
注記
注記

同じアプローチを使用して、プロビジョニングプロセス中に実行される独自のカスタムスクリプトを追加します。 詳細については、第5章 「Edge Image Builderを使用したスタンドアロンクラスター」を参照してください。

4.4.4.2 イメージの作成

前のセクションに従ってディレクトリ構造が準備できたら、次のコマンドを実行してイメージをビルドします。

podman run --rm --privileged -it -v $PWD:/eib \
 registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
 build --definition-file downstream-cluster-config.yaml

これにより、上記で説明した定義に基づいて、SLE-Micro-eib-output.raw という名前の出力イメージファイルが作成されます。

出力イメージは、Metal3 チャート (注記) で有効化された media-server コンテナ、またはその他のローカルでアクセス可能なサーバーなど、Web サーバー経由で利用できるようにする必要があります。 以下の例では、このサーバーを imagecache.local:8080 と呼びます。

注記
注記

EIB イメージをダウンストリームクラスターにデプロイする場合、Metal3MachineTemplate オブジェクトにイメージの sha256 合計を含める必要もあります。 これは次のように生成できます。

sha256sum <image_file> > <image_file>.sha256
# On this example:
sha256sum SLE-Micro-eib-output.raw > SLE-Micro-eib-output.raw.sha256

4.4.5 BareMetalHost インベントリの追加

自動デプロイメントのためにベアメタルサーバーを登録するには、BMC アクセス資格情報を格納する Secret と、BMC 接続やその他の詳細を定義する Metal3 BareMetalHost リソースという 2 つのリソースを作成する必要があります。

apiVersion: v1
kind: Secret
metadata:
  name: controlplane-0-credentials
type: Opaque
data:
  username: YWRtaW4=
  password: cGFzc3dvcmQ=
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: controlplane-0
  labels:
    cluster-role: control-plane
spec:
  architecture: x86_64
  online: true
  bootMACAddress: "00:f3:65:8a:a3:b0"
  bmc:
    address: redfish-virtualmedia://192.168.125.1:8000/redfish/v1/Systems/68bd0fb6-d124-4d17-a904-cdf33efe83ab
    disableCertificateVerification: true
    credentialsName: controlplane-0-credentials

以下の点に注意してください。

  • Secret のユーザー名/パスワードは base64 でエンコードされている必要があります。これには末尾の改行を含めないでください(例:echo -n を使用し、echo だけを使わないでください!)。

  • cluster-role ラベルは、今設定することも、クラスター作成時に設定することもできます。以下の例では、control-plane または worker を想定しています。

  • bootMACAddress は、ホストのコントロールプレーンNICと一致する有効なMACアドレスである必要があります。

  • bmc アドレスはBMC管理APIへの接続であり、以下がサポートされています。

    • redfish-virtualmedia://<IP ADDRESS>/redfish/v1/Systems/<SYSTEM ID>:Redfish 仮想メディア(例:SuperMicro)

    • idrac-virtualmedia://<IP ADDRESS>/redfish/v1/Systems/System.Embedded.1:Dell iDRAC

  • BareMetalHost APIの詳細については、 アップストリームAPIドキュメントを参照してください。

4.4.5.1 スタティック IP アドレスを設定する

上記の BareMetalHost の例では、コントロールプレーンのネットワーク構成が DHCP によって提供されることを前提としていますが、スタティック IP のように手動構成が必要なシナリオでは、以下のように追加の構成を提供することが可能です。

4.4.5.1.1 スタティック ネットワーク構成用の追加スクリプト

Edge Image Builder でベースイメージを作成する際、network フォルダーに以下の configure-network.sh ファイルを作成します。

これは初回起動時に構成ドライブのデータを使用し、 NM Configurator ツールを使用してホストのネットワークを構成します。

#!/bin/bash

set -eux

# Attempt to statically configure a NIC in the case where we find a network_data.json
# In a configuration drive

CONFIG_DRIVE=$(blkid --label config-2 || true)
if [ -z "${CONFIG_DRIVE}" ]; then
  echo "No config-2 device found, skipping network configuration"
  exit 0
fi

mount -o ro $CONFIG_DRIVE /mnt

META_DATA_FILE="/mnt/openstack/latest/meta_data.json"
if [ ! -f "${META_DATA_FILE}" ]; then
  umount /mnt
  echo "No meta_data.json found, skipping hostname configuration"
  exit 0
fi

DESIRED_HOSTNAME=$(cat /mnt/openstack/latest/meta_data.json | tr ',{}' '\n' | grep '"metal3-name"' | sed 's/.*\"metal3-name\": \"\(.*\)\"/\1/')
echo "${DESIRED_HOSTNAME}" > /etc/hostname

NETWORK_DATA_FILE="/mnt/openstack/latest/network_data.json"

if [ ! -f "${NETWORK_DATA_FILE}" ]; then
  umount /mnt
  echo "No network_data.json found, skipping network configuration"
  exit 0
fi

mkdir -p /tmp/nmc/{desired,generated}
cp ${NETWORK_DATA_FILE} /tmp/nmc/desired/_all.yaml
umount /mnt

./nmc generate --config-dir /tmp/nmc/desired --output-dir /tmp/nmc/generated
./nmc apply --config-dir /tmp/nmc/generated
4.4.5.1.2 ホスト ネットワーク構成を含む追加のSecret

NM Configurator (第13章 「エッジネットワーキング」)でサポートされている nmstate 形式のデータを含む追加のSecretを、各ホストに対して定義できます。

そのSecretは、`BareMetalHost`リソース内で`preprovisioningNetworkDataName`スペックフィールドを介して参照されます。

apiVersion: v1
kind: Secret
metadata:
  name: controlplane-0-networkdata
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: enp1s0
      type: ethernet
      state: up
      mac-address: "00:f3:65:8a:a3:b0"
      ipv4:
        address:
        - ip:  192.168.125.200
          prefix-length: 24
        enabled: true
        dhcp: false
    dns-resolver:
      config:
        server:
        - 192.168.125.1
    routes:
      config:
      - destination: 0.0.0.0/0
        next-hop-address: 192.168.125.1
        next-hop-interface: enp1s0
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: controlplane-0
  labels:
    cluster-role: control-plane
spec:
  preprovisioningNetworkDataName: controlplane-0-networkdata
# Remaining content as in previous example
注記
注記

状況によっては、MACアドレスを省略できる場合があります。詳細については、13.5.8項 「統合ノード設定」を参照してください。

4.4.5.2 BareMetalHost preparation

上記のようにBareMetalHostリソースと関連するSecretを作成した後、ホスト準備ワークフローがトリガーされます。

  • ラムディスクイメージは、ターゲットホストBMCへの仮想メディア接続によってブートされます。

  • ラムディスクはハードウェアの詳細を検査し、プロビジョニングのためにホストを準備します(例えば、ディスクから以前のデータを消去するなど)。

  • このプロセスが完了すると、BareMetalHost `status.hardware`フィールドのハードウェア詳細が更新され、確認できるようになります。

このプロセスには数分かかる場合がありますが、完了するとBareMetalHostの状態が`available`になるはずです。

% kubectl get baremetalhost
NAME             STATE       CONSUMER   ONLINE   ERROR   AGE
controlplane-0   available              true             9m44s
worker-0         available              true             9m44s

4.4.6 ダウンストリームクラスターの作成

次に、ダウンストリームクラスターを定義するCluster APIリソースと、BareMetalHostリソースをプロビジョニングし、起動してRKE2クラスターを形成するためのMachineリソースを作成します。

4.4.7 コントロールプレーンのデプロイメント

コントロールプレーンをデプロイするために、以下のリソースを含む、以下のようなYAMLマニフェストを定義します。

  • Clusterリソースは、クラスター名、ネットワーク、およびコントロールプレーン/インフラストラクチャプロバイダーのタイプ(この場合はRKE2/Metal3)を定義します。

  • Metal3Clusterは、コントロールプレーンのエンドポイント(シングルノードの場合はホストIP、マルチノードの場合はロードバランサーエンドポイント。この例ではシングルノードを想定)を定義します。

  • RKE2ControlPlaneは、RKE2のバージョンと、クラスターのブートストラップ中に必要な追加設定を定義します。

  • Metal3MachineTemplateは、BareMetalHostリソースに適用されるOSイメージを定義し、hostSelectorは使用するBareMetalHostを定義します。

  • Metal3DataTemplateは、BareMetalHostに渡される追加のmetaDataを定義します(注:networkDataは現在Edgeソリューションではサポートされていません)。

注記
注記

簡潔にするため、この例ではBareMetalHostがIPアドレス`192.168.125.200`で設定されているシングルノードのコントロールプレーンを想定しています。より高度なマルチノードの例については、パートVII「完全自動化されたダイレクトネットワークプロビジョニング」を参照してください。

apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
  name: sample-cluster
  namespace: default
  labels:
    cluster-api.cattle.io/rancher-auto-import: "true"
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
    services:
      cidrBlocks:
        - 10.96.0.0/12
  controlPlaneRef:
    apiGroup: controlplane.cluster.x-k8s.io
    kind: RKE2ControlPlane
    name: sample-cluster
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3Cluster
    name: sample-cluster
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3Cluster
metadata:
  name: sample-cluster
  namespace: default
spec:
  controlPlaneEndpoint:
    host: 192.168.125.200
    port: 6443
  cloudProviderEnabled: false
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: sample-cluster
  namespace: default
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: sample-cluster-controlplane
  replicas: 1
  version: v1.36.3+rke2r1
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  agentConfig:
    format: ignition
    kubelet:
      extraArgs:
      - provider-id=metal3://PROVIDERID
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
          - name: rke2-preinstall.service
            enabled: true
            contents: |
              [Unit]
              Description=rke2-preinstall
              Wants=network-online.target
              Before=rke2-install.service
              ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
              [Service]
              Type=oneshot
              User=root
              ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
              # Note we use _ as a delimiter for sed here because the providerid includes / characters
              ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStartPost=/bin/sh -c "umount /mnt"
              [Install]
              WantedBy=multi-user.target
        storage:
          directories:
          - path: /var/lib/rancher/rke2/server/manifests
            overwrite: true
          files:
          - path: /var/lib/rancher/rke2/server/manifests/rke2-traefik-config.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: helm.cattle.io/v1
                kind: HelmChartConfig
                metadata:
                  name: rke2-traefik
                  namespace: kube-system
                spec:
                  valuesContent: |-
                    ingressClass:
                      isDefaultClass: true
                    ports:
                      web:
                        hostPort: null    # disallow hostPort
                        exposedPort: 80
                      websecure:
                        hostPort: null    # disallow hostPort
                        exposedPort: 443
                    service:
                      enabled: true
                      spec:
                        type: LoadBalancer
                        externalTrafficPolicy: Local
                        allocateLoadBalancerNodePorts: false
            mode: 0644
            user:
              name: root
            group:
              name: root
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3MachineTemplate
metadata:
  name: sample-cluster-controlplane
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: sample-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/SLE-Micro-eib-output.raw.sha256
        checksumType: sha256
        diskFormat: raw
        url: http://imagecache.local:8080/SLE-Micro-eib-output.raw
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3DataTemplate
metadata:
  name: sample-cluster-controlplane-template
  namespace: default
spec:
  clusterName: sample-cluster
  metaData:
    objectNames:
    - key: name
      object: machine
    - key: local-hostname
      object: machine
    - key: local_hostname
      object: machine
注記
注記

`cluster.x-k8s.io`オブジェクトにラベル`cluster-api.cattle.io/rancher-auto-import: "true"`を追加すると、クラスターがRancherにインポートされます(対応する`clusters.management.cattle.io`オブジェクトが作成されます)。 詳細については、 Cluster APIドキュメントを参照してください。

環境に合わせて調整した後、`kubectl`を使用して例を適用し、`clusterctl`を使用してクラスターの状態を監視できます。

% kubectl apply -f rke2-control-plane.yaml

# Wait for the cluster to be provisioned
% clusterctl describe cluster sample-cluster
NAME                                                    READY  SEVERITY  REASON  SINCE  MESSAGE
Cluster/sample-cluster                                  True                     22m
├─ClusterInfrastructure - Metal3Cluster/sample-cluster  True                     27m
├─ControlPlane - RKE2ControlPlane/sample-cluster        True                     22m
│ └─Machine/sample-cluster-chflc                        True                     23m

4.4.8 ワーカー/コンピュートのデプロイメント

コントロールプレーンのデプロイメントと同様に、以下のリソースを含むYAMLマニフェストを定義します。

  • MachineDeploymentは、レプリカ(ホスト)の数とブートストラップ/インフラストラクチャプロバイダー(この場合はRKE2/Metal3)を定義します。

  • RKE2ConfigTemplateは、エージェントホストの起動のためのRKE2バージョンと初回起動時の設定を記述します。

  • Metal3MachineTemplateは、BareMetalHostリソースに適用されるOSイメージを定義し、ホストセレクターは使用するBareMetalHostを定義します。

  • Metal3DataTemplateは、BareMetalHostに渡される追加のメタデータを定義します(`networkData`は現在サポートされていないことに注意してください)。

apiVersion: cluster.x-k8s.io/v1beta2
kind: MachineDeployment
metadata:
  labels:
    cluster.x-k8s.io/cluster-name: sample-cluster
  name: sample-cluster
  namespace: default
spec:
  clusterName: sample-cluster
  replicas: 1
  selector:
    matchLabels:
      cluster.x-k8s.io/cluster-name: sample-cluster
  template:
    metadata:
      labels:
        cluster.x-k8s.io/cluster-name: sample-cluster
    spec:
      bootstrap:
        configRef:
          apiGroup: bootstrap.cluster.x-k8s.io
          kind: RKE2ConfigTemplate
          name: sample-cluster-workers
      clusterName: sample-cluster
      infrastructureRef:
        apiGroup: infrastructure.cluster.x-k8s.io
        kind: Metal3MachineTemplate
        name: sample-cluster-workers
      deletion:
        nodeDrainTimeoutSeconds: 0
      version: v1.36.3+rke2r1
---
apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
kind: RKE2ConfigTemplate
metadata:
  name: sample-cluster-workers
  namespace: default
spec:
  template:
    spec:
      agentConfig:
        format: ignition
        version: v1.36.3+rke2r1
        kubelet:
          extraArgs:
          - provider-id=metal3://PROVIDERID
        additionalUserData:
          config: |
            variant: fcos
            version: 1.4.0
            systemd:
              units:
              - name: rke2-preinstall.service
                enabled: true
                contents: |
                  [Unit]
                  Description=rke2-preinstall
                  Wants=network-online.target
                  Before=rke2-install.service
                  ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                  [Service]
                  Type=oneshot
                  User=root
                  ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                  # Note we use _ as a delimiter for sed here because the providerid includes / characters
                  ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                  ExecStartPost=/bin/sh -c "umount /mnt"
                  [Install]
                  WantedBy=multi-user.target
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3MachineTemplate
metadata:
  name: sample-cluster-workers
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: sample-cluster-workers-template
      hostSelector:
        matchLabels:
          cluster-role: worker
      image:
        checksum: http://imagecache.local:8080/SLE-Micro-eib-output.raw.sha256
        checksumType: sha256
        diskFormat: raw
        url: http://imagecache.local:8080/SLE-Micro-eib-output.raw
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3DataTemplate
metadata:
  name: sample-cluster-workers-template
  namespace: default
spec:
  clusterName: sample-cluster
  metaData:
    objectNames:
    - key: name
      object: machine
    - key: local-hostname
      object: machine
    - key: local_hostname
      object: machine

上記の例をコピーして環境に合わせて調整したら、`kubectl`を使用して適用できます。その後、`clusterctl`でクラスターの状態を監視できます。

% kubectl apply -f rke2-agent.yaml

# Wait for the worker nodes to be provisioned
% clusterctl describe cluster sample-cluster
NAME                                                    READY  SEVERITY  REASON  SINCE  MESSAGE
Cluster/sample-cluster                                  True                     25m
├─ClusterInfrastructure - Metal3Cluster/sample-cluster  True                     30m
├─ControlPlane - RKE2ControlPlane/sample-cluster        True                     25m
│ └─Machine/sample-cluster-chflc                        True                     27m
└─Workers
  └─MachineDeployment/sample-cluster                    True                     22m
    └─Machine/sample-cluster-56df5b4499-zfljj           True                     23m

4.4.9 クラスターのデプロビジョニング

ダウンストリームクラスターは、上記の作成手順で適用されたリソースを削除することでデプロビジョニングできます。

% kubectl delete -f rke2-agent.yaml
% kubectl delete -f rke2-control-plane.yaml

これによりBareMetalHostリソースのデプロビジョニングがトリガーされます。これには数分かかる場合があり、その後、リソースは再び利用可能な状態になるはずです。

% kubectl get bmh
NAME             STATE            CONSUMER                            ONLINE   ERROR   AGE
controlplane-0   deprovisioning   sample-cluster-controlplane-vlrt6   false            10m
worker-0         deprovisioning   sample-cluster-workers-785x5        false            10m

...

% kubectl get bmh
NAME             STATE       CONSUMER   ONLINE   ERROR   AGE
controlplane-0   available              false            15m
worker-0         available              false            15m

4.5 当バージョンの注意事項

  • アップストリームの IP Address Management controllerは、SLEMicroにおけるネットワーク構成ツールおよび初回起動ツールチェーンの選択とまだ互換性がないため、現在サポートされていません。

  • 関連して、IPAMリソースおよびMetal3DataTemplateのnetworkDataフィールドは現在サポートされていません。

  • 現在、redfish-virtualmedia経由のデプロイメントのみがサポートされています。

4.6 計画されている変更

  • IPAMリソースのサポートとnetworkDataフィールドによる設定を有効にする

4.7 その他のリソース

SUSE Telco Cloud Management Cluster Documentation (パートV「管理クラスタのセットアップ」)には、通信事業者向けユースケースにおけるMetal3のより高度な使用例が記載されています。

4.7.1 シングルノードの設定

管理クラスターがシングルノードであるテスト/PoC環境では、MetalLBで管理される追加のフローティングIPの要件を回避することが可能です。

このモードでは、管理クラスターAPIのエンドポイントは管理クラスターのIPとなるため、DHCPを使用する場合は予約しておくか、管理クラスターのIPが変更されないように静的に構成する必要があります。以下ではこれを`<MANAGEMENT_CLUSTER_IP>`と呼びます。

このシナリオを有効にするために必要なMetal3チャートの値は以下の通りです。

global:
  ironicIP: <MANAGEMENT_CLUSTER_IP>
metal3-ironic:
  service:
    type: NodePort

4.7.2 virtualmedia ISOアタッチメントのTLS無効化

一部のサーバーベンダーは、BMCに仮想メディアISOイメージをアタッチする際にSSL接続を検証します。Metal3デプロイメント用に生成された証明書は自己署名されているため、これが問題を引き起こす可能性があります。この問題を回避するために、Metal3チャートの値を使用して、仮想メディアディスクのアタッチメントに対してのみTLSを無効にすることが可能です。設定は以下の通りです。

global:
  enable_vmedia_tls: false

代替案としては、CA証明書でBMCを構成することです。この場合、`kubectl`を使用してクラスターから証明書を読み取ることができます。

kubectl get secret -n metal3-system ironic-vmedia-cert -o yaml

その後、サーバーのBMCコンソールで証明書を構成できますが、その手順はベンダーによって異なり、すべてのベンダーで可能とは限りません。その場合は`enable_vmedia_tls`フラグが必要になることがあります。

4.7.3 ストレージの設定

管理クラスターがシングルノードであるテスト/PoC環境では永続ストレージは不要ですが、本番環境のユースケースでは、ポッドの再起動/再スケジュール時にMetal3に関連するイメージを永続化できるよう、管理クラスターにSUSE Storage(Longhorn)をインストールすることが推奨されます。

この永続ストレージを有効にするために必要なMetal3チャートの値は以下の通りです。

metal3-ironic:
  persistence:
    ironic:
      size: "5Gi"

永続ストレージを備えた管理クラスターの構成方法の詳細については、SUSE Telco Cloud Management Cluster Documentation (パートV「管理クラスタのセットアップ」)を参照してください。

5 Edge Image Builderを使用したスタンドアロンクラスター

Edge Image Builder (EIB) は、完全にエアギャップされたシナリオであっても、マシンの起動用にカスタマイズされた起動可能な (CRB) ディスクイメージを生成するプロセスを効率化するツールです。EIBは、SUSE Telco Cloudの3つのデプロイメントフットプリントすべてで使用するデプロイメントイメージを作成するために使用されます。ユーザーの追加やタイムゾーンの設定といった最小限のカスタマイズから、複雑なネットワーク構成の設定、マルチノードKubernetesクラスターのデプロイメント、顧客ワークロードのデプロイメント、Rancher/ElementalおよびSUSE Multi-Linux Managerを介した集中管理プラットフォームへの登録など、包括的に構成されたイメージの提供まで、柔軟に対応できます。EIBはコンテナイメージ内で実行されるため、プラットフォーム間で非常に移植性が高く、必要なすべての依存関係が自己完結しているため、ツールを操作するために使用されるシステムのインストール済みパッケージへの影響を最小限に抑えることができます。

注記
注記

マルチノードシナリオの場合、EIBはMetalLBとEndpoint Copier Operatorを自動的にデプロイし、同じビルド済みイメージを使用してプロビジョニングされたホストが自動的にKubernetesクラスターに参加できるようにします。

詳細については、Edge Image Builderの概要 (第12章 「Edge Image Builder」)をお読みください。

警告
警告

Edge Image Builder 1.3.4は、SUSE Linux Micro 6.2イメージのカスタマイズをサポートしています。 SUSE Linux Enterprise Micro 5.5や6.0などの古いバージョンはサポートされていません。

5.1 前提条件

注記
注記

非本番環境の目的であれば、openSUSE Leap 15.6またはopenSUSE Tumbleweedをビルドホストマシンとして使用できます。 互換性のあるコンテナランタイムが利用可能であれば、他のオペレーティングシステムでも機能する可能性があります。

5.1.1 EIBイメージの取得

EIBコンテナイメージは公開されており、イメージビルドホストで以下のコマンドを実行することで、SUSE Telco Cloudレジストリからダウンロードできます。

podman pull registry.suse.com/edge/3.7/edge-image-builder:1.3.4

5.2 イメージ設定ディレクトリの作成

EIBはコンテナ内で実行されるため、ホストから設定ディレクトリをマウントする必要があります。これにより、目的の設定を指定できるようになり、ビルドプロセス中にEIBが必要な入力ファイルやサポートアーティファクトにアクセスできるようになります。このディレクトリは特定の構造に従う必要があります。このディレクトリがホームディレクトリに存在し、「eib」という名前であると想定して作成しましょう。

export CONFIG_DIR=$HOME/eib
mkdir -p $CONFIG_DIR/base-images

前のステップで、SUSE Linux Micro 6.2入力イメージをホストする「base-images」ディレクトリを作成しました。イメージが設定ディレクトリにコピーされていることを確認しましょう。

cp /path/to/SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso $CONFIG_DIR/base-images/slemicro.iso
注記
注記

EIBの実行中、元のベースイメージは*変更されません*。EIB設定ディレクトリのルートに、目的の設定が適用された新しいカスタマイズ済みバージョンが作成されます。

この時点での設定ディレクトリは、以下のようになっているはずです。

└── base-images/
    └── slemicro.iso

5.3 イメージ定義ファイルの作成

定義ファイルには、Edge Image Builderがサポートする構成可能なオプションの大部分が記述されています。オプションの完全な例はhttps://github.com/suse-edge/edge-image-builder/blob/release-1.3/pkg/image/testdata/full-valid-example.yaml[こちら]で確認できます。また、以下で説明するものよりも包括的な例については、https://github.com/suse-edge/edge-image-builder/blob/release-1.3/docs/building-images.md[アップストリームのイメージ構築ガイド]を参照することをお勧めします。OSイメージ用の非常に基本的な定義ファイルから始めましょう。

cat << EOF > $CONFIG_DIR/iso-definition.yaml
apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
EOF

この定義は、AMD64/Intel 64ベースのシステムの出力イメージを生成することを指定しています。さらなる変更のベースとして使用されるイメージは、iso`イメージで、名前は`slemicro.iso、$CONFIG_DIR/base-images/slemicro.iso`に配置されていることが想定されています。また、EIBによるイメージの変更完了後、出力イメージには`eib-image.iso`という名前が付けられ、デフォルトでは$CONFIG_DIR`に配置されることも示されています。

これで、ディレクトリ構造は以下のようになっているはずです。

├── iso-definition.yaml
└── base-images/
    └── slemicro.iso

以下のセクションでは、一般的な操作の例をいくつか説明します。

5.3.1 オペレーティングシステム(OS)の設定

EIBの`operatingSystem`セクションは、オペレーティングシステムのインストール先やイメージサイズなどを設定するためのものです。 これはオプションのセクションであり、1つ以上のカスタマイズを適用する場合を除き、含める必要はありません。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-Base-RT-SelfInstall.iso
operatingSystem:
  isoConfiguration:
    installDevice: /dev/disk/by-id/ata-QEMU_HARDDISK_111-disk1 # first defined disk

タイプ固有の設定. カスタマイズするイメージのタイプに応じて、以下のオプションセクションのいずれかを含めることができます。

  • isoConfiguration - オプション。このセクションの設定はISOイメージにのみ適用されます。

  • installDevice - オプション。インストールデバイスとして使用するディスクを指定します。これはブロックデバイスである必要があり、デフォルトではディスク上のデータは自動的に消去されます。 さらに、この属性を指定するとGRUBオーバーライドがトリガーされ、ユーザーにインストール開始を促すことなくオペレーティングシステムが自動的にインストールされるため、完全に無人で自動化されたインストールが可能になります。省略した場合、ユーザーはGRUBメニューから「Install」オプションを選択する必要があり、さらにインストールディスクの選択や、その過程でデバイスが消去されることの確認も求められます。

    注記
    注記

    installDevice`セクションで使用されるデバイスは、/dev/sda`として指定するか、/dev/disk/by-id、/dev/disk/by-path`という命名規則を使用して、適切なデバイスが使用されていることを確認できます。 libvirt VMを使用している場合、VMのディスクを作成する際に`serial`属性値を指定できます(例:`serial=111-disk1)。これにより、installDevice`値で`by-id`という命名規則(例:/dev/disk/by-id/ata-QEMU_HARDDISK_111-disk1`)を使用して使用できるようになります(ATAデバイスを使用している場合、`libvirt`は自動的にIDの先頭に`ata-QEMU_HARDDISK_`を付加します。virtioデバイスの場合は`virtio-`を付加します。詳細については、 #17670 virtio issueを参照してください)。

  • rawConfiguration - オプション。このセクションの設定は、RAWイメージにのみ適用されます。

  • diskSize - オプション。EIBが最終的なイメージをリサイズする際に設定する、希望するRAWディスクイメージサイズを指定します。これは、ディスクイメージが、イメージに埋め込まれるあらゆるアーティファクトを収容できる十分な大きさであることを確認するために重要です。システムが起動時に自動的に拡張されてブロックデバイスのサイズを満たすため、SDカードのサイズ(直接ディスクに書き込む場合はブロックデバイスのサイズ)よりわずかに小さく設定することをお勧めします。これはオプションですが、強く推奨されます。「M」(メガバイト)、「G」(ギガバイト)、または「T」(テラバイト)をサフィックスとして付けた整数で指定します(例:「32G」)。

  • luksKey - 暗号化されたイメージには必須です。暗号化されたRAWイメージに対して指定されたLUKSキーは、EIBがビルドプロセスを完了するために必要です。

  • expandEncryptedPartition - オプション。デフォルトでは無効になっています。有効にすると、暗号化されたパーティションが自動的に最大サイズまで拡張されます。例:`diskSize`が`25G`で、このフィールドが`true`の場合、EIBはビルドプロセス中に暗号化されたパーティションを`25G`まで拡張します。

5.3.2 OSユーザーの設定

EIBでは、パスワードやSSHキーなどのログイン情報を持つユーザーを事前に設定でき、固定のrootパスワードを設定することも可能です。この例の一部としてrootパスワードを固定します。最初のステップは、`OpenSSL`を使用して一方向暗号化されたパスワードを作成することです。

openssl passwd -6 SecurePassword

これにより、以下のような出力が得られます。

$6$G392FCbxVgn[...]Y7zTXnC1

次に、定義ファイルに`operatingSystem`というセクションを追加し、その中に`users`配列を含めることができます。結果として得られるファイルは、以下のようになります。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$G392FCbxVgn[...]Y7zTXnC1
注記
注記

さらにユーザーを追加したり、ホームディレクトリを作成したり、ユーザーIDを設定したり、SSHキー認証を追加したり、グループ情報を変更したりすることも可能です。その他の例については、https://github.com/suse-edge/edge-image-builder/blob/release-1.3/docs/building-images.md[アップストリームのイメージ構築ガイド]を参照してください。

5.3.3 OS時刻の設定

time`セクションはオプションですが、証明書やクロックスキューに関する潜在的な問題を回避するために設定することを強く推奨します。EIBは、ここでのパラメータに応じてchronydおよび/etc/localtime`を設定します。

operatingSystem:
  time:
    timezone: Europe/London
    ntp:
      forceWait: true
      pools:
        - 2.suse.pool.ntp.org
      servers:
        - 10.0.0.1
        - 10.0.0.2
  • `timezone`は、「地域/場所」(例:「Europe/London」)の形式でタイムゾーンを指定します。完全なリストは、Linuxシステムで`timedatectl list-timezones`を実行することで確認できます。

  • ntp - NTPの設定に関連する属性を定義します(chronydを使用):

  • forceWait - 他のサービスを開始する前に、chronydがタイムソースの同期を試みるよう要求します(タイムアウトは180秒)。

  • pools - chronydがデータソースとして使用するプールのリストを指定します(`iburst`を使用して初期同期にかかる時間を短縮します)。

  • servers - chronydがデータソースとして使用するサーバーのリストを指定します(`iburst`を使用して初期同期にかかる時間を短縮します)。

注記
注記

この例で提供されている値は、説明のみを目的としています。お客様の特定の要件に合わせて調整してください。

5.3.4 証明書の追加

`certificates`ディレクトリに保存されている拡張子が「.pem」または「.crt」の証明書ファイルは、ノードのシステム全体の証明書ストアにインストールされます。

.
├── definition.yaml
└── certificates
    ├── my-ca.pem
    └── my-ca.crt

詳細については、 「TLS証明書による通信の保護」ガイドを参照してください。

5.3.5 オペレーティングシステムファイルの追加

イメージ構成ディレクトリの`os-files`ディレクトリに配置されたファイルは、ビルドされたイメージのファイルシステムに自動的にコピーされます。 コピーされる際、正確なディレクトリが保持されます。 例えば、ファイルが`os-files/etc`という名前のサブディレクトリに存在する場合、そのファイルはビルドされたイメージの`/etc`ディレクトリに配置されます。

注記
注記

`os-files`ディレクトリが存在する場合、空であってはなりません。

.
├── definition.yaml
└── os-files
    └── etc
        └── ssh
            └── sshd_config

5.3.6 RPMパッケージの設定

EIBの主な機能の1つは、イメージに追加のソフトウェアパッケージを追加するメカニズムを提供することです。これにより、インストール完了時にシステムがインストールされたパッケージをすぐに活用できるようになります。EIBでは、ユーザーは以下を指定できます。

  • イメージ定義内のリストによるパッケージ名での指定

  • これらのパッケージを検索するネットワークリポジトリ

  • リストされたパッケージを公式のSUSEリポジトリから検索するためのSUSE Customer Center (SCC) 認証情報

  • `$CONFIG_DIR/rpms`ディレクトリを介した、ネットワークリポジトリに存在しないカスタムRPMのサイドロード

  • 同じディレクトリ($CONFIG_DIR/rpms/gpg-keys)を介した、サードパーティパッケージの検証を有効にするためのGPGキー

EIBは、イメージビルド時にパッケージ解決処理を実行します。ベースイメージを入力として受け取り、リストで指定されたか、ローカルで提供されたすべてのパッケージの取得とインストールを試みます。EIBは、すべてのパッケージを依存関係を含めて出力イメージ内のリポジトリにダウンロードし、最初の起動プロセス中にこれらをインストールするようにシステムに指示します。このプロセスをイメージビルド中に実行することで、エッジノードなどの目的のプラットフォームで、初回起動時にパッケージが確実にインストールされるようになります。これは、運用中にネットワーク経由でパッケージを取得するのではなく、追加パッケージをイメージに組み込んでおきたい環境(エアギャップ環境やネットワークが制限された環境など)でも有利です。

これを実証する簡単な例として、サードパーティのベンダーがサポートするNVIDIAリポジトリにある`nvidia-container-toolkit` RPMパッケージをインストールします。

  packages:
    packageList:
      - nvidia-container-toolkit
    additionalRepos:
      - url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64

結果として得られる定義ファイルは次のようになります。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$G392FCbxVgn[...]Y7zTXnC1
  packages:
    packageList:
      - nvidia-container-toolkit
    additionalRepos:
      - url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64

上記は簡単な例ですが、念のため、イメージ生成を実行する前にNVIDIAパッケージ署名キーをダウンロードしてください。

$ mkdir -p $CONFIG_DIR/rpms/gpg-keys
$ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey > $CONFIG_DIR/rpms/gpg-keys/nvidia.gpg
警告
警告

この方法でRPMを追加することは、サポートされているサードパーティ製コンポーネントや、ユーザーが提供(および保守)するパッケージを追加することを目的としています。このメカニズムは、通常SUSE Linux Microでサポートされないパッケージの追加には使用しないでください。このメカニズムを使用して(サポートされていない)openSUSEリポジトリからコンポーネントを追加した場合(新しいリリースやサービスパックからのものを含む)、依存関係の解決によってオペレーティングシステムのコア部分が置き換えられ、結果としてシステムが期待通りに動作しているように見えても、サポート対象外の構成になる可能性があります。不明な点がある場合は、SUSEの担当者に連絡し、希望する構成がサポート可能かどうかを確認してください。

注記
注記

追加の例を含むより包括的なガイドは、https://github.com/suse-edge/edge-image-builder/blob/release-1.3/docs/installing-packages.md[アップストリームのパッケージインストールガイド]にあります。

5.3.7 Kubernetesクラスターとユーザーワークロードの設定

EIBのもう一つの特徴は、単一ノードおよびマルチノードの高可用性Kubernetesクラスターのデプロイを自動化するために使用できることです。これらは「インプレースで起動」されます(つまり、調整のための集中管理インフラストラクチャを一切必要としません)。このアプローチの主な目的は、エアギャップ環境やネットワーク制限のある環境でのデプロイですが、完全かつ無制限のネットワークアクセスが利用可能な場合でも、スタンドアロンクラスターを迅速に起動する方法としても機能します。

この方法により、カスタマイズされたオペレーティングシステムのデプロイだけでなく、Kubernetes構成、Helmチャートを介した追加のレイヤーコンポーネント、および提供されたKubernetesマニフェストを介したユーザーワークロードを指定することも可能になります。ただし、この方法を使用する背後にある設計原則は、ユーザーがエアギャップを望んでいるとデフォルトで想定することです。したがって、イメージ定義で指定されたすべてのアイテムはイメージ内に取り込まれ、これにはユーザーが提供したワークロードも含まれます。EIBは、定義によって必要とされる検出されたイメージがローカルにコピーされ、結果としてデプロイされたシステム内の組み込みイメージレジストリによって提供されることを保証します。

次の例では、既存のイメージ定義を使用してKubernetes構成を指定します(この例ではシステムとその役割がリストされていないため、デフォルトで単一ノードと想定します)。これにより、EIBは単一ノードのRKE2 Kubernetesクラスターをプロビジョニングするように指示されます。ユーザーが提供したワークロード(マニフェスト経由)とレイヤーコンポーネント(Helm経由)の両方のデプロイの自動化を示すために、SUSE Telco Cloud Helmチャートを介してKubeVirtをインストールし、Kubernetesマニフェストを介してNGINXをインストールします。既存のイメージ定義に追加する必要がある追加の構成は次のとおりです。

kubernetes:
  version: v1.36.3+rke2r1
  manifests:
    urls:
      - https://k8s.io/examples/application/nginx-app.yaml
  helm:
    charts:
      - name: kubevirt
        version: 307.0.3+up0.8.0
        repositoryName: suse-edge
    repositories:
      - name: suse-edge
        url: oci://registry.suse.com/edge/charts

結果として得られる完全な定義ファイルは、次のようになります。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$G392FCbxVgn[...]Y7zTXnC1
  packages:
    packageList:
      - nvidia-container-toolkit
    additionalRepos:
      - url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
kubernetes:
  version: v1.36.3+k3s1
  manifests:
    urls:
      - https://k8s.io/examples/application/nginx-app.yaml
  helm:
    charts:
      - name: kubevirt
        version: 307.0.3+up0.8.0
        repositoryName: suse-edge
    repositories:
      - name: suse-edge
        url: oci://registry.suse.com/edge/charts
注記
注記

マルチノードデプロイメント、カスタムネットワーク、Helmチャートのオプション/値などのその他の例については、https://github.com/suse-edge/edge-image-builder/blob/release-1.3/docs/building-images.md[アップストリームドキュメント]を参照してください。

5.3.8 ネットワークの設定

このクイックスタートの最後の例では、EIBによって生成されたイメージでシステムがプロビジョニングされる際に立ち上がるネットワークを設定してみましょう。ネットワーク設定が提供されない限り、デフォルトのモデルでは、起動時に検出されたすべてのインターフェースでDHCPが使用されることを理解しておくことが重要です。しかし、これは必ずしも望ましい設定とは限りません。特にDHCPが利用できず、静的設定を提供する必要がある場合や、ボンド、LACP、VLANなどのより複雑なネットワーク設定を行う必要がある場合、あるいはホスト名、DNSサーバー、ルートなどの特定のパラメータを上書きする必要がある場合には特にそうです。

EIBは、対象システムがMACアドレスにより一意に識別される場合にノードごとに設定を適用するか、すべてのマシンに同一の設定を上書き適用するオプションを提供します。これは、システムのMACアドレスが不明な場合に特に有用です。EIBは、Network Manager Configurator(略して`nmc`)という追加ツールを使用します。これはSUSE Telco Cloudチームによって構築されたツールで、 nmstate.io宣言型ネットワークスキーマに基づいてカスタムネットワーク設定を適用できるようにするものです。起動時に、起動中のノードを識別し、サービスが立ち上がる前に目的のネットワーク設定を適用します。

次に、必要な`network`ディレクトリ内のノード固有のファイル(目的のホスト名に基づく)に目的のネットワーク状態を記述することで、単一インターフェースを持つシステムの静的ネットワーク設定を適用します。

mkdir $CONFIG_DIR/network

cat << EOF > $CONFIG_DIR/network/host1.local.yaml
routes:
  config:
  - destination: 0.0.0.0/0
    metric: 100
    next-hop-address: 192.168.122.1
    next-hop-interface: eth0
    table-id: 254
  - destination: 192.168.122.0/24
    metric: 100
    next-hop-address: 192.168.122.1
    next-hop-interface: eth0
    table-id: 254
dns-resolver:
  config:
    server:
    - 192.168.122.1
    - 8.8.8.8
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: 34:8A:B1:4B:16:E7
  ipv4:
    address:
    - ip: 192.168.122.50
      prefix-length: 24
    dhcp: false
    enabled: true
  ipv6:
    enabled: false
EOF
警告
警告

上記の例は、仮想マシン上でテストが実行されていることを前提として、デフォルトの`192.168.122.0/24`サブネット用に設定されています。MACアドレスを忘れないように、環境に合わせて調整してください。同じイメージを使用して複数のノードをプロビジョニングできるため、EIB(`nmc`経由)によって構成されるネットワークは、MACアドレスによってノードを一意に識別できるかどうかに依存します。そのため、起動中に`nmc`が各マシンに正しいネットワーク設定を適用します。つまり、インストール先のシステムのMACアドレスを知っておく必要があるということです。あるいは、デフォルトの動作はDHCPに依存することですが、`configure-network.sh`フックを利用してすべてのノードに共通の設定を適用することもできます。詳細については、ネットワークガイド (第13章 「エッジネットワーキング」)を参照してください。

結果として得られるファイル構造は次のようになります:

├── iso-definition.yaml
├── base-images/
│   └── slemicro.iso
└── network/
    └── host1.local.yaml

作成したネットワーク設定が解析され、必要なNetworkManager接続ファイルが自動的に生成されて、EIBによって作成される新しいインストールイメージに挿入されます。これらのファイルはホストのプロビジョニング中に適用され、完全なネットワーク設定が適用されます。

注記
注記

上記の設定に関するより包括的な説明とこの機能の例については、エッジネットワーキングコンポーネント (第13章 「エッジネットワーキング」)を参照してください。

5.4 イメージのビルド

ベースイメージとEIBが使用するイメージ定義が準備できたので、イメージをビルドしましょう。これには、単に`podman`を使用して「build」コマンドでEIBコンテナを呼び出し、定義ファイルを指定します:

podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
build --definition-file iso-definition.yaml

コマンドの出力は次のようになります:

Setting up Podman API listener...
Downloading file: dl-manifest-1.yaml 100% (498/498 B, 9.5 MB/s)
Pulling selected Helm charts... 100% (1/1, 43 it/min)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Resolving package dependencies...
Rpm .......................... [SUCCESS]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% (3/3, 10 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Downloading file: rke2-images-core.linux-amd64.tar.zst 100% (657/657 MB, 48 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% (368/368 MB, 48 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% (35/35 MB, 50 MB/s)
Downloading file: sha256sum-amd64.txt 100% (4.3/4.3 kB, 6.2 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

ビルドされたISOイメージは`$CONFIG_DIR/eib-image.iso`に保存されます:

├── iso-definition.yaml
├── eib-image.iso
├── _build
│   └── cache/
│       └── ...
│   └── build-<timestamp>/
│       └── ...
├── base-images/
│   └── slemicro.iso
└── network/
    └── host1.local.yaml

各ビルドは、`$CONFIG_DIR/_build/`内にタイムスタンプ付きのフォルダーを作成します。これには、ビルドのログ、ビルド中に使用されたアーティファクト、およびCRBイメージに追加されるすべてのスクリプトとアーティファクトを含む`combustion`ディレクトリと`artefacts`ディレクトリが含まれます。

このディレクトリの内容は次のようになります:

├── build-<timestamp>/
│   │── combustion/
│   │   ├── 05-configure-network.sh
│   │   ├── 10-rpm-install.sh
│   │   ├── 12-keymap-setup.sh
│   │   ├── 13b-add-users.sh
│   │   ├── 20-k8s-install.sh
│   │   ├── 26-embedded-registry.sh
│   │   ├── 48-message.sh
│   │   ├── network/
│   │   │   ├── host1.local/
│   │   │   │   └── eth0.nmconnection
│   │   │   └── host_config.yaml
│   │   ├── nmc
│   │   └── script
│   │── artefacts/
│   │   │── registry/
│   │   │   ├── hauler
│   │   │   ├── nginx:<version>-registry.tar.zst
│   │   │   ├── rancher_kubectl:<version>-registry.tar.zst
│   │   │   └── registry.suse.com_suse_sles_15.6_virt-operator:<version>-registry.tar.zst
│   │   │── rpms/
│   │   │   └── rpm-repo
│   │   │       ├── addrepo0
│   │   │       │   ├── nvidia-container-toolkit-<version>.rpm
│   │   │       │   ├── nvidia-container-toolkit-base-<version>.rpm
│   │   │       │   ├── libnvidia-container1-<version>.rpm
│   │   │       │   └── libnvidia-container-tools-<version>.rpm
│   │   │       ├── repodata
│   │   │       │   ├── ...
│   │   │       └── zypper-success
│   │   └── kubernetes/
│   │       ├── rke2_installer.sh
│   │       ├── registries.yaml
│   │       ├── server.yaml
│   │       ├── images/
│   │       │   ├── rke2-images-cilium.linux-amd64.tar.zst
│   │       │   └── rke2-images-core.linux-amd64.tar.zst
│   │       ├── install/
│   │       │   ├── rke2.linux-amd64.tar.gz
│   │       │   └── sha256sum-amd64.txt
│   │       └── manifests/
│   │           ├── dl-manifest-1.yaml
│   │           └── kubevirt.yaml
│   ├── createrepo.log
│   ├── eib-build.log
│   ├── embedded-registry.log
│   ├── helm
│   │   └── kubevirt
│   │       └── kubevirt-0.4.0.tgz
│   ├── helm-pull.log
│   ├── helm-template.log
│   ├── iso-build.log
│   ├── iso-build.sh
│   ├── iso-extract
│   │   └── ...
│   ├── iso-extract.log
│   ├── iso-extract.sh
│   ├── modify-raw-image.sh
│   ├── network-config.log
│   ├── podman-image-build.log
│   ├── podman-system-service.log
│   ├── prepare-resolver-base-tarball-image.log
│   ├── prepare-resolver-base-tarball-image.sh
│   ├── raw-build.log
│   ├── raw-extract
│   │   └── ...
│   └── resolver-image-build
│       └──...
└── cache
    └── ...

ビルドが失敗した場合、`eib-build.log`が情報を含む最初のログとなります。そこから、デバッグのために失敗したコンポーネントへと案内されます。

この時点で、すぐに使用できるイメージが用意できているはずです:

  1. SUSE Linux Micro 6.2をデプロイする

  2. ルートパスワードを設定する

  3. `nvidia-container-toolkit`パッケージをインストールする

  4. コンテンツをローカルで提供するように組み込みコンテナレジストリを設定する

  5. シングルノードのRKE2をインストールする

  6. 静的ネットワーク設定を行う

  7. KubeVirtをインストールします

  8. ユーザーが提供したマニフェストをデプロイします

5.5 イメージビルドプロセスのデバッグ

イメージビルドプロセスが失敗した場合は、https://github.com/suse-edge/edge-image-builder/blob/release-1.3/docs/debugging.md[アップストリームのデバッグガイド]を参照してください。

5.6 新しくビルドしたイメージのテスト

新しくビルドしたCRBイメージのテスト方法については、https://github.com/suse-edge/edge-image-builder/blob/release-1.3/docs/testing-guide.md[アップストリームのイメージテストガイド]を参照してください。

パート III コンポーネント

Edge用コンポーネントのリスト

6 Rancher

https://ranchermanager.docs.rancher.com/v2.15.のRancherドキュメントを参照してください

Rancherは、複数の環境にわたるKubernetesクラスタのデプロイ、運用、監視を効率化する、強力なオープンソースのKubernetes管理プラットフォームです。オンプレミス、クラウド、エッジのいずれでクラスタを管理する場合でも、RancherはすべてのKubernetesニーズに対応する統合された一元管理プラットフォームを提供します。

6.1 Rancherの主な機能

  • マルチクラスタ管理:Rancherの直感的なインターフェースにより、パブリッククラウド、プライベートデータセンター、エッジロケーションなど、どこからでもKubernetesクラスタを管理できます。

  • セキュリティとコンプライアンス:Rancherは、Kubernetes環境全体でセキュリティポリシー、ロールベースのアクセス制御(RBAC)、およびコンプライアンス基準を適用します。

  • クラスタ運用の簡素化:Rancherはクラスタのプロビジョニング、アップグレード、トラブルシューティングを自動化し、あらゆる規模のチームのKubernetes運用を簡素化します。

  • 一元化されたアプリケーションカタログ:Rancherのアプリケーションカタログは、多様なHelmチャートとKubernetes Operatorを提供し、コンテナ化されたアプリケーションのデプロイと管理を容易にします。

  • 継続的デリバリ:RancherはGitOpsとCI/CDパイプラインをサポートしており、自動化された効率的なアプリケーションデリバリープロセスを実現します。

6.2 SUSE Telco CloudにおけるRancherの利用

RancherはSUSE Telco Cloudスタックにいくつかのコア機能を提供します。

6.2.1 一元化されたKubernetes管理

多数の分散クラスタを伴う一般的なエッジデプロイメントにおいて、RancherはこれらのKubernetesクラスタを管理するための中心的なコントロールプレーンとして機能します。プロビジョニング、アップグレード、監視、トラブルシューティングのための統合インターフェースを提供し、運用を簡素化して一貫性を確保します。

6.2.2 クラスタ展開の簡素化

Rancherは、軽量なSUSE Linux Microオペレーティングシステム上でのKubernetesクラスタ作成を効率化し、堅牢なKubernetes機能によるエッジインフラストラクチャの展開を容易にします。

6.2.3 アプリケーションの展開と管理

統合されたRancherアプリケーションカタログにより、SUSE Telco Cloudクラスタ全体でのコンテナ化されたアプリケーションの展開と管理が簡素化され、エッジワークロードのシームレスな展開が可能になります。

6.2.4 セキュリティとポリシーの適用

Rancherは、ポリシーに基づくガバナンストール、ロールベースのアクセス制御(RBAC)、および外部認証プロバイダーとの統合を提供します。これは、分散環境において不可欠なSUSE Telco Cloudデプロイメントのセキュリティとコンプライアンスを維持するのに役立ちます。

6.3 ベストプラクティス

6.3.1 GitOps

RancherにはFleetがビルトインコンポーネントとして含まれており、Gitに保存されたコードを使用してクラスタ設定とアプリケーションのデプロイメントを管理できます。

6.3.2 監視

Rancherには、PrometheusやGrafanaなどの監視およびログ記録ツールが組み込まれており、クラスタの健全性とパフォーマンスを包括的に把握できます。

6.4 Edge Image Builderを使用したインストール

SUSE Telco Cloudは、SUSE Linux Micro OSのベースイメージをカスタマイズするために第12章 「Edge Image Builder」を使用しています。 EIBによってプロビジョニングされたKubernetesクラスタ上にRancherをエアギャップ(された)インストールするには、64.6項 「Rancherインストール」に従ってください。

6.5 その他の資料

7 Rancherダッシュボード拡張機能

拡張機能を使用すると、ユーザー、開発者、パートナー、および顧客はRancher UIを拡張および強化できます。SUSE Telco CloudはKubeVirtダッシュボード拡張機能を提供します。

Rancherダッシュボード拡張機能に関する一般的な情報については、`https://ranchermanager.docs.rancher.com/v2.15/integrations-in-rancher/rancher-extensions[Rancher documentation]`を参照してください。

7.1 インストール

ダッシュボード拡張機能を含むすべてのSUSE Telco Cloud 3.7コンポーネントは、OCIアーティファクトとして配布されます。SUSE Telco Cloud拡張機能をインストールするには、RancherダッシュボードUI、Helm、またはFleetを使用できます。

7.1.1 RancherダッシュボードUIを使用したインストール

  1. ナビゲーションサイドバーの*Configuration*セクションにある*Extensions*をクリックします。

  2. Extensionsページで、右上の縦3点リーダメニューをクリックし、*Manage Repositories*を選択します。

    各拡張機能は、独自のOCIアーティファクトを介して配布されます。これらはSUSE Telco Cloud Helmチャートリポジトリから入手できます。

  3. *Repositoriesページ*で、`Create`をクリックします。

  4. フォームでリポジトリ名とURLを指定し、`Create`をクリックします。

    SUSE Telco Cloud HelmチャートリポジトリURL: oci://registry.suse.com/edge/charts

    dashboard extensions create oci repository
  5. 拡張機能リポジトリがリストに追加され、`Active`状態になっていることが確認できます。

    dashboard extensions repositories list
  6. ナビゲーションサイドバーの*Configuration*セクションにある*Extensions*に戻ります。

    *Available*タブで、インストール可能な拡張機能を確認できます。

    dashboard extensions available extensions
  7. 拡張機能カードで`Install`をクリックし、インストールを確定します。

    拡張機能がインストールされると、Rancher UIは`https://ranchermanager.docs.rancher.com/v2.15/integrations-in-rancher/rancher-extensions#installing-extensions[]`で説明されているようにページをリロードするよう促します。

7.1.2 Helmを使用したインストール

# KubeVirt extension
helm install kubevirt-dashboard-extension oci://registry.suse.com/edge/charts/kubevirt-dashboard-extension --version 307.0.5+up1.4.2 --namespace cattle-ui-plugin-system
注記
注記

拡張機能は cattle-ui-plugin-system ネームスペースにインストールする必要があります。

注記
注記

拡張機能がインストールされた後、RancherダッシュボードUIをリロードする必要があります。

7.1.3 Fleetを使ったインストール

Fleetを使用してダッシュボード拡張機能をインストールするには、カスタム gitRepo バンドル設定ファイルを指す Git リポジトリを指定する fleet.yaml リソースを定義する必要があります。

# KubeVirt extension fleet.yaml
defaultNamespace: cattle-ui-plugin-system
helm:
  releaseName: kubevirt-dashboard-extension
  chart: oci://registry.suse.com/edge/charts/kubevirt-dashboard-extension
  version: "307.0.5+up1.4.2"
注記
注記

releaseName プロパティは必須であり、拡張機能が正しくインストールされるように拡張機能名と一致させる必要があります。

cat <<- EOF | kubectl apply -f -
apiVersion: fleet.cattle.io/v1alpha1
metadata:
  name: edge-dashboard-extensions
  namespace: fleet-local
spec:
  repo: https://github.com/suse-edge/fleet-examples.git
  branch: main
  paths:
  - fleets/kubevirt-dashboard-extension/
EOF

詳細については、第9章 「Fleet」 および fleet-examples リポジトリを参照してください。

拡張機能がインストールされると、Extensions セクションの Installed タブに一覧表示されます。これらはアプリ/Marketplace を介してインストールされるわけではないため、Third-Party ラベルが付けられます。

installed dashboard extensions

7.2 KubeVirt ダッシュボード拡張機能

KubeVirt 拡張機能は、RancherダッシュボードUIに基本的な仮想マシン管理機能を提供します。その機能については、19.7.2項 「KubeVirt Rancherダッシュボード拡張機能の使用」 で説明されています。

8 Rancher Turtles

Rancher Turtlesマニュアルは https://documentation.suse.com/cloudnative/cluster-api/を参照してください

Rancher Turtlesは、Rancher ManagerとCluster API (CAPI)の統合を提供するKubernetes Operatorで、RancherにCAPIのフルサポートをもたらすことを目的としています。

8.1 Rancher Turtlesの主な機能

  • CAPIでプロビジョニングされたクラスタにRancher Cluster Agentをインストールすることで、CAPIクラスタをRancherに自動的にインポートします。

  • CAPI Operatorを介して、CAPIコントローラの依存関係をインストールおよび構成します。

  • CAPIProvider APIを介して、インストール済みのCAPIプロバイダの依存関係を管理します。

8.2 SUSE Telco CloudでのRancher Turtlesの使用

SUSE Telco Cloudスタックは、rancher-turtles-providers Helmチャートを提供し、CAPIProvider APIを介して特定のCAPIプロバイダを有効にします。

  • RKE2コントロールプレーンおよびブートストラッププロバイダ

  • Metal3 (第11章 「Metal3」)インフラストラクチャプロバイダ

  • Metal3 (第11章 「Metal3」) IPAMプロバイダ(現在サポートされていません)

  • Fleetアドオンプロバイダ

ラッパーチャートを介してインストールされたデフォルトのプロバイダのみがサポートされています。代替のコントロールプレーン、ブートストラップ、およびインフラストラクチャプロバイダは、現在SUSE Telco Cloudスタックの一部としてはサポートされていません。

8.3 Rancher Turtlesのインストール

Rancher 2.13以降、RancherをインストールするとRancher Turtlesがデフォルトで有効になります。

Rancher Turtlesプロバイダは、Metal3クイックスタート (第4章 「Metal3によるBMC自動デプロイメント」)ガイド、または管理クラスタ (パートV「管理クラスタのセットアップ」)のマニュアルに従ってインストールできます。

8.4 その他の資料

9 Fleet

Fleetは、ユーザーがローカルクラスタをより詳細に制御し、GitOpsを通じて継続的に監視できるように設計された、コンテナ管理およびデプロイメントエンジンです。Fleetはスケーリング能力だけでなく、クラスターに何がインストールされているかを正確に監視するための高度な制御と可視性をユーザーに提供します。

Fleetは、生のKubernetes YAML、Helmチャート、Kustomize、またはこれら3つの任意の組み合わせのGitからのデプロイメントを管理できます。ソースに関係なく、すべてのリソースは動的にHelmチャートに変換され、Helmがクラスター内のすべてのリソースをデプロイするためのエンジンとして使用されます。その結果、ユーザーはクラスターの高度な制御、一貫性、および監査可能性を享受できます。

Fleetの仕組みの詳細については、 Fleet Architectureを参照してください。

9.1 Helmを使用したFleetのインストール

FleetはRancherに組み込まれていますが、Helmを使用して任意のKubernetesクラスター上にスタンドアロンアプリケーションとして インストールすることもできます。

9.2 RancherでのFleetの使用

RancherはFleetを使用して、管理対象クラスター全体にアプリケーションをデプロイします。Fleetによる継続的デリバリは、大規模なGitOpsを導入し、多数のクラスターで実行されるアプリケーションを管理するように設計されています。

FleetはRancherの統合コンポーネントとして優れた機能を発揮します。Rancherで管理されるクラスターには、インストール/インポートプロセスの一環としてFleetエージェントが自動的にデプロイされ、そのクラスターは直ちにFleetによる管理が可能になります。

9.3 Rancher UIでのFleetへのアクセス

FleetはRancherにプリインストールされており、Rancher UIの*Continuous Delivery*オプションによって管理されます。

fleet dashboard

継続的デリバリセクションは、以下の項目で構成されています。

9.3.1 ダッシュボード

すべてのワークスペースにわたるすべてのGitOpsリポジトリの概要ページ。リポジトリを持つワークスペースのみが表示されます。

9.3.2 Gitリポジトリ

選択したワークスペース内のGitOpsリポジトリのリストです。ページ上部のドロップダウンリストを使用して、アクティブなワークスペースを選択します。

9.3.3 クラスタ

管理対象クラスタのリストです。デフォルトでは、すべてのRancher管理対象クラスタが`fleet-default`ワークスペースに追加されます。fleet-local`ワークスペースには、ローカル(管理)クラスタが含まれます。ここから、クラスタの `Pause または Force update を実行するか、もしくはクラスタを別のワークスペースに移動することが可能です。クラスタを編集すると、クラスタのグループ化に使用されるラベルや注釈を更新できます。

9.3.4 クラスタグループ

このセクションでは、セレクタを使用してワークスペース内のクラスタをカスタムグループ化できます。

9.3.5 詳細

「詳細」セクションでは、ワークスペースやその他の関連するFleetリソースを管理できます。

9.4 Rancherダッシュボードを使用してRancherおよびFleetでKubeVirtをインストールする例

  1. `fleet.yaml`ファイルを含むGitリポジトリを作成します。

    defaultNamespace: kubevirt
    helm:
      chart: "oci://registry.suse.com/edge/charts/kubevirt"
      version: "307.0.3+up0.8.0"
      # kubevirt namespace is created by kubevirt as well, we need to take ownership of it
      takeOwnership: true
  2. Rancherダッシュボードで、*☰ > Continuous Delivery > Git Repos*に移動し、`Add Repository`をクリックします。

  3. リポジトリ作成ウィザードに従ってGitリポジトリを作成します。名前、リポジトリURL(前のステップで作成したGitリポジトリを参照)を入力し、適切なブランチまたはリビジョンを選択します。より複雑なリポジトリの場合は、*パス*を指定して、単一のリポジトリ内で複数のディレクトリを使用します。

    fleet create repo1
  4. `Next`をクリックします。

  5. 次のステップでは、ワークロードのデプロイ先を定義できます。クラスタの選択にはいくつかの基本的なオプションがあります。クラスタを選択しない、すべてのクラスタを選択する、または特定の管理対象クラスタやクラスタグループ(定義されている場合)を直接選択することができます。「詳細」オプションを使用すると、YAMLを介してセレクタを直接編集できます。

    fleet create repo2
  6. `Create`をクリックします。リポジトリが作成されます。これ以降、ワークロードはリポジトリ定義に一致するクラスタ上にインストールされ、同期が維持されます。

9.5 デバッグと問題解決

「詳細」ナビゲーションセクションでは、低レベルのFleetリソースの概要を提供します。 バンドルは、Gitからのリソースのオーケストレーションに使用される内部リソースです。Gitリポジトリがスキャンされると、1つ以上のバンドルが生成されます。

特定のリポジトリに関連するバンドルを見つけるには、Gitリポジトリの詳細ページに移動し、`Bundles`タブをクリックします。

fleet repo bundles

各クラスターについて、バンドルは作成されたBundleDeploymentリソースに適用されます。BundleDeploymentの詳細を表示するには、Gitリポジトリ詳細ページの右上にある`Graph`ボタンをクリックします。 *リポジトリ > バンドル > BundleDeployments*のグラフが読み込まれます。グラフ内のBundleDeploymentをクリックして詳細を確認し、`Id`をクリックしてBundleDeploymentのYAMLを表示します。

fleet repo graph

Fleetのトラブルシューティングのヒントに関する詳細については、 こちらを参照してください。

9.6 Fleetの例

Edgeチームは、Fleetを使用してEdgeプロジェクトをインストールする例を含む リポジトリを管理しています。

Fleetプロジェクトには、 fleet-examplesリポジトリが含まれており、 Gitリポジトリ構造のすべてのユースケースを網羅しています。

10 SUSE Linux Micro

SUSE Linux Micro公式ドキュメントを参照してください

SUSE Linux Microは、エッジ向けの軽量で安全なオペレーティングシステムです。SUSE Linux Enterprise Microは、SUSE Linux Enterpriseのエンタープライズ強化コンポーネントと開発者が最新の不変のOSに求める機能をマージします。その結果、使いやすく、クラス最高のコンプライアンスを備えた、信頼性の高いインフラストラクチャプラットフォームが得られます。

10.1 SUSE Telco CloudはどのようにSUSE Linux Microを使用しますか?

当社は、プラットフォームスタックのベースオペレーティングシステムとしてSUSE Linux Microを使用しています。これにより、安全で安定した最小限の基盤を用いて、構築作業を円滑に進めることができます。

SUSE Linux Microは、ファイルシステム(Btrfs)スナップショットを使用して、アップグレードで問題が発生した場合に簡単にロールバックできるという独自の特徴があります。これにより、問題が発生した場合でも、物理的なアクセスなしでプラットフォーム全体の安全なリモートアップグレードが可能になります。

10.2 ベストプラクティス

10.2.1 インストールメディア

SUSE Telco CloudはEdge Image Builder (第12章 「Edge Image Builder」)を使用して、SUSE Linux Microの自己インストール用インストールイメージを事前構成します。

10.2.2 ローカル管理

SUSE Linux MicroにはCockpitが付属しており、Webアプリケーションを通じてホストをローカルで管理できます。

このサービスはデフォルトで無効になっていますが、systemdサービス`cockpit.socket`を有効にすることで開始できます。 Cockpitはデフォルトでrootログインを禁止しているため、管理者権限を持つユーザーを作成することを推奨します。詳細については、https://documentation.suse.com/sle-micro/6.2/[SUSE Linux Micro公式ドキュメント]を参照してください。

10.3 当バージョンの注意事項

  • 現在、SUSE Linux Microではデスクトップ環境は利用できませんが、コンテナ化されたソリューションが開発中です。

11 Metal3

Metal3は、Kubernetes向けのベアメタルインフラストラクチャ管理機能を提供するCNCFプロジェクトです。

Metal3は、 Redfishなどの帯域外プロトコルによる管理をサポートするベアメタルサーバーのライフサイクルを管理するための、Kubernetesネイティブなリソースを提供します。

また、 Cluster API (CAPI)に対する成熟したサポートも備えています。 これにより、広く採用されているベンダー中立のAPIを介して、複数のインフラストラクチャプロバイダー全体でハードウェアリソースを管理できるようになります。 Cluster APIは、MachineオブジェクトのインフラストラクチャバックエンドとしてMetal3を使用します。

11.1 SUSE Telco CloudはどのようにMetal3を使用しますか?

SUSE Telco CloudはMetal3を使用して、サーバーなどの物理ハードウェアのライフサイクルを管理します。ハードウェアは、Metal3がサポートする帯域外管理プロトコル(Redfishなど)をサポートしている必要があります。SUSE Telco Cloud管理クラスターがダウンストリームクラスターのプロビジョニングまたはデプロビジョニングを行う際、Metal3はRedfishを介してサーバーのBMCと対話します。以下の操作は、通常、この対話の一部となります。

  • 仮想メディアのマウントおよびアンマウント。

  • サーバーの電源オン、電源オフ、およびリセット。

このアプローチは、ターゲットハードウェアが帯域外管理をサポートしており、完全に自動化されたインフラストラクチャ管理フローが求められるシナリオで役立ちます。

Metal3とCAPIは、自動化された検査、クリーニング、プロビジョニング/デプロビジョニングを含む、ベアメタルサーバーのインベントリおよび状態管理を可能にする宣言型APIを提供します。

11.2 当バージョンの注意事項

  • アップストリームの IP Address Management controllerは、現在、当社のネットワーク構成ツールの選択と互換性がないため、サポートされていません。ただし、ipam-controller-manager`ポッドが`metal3-ipam-system`ネームスペースでホストされている必要があります。CAPM3は`ipam CRDの存在を要求するためです。

  • 関連して、IPAMリソースおよびMetal3DataTemplateのnetworkDataフィールドはサポートされていません。

  • 現在、redfish-virtualmedia経由のデプロイのみがサポートされています。

12 Edge Image Builder

公式リポジトリを参照してください。

Edge Image Builder (EIB) は、マシンの起動用に、カスタマイズされた起動可能(CRB)ディスクイメージの生成を効率化するツールです。これらのイメージにより、単一のイメージでSUSEソフトウェアスタック全体の包括的なデプロイメントが可能になります。

EIBはすべてのプロビジョニングシナリオに対応するCRBイメージを作成できますが、ネットワークが制限されている、または完全に隔離されたエアギャップ(された)環境でのデプロイメントにおいて、EIBは非常に大きな価値を発揮します。

12.1 SUSE Telco CloudはどのようにEdge Image Builderを使用しますか?

SUSE Telco Cloudは、さまざまなシナリオに対応するカスタマイズされたSUSE Linux Microイメージを簡素かつ迅速に構成するためにEIBを使用します。これらのシナリオには、以下のような仮想マシンおよびベアメタルマシンのブートストラップが含まれます。

  • K3s/RKE2 Kubernetesの完全なエアギャップ(された)環境でのデプロイメント(シングルおよびマルチノード)

  • HelmチャートおよびKubernetesマニフェストの完全なエアギャップ(された)環境でのデプロイメント

  • Elemental API経由でのRancherへの登録

  • Metal3

  • カスタマイズされたネットワーク(例:静的IP、ホスト名、VLAN、ボンディングなど)

  • カスタマイズされたオペレーティングシステムの構成(例:ユーザー、グループ、パスワード、SSHキー、プロキシ、NTP、カスタムSSL証明書など)

  • ホストレベルおよびサイドロードされたRPMパッケージのエアギャップ(された)環境でのインストール(依存関係の解決を含む)

  • OS管理のためのSUSE Multi-Linux Managerへの登録

  • 組み込みコンテナイメージ

  • カーネルのコマンドライン引数

  • 起動時に有効/無効にするSystemdユニット

  • 手動タスク用のカスタムスクリプトおよびファイル

12.2 はじめに

Edge Image Builderの使用方法とテストに関する包括的なドキュメントは、https://github.com/suse-edge/edge-image-builder/tree/release-1.3/docs[こちら]にあります。

さらに、基本的なデプロイメントシナリオを網羅した第5章 「Edge Image Builderを使用したスタンドアロンクラスター」も参照してください。

このツールに慣れましたら、EIBのヒントとコツのセクション (パートX「ヒントとトラブルシューティング」)ページで、さらに役立つ情報をご覧ください。

12.3 当バージョンの注意事項

  • EIBは、Helmチャートをテンプレート化し、テンプレート内のすべてのイメージを解析することで、Helmチャートに対してエアギャップ処理を施します。Helmチャートがすべてのイメージをテンプレート内に保持せず、代わりにイメージをサイドロードする場合、EIBはそれらのイメージを自動的にエアギャップすることはできません。この解決策として、検出されなかったイメージを定義ファイルの`embeddedArtifactRegistry`セクションに手動で追加してください。

13 エッジネットワーキング

このセクションでは、SUSE Telco Cloudソリューションにおけるネットワーク設定へのアプローチについて説明します。 SUSE Linux MicroでNetworkManagerを宣言的な方法で設定する方法と、関連ツールがどのように統合されているかを説明します。

13.1 NetworkManagerの概要

NetworkManagerは、プライマリネットワーク接続とその他の接続インタフェースを管理するツールです。

NetworkManagerは、ネットワーク設定を目的の状態を含む接続ファイルとして保存します。 これらの接続は、`/etc/NetworkManager/system-connections/`ディレクトリにファイルとして保存されます。

NetworkManagerの詳細については、https://documentation.suse.com/sle-micro/6.2/html/Micro-network-configuration/index.html[SUSE Linux Microドキュメント]を参照してください。

13.2 nmstateの概要

nmstateは、事前定義されたスキーマを介してネットワーク設定用の宣言型APIを提供する、広く採用されているライブラリ(および付属のCLIツール)です。

nmstateの詳細については、 アップストリームドキュメントを参照してください。

13.3 次のように入力します。NetworkManager Configurator (nmc)

SUSE Telco Cloudで利用可能なネットワークカスタマイズオプションは、NetworkManager Configurator、略して_nmc_と呼ばれるCLIツールを介して実現されます。 これはnmstateライブラリによって提供される機能を活用しており、そのため、静的IPアドレス、DNSサーバー、VLAN、ボンディング、ブリッジなどの設定を完全に行うことができます。 このツールを使用すると、事前定義された目的の状態からネットワーク設定を生成し、それらを多くの異なるノードに自動化された方法で適用できます。

NetworkManager Configurator (nmc)の詳細については、 アップストリームリポジトリを参照してください。

13.4 SUSE Telco CloudはどのようにNetworkManager Configuratorを使用しますか?

SUSE Telco Cloudは、さまざまなプロビジョニングモデルにおけるネットワークのカスタマイズに_nmc_を利用します。 * ダイレクトネットワークプロビジョニングシナリオにおけるカスタムネットワーク設定 (第4章 「Metal3によるBMC自動デプロイメント」) * イメージベースのプロビジョニングシナリオにおける宣言型静的設定 (第5章 「Edge Image Builderを使用したスタンドアロンクラスター」)

13.5 Edge Image Builderによる設定

Edge Image Builder (EIB) は、単一のOSイメージで複数のホストを構成できるようにするツールです。 このセクションでは、宣言型アプローチを使用して目的のネットワーク状態を記述する方法、それらがどのように対応するNetworkManager接続に変換されるか、そしてプロビジョニングプロセス中にどのように適用されるかを示します。

13.5.1 前提条件

このガイドに従う場合は、以下のものがすでに用意されていることを前提としています。

  • SLES 15 SP6またはopenSUSE Leap 15.6を実行しているAMD64/Intel 64物理ホスト(または仮想マシン)

  • 利用可能なコンテナランタイム(例:Podman)

  • こちらにあるSUSE Linux Micro 6.2 RAWイメージのコピー

13.5.2 Edge Image Builderコンテナイメージの取得

EIBコンテナイメージは公開されており、以下のコマンドを実行することでSUSE Telco Cloudレジストリからダウンロードできます。

podman pull registry.suse.com/edge/3.7/edge-image-builder:1.3.4

13.5.3 イメージ構成ディレクトリの作成

設定ディレクトリの作成から始めましょう。

export CONFIG_DIR=$HOME/eib
mkdir -p $CONFIG_DIR/base-images

次に、ダウンロードしたベースイメージのコピーを設定ディレクトリに確実に移動します。

mv /path/to/downloads/SL-Micro.x86_64-6.2-Base-GM.raw $CONFIG_DIR/base-images/
注記
注記

EIBがベースイメージの入力を変更することはありません。変更を加えた新しいイメージが作成されます。

この時点での設定ディレクトリは、以下のようになっているはずです。

└── base-images/
    └── SL-Micro.x86_64-6.2-Base-GM.raw

13.5.4 イメージ定義ファイルの作成

定義ファイルには、Edge Image Builderがサポートする構成可能なオプションの大部分が記述されています。

OSイメージの非常に基本的な定義ファイルから始めましょう。

cat << EOF > $CONFIG_DIR/definition.yaml
apiVersion: 1.3
image:
  arch: x86_64
  imageType: raw
  baseImage: SL-Micro.x86_64-6.2-Base-GM.raw
  outputImageName: modified-image.raw
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
EOF

`image`セクションは必須であり、入力イメージ、そのアーキテクチャとタイプ、および出力イメージの名前を指定します。 `operatingSystem`セクションはオプションであり、`root/eib`ユーザー名/パスワードを使用してプロビジョニングされたシステムへのログインを有効にするための構成が含まれています。

注記
注記

`openssl passwd -6 <password>`を実行して、独自の暗号化されたパスワードを自由に使用してください。

この時点での設定ディレクトリは、以下のようになっているはずです。

├── definition.yaml
└── base-images/
    └── SL-Micro.x86_64-6.2-Base-GM.raw

13.5.5 ネットワーク構成の定義

目的のネットワーク構成は、作成したばかりのイメージ定義ファイルの一部ではありません。 これらを特別な`network/`ディレクトリの下に配置します。作成しましょう。

mkdir -p $CONFIG_DIR/network

前述のように、NetworkManager Configurator(nmc)ツールは、定義済みのスキーマ形式の入力を想定しています。 さまざまなネットワークオプションの設定方法については、 アップストリームのNMStateの例のドキュメントで確認できます。

このガイドでは、3つの異なるノードでネットワークを設定する方法を説明します。

  • 2つのイーサネットインターフェイスを使用するノード

  • ネットワークボンディングを使用するノード

  • ネットワークブリッジを使用するノード

警告
警告

本番環境のビルド、特にKubernetesクラスターを構成する場合は、完全に異なるネットワーク設定を使用することは推奨されません。 ネットワーク構成は、一般的にノード間、あるいは少なくとも特定のクラスター内の役割間で均一である必要があります。 このガイドには、参考例としてさまざまなオプションが含まれています。

注記
注記

以下では、IPアドレス範囲`192.168.122.1/24`を持つデフォルトの`libvirt`ネットワークを想定しています。 環境が異なる場合は、それに応じて調整してください。

`node1.suse.com`と呼ぶ最初のノードの目的の状態を作成しましょう。

cat << EOF > $CONFIG_DIR/network/node1.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: eth0
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: eth0
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E1
    ipv4:
      address:
        - ip: 192.168.122.50
          prefix-length: 24
      dhcp: false
      enabled: true
    ipv6:
      enabled: false
  - name: eth3
    type: ethernet
    state: down
    mac-address: 34:8A:B1:4B:16:E2
    ipv4:
      address:
        - ip: 192.168.122.55
          prefix-length: 24
      dhcp: false
      enabled: true
    ipv6:
      enabled: false
EOF

この例では、2つのイーサネットインターフェイス(eth0およびeth3)の目的の状態、要求されたIPアドレス、ルーティング、およびDNS解決を定義します。

警告
警告

すべてのイーサネットインターフェイスのMACアドレスがリストされていることを確認する必要があります。 これらは、プロビジョニングプロセス中にノードの識別子として使用され、どの構成を適用すべきかを決定するために役立ちます。 このようにして、単一のISOまたはRAWイメージを使用して複数のノードを構成できます。

次は、`node2.suse.com`と呼ぶ2番目のノードで、ネットワークボンディングを使用します。

cat << EOF > $CONFIG_DIR/network/node2.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: bond99
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: bond99
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: bond99
    type: bond
    state: up
    ipv4:
      address:
        - ip: 192.168.122.60
          prefix-length: 24
      enabled: true
    link-aggregation:
      mode: balance-rr
      options:
        miimon: '140'
      port:
        - eth0
        - eth1
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E3
    ipv4:
      enabled: false
    ipv6:
      enabled: false
  - name: eth1
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E4
    ipv4:
      enabled: false
    ipv6:
      enabled: false
EOF

この例では、IPアドレッシングを有効にしない2つのイーサネットインターフェイス(eth0およびeth1)の目的の状態と、ラウンドロビンポリシーを持つボンド、およびネットワークトラフィックの転送に使用されるそれぞれの宛先アドレスを定義します。

最後に、ネットワークブリッジを利用する3番目で最後の目的の状態ファイルを作成します。これを`node3.suse.com`と呼びます。

cat << EOF > $CONFIG_DIR/network/node3.suse.com.yaml
routes:
  config:
    - destination: 0.0.0.0/0
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: linux-br0
      table-id: 254
    - destination: 192.168.122.0/24
      metric: 100
      next-hop-address: 192.168.122.1
      next-hop-interface: linux-br0
      table-id: 254
dns-resolver:
  config:
    server:
      - 192.168.122.1
      - 8.8.8.8
interfaces:
  - name: eth0
    type: ethernet
    state: up
    mac-address: 34:8A:B1:4B:16:E5
    ipv4:
      enabled: false
    ipv6:
      enabled: false
  - name: linux-br0
    type: linux-bridge
    state: up
    ipv4:
      address:
        - ip: 192.168.122.70
          prefix-length: 24
      dhcp: false
      enabled: true
    bridge:
      options:
        group-forward-mask: 0
        mac-ageing-time: 300
        multicast-snooping: true
        stp:
          enabled: true
          forward-delay: 15
          hello-time: 2
          max-age: 20
          priority: 32768
      port:
        - name: eth0
          stp-hairpin-mode: false
          stp-path-cost: 100
          stp-priority: 32
EOF

この時点での設定ディレクトリは、以下のようになっているはずです。

├── definition.yaml
├── network/
│   │── node1.suse.com.yaml
│   │── node2.suse.com.yaml
│   └── node3.suse.com.yaml
└── base-images/
    └── SL-Micro.x86_64-6.2-Base-GM.raw
注記
注記

`network/`ディレクトリ内のファイル名は意図的なものです。 これらは、プロビジョニングプロセス中に設定されるホスト名に対応しています。

13.5.6 OSイメージのビルド

必要な構成がすべて整いましたので、単に以下を実行してイメージをビルドできます。

podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.7/edge-image-builder:1.3.4 build --definition-file definition.yaml

出力は以下のような内容である必要があります。

Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Systemd ...................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Embedded Artifact Registry ... [SKIPPED]
Keymap ....................... [SUCCESS]
Kubernetes ................... [SKIPPED]
Certificates ................. [SKIPPED]
Building RAW image...
Kernel Params ................ [SKIPPED]
Image build complete!

上記のコードスニペットは、`Network`コンポーネントが正常に構成されたことを示しており、エッジノードのプロビジョニングに進むことができます。

注記
注記

ログファイル(network-config.log)および対応するNetworkManager接続ファイルは、イメージ実行のタイムスタンプ付きディレクトリの下にある、結果の`_build`ディレクトリで確認できます。

13.5.7 エッジノードのプロビジョニング

作成されたRAWイメージをコピーしましょう。

mkdir edge-nodes && cd edge-nodes
for i in {1..4}; do cp $CONFIG_DIR/modified-image.raw node$i.raw; done

ビルドされたイメージを4回コピーしましたが、3つのノードのネットワーク構成しか指定していないことに気づくでしょう。 これは、どの目的の構成にも一致しないノードをプロビジョニングした場合に何が起こるかを紹介するためでもあります。

注記
注記

このガイドでは、ノードプロビジョニングの例として仮想化を使用します。BIOSで必要な拡張機能が有効になっていることを確認してください(詳細は こちらを参照してください)。

コピーされたrawディスクを使用して仮想マシンを作成するために、`virt-install`を使用します。 各仮想マシンは、10 GBのRAMと6つのvCPUを使用します。

13.5.7.1 最初のノードのプロビジョニング

仮想マシンを作成しましょう。

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=node1.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E1 --network default,mac=34:8A:B1:4B:16:E2 --virt-type kvm --import
注記
注記

上記で説明した目的の状態にあるものと同じMACアドレスでネットワークインタフェースを作成することが重要です。

操作が完了すると、次のようなものが表示されます。

Starting install...
Creating domain...

Running text console command: virsh --connect qemu:///system console node1
Connected to domain 'node1'
Escape character is ^] (Ctrl + ])


Welcome to SUSE Linux Micro 6.0 (x86_64) - Kernel 6.4.0-18-default (tty1).

SSH host key: SHA256:XN/R5Tw43reG+QsOw480LxCnhkc/1uqMdwlI6KUBY70 (RSA)
SSH host key: SHA256:/96yGrPGKlhn04f1rb9cXv/2WJt4TtrIN5yEcN66r3s (DSA)
SSH host key: SHA256:Dy/YjBQ7LwjZGaaVcMhTWZNSOstxXBsPsvgJTJq5t00 (ECDSA)
SSH host key: SHA256:TNGqY1LRddpxD/jn/8dkT/9YmVl9hiwulqmayP+wOWQ (ED25519)
eth0: 192.168.122.50
eth1:


Configured with the Edge Image Builder
Activate the web console with: systemctl enable --now cockpit.socket

node1 login:

これで、`root:eib`の資格情報のペアを使用してログインできるようになりました。 ここで提示された`virsh console`よりも好む場合は、ホストにSSHで接続することもできます。

ログインしたら、すべての設定が適切に行われていることを確認しましょう。

ホスト名が正しく設定されていることを確認します。

node1:~ # hostnamectl
 Static hostname: node1.suse.com
 ...

ルーティングが正しく構成されていることを確認します。

node1:~ # ip r
default via 192.168.122.1 dev eth0 proto static metric 100
192.168.122.0/24 dev eth0 proto static scope link metric 100
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.50 metric 100

インターネット接続が利用可能であることを確認します。

node1:~ # ping google.com
PING google.com (142.250.72.78) 56(84) bytes of data.
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=1 ttl=56 time=13.2 ms
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=2 ttl=56 time=13.4 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 13.248/13.304/13.361/0.056 ms

イーサネットインターフェイスが正確に2つ構成されており、そのうちの1つだけがアクティブであることを確認します。

node1:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e1 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.50/24 brd 192.168.122.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e2 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    altname ens3

node1:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1  7e211aea-3d14-59cf-a4fa-be91dac5dbba  ethernet  --      /etc/NetworkManager/system-connections/eth1.nmconnection

2番目のインターフェイスが、目的のネットワーク状態で事前定義された`eth3`ではなく、`eth1`になっていることに気づくでしょう。 これは、NetworkManager Configurator(nmc)が、OSがMACアドレス`34:8a:b1:4b:16:e2`を持つNICに異なる名前を割り当てたことを検出し、それに応じて設定を調整できるためです。

プロビジョニングのCombustionフェーズを検査して、これが実際に発生したことを確認します。

node1:~ # journalctl -u combustion | grep nmc
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Identified host: node1.suse.com
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Set hostname: node1.suse.com
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Processing interface 'eth0'...
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Processing interface 'eth3'...
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc::apply_conf] Using interface name 'eth1' instead of the preconfigured 'eth3'
Apr 23 09:20:19 localhost.localdomain combustion[1360]: [2024-04-23T09:20:19Z INFO  nmc] Successfully applied config

残りのノードをプロビジョニングしますが、最終的な構成の相違点のみを示します。 プロビジョニングしようとしているすべてのノードに対して、上記のチェックの一部またはすべてを自由に行ってください。

13.5.7.2 2番目のノードのプロビジョニング

仮想マシンを作成しましょう。

virt-install --name node2 --ram 10000 --vcpus 6 --disk path=node2.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E3 --network default,mac=34:8A:B1:4B:16:E4 --virt-type kvm --import

仮想マシンが起動して実行されたら、このノードがボンドインタフェースを使用していることを確認できます。

node2:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond99 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond99 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff permaddr 34:8a:b1:4b:16:e4
    altname enp0s3
    altname ens3
4: bond99: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.60/24 brd 192.168.122.255 scope global noprefixroute bond99
       valid_lft forever preferred_lft forever

ルーティングがボンドを使用していることを確認します。

node2:~ # ip r
default via 192.168.122.1 dev bond99 proto static metric 100
192.168.122.0/24 dev bond99 proto static scope link metric 100
192.168.122.0/24 dev bond99 proto kernel scope link src 192.168.122.60 metric 300

静的接続ファイルが適切に使用されていることを確認します。

node2:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME    UUID                                  TYPE      DEVICE  FILENAME
bond99  4a920503-4862-5505-80fd-4738d07f44c6  bond      bond99  /etc/NetworkManager/system-connections/bond99.nmconnection
eth0    dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1    0523c0a1-5f5e-5603-bcf2-68155d5d322e  ethernet  eth1    /etc/NetworkManager/system-connections/eth1.nmconnection

13.5.7.3 3番目のノードのプロビジョニング

仮想マシンを作成しましょう。

virt-install --name node3 --ram 10000 --vcpus 6 --disk path=node3.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default,mac=34:8A:B1:4B:16:E5 --virt-type kvm --import

仮想マシンが起動して実行されたら、このノードがネットワークブリッジを使用していることを確認できます。

node3:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master linux-br0 state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e5 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
3: linux-br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 34:8a:b1:4b:16:e5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.70/24 brd 192.168.122.255 scope global noprefixroute linux-br0
       valid_lft forever preferred_lft forever

ルーティングがブリッジを使用していることを確認します。

node3:~ # ip r
default via 192.168.122.1 dev linux-br0 proto static metric 100
192.168.122.0/24 dev linux-br0 proto static scope link metric 100
192.168.122.0/24 dev linux-br0 proto kernel scope link src 192.168.122.70 metric 425

静的接続ファイルが適切に使用されていることを確認します。

node3:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME       UUID                                  TYPE      DEVICE     FILENAME
linux-br0  1f8f1469-ed20-5f2c-bacb-a6767bee9bc0  bridge    linux-br0  /etc/NetworkManager/system-connections/linux-br0.nmconnection
eth0       dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0       /etc/NetworkManager/system-connections/eth0.nmconnection

13.5.7.4 4番目のノードのプロビジョニング

最後に、MACアドレスによる事前定義された構成のいずれにも一致しないノードをプロビジョニングします。 このような場合、デフォルトでDHCPを使用してネットワークインタフェースを構成します。

仮想マシンを作成しましょう。

virt-install --name node4 --ram 10000 --vcpus 6 --disk path=node4.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --virt-type kvm --import

仮想マシンが起動して実行されたら、このノードがネットワークインタフェースにランダムなIPアドレスを使用していることを確認できます。

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:56:63:71 brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.86/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
       valid_lft 3542sec preferred_lft 3542sec
    inet6 fe80::5054:ff:fe56:6371/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

nmcがこのノードに対して静的設定の適用に失敗したことを確認します。

localhost:~ # journalctl -u combustion | grep nmc
Apr 23 12:15:45 localhost.localdomain combustion[1357]: [2024-04-23T12:15:45Z ERROR nmc] Applying config failed: None of the preconfigured hosts match local NICs

イーサネットインタフェースがDHCP経由で設定されたことを確認します。

localhost:~ # journalctl | grep eth0
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7801] manager: (eth0): new Ethernet device (/org/freedesktop/NetworkManager/Devices/2)
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7802] device (eth0): state change: unmanaged -> unavailable (reason 'managed', sys-iface-state: 'external')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7929] device (eth0): carrier: link connected
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7931] device (eth0): state change: unavailable -> disconnected (reason 'carrier-changed', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7944] device (eth0): Activation: starting connection 'Wired Connection' (300ed658-08d4-4281-9f8c-d1b8882d29b9)
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7945] device (eth0): state change: disconnected -> prepare (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7947] device (eth0): state change: prepare -> config (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7953] device (eth0): state change: config -> ip-config (reason 'none', sys-iface-state: 'managed')
Apr 23 12:15:29 localhost.localdomain NetworkManager[704]: <info>  [1713874529.7964] dhcp4 (eth0): activation: beginning transaction (timeout in 90 seconds)
Apr 23 12:15:33 localhost.localdomain NetworkManager[704]: <info>  [1713874533.1272] dhcp4 (eth0): state changed new lease, address=192.168.122.86

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME              UUID                                  TYPE      DEVICE  FILENAME
Wired Connection  300ed658-08d4-4281-9f8c-d1b8882d29b9  ethernet  eth0    /var/run/NetworkManager/system-connections/default_connection.nmconnection

13.5.8 統合ノード設定

既知のMACアドレスに依存することが選択肢とならない場合があります。このような場合、_統合設定_を選択できます。これにより、`_all.yaml`ファイルで設定を指定し、プロビジョニングされたすべてのノードに適用できるようになります。

異なる設定構造を使用してエッジノードを構築およびプロビジョニングします。[image-config-dir-creation]から13.5.5項 「ネットワーク構成の定義」までのすべての手順に従ってください。

この例では、2つのイーサネットインターフェイス(eth0およびeth1)の目的の状態を定義します。1つはDHCPを使用し、もう1つは静的IPアドレスを割り当てます。

mkdir -p $CONFIG_DIR/network

cat <<- EOF > $CONFIG_DIR/network/_all.yaml
interfaces:
- name: eth0
  type: ethernet
  state: up
  ipv4:
    dhcp: true
    enabled: true
  ipv6:
    enabled: false
- name: eth1
  type: ethernet
  state: up
  ipv4:
    address:
    - ip: 10.0.0.1
      prefix-length: 24
    enabled: true
    dhcp: false
  ipv6:
    enabled: false
EOF

イメージをビルドしましょう。

podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.7/edge-image-builder:1.3.4 build --definition-file definition.yaml

イメージが正常にビルドされたら、それを使用して仮想マシンを作成しましょう。

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=$CONFIG_DIR/modified-image.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --network default --virt-type kvm --import

プロビジョニング処理には数分かかる場合があります。完了したら、提供された資格情報を使用してシステムにログインしてください。

ルーティングが正しく構成されていることを確認します。

localhost:~ # ip r
default via 192.168.122.1 dev eth0 proto dhcp src 192.168.122.100 metric 100
10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.1 metric 101
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.100 metric 100

インターネット接続が利用可能であることを確認します。

localhost:~ # ping google.com
PING google.com (142.250.72.46) 56(84) bytes of data.
64 bytes from den16s08-in-f14.1e100.net (142.250.72.46): icmp_seq=1 ttl=56 time=14.3 ms
64 bytes from den16s08-in-f14.1e100.net (142.250.72.46): icmp_seq=2 ttl=56 time=14.2 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 14.196/14.260/14.324/0.064 ms

イーサネットインタフェースが設定され、アクティブになっていることを確認してください。

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:26:44:7a brd ff:ff:ff:ff:ff:ff
    altname enp1s0
    inet 192.168.122.100/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0
       valid_lft 3505sec preferred_lft 3505sec
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:ec:57:9e brd ff:ff:ff:ff:ff:ff
    altname enp7s0
    inet 10.0.0.1/24 brd 10.0.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection
eth1  0523c0a1-5f5e-5603-bcf2-68155d5d322e  ethernet  eth1    /etc/NetworkManager/system-connections/eth1.nmconnection

localhost:~ # cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70

[ipv4]
dhcp-client-id=mac
dhcp-send-hostname=true
dhcp-timeout=2147483647
ignore-auto-dns=false
ignore-auto-routes=false
method=auto
never-default=false

[ipv6]
addr-gen-mode=0
dhcp-timeout=2147483647
method=disabled

localhost:~ # cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
id=eth1
interface-name=eth1
type=802-3-ethernet
uuid=0523c0a1-5f5e-5603-bcf2-68155d5d322e

[ipv4]
address0=10.0.0.1/24
dhcp-timeout=2147483647
method=manual

[ipv6]
addr-gen-mode=0
dhcp-timeout=2147483647
method=disabled

13.5.9 カスタムネットワーク設定

Edge Image Builderのデフォルトのネットワーク設定についてはすでに説明しましたが、これはNetworkManager Configuratorに依存しています。 ただし、カスタムスクリプトを使用して変更するオプションもあります。このオプションは非常に柔軟でMACアドレスにも依存しませんが、単一のイメージで複数のノードを起動する場合、使用するのがはるかに不便であるという制限があります。

注記
注記

/network ディレクトリの下にある、目的のネットワーク状態を記述したファイルを使用して、デフォルトのネットワーク設定を使用することをお勧めします。 その動作がユースケースに適用できない場合にのみ、カスタムスクリプトを選択してください。

異なる設定構造を使用してエッジノードを構築およびプロビジョニングします。[image-config-dir-creation]から13.5.5項 「ネットワーク構成の定義」までのすべての手順に従ってください。

この例では、プロビジョニングされたすべてのノードで eth0 インターフェイスに静的設定を適用し、NetworkManagerによって自動的に作成された有線接続を削除および無効化するカスタムスクリプトを作成します。これは、クラスター内のすべてのノードが同一のネットワーク設定を持つようにしたい場合に有益であり、そのため、イメージ作成前に各ノードのMACアドレスを気にする必要がありません。

まず、接続ファイルを /custom/files ディレクトリに保存することから始めましょう。

mkdir -p $CONFIG_DIR/custom/files

cat << EOF > $CONFIG_DIR/custom/files/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
autoconnect-retries=1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
wait-device-timeout=60000

[ipv4]
dhcp-timeout=2147483647
method=auto

[ipv6]
addr-gen-mode=eui64
dhcp-timeout=2147483647
method=disabled
EOF

静的設定が作成されたので、カスタムネットワークスクリプトも作成します。

mkdir -p $CONFIG_DIR/network

cat << EOF > $CONFIG_DIR/network/configure-network.sh
#!/bin/bash
set -eux

# Remove and disable wired connections
mkdir -p /etc/NetworkManager/conf.d/
printf "[main]\nno-auto-default=*\n" > /etc/NetworkManager/conf.d/no-auto-default.conf
rm -f /var/run/NetworkManager/system-connections/* || true

# Copy pre-configured network configuration files into NetworkManager
mkdir -p /etc/NetworkManager/system-connections/
cp eth0.nmconnection /etc/NetworkManager/system-connections/
chmod 600 /etc/NetworkManager/system-connections/*.nmconnection
EOF

chmod a+x $CONFIG_DIR/network/configure-network.sh
注記
注記

nmcバイナリは引き続きデフォルトで含まれるため、必要に応じて configure-network.sh スクリプトで使用することもできます。

警告
警告

カスタムスクリプトは、常に設定ディレクトリ内の /network/configure-network.sh に配置する必要があります。ファイルが存在する場合、他のすべてのファイルは無視されます。 YAML形式の静的構成とカスタムスクリプトの両方を同時に使用してネットワークを構成することはできません。

この時点での設定ディレクトリは、以下のようになっているはずです。

├── definition.yaml
├── custom/
│   └── files/
│       └── eth0.nmconnection
├── network/
│   └── configure-network.sh
└── base-images/
    └── SL-Micro.x86_64-6.2-Base-GM.raw

イメージをビルドしましょう。

podman run --rm -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.7/edge-image-builder:1.3.4 build --definition-file definition.yaml

イメージが正常にビルドされたら、それを使用して仮想マシンを作成しましょう。

virt-install --name node1 --ram 10000 --vcpus 6 --disk path=$CONFIG_DIR/modified-image.raw,format=raw --osinfo detect=on,name=sle-unknown --graphics none --console pty,target_type=serial --network default --virt-type kvm --import

プロビジョニング処理には数分かかる場合があります。完了したら、提供された資格情報を使用してシステムにログインしてください。

ルーティングが正しく構成されていることを確認します。

localhost:~ # ip r
default via 192.168.122.1 dev eth0 proto dhcp src 192.168.122.185 metric 100
192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.185 metric 100

インターネット接続が利用可能であることを確認します。

localhost:~ # ping google.com
PING google.com (142.250.72.78) 56(84) bytes of data.
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=1 ttl=56 time=13.6 ms
64 bytes from den16s09-in-f14.1e100.net (142.250.72.78): icmp_seq=2 ttl=56 time=13.6 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 13.592/13.599/13.606/0.007 ms

接続ファイルを使用してイーサネットインタフェースが静的に設定され、アクティブになっていることを確認してください。

localhost:~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:31:d0:1b brd ff:ff:ff:ff:ff:ff
    altname enp0s2
    altname ens2
    inet 192.168.122.185/24 brd 192.168.122.255 scope global dynamic noprefixroute eth0

localhost:~ # nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME con show
NAME  UUID                                  TYPE      DEVICE  FILENAME
eth0  dfd202f5-562f-5f07-8f2a-a7717756fb70  ethernet  eth0    /etc/NetworkManager/system-connections/eth0.nmconnection

localhost:~ # cat  /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
autoconnect=true
autoconnect-slaves=-1
autoconnect-retries=1
id=eth0
interface-name=eth0
type=802-3-ethernet
uuid=dfd202f5-562f-5f07-8f2a-a7717756fb70
wait-device-timeout=60000

[ipv4]
dhcp-timeout=2147483647
method=auto

[ipv6]
addr-gen-mode=eui64
dhcp-timeout=2147483647
method=disabled

14 RKE2

RKE2公式ドキュメントを参照してください。

RKE2は、以下によってセキュリティとコンプライアンスに重点を置いた、完全に準拠したKubernetesディストリビューションです。

  • クラスタが最小限のオペレータの介入でCIS Kubernetesベンチマークv1.6またはv1.23に合格できるようにするデフォルトと設定オプションを提供すること

  • FIPS 140-2コンプライアンスを有効にすること

  • RKE2ビルドパイプラインで trivyを使用して、コンポーネントのCVEを定期的にスキャンすること

RKE2は、コントロールプレーンのコンポーネントをkubeletによって管理される静的ポッドとして起動します。組み込みのコンテナランタイムはcontainerdです。

注意:RKE2は、現在ターゲットとしている別のユースケースとセクターを伝えるために、RKE Governmentとしても知られています。

14.1 RKE2とK3sの比較

K3sは、エッジ、IoT、ARMに焦点を当てた、完全に準拠した軽量なKubernetesディストリビューションであり、使いやすさとリソースが制限された環境向けに最適化されています。

RKE2は、RKEの1.xバージョン(以下、RKE1と呼びます)とK3sの両方の長所を兼ね備えています。

K3sからは、そのユーザビリティ、運用の容易さ、デプロイモデルを継承しています。

RKE1からは、アップストリームのKubernetesとの密接な整合性を継承しています。K3sは、エッジデプロイメント向けに最適化するため、アップストリーム Kubernetes から一部乖離していますが、RKE1 と RKE2 はアップストリームと密接に整合性を保つことができます。

14.2 SUSE Telco CloudはどのようにRKE2を使用していますか?

RKE2はSUSE Telco Cloudスタックの基本的な構成要素です。これはSUSE Linux Micro (第10章 「SUSE Linux Micro」)の上で動作し、エッジワークロードのデプロイに必要な標準的なKubernetesインターフェースを提供します。

14.3 ベストプラクティス

14.3.1 インストール

SUSE Telco Cloudスタックの一部としてRKE2をインストールする推奨方法は、Edge Image Builder(EIB)を使用することです。RKE2をデプロイするための設定方法の詳細については、EIBドキュメント (第12章 「Edge Image Builder」)を参照してください。

EIBは、RKE2のバージョン指定、 サーバーや エージェントの設定など、RKE2が必要とするあらゆるパラメータをサポートする柔軟性を備えており、すべてのエッジユースケースをカバーします。

Metal3に関連するその他のユースケースにおいても、RKE2が使用およびインストールされています。それらの特定のケースでは、 Cluster API Provider RKE2が、Edge Stackを使用してMetal3でプロビジョニングされるクラスター上にRKE2を自動的にデプロイします。

それらのケースでは、関連するさまざまなCRDにRKE2設定を適用する必要があります。RKE2ControlPlane CRDを使用して異なるCNIを提供する方法の例を以下に示します。

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  serverConfig:
    cni: calico
    cniMultusEnable: true
...

Metal3のユースケースの詳細については、第11章 「Metal3」を参照してください。

14.3.2 高可用性

HAデプロイメントの場合、EIBはMetalLB (第17章 「MetalLB」)とEndpoint Copier Operator (第18章 「Endpoint Copier Operator」)を自動的にデプロイおよび構成し、RKE2 APIエンドポイントを外部に公開します。

14.3.3 ネットワーキング

SUSE Telco Cloudスタックは、 Ciliumと Calicoをサポートしており、デフォルトの CNI は Cilium です。また、Pod が複数のネットワークインタフェースを必要とする場合は、 Multusメタプラグインも使用できます。RKE2スタンドアロンは、 より広範なCNIオプションをサポートしています。

14.3.4 ストレージ

RKE2は、いかなる種類の永続ストレージクラスやオペレーターも提供しません。複数のノードにまたがるクラスターには、SUSE Storage (第15章 「SUSE Storage」)の使用が推奨されます。

SUSE Storageは、Kubernetes向けに設計された、軽量で信頼性が高く、ユーザーフレンドリーな分散ブロックストレージシステムです。これは、Rancher Labsによって最初に開発され、現在はCNCFの下でインキュベーションされているオープンソースプロジェクトであるLonghornに基づいた製品です。

15.1 前提条件

このガイドに従う場合、以下のものがすでに利用可能であることを前提としています。

  • SUSE Linux Micro 6.2がインストールされたホストが、物理・仮想を問わず少なくとも1台必要です。

  • K3sまたはRKE2のいずれかがインストールされたKubernetesクラスターが必要です。

  • Helm

15.2 SUSE Storageの手動インストール

15.2.1 Open-iSCSIのインストール

SUSE Storageをデプロイおよび使用するための主要な要件は、`open-iscsi`パッケージのインストールと、すべてのKubernetesノードで実行される`iscsid`デーモンです。 Longhornはホスト上の`iscsiadm`に依存してKubernetesに永続ボリュームを提供するため、これが必要です。

インストールしましょう。

transactional-update pkg install open-iscsi

SUSE Linux Microはイミュータブル(変更不可)なオペレーティングシステムであるため、操作が完了すると、パッケージは新しいスナップショットにのみインストールされることに注意することが重要です。 それをロードし、`iscsid`デーモンを実行開始させるには、作成したばかりの新しいスナップショットで再起動する必要があります。 準備ができたら、rebootコマンドを発行してください。

reboot
ヒント
ヒント

open-iscsiのインストールに関する追加のヘルプについては、https://longhorn.io/docs/1.12.1/deploy/install/#installing-open-iscsi[公式Longhornドキュメント]を参照してください。

15.2.2 SUSE Storageのインストール

KubernetesクラスターにSUSE Storageをインストールする方法はいくつかあります。 このガイドではHelmによるインストール手順を説明しますが、別の方法を希望する場合は、https://longhorn.io/docs/1.12.1/deploy/install/[公式ドキュメント]に従ってください。

SUSE Telco Cloud 3.7以降では、新しいボリュームに対してV2データエンジンが推奨されます。 有効にする前に、必要なブロックデバイスを準備し、第66章 「SUSE Storage V2データエンジン」を確認してください。

  1. Rancherアプリケーションコレクションにログインします。

    helm registry login dp.apps.rancher.io --username $APPS.RANCHER.IO_USERNAME --password $APPS.RANCHER.IO_ACCESS_TOKEN
  2. `longhorn-system`ネームスペースにSUSE Storageをインストールし、コンテナレジストリの認証情報を追加します。

    helm install longhorn oci://dp.apps.rancher.io/charts/suse-storage \
      --version 1.12.1 \
      --namespace longhorn-system \
      --create-namespace \
      --set privateRegistry.createSecret=true \
      --set privateRegistry.registryUrl=dp.apps.rancher.io \
      --set privateRegistry.registryUser=$APPS.RANCHER.IO_USERNAME \
      --set privateRegistry.registryPasswd=$APPS.RANCHER.IO_ACCESS_TOKEN \
      --set privateRegistry.registrySecret=application-collection \
      --set defaultSettings.v1DataEngine=false \
      --set defaultSettings.v2DataEngine=true \
      --set persistence.dataEngine=v2
  3. デプロイが成功したことを確認します:

    kubectl -n longhorn-system get pods
    localhost:~ # kubectl -n longhorn-system get pods
    NAME                                                READY   STATUS    RESTARTS        AGE
    csi-attacher-7656559cf4-pkhh6                       1/1     Running   0               103s
    csi-attacher-7656559cf4-pnzw5                       1/1     Running   0               103s
    csi-attacher-7656559cf4-z94mm                       1/1     Running   0               103s
    csi-provisioner-6d9cf6456d-kcwtq                    1/1     Running   0               103s
    csi-provisioner-6d9cf6456d-mvvml                    1/1     Running   0               103s
    csi-provisioner-6d9cf6456d-q4f88                    1/1     Running   0               103s
    csi-resizer-f587cd467-clr2n                         1/1     Running   0               103s
    csi-resizer-f587cd467-z28v4                         1/1     Running   0               103s
    csi-resizer-f587cd467-zxmtx                         1/1     Running   0               103s
    csi-snapshotter-6dcdf78684-757mg                    1/1     Running   0               103s
    csi-snapshotter-6dcdf78684-8ktgc                    1/1     Running   0               103s
    csi-snapshotter-6dcdf78684-ffsqr                    1/1     Running   0               103s
    engine-image-ei-099f845a-lvdtr                      1/1     Running   0               2m21s
    instance-manager-4adffddaffe02374cd5635b8a6113de7   1/1     Running   0               111s
    longhorn-csi-plugin-w7pwr                           3/3     Running   0               103s
    longhorn-driver-deployer-6886fb84bc-wm9h6           1/1     Running   2 (2m32s ago)   2m45s
    longhorn-manager-zblbl                              2/2     Running   0               2m45s
    longhorn-ui-6bcc65d4bd-mcn6r                        1/1     Running   0               2m45s
    longhorn-ui-6bcc65d4bd-rwf97                        1/1     Running   0               2m45s

15.3 SUSE Storage ボリュームの作成

SUSE Storage は、ポッド用の PersistentVolume オブジェクトを自動的にプロビジョニングするために、StorageClass と呼ばれる Kubernetes リソースを利用します。 StorageClass は、管理者が提供するストレージの クラス や プロファイル を記述するための手段であると考えてください。

次の例では、V2 `StorageClass`を作成します。 V2データエンジンとスケジュール可能なブロックディスクは、第66章 「SUSE Storage V2データエンジン」で説明されているようにあらかじめ構成されている必要があります。

kubectl apply -f - <<EOF
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: longhorn-v2-example
provisioner: driver.longhorn.io
allowVolumeExpansion: true
parameters:
  dataEngine: "v2"
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880" # 48 hours in minutes
  fromBackup: ""
  fsType: "ext4"
EOF

StorageClass が配置されたので、それを参照する PersistentVolumeClaim が必要です。 PersistentVolumeClaim (PVC) は、ユーザーによるストレージの要求です。PVC は PersistentVolume リソースを消費します。 要求では、特定のサイズやアクセスモードを指定できます(例:読み取り/書き込みで1回マウント、または読み取り専用で複数回マウントなど)。

PersistentVolumeClaim を作成しましょう:

kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: longhorn-volv-pvc
  namespace: longhorn-system
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: longhorn-v2-example
  resources:
    requests:
      storage: 2Gi
EOF

以上です!PersistentVolumeClaim が作成されたら、それを Pod にアタッチする作業に進むことができます。 Pod がデプロイされると、Kubernetes は Longhorn Volume を作成し、ストレージが利用可能な場合はそれを Pod にバインドします。

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: volume-test
  namespace: longhorn-system
spec:
  containers:
  - name: volume-test
    image: nginx:stable-alpine
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: volv
      mountPath: /data
    ports:
    - containerPort: 80
  volumes:
  - name: volv
    persistentVolumeClaim:
      claimName: longhorn-volv-pvc
EOF
ヒント
ヒント

Kubernetes におけるストレージの概念は複雑ですが、重要なトピックです。最も一般的な Kubernetes リソースについて簡単に触れましたが、Longhorn が提供する 用語ドキュメント に目を通しておくことをお勧めします。

この例では、結果は次のようになるはずです:

localhost:~ # kubectl get storageclass
NAME                 PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
longhorn (default)   driver.longhorn.io   Delete          Immediate           true                   12m
longhorn-v2-example  driver.longhorn.io   Delete          Immediate           true                   24s

localhost:~ # kubectl get pvc -n longhorn-system
NAME                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
longhorn-volv-pvc   Bound    pvc-f663a92e-ac32-49ae-b8e5-8a6cc29a7d1e   2Gi        RWO            longhorn-v2-example   54s

localhost:~ # kubectl get pods -n longhorn-system
NAME                                                READY   STATUS    RESTARTS      AGE
csi-attacher-5c4bfdcf59-qmjtz                       1/1     Running   0             14m
csi-attacher-5c4bfdcf59-s7n65                       1/1     Running   0             14m
csi-attacher-5c4bfdcf59-w9xgs                       1/1     Running   0             14m
csi-provisioner-667796df57-fmz2d                    1/1     Running   0             14m
csi-provisioner-667796df57-p7rjr                    1/1     Running   0             14m
csi-provisioner-667796df57-w9fdq                    1/1     Running   0             14m
csi-resizer-694f8f5f64-2rb8v                        1/1     Running   0             14m
csi-resizer-694f8f5f64-z9v9x                        1/1     Running   0             14m
csi-resizer-694f8f5f64-zlncz                        1/1     Running   0             14m
csi-snapshotter-959b69d4b-5dpvj                     1/1     Running   0             14m
csi-snapshotter-959b69d4b-lwwkv                     1/1     Running   0             14m
csi-snapshotter-959b69d4b-tzhwc                     1/1     Running   0             14m
engine-image-ei-5cefaf2b-hvdv5                      1/1     Running   0             14m
instance-manager-0ee452a2e9583753e35ad00602250c5b   1/1     Running   0             14m
longhorn-csi-plugin-gd2jx                           3/3     Running   0             14m
longhorn-driver-deployer-9f4fc86-j6h2b              1/1     Running   0             15m
longhorn-manager-z4lnl                              1/1     Running   0             15m
longhorn-ui-5f4b7bbf69-bln7h                        1/1     Running   3 (14m ago)   15m
longhorn-ui-5f4b7bbf69-lh97n                        1/1     Running   3 (14m ago)   15m
volume-test                                         1/1     Running   0             26s

15.4 UIへのアクセス

kubectl または Helm を使用して SUSE Storage をインストールした場合は、クラスターへの外部トラフィックを許可するために Ingress コントローラーをセットアップする必要があります。認証はデフォルトでは有効になっていません。Rancherカタログアプリが使用されていた場合、Rancherはアクセス制御(rancher-proxy)を備えたIngressコントローラーを自動的に作成しました。

  1. Longhornの外部サービスIPアドレスを取得します。

    kubectl -n longhorn-system get svc
  2. longhorn-frontend IPアドレスを取得したら、ブラウザーでそのアドレスに移動してUIの使用を開始できます。

15.5 Edge Image Builderを使用したインストール

SUSE Telco Cloudは、ベースとなるSUSE Linux Micro OSイメージをカスタマイズするために第12章 「Edge Image Builder」を使用しています。 その上にSUSE Storageを搭載したRKE2クラスターをプロビジョニングする方法を説明します。

定義ファイルを作成しましょう。

export CONFIG_DIR=$HOME/eib
mkdir -p $CONFIG_DIR

cat << EOF > $CONFIG_DIR/iso-definition.yaml
apiVersion: 1.3
image:
  imageType: iso
  baseImage: SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
  arch: x86_64
  outputImageName: eib-image.iso
kubernetes:
  version: v1.36.3+rke2r1
  helm:
    charts:
      - name: suse-storage
        releaseName: longhorn
        version: 1.12.1
        repositoryName: rancher-application-collection
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
    repositories:
      - name: rancher-application-collection
        url: oci://dp.apps.rancher.io/charts
        authentication:
          username: $APPS.RANCHER.IO_USERNAME
          password: $APPS.RANCHER.IO_ACCESS_TOKEN
embeddedArtifactRegistry:
  registries:
    - uri: dp.apps.rancher.io
      authentication:
        username: $APPS.RANCHER.IO_USERNAME
        password: $APPS.RANCHER.IO_ACCESS_TOKEN
  images:
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-attacher:4.12.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-provisioner:5.3.0-17.8
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-resizer:2.2.1-10.8
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-snapshotter:8.6.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-livenessprobe:2.19.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-node-driver-registrar:2.17.0-17.6
    - name: dp.apps.rancher.io/containers/longhorn-backing-image-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-engine:1.12.1-1.6
    - name: dp.apps.rancher.io/containers/longhorn-instance-manager:1.12.1-1.7
    - name: dp.apps.rancher.io/containers/longhorn-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-share-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-ui:1.12.1-1.3
    - name: dp.apps.rancher.io/containers/rancher-support-bundle-kit:0.0.92-13.12
operatingSystem:
  packages:
    sccRegistrationCode: <reg-code>
    packageList:
      - open-iscsi
  users:
  - username: root
    encryptedPassword: \$6\$jHugJNNd3HElGsUZ\$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
EOF
注記
注記

Helmチャートの値は、`helm.charts[].valuesFile`で提供される別のファイルを使用してカスタマイズできます。 詳細については、https://github.com/suse-edge/edge-image-builder/blob/release-1.3/docs/building-images.md#kubernetes[アップストリームのドキュメント]を参照してください。 V2データエンジンを使用するには、V2の設定値を含め、必要なRAWブロックデバイスが第66章 「SUSE Storage V2データエンジン」で説明されているように準備および登録されていることを確認してください。

イメージをビルドしましょう。

podman run --rm --privileged -it -v $CONFIG_DIR:/eib registry.suse.com/edge/3.7/edge-image-builder:1.3.4 build --definition-file $CONFIG_DIR/iso-definition.yaml

イメージのビルドが完了したら、それを使用して物理ホストまたは仮想ホストにOSをインストールできます。 プロビジョニングが完了したら、`root:eib`の資格情報ペアを使用してシステムにログインできます。

SUSE Storageが正常にデプロイされたことを確認してください。

localhost:~ # /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml -n longhorn-system get pods
NAME                                                READY   STATUS    RESTARTS        AGE
csi-attacher-5c4bfdcf59-qmjtz                       1/1     Running   0               103s
csi-attacher-5c4bfdcf59-s7n65                       1/1     Running   0               103s
csi-attacher-5c4bfdcf59-w9xgs                       1/1     Running   0               103s
csi-provisioner-667796df57-fmz2d                    1/1     Running   0               103s
csi-provisioner-667796df57-p7rjr                    1/1     Running   0               103s
csi-provisioner-667796df57-w9fdq                    1/1     Running   0               103s
csi-resizer-694f8f5f64-2rb8v                        1/1     Running   0               103s
csi-resizer-694f8f5f64-z9v9x                        1/1     Running   0               103s
csi-resizer-694f8f5f64-zlncz                        1/1     Running   0               103s
csi-snapshotter-959b69d4b-5dpvj                     1/1     Running   0               103s
csi-snapshotter-959b69d4b-lwwkv                     1/1     Running   0               103s
csi-snapshotter-959b69d4b-tzhwc                     1/1     Running   0               103s
engine-image-ei-5cefaf2b-hvdv5                      1/1     Running   0               109s
instance-manager-0ee452a2e9583753e35ad00602250c5b   1/1     Running   0               109s
longhorn-csi-plugin-gd2jx                           3/3     Running   0               103s
longhorn-driver-deployer-9f4fc86-j6h2b              1/1     Running   0               2m28s
longhorn-manager-z4lnl                              1/1     Running   0               2m28s
longhorn-ui-5f4b7bbf69-bln7h                        1/1     Running   3 (2m7s ago)    2m28s
longhorn-ui-5f4b7bbf69-lh97n                        1/1     Running   3 (2m10s ago)   2m28s
注記
注記

このインストールは、完全にエアギャップ(された)環境では機能しません。 そのような場合は、64.8項 「SUSE Storageのインストール」を参照してください。

SUSE Securityは、L7ネットワークセキュリティ、ランタイムセキュリティ、サプライチェーンセキュリティ、およびコンプライアンスチェックを統合パッケージとして提供する、Kubernetes向けのセキュリティソリューションです。

SUSE Securityは、複数のコンテナのプラットフォームとしてデプロイされる製品であり、各コンテナはさまざまなポートやインターフェースを介して通信します。その内部では、基盤となるコンテナセキュリティコンポーネントとしてNeuVectorを使用しています。SUSE Securityプラットフォームは、以下のコンテナで構成されています。

  • マネージャWebベースのコンソールを提供するステートレスコンテナです。通常は1つあれば十分であり、どこでも実行可能です。マネージャのエラーが発生しても、コントローラやEnforcerの動作には一切影響しません。ただし、特定の通知(イベント)や最近の接続データはマネージャによってメモリ内にキャッシュされるため、これらを表示することはできなくなります。

  • コントローラSUSE Securityの「コントロールプレーン」はHA構成でデプロイする必要があるため、ノード障害が発生しても設定が失われることはありません。これらはどこでも実行可能ですが、その重要性から「管理」ノード、マスターノード、またはインフラノードに配置されることが一般的です。

  • EnforcerこのコンテナはDaemonSetとしてデプロイされるため、保護対象のすべてのノードに1つのEnforcerが配置されます。通常はすべてのワーカーノードにデプロイされますが、マスターノードやインフラノードでもデプロイできるようにスケジューリングを有効にすることも可能です。注意:Enforcerがクラスターノード上に存在せず、そのノード上のポッドから接続が発生した場合、SUSE Securityはそれらを「管理対象外」のワークロードとしてラベル付けします。

  • スキャナーコントローラの指示に従い、ビルトインのCVEデータベースを使用して脆弱性スキャンを実行します。スキャン容量を増やすために、複数のスキャナーをデプロイできます。スキャナーはどこでも実行できますが、多くの場合、コントローラが実行されているノードで実行されます。スキャナーノードのサイジングに関する考慮事項については、以下を参照してください。スキャナーは、ビルドフェーズでのスキャンに使用する場合、例えばスキャンをトリガーして結果を取得し、スキャナーを停止するパイプライン内で、独立して呼び出すこともできます。スキャナーには最新のCVEデータベースが含まれているため、毎日更新する必要があります。

  • アップデーター。アップデーターは、CVEデータベースの更新が必要なときに、KubernetesのCronジョブを通じてスキャナーの更新をトリガーします。ご使用の環境に合わせて必ず設定してください。

SUSE Securityのより詳細なオンボーディングおよびベストプラクティスに関するドキュメントは、 こちらから入手できます。

16.1 SUSE Telco CloudはどのようにSUSE Securityを使用しますか?

SUSE Telco Cloudは、エッジデプロイメントの出発点として、より軽量なSUSE Security構成を提供します。

16.2 重要な注意事項

  • `Scanner`コンテナには、スキャン対象のイメージをメモリにプルして開くための十分なメモリが必要です。1 GBを超えるイメージをスキャンするには、スキャナーのメモリを、想定される最大のイメージサイズよりわずかに大きく増やしてください。

  • 保護モードでは、高いネットワーク接続が予想されます。`Enforcer`は、保護(インラインファイアウォールブロッキング)モード時に、接続およびペイロード(DLP)の可能性を保持・検査するためにCPUとメモリを必要とします。メモリを増やし、`Enforcer`にCPUコアを割り当てることで、十分なパケットフィルタリング容量を確保できます。

16.3 Edge Image Builderを使用したインストール

SUSE Telco Cloudは、ベースとなるSUSE Linux Micro OSイメージをカスタマイズするために第12章 「Edge Image Builder」を使用しています。 EIBによってプロビジョニングされたKubernetesクラスター上でSUSE Securityを、エアギャップ(された)環境でインストールするには、64.7項 「SUSE Securityインストール」に従ってください。

17 MetalLB

MetalLB公式ドキュメントを参照してください。

MetalLBは、標準的なルーティングプロトコルを使用する、ベアメタルKubernetesクラスター向けのロードバランサー実装です。

ベアメタル環境では、ネットワークロードバランサーのセットアップはクラウド環境よりも著しく複雑です。クラウドセットアップにおける単純なAPI呼び出しとは異なり、ベアメタルでは、高可用性(HA)を管理したり、単一ノードのロードバランサーに固有の潜在的な単一障害点(SPOF)に対処したりするために、専用のネットワークアプライアンス、またはロードバランサーと仮想IP(VIP)構成の組み合わせが必要になります。これらの構成は容易に自動化できず、コンポーネントが動的にスケールアップおよびスケールダウンするKubernetesデプロイメントにおいて課題となります。

MetalLBは、Kubernetesモデルを活用して、ベアメタルセットアップであってもクラウド環境で動作しているかのように、ロードバランサー型のサービスを作成することで、これらの課題に対処します。

L2モード(ARP _トリック_を使用)または BGPを介した、2つの異なるアプローチがあります。主にL2は特別なネットワーク機器を必要としませんが、一般的にはBGPの方が優れています。ユースケースによります。

17.1 SUSE Telco CloudはどのようにMetalLBを使用しますか?

SUSE Telco CloudはMetalLBを3つの主要な方法で使用します。

  • ロードバランサーソリューションとして:MetalLBは、ベアメタルマシンのロードバランサーソリューションとして機能します。

  • HA K3s/RKE2セットアップの場合:MetalLBは、仮想IPアドレスを使用してKubernetes APIの負荷分散を可能にします。

  • L3 BGPソリューションとして、MetalLBはサービスIPへのルートを近隣のルーターにアドバタイズします。

注記
注記

APIを公開できるようにするため、Endpoint Copier Operator (第18章 「Endpoint Copier Operator」)を使用し、`kubernetes`サービスから`kubernetes-vip`ロードバランサーサービスへのK8s APIエンドポイントをsyncし続けます。

17.2 ベストプラクティス

L2モードでのMetalLBのインストールについては第61章 「K3s上のMetalLB(レイヤー2モードを使用)」で、L3モードについては第62章 「K3s上のMetalLB(レイヤー3モードを使用)」で説明されています。

高可用性トポロジーを実現するために`kube-api-server`の前にMetalLBをインストールするガイドは、第63章 「Kubernetes APIサーバーの前にあるMetalLB」にあります。

17.3 当バージョンの注意事項

  • K3sには、Klipper`と呼ばれるロードバランサーソリューションが付属しています。MetalLBを使用するには、`Klipper`を無効にする必要があります。これは、 K3sドキュメントで説明されているように、--disable servicelb`オプションを指定してK3sサーバーを起動することで実行できます。

18 Endpoint Copier Operator

Endpoint Copier Operatorは、KubernetesのServiceとEndpointのコピーを作成し、それらをsyncし続けることを目的としたKubernetesオペレーターです。

18.1 SUSE Telco CloudはどのようにEndpoint Copier Operatorを使用しますか?

SUSE Telco Cloudにおいて、Endpoint Copier OperatorはK3s/RKE2クラスターの高可用性(HA)セットアップを実現する上で重要な役割を果たします。これは、タイプ`kubernetes-vip`の`LoadBalancer`サービスを作成し、そのEndpointがKubernetesのEndpointと常に同期されるようにすることで実現されます。MetalLB (第17章 「MetalLB」)は`kubernetes-vip`サービスの管理に活用されており、公開されたIPアドレスは他のノードからクラスターに参加するために使用されます。

18.2 ベストプラクティス

Endpoint Copier Operatorの使用に関する包括的なドキュメントは、 こちらにあります。

さらに、Endpoint Copier OperatorとMetalLBを使用したK3s/RKE2 HAセットアップの実現に関するガイド (第61章 「K3s上のMetalLB(レイヤー2モードを使用)」)も参照してください。

18.3 当バージョンの注意事項

現在、Endpoint Copier Operatorは1つのService/Endpointのみを扱うように制限されています。複数のService/Endpointをサポートするための機能強化が将来的に計画されています。

19 エッジ仮想化

このセクションでは、エッジ仮想化を使用してエッジノード上で仮想マシンを実行する方法について説明します。エッジ仮想化は、軽量な仮想化のユースケース向けに設計されており、仮想化アプリケーションとコンテナ化アプリケーションの両方の展開と管理に共通のワークフローが利用されることが想定されています。

SUSE Telco Cloud 仮想化には、仮想マシンを実行するための2つの方法があります。

  1. ホストレベルでlibvirt+qemu-kvmを介して仮想マシンを手動でデプロイする(Kubernetesが関与しない場合)

  2. Kubernetesベースの仮想マシン管理のためにKubeVirtオペレーターをデプロイする

どちらのオプションも有効ですが、以下では2番目のオプションのみを扱います。SUSE Linux Microが提供する標準のすぐに使える仮想化メカニズムを使用したい場合は、包括的なガイドが こちらにあります。これは主にSUSE Linux Enterprise Server向けに書かれていますが、概念はほぼ同じです。

本ガイドでは、まず、すでにデプロイ済みのシステムに追加の仮想化コンポーネントをデプロイする方法を説明し、続いて、Edge Image Builderを使用して初期デプロイにこの構成を組み込む方法を説明するセクションを設けています。基本事項を確認せず、手動で設定を行いたい場合は、そのセクションまでスキップしてください。

19.1 KubeVirtの概要

KubeVirtを使用すると、他のコンテナ化されたワークロードと並行して、Kubernetesで仮想マシンを管理できます。これは、Linux仮想化スタックのユーザスペース部分をコンテナ内で実行することで実現されます。これにより、ホストシステムへの要件が最小限に抑えられ、セットアップと管理が容易になります。

KubeVirtのアーキテクチャの詳細については、アップストリームのドキュメントを参照してください。

19.2 前提条件

このガイドに従う場合、以下のものがすでに利用可能であることを前提としています。

  • SUSE Linux Micro 6.2がインストールされ、BIOSで仮想化拡張機能が有効になっている物理ホストが少なくとも1台(詳細はhttps://documentation.suse.com/sles/15-SP6/html/SLES-all/cha-virt-support.html#sec-kvm-requires-hardware[こちら]を参照)。

  • ノード全体に、K3s/RKE2 Kubernetesクラスターがすでに展開されており、クラスターへのスーパーユーザアクセスを可能にする適切な`kubeconfig`があること。

  • ルートユーザへのアクセス — これらの手順は、あなたがルートユーザであり、not sudo を使って権限を昇格させていないことを前提としています。

  • ローカル環境で Helm が利用可能であり、Kubernetes クラスターへの設定のプッシュおよび必要なイメージのダウンロードが可能な適切なネットワーク接続があることを確認してください。

19.3 エッジ仮想化の手動インストール

このガイドでは Kubernetes のデプロイ手順については説明しませんが、SUSE Telco Cloud に適したバージョンの K3s または RKE2 がインストールされており、標準の kubectl コマンドをスーパーユーザーとして実行できるように kubeconfig が構成されていることを前提としています。ノードがシングルノードクラスターを構成していることを前提としていますが、マルチノードデプロイメントでも大きな違いはありません。

SUSE Telco Cloud Virtualization は、以下の3つの個別の Helm チャートを介してデプロイメントされます。

  • KubeVirt:仮想化のコアコンポーネントであり、Kubernetes が仮想マシンをデプロイおよび管理できるようにするために必要な Kubernetes CRD、オペレーター、およびその他のコンポーネントです。

  • KubeVirt Dashboard Extension:仮想マシンの起動/停止やコンソールへのアクセスなど、基本的な仮想マシン管理を可能にするオプションの Rancher UI 拡張機能です。

  • Containerized Data Importer (CDI):KubeVirt の永続ストレージ統合を可能にする追加コンポーネントです。仮想マシンがデータ用に既存の Kubernetes ストレージバックエンドを使用できるようにするだけでなく、ユーザーが仮想マシン用のデータボリュームをインポートまたはクローンすることも可能にします。

これらの Helm チャートはそれぞれ、現在使用している SUSE Telco Cloud リリースに合わせてバージョン管理されています。本番環境やサポート対象の用途では、SUSE Registry にあるアーティファクトを使用してください。

まず、kubectl アクセスが機能していることを確認します。

$ kubectl get nodes

以下のような出力が表示されるはずです。

NAME                   STATUS   ROLES                       AGE     VERSION
node1.edge.rdo.wales   Ready    control-plane,etcd,master   4h20m   v1.30.5+rke2r1
node2.edge.rdo.wales   Ready    control-plane,etcd,master   4h15m   v1.30.5+rke2r1
node3.edge.rdo.wales   Ready    control-plane,etcd,master   4h15m   v1.30.5+rke2r1

これで、KubeVirt および Containerized Data Importer (CDI) Helm チャートのインストールに進むことができます。

$ helm install kubevirt oci://registry.suse.com/edge/charts/kubevirt --namespace kubevirt-system --create-namespace
$ helm install cdi oci://registry.suse.com/edge/charts/cdi --namespace cdi-system --create-namespace

数分以内に、すべての KubeVirt および CDI コンポーネントがデプロイされます。これは、kubevirt-system および cdi-system 名前空間にデプロイされたすべてのリソースを確認することで検証できます。

KubeVirt リソースの検証:

$ kubectl get all -n kubevirt-system

以下のような出力が表示されるはずです。

NAME                                   READY   STATUS    RESTARTS      AGE
pod/virt-operator-5fbcf48d58-p7xpm     1/1     Running   0             2m24s
pod/virt-operator-5fbcf48d58-wnf6s     1/1     Running   0             2m24s
pod/virt-handler-t594x                 1/1     Running   0             93s
pod/virt-controller-5f84c69884-cwjvd   1/1     Running   1 (64s ago)   93s
pod/virt-controller-5f84c69884-xxw6q   1/1     Running   1 (64s ago)   93s
pod/virt-api-7dfc54cf95-v8kcl          1/1     Running   1 (59s ago)   118s

NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubevirt-prometheus-metrics   ClusterIP   None            <none>        443/TCP   2m1s
service/virt-api                      ClusterIP   10.43.56.140    <none>        443/TCP   2m1s
service/kubevirt-operator-webhook     ClusterIP   10.43.201.121   <none>        443/TCP   2m1s
service/virt-exportproxy              ClusterIP   10.43.83.23     <none>        443/TCP   2m1s

NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/virt-handler   1         1         1       1            1           kubernetes.io/os=linux   93s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/virt-operator     2/2     2            2           2m24s
deployment.apps/virt-controller   2/2     2            2           93s
deployment.apps/virt-api          1/1     1            1           118s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/virt-operator-5fbcf48d58     2         2         2       2m24s
replicaset.apps/virt-controller-5f84c69884   2         2         2       93s
replicaset.apps/virt-api-7dfc54cf95          1         1         1       118s

NAME                            AGE     PHASE
kubevirt.kubevirt.io/kubevirt   2m24s   Deployed

CDI リソースの検証:

$ kubectl get all -n cdi-system

以下のような出力が表示されるはずです。

NAME                                   READY   STATUS    RESTARTS   AGE
pod/cdi-operator-55c74f4b86-692xb      1/1     Running   0          2m24s
pod/cdi-apiserver-db465b888-62lvr      1/1     Running   0          2m21s
pod/cdi-deployment-56c7d74995-mgkfn    1/1     Running   0          2m21s
pod/cdi-uploadproxy-7d7b94b968-6kxc2   1/1     Running   0          2m22s

NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/cdi-uploadproxy          ClusterIP   10.43.117.7    <none>        443/TCP    2m22s
service/cdi-api                  ClusterIP   10.43.20.101   <none>        443/TCP    2m22s
service/cdi-prometheus-metrics   ClusterIP   10.43.39.153   <none>        8080/TCP   2m21s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cdi-operator      1/1     1            1           2m24s
deployment.apps/cdi-apiserver     1/1     1            1           2m22s
deployment.apps/cdi-deployment    1/1     1            1           2m21s
deployment.apps/cdi-uploadproxy   1/1     1            1           2m22s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/cdi-operator-55c74f4b86      1         1         1       2m24s
replicaset.apps/cdi-apiserver-db465b888      1         1         1       2m21s
replicaset.apps/cdi-deployment-56c7d74995    1         1         1       2m21s
replicaset.apps/cdi-uploadproxy-7d7b94b968   1         1         1       2m22s

VirtualMachine カスタムリソース定義(CRD)がデプロイされていることを確認するには、以下を使用して検証できます。

$ kubectl explain virtualmachine

これにより VirtualMachine オブジェクトの定義が出力されるはずであり、以下のように表示されます。

GROUP:      kubevirt.io
KIND:       VirtualMachine
VERSION:    v1

DESCRIPTION:
    VirtualMachine handles the VirtualMachines that are not running or are in a
    stopped state The VirtualMachine contains the template to create the
    VirtualMachineInstance. It also mirrors the running state of the created
    VirtualMachineInstance in its status.
(snip)

19.4 仮想マシンのデプロイ

KubeVirt と CDI がデプロイされたので、 openSUSE Tumbleweed に基づく単純な仮想マシンを定義してみましょう。この仮想マシンは最も単純な設定であり、他のポッドと同じネットワーク設定にするために標準の「ポッドネットワーク」を使用しています。また、非永続ストレージを採用しているため、 PVC を持たないコンテナと同様に、ストレージはエフェメラル (一時的) になります。

$ cat <<EOF > user-data.yaml
#cloud-config
disable_root: false
ssh_pwauth: True
users:
  - default
  - name: suse
    groups: sudo
    shell: /bin/bash
    sudo:  ALL=(ALL) NOPASSWD:ALL
    lock_passwd: False
    plain_text_passwd: 'suse'
EOF
$ kubectl apply -f - <<EOF
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: tumbleweed
  namespace: default
spec:
  runStrategy: Always
  template:
    spec:
      domain:
        devices: {}
        machine:
          type: q35
        memory:
          guest: 2Gi
        resources: {}
      volumes:
      - containerDisk:
          image: quay.io/containerdisks/opensuse-tumbleweed:1.0.0
        name: tumbleweed-containerdisk-0
      - cloudInitNoCloud:
          userDataBase64: $(cat user-data.yaml | base64 -w 0)
        name: cloudinitdisk
EOF

これにより、VirtualMachine が作成されたことが出力されるはずです。

virtualmachine.kubevirt.io/tumbleweed created

この VirtualMachine 定義は最小限であり、設定に関する詳細はほとんど指定されていません。これは単に、2 GB のメモリを備えたマシンタイプ「 q35」であり、エフェメラル containerDisk (つまり、リモートイメージリポジトリのコンテナイメージに保存されるディスクイメージ) に基づくディスクイメージを使用すること、および起動時にユーザー作成とパスワード強制のためにのみ使用される base64 エンコードされた cloudInit ディスクを指定していることを示しています (base64 -d を使用してデコードしてください)。

注記
注記

この仮想マシンイメージはテスト専用です。このイメージは公式にサポートされておらず、ドキュメントの例としてのみ提供されています。

このマシンは openSUSE Tumbleweed ディスクイメージをダウンロードする必要があるため、起動に数分かかります。ダウンロードが完了したら、仮想マシンの情報を確認して、仮想マシンの詳細を表示できます。

$ kubectl get vmi

これにより、仮想マシンが起動されたノードと、仮想マシンの IP アドレスが表示されます。ポッドネットワークを使用しているため、報告される IP アドレスは他のポッドと同様であり、そのようにルーティング可能であることに注意してください。

NAME         AGE     PHASE     IP           NODENAME               READY
tumbleweed   4m24s   Running   10.42.2.98   node3.edge.rdo.wales   True

これらのコマンドを Kubernetes クラスターノード自体で実行し、トラフィックをポッドに直接ルーティングする CNI (Cilium など) を使用している場合は、マシン自体に直接 ssh できるはずです。以下の IP アドレスを、仮想マシンに割り当てられたものに置き換えてください。

$ ssh suse@10.42.2.98
(password is "suse")

この仮想マシンに入ったら自由に操作できますが、リソースが制限されており、ディスク容量が 1 GB しかないことに注意してください。終了したら、Ctrl-D または exit を実行して SSH セッションから切断します。

仮想マシンプロセスは、引き続き標準の Kubernetes ポッドにラップされています。VirtualMachine CRD は目的の仮想マシンを表すものですが、仮想マシンが実際に起動されるプロセスは、他のアプリケーションと同様に、標準の Kubernetes ポッドである virt-launcher ポッドを介して行われます。起動した仮想マシンごとに、virt-launcher ポッドがあることがわかります。

$ kubectl get pods

これにより、定義した Tumbleweed マシンの virt-launcher ポッドが表示されるはずです。

NAME                             READY   STATUS    RESTARTS   AGE
virt-launcher-tumbleweed-8gcn4   3/3     Running   0          10m

この`virt-launcher`ポッドの中を見ると、`libvirt`プロセスと`qemu-kvm`プロセスが実行されていることがわかります。ポッド自体に入って内部を確認できます。その際、以下のコマンドを自分のポッド名に合わせて調整する必要があることに注意してください。

$ kubectl exec -it virt-launcher-tumbleweed-8gcn4 -- bash

ポッドに入ったら、プロセスを確認するとともに、virsh コマンドを実行してみてください。qemu-system-x86_64 バイナリが実行されている様子と、仮想マシンを監視するための特定のプロセスを確認できます。また、ディスクイメージの場所や、ネットワークがどのように接続されているか(tap デバイスとして)も確認できます。

qemu@tumbleweed:/> ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ssl    0:00 /usr/bin/virt-launcher-monitor --qemu-timeout 269s --name tumbleweed --uid b9655c11-38f7-4fa8-8f5d-bfe987dab42c --namespace default --kubevirt-share-dir /var/run/kubevirt --ephemeral-disk-dir /var/run/kubevirt-ephemeral-disks --container-disk-dir /var/run/kube
   12 ?        Sl     0:01 /usr/bin/virt-launcher --qemu-timeout 269s --name tumbleweed --uid b9655c11-38f7-4fa8-8f5d-bfe987dab42c --namespace default --kubevirt-share-dir /var/run/kubevirt --ephemeral-disk-dir /var/run/kubevirt-ephemeral-disks --container-disk-dir /var/run/kubevirt/con
   24 ?        Sl     0:00 /usr/sbin/virtlogd -f /etc/libvirt/virtlogd.conf
   25 ?        Sl     0:01 /usr/sbin/virtqemud -f /var/run/libvirt/virtqemud.conf
   83 ?        Sl     0:31 /usr/bin/qemu-system-x86_64 -name guest=default_tumbleweed,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/run/kubevirt-private/libvirt/qemu/lib/domain-1-default_tumbleweed/master-key.aes"} -machine pc-q35-7.1,usb
  286 pts/0    Ss     0:00 bash
  320 pts/0    R+     0:00 ps ax

qemu@tumbleweed:/> virsh list --all
 Id   Name                 State
------------------------------------
 1    default_tumbleweed   running

qemu@tumbleweed:/> virsh domblklist 1
 Target   Source
---------------------------------------------------------------------------------------------
 sda      /var/run/kubevirt-ephemeral-disks/disk-data/tumbleweed-containerdisk-0/disk.qcow2
 sdb      /var/run/kubevirt-ephemeral-disks/cloud-init-data/default/tumbleweed/noCloud.iso

qemu@tumbleweed:/> virsh domiflist 1
 Interface   Type       Source   Model                     MAC
------------------------------------------------------------------------------
 tap0        ethernet   -        virtio-non-transitional   e6:e9:1a:05:c0:92

qemu@tumbleweed:/> exit
exit

最後に、この仮想マシンを削除してクリーンアップしましょう。

$ kubectl delete vm/tumbleweed
virtualmachine.kubevirt.io "tumbleweed" deleted

19.5 virtctl の使用

標準的な Kubernetes CLI ツールである kubectl に加え、KubeVirt には付随する CLI ユーティリティが用意されており、仮想化の世界と Kubernetes が設計された世界との間のギャップを埋めるような方法でクラスターとやり取りすることができます。例えば、virtctl ツールは、仮想マシンのライフサイクル管理(起動、停止、再起動など)、仮想コンソールへのアクセス、仮想マシンイメージのアップロード、さらには API や CRD を直接使用せずにサービスなどの Kubernetes 構成要素とやり取りする機能を提供します。

virtctl ツールの最新の安定版をダウンロードしましょう。

$ export VERSION=v1.8.3
$ wget https://github.com/kubevirt/kubevirt/releases/download/$VERSION/virtctl-$VERSION-linux-amd64

異なるアーキテクチャや Linux 以外のマシンを使用している場合は、他のリリースを こちらから見つけることができます。続行する前にこれを実行可能にする必要があります。また、`$PATH`内の場所に移動しておくと便利かもしれません。

$ mv virtctl-$VERSION-linux-amd64 /usr/local/bin/virtctl
$ chmod a+x /usr/local/bin/virtctl

その後、virtctl コマンドラインツールを使用して仮想マシンを作成できます。以前の仮想マシンを複製してみましょう。出力を直接`kubectl apply`にパイプしていることに注意してください。

$ cat <<EOF >  user-data.yaml
#cloud-config
disable_root: false
ssh_pwauth: True
users:
  - default
  - name: suse
    groups: sudo
    shell: /bin/bash
    sudo:  ALL=(ALL) NOPASSWD:ALL
    lock_passwd: False
    plain_text_passwd: 'suse'
EOF
$ alias virtctl=echo
$ virtctl create vm --name virtctl-example --memory=1Gi \
    --volume-containerdisk=src:quay.io/containerdisks/opensuse-tumbleweed:1.0.0 \
    --cloud-init-user-data "$(cat user-data.yaml | base64 -w 0)"

これで仮想マシンが実行されていることが表示されるはずです(コンテナイメージがキャッシュされるため、今回ははるかに早く起動するはずです)。

$ kubectl get vmi
NAME              AGE   PHASE     IP           NODENAME               READY
virtctl-example   52s   Running   10.42.2.29   node3.edge.rdo.wales   True

これで`virtctl`を使用して仮想マシンに直接接続できます。

$ virtctl ssh suse@virtctl-example
(password is "suse" - Ctrl-D to exit)

`virtctl`で使用できる他のコマンドはたくさんあります。例えば、ネットワークが機能していない場合に`virtctl console`を使用してシリアルコンソールにアクセスしたり、`virtctl guestosinfo`を使用して包括的なOS情報を取得したりできます。ただし、ゲストに`qemu-guest-agent`がインストールされ、実行されている必要があります。

最後に、仮想マシンを一時停止して再開してみましょう。

$ virtctl pause vm virtctl-example
VMI virtctl-example was scheduled to pause

VirtualMachine オブジェクトが Paused と表示され、VirtualMachineInstance オブジェクトが Running と表示されますが、READY=False であることがわかります。

$ kubectl get vm
NAME              AGE     STATUS   READY
virtctl-example   8m14s   Paused   False

$ kubectl get vmi
NAME              AGE     PHASE     IP           NODENAME               READY
virtctl-example   8m15s   Running   10.42.2.29   node3.edge.rdo.wales   False

また、仮想マシンに接続できなくなったこともわかります。

$ virtctl ssh suse@virtctl-example
can't access VMI virtctl-example: Operation cannot be fulfilled on virtualmachineinstance.kubevirt.io "virtctl-example": VMI is paused

仮想マシンを再開して、もう一度試してみましょう。

$ virtctl unpause vm virtctl-example
VMI virtctl-example was scheduled to unpause

これで接続を再確立できるはずです。

$ virtctl ssh suse@virtctl-example
suse@vmi/virtctl-example.default's password:
suse@virtctl-example:~> exit
logout

最後に、仮想マシンを削除しましょう。

$ kubectl delete vm/virtctl-example
virtualmachine.kubevirt.io "virtctl-example" deleted

19.6 単純なIngressネットワーキング

このセクションでは、仮想マシンを標準のKubernetesサービスとして公開し、例えば Traefik with RKE2 や Traefik with K3s といったKubernetes Ingressサービス経由で利用可能にする方法を説明します。このドキュメントでは、これらのコンポーネントがすでに適切に設定されており、適切なDNSポインタ(例えばワイルドカードなど)を使用して、適切なIngress解決のためにKubernetesサーバーノードまたはIngress仮想IPを指していることを前提としています。

注記
注記

SUSE Telco Cloud 3.1以降で、K3sをマルチサーバーノード構成で使用している場合、Ingress用にMetalLBベースのVIPを設定する必要があったかもしれませんが、RKE2ではこれは不要です。

この例の環境では、別のopenSUSE Tumbleweed仮想マシンがデプロイされ、cloud-initを使用して起動時にNGINXが単純なWebサーバーとしてインストールされます。また、呼び出しが行われた際に期待通りに動作することを確認するため、単純なメッセージが返されるように設定されています。これを行う方法を確認するには、以下の出力の base64 -d セクションをご覧ください。

それでは、この仮想マシンを作成しましょう。

$ cat <<EOF > user-data.yaml
#cloud-config
disable_root: false
ssh_pwauth: True
users:
  - default
  - name: suse
    groups: sudo
    shell: /bin/bash
    sudo:  ALL=(ALL) NOPASSWD:ALL
    lock_passwd: False
    plain_text_passwd: 'suse'
EOF
$ kubectl apply -f - <<EOF
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ingress-example
  namespace: default
spec:
  runStrategy: Always
  template:
    metadata:
      labels:
        app: nginx
    spec:
      domain:
        devices: {}
        machine:
          type: q35
        memory:
          guest: 2Gi
        resources: {}
      volumes:
      - containerDisk:
          image: quay.io/containerdisks/opensuse-tumbleweed:1.0.0
        name: tumbleweed-containerdisk-0
      - cloudInitNoCloud:
          userDataBase64: $(cat user-data.yaml | base64 -w 0)
        name: cloudinitdisk
EOF

この仮想マシンが正常に起動したら、virtctl コマンドを使用して、外部ポート 8080、ターゲットポート 80(NGINXがデフォルトでリスンするポート)で VirtualMachineInstance を公開できます。ここでは、仮想マシンオブジェクトとポッド間のマッピングを認識できるため、virtctl コマンドを使用します。これにより、新しいサービスが作成されます。

$ virtctl expose vmi ingress-example --port=8080 --target-port=80 --name=ingress-example
Service ingress-example successfully exposed for vmi ingress-example

そうすると、適切なサービスが自動的に作成されます。

$ kubectl get svc/ingress-example
NAME              TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                         AGE
ingress-example   ClusterIP      10.43.217.19    <none>            8080/TCP                        9s

次に、kubectl create ingress を使用すると、このサービスを指すIngressオブジェクトを作成できます。ここでのURL( ingress オブジェクトでは「ホスト」として知られています)をDNS設定に合わせて調整し、ポート 8080 を指すようにしてください。

$ kubectl create ingress ingress-example --rule=ingress-example.suse.local/=ingress-example:8080

DNSが正しく設定されていれば、すぐにURLに対してcurlを実行できるはずです。

$ curl ingress-example.suse.local
It works!

この仮想マシンとそのサービスおよびイングレスリソースを削除してクリーンアップしましょう。

$ kubectl delete vm/ingress-example svc/ingress-example ingress/ingress-example
virtualmachine.kubevirt.io "ingress-example" deleted
service "ingress-example" deleted
ingress.networking.k8s.io "ingress-example" deleted

19.7 Rancher UI拡張機能の使用

SUSE Telco Cloud VirtualizationはRancher Manager用のUI拡張機能を提供し、RancherダッシュボードUIを使用した基本的な仮想マシン管理を可能にします。

19.7.1 インストール

インストールガイダンスについては、Rancher Dashboard Extensions (第7章 「Rancherダッシュボード拡張機能」)を参照してください。

19.7.2 KubeVirt Rancherダッシュボード拡張機能の使用

この拡張機能により、Cluster Explorerに新しい*KubeVirt*セクションが追加されます。このセクションは、KubeVirtがインストールされているすべての管理対象クラスターに追加されます。

この拡張機能を使用すると、KubeVirt仮想マシンリソースを直接操作して、仮想マシンのライフサイクルを管理できます。

19.7.2.1 仮想マシンの作成

  1. 左側のナビゲーションでKubeVirtが有効な管理対象クラスターをクリックし、*Cluster Explorer*に移動します。

  2. *KubeVirt > Virtual Machines*ページに移動し、画面右上の`Create from YAML`をクリックします。

  3. 仮想マシンの定義を入力または貼り付けて、`Create`を押します。「仮想マシンのデプロイ」セクションの仮想マシン定義を参考にしてください。

virtual machines page

19.7.2.2 仮想マシンのアクション

各仮想マシンの右側にある*⋮*ドロップダウンリストからアクセスできるアクションメニューを使用して、開始、停止、一時停止、またはソフト再起動のアクションを実行できます。または、アクションを実行する仮想マシンを選択して、リストの上部にあるグループアクションを使用することもできます。

アクションを実行すると、仮想マシンの実行戦略に影響を与える可能性があります。詳細については、 KubeVirtドキュメントの表を参照してください。

19.7.2.3 仮想マシンコンソールへのアクセス

「Virtual machines」リストには、*VNCまたはシリアルコンソール*を使用してマシンに接続できる`Console`ドロップダウンリストが用意されています。このアクションは、実行中のマシンでのみ利用可能です。

仮想マシンを起動した直後は、コンソールにアクセスできるようになるまで少し時間がかかる場合があります。

vnc console ui

19.8 Edge Image Builderを使用したインストール

SUSE Telco Cloudは、ベースとなるSUSE Linux Micro OSイメージをカスタマイズするために第12章 「Edge Image Builder」を使用しています。 64.9項 「KubeVirtおよびCDIのインストール」に従って、EIBによってプロビジョニングされたKubernetesクラスター上で、KubeVirtとCDIの両方をエアギャップ(された)インストールしてください。

20 System Upgrade Controller

System Upgrade Controllerのドキュメントを参照してください。

System Upgrade Controller(SUC)は、汎用的なKubernetesネイティブのアップグレードコントローラー(ノード用)を提供することを目的としています。これは、アップグレードポリシーや要件を定義するための新しいCRDである「Plan」を導入します。Planとは、クラスター内のノードの変更を意図した計画です。

20.1 SUSE Telco CloudはどのようにSystem Upgrade Controllerを使用しますか?

SUSE Telco Cloudは`SUC`を使用して、管理クラスターおよびダウンストリームクラスターにおけるOSとKubernetesのバージョンアップグレードに関連するさまざまな「Day 2」オペレーションを促進します。

「Day 2」オペレーションは`SUC Plans`を通じて定義されます。これらのプランに基づいて、`SUC`は各ノードにワークロードをデプロイし、それぞれの「Day 2」オペレーションを実行します。

`SUC`は第21章 「Upgrade Controller」内でも使用されます。SUCとUpgrade Controllerの主な違いの詳細については、21.2項 「Upgrade Controller vs System Upgrade Controller」を参照してください。

20.2 System Upgrade Controllerのインストール

重要
重要

Rancher v2.10.0以降、`System Upgrade Controller`は自動的にインストールされます。

以下の手順は、環境がRancherによって管理されていない場合、またはRancherのバージョンが`v2.10.0`より低い場合のみ実行してください。

suse-edge/fleet-examplesリポジトリにあるFleet (第9章 「Fleet」)を使用してSUCをインストールすることをお勧めします。

注記
注記

`suse-edge/fleet-examples`リポジトリによって提供されるリソースは、*必ず*有効なfleet-examplesリリースから使用する必要があります。使用する必要があるリリースを確認するには、リリースノート (第78章 「リリースノート」)を参照してください。

Fleetを使用してSUCをインストールできない場合は、RancherのHelmチャートリポジトリからインストールするか、RancherのHelmチャートを独自のサードパーティGitOpsワークフローに組み込むことができます。

このセクションでは、次の内容について説明します。

20.2.1 System Upgrade Controller Fleetのインストール

Fleetを使用する場合、SUCのデプロイに使用できるリソースは2つあります:

20.2.1.1 System Upgrade Controllerのインストール - GitRepo

注記
注記

このプロセスは、Rancher UIが利用可能な場合は、それを通じて行うこともできます。詳細については、Rancher UIでのFleetへのアクセスを参照してください。

*管理*クラスターで:

  1. SUCをデプロイするクラスターを決定します。これは、*管理*クラスター上の適切なFleetワークスペースにSUC `GitRepo`リソースをデプロイすることで実行されます。デフォルトでは、Fleetには2つのワークスペースがあります:

    • fleet-local - *管理*クラスターにデプロイする必要があるリソース用。

    • fleet-default - *ダウンストリーム*クラスターにデプロイする必要があるリソース用。

      Fleetワークスペースの詳細については、アップストリームのドキュメントを参照してください。

  2. `GitRepo`リソースをデプロイします:

    • 管理クラスターにSUCをデプロイするには:

      kubectl apply -n fleet-local -f - <<EOF
      apiVersion: fleet.cattle.io/v1alpha1
      kind: GitRepo
      metadata:
        name: system-upgrade-controller
      spec:
        revision: release-3.7.0
        paths:
        - fleets/day2/system-upgrade-controller
        repo: https://github.com/suse-edge/fleet-examples.git
      EOF
    • ダウンストリームクラスターにSUCをデプロイするには:

      注記
      注記

      以下のリソースをデプロイする前に、Fleetがどのダウンストリームクラスターにリソースをデプロイすべきかを認識できるよう、有効な targets 設定を 指定する必要があります。ダウンストリームクラスターへのマッピング方法については、ダウンストリームクラスターへのマッピング を参照してください。

      kubectl apply -n fleet-default -f - <<EOF
      apiVersion: fleet.cattle.io/v1alpha1
      kind: GitRepo
      metadata:
        name: system-upgrade-controller
      spec:
        revision: release-3.7.0
        paths:
        - fleets/day2/system-upgrade-controller
        repo: https://github.com/suse-edge/fleet-examples.git
        targets:
        - clusterSelector: CHANGEME
        # Example matching all clusters:
        # targets:
        # - clusterSelector: {}
      EOF
  3. GitRepo リソースがデプロイされていることを確認します:

    # Namespace will vary based on where you want to deploy SUC
    kubectl get gitrepo system-upgrade-controller -n <fleet-local/fleet-default>
    
    NAME                        REPO                                              COMMIT          BUNDLEDEPLOYMENTS-READY   STATUS
    system-upgrade-controller   https://github.com/suse-edge/fleet-examples.git   release-3.7.0   1/1
  4. System Upgrade Controllerのデプロイメントを検証します:

    kubectl get deployment system-upgrade-controller -n cattle-system
    NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
    system-upgrade-controller   1/1     1            1           2m20s

20.2.1.2 System Upgrade Controllerのインストール - Bundle

このセクションでは、fleet-cli を使用して、標準のFleet構成から Bundle リソースをビルドおよびデプロイする方法を説明します。

  1. ネットワークアクセスが可能なマシンで fleet-cli をダウンロードします:

    注記
    注記

    ダウンロードするfleet-cliのバージョンが、クラスターにデプロイされているFleetのバージョンと一致していることを確認してください。

    • Macユーザー向けには、fleet-cli のHomebrew Formulaeが用意されています。

    • LinuxおよびWindowsユーザー向けには、各Fleet リリースの assets としてバイナリが提供されています。

      • Linux AMD:

        curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/v0.16.1/fleet-linux-amd64
      • Linux ARM:

        curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/v0.16.1/fleet-linux-arm64
  2. fleet-cli を実行可能にしてください:

    chmod +x fleet-cli
  3. 使用する suse-edge/fleet-examples リリース をクローンします:

    git clone -b release-3.7.0 https://github.com/suse-edge/fleet-examples.git
  4. fleet-examples リポジトリにあるSUC fleetに移動します:

    cd fleet-examples/fleets/day2/system-upgrade-controller
  5. SUCをデプロイするクラスターを決定します。これは、管理クラスター内の適切なFleetワークスペースにSUCバンドルをデプロイすることで実行されます。デフォルトでは、Fleetには2つのワークスペースがあります:

    • fleet-local - *管理*クラスターにデプロイする必要があるリソース用。

    • fleet-default - *ダウンストリーム*クラスターにデプロイする必要があるリソース用。

      Fleetワークスペースの詳細については、アップストリームのドキュメントを参照してください。

  6. SUCをダウンストリームクラスターのみにデプロイする場合は、特定のクラスターに一致する targets.yaml ファイルを作成してください:

    cat > targets.yaml <<EOF
    targets:
    - clusterSelector: CHANGEME
    EOF

    ダウンストリームクラスターへのマッピング方法については、ダウンストリームクラスターへのマッピング を参照してください。

  7. バンドルのビルドに進みます:

    注記
    注記

    fleet-examples/fleets/day2/system-upgrade-controller ディレクトリにfleet-cliを*ダウンロードしない*ように注意してください。そうしないと、バンドルに同梱されてしまい、推奨されません。

    • 管理クラスターにSUCをデプロイするには、以下を実行します。

      fleet-cli apply --compress -n fleet-local -o - system-upgrade-controller . > system-upgrade-controller-bundle.yaml
    • ダウンストリームクラスターにSUCをデプロイするには、以下を実行します。

      fleet-cli apply --compress --targets-file=targets.yaml -n fleet-default -o - system-upgrade-controller . > system-upgrade-controller-bundle.yaml

      このプロセスの詳細については、Helmチャートをバンドルに変換するを参照してください。

      fleet-cli apply コマンドの詳細については、fleet applyを参照してください。

  8. system-upgrade-controller-bundle.yaml バンドルを管理クラスターのマシンに転送します。

    scp system-upgrade-controller-bundle.yaml <machine-address>:<filesystem-path>
  9. 管理クラスター上で、system-upgrade-controller-bundle.yaml バンドルをデプロイします。

    kubectl apply -f system-upgrade-controller-bundle.yaml
  10. 管理クラスター上で、バンドルがデプロイされていることを検証します。

    # Namespace will vary based on where you want to deploy SUC
    kubectl get bundle system-upgrade-controller -n <fleet-local/fleet-default>
    
    NAME                        BUNDLEDEPLOYMENTS-READY   STATUS
    system-upgrade-controller   1/1
  11. バンドルをデプロイしたFleetワークスペースに基づいて、クラスターに移動し、SUCのデプロイを検証します。

    注記
    注記

    SUCは常に cattle-system ネームスペースにデプロイされます。

    kubectl get deployment system-upgrade-controller -n cattle-system
    NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
    system-upgrade-controller   1/1     1            1           111s

20.2.2 System Upgrade ControllerのHelmインストール

  1. Rancherチャートリポジトリを追加します。

    helm repo add rancher-charts https://charts.rancher.io/
  2. SUCチャートをデプロイします。

    helm install system-upgrade-controller rancher-charts/system-upgrade-controller --version 110.0.0 --set global.cattle.psp.enabled=false -n cattle-system --create-namespace

    これにより、Edge 3.7 プラットフォームで必要とされるSUCバージョン v0.20.1 がインストールされます。

  3. SUCのデプロイメントを検証します。

    kubectl get deployment system-upgrade-controller -n cattle-system
    NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
    system-upgrade-controller   1/1     1            1           37s

20.3 System Upgrade Controllerプランの監視

SUCプランは、以下の方法で確認できます。

重要
重要

SUCプラン用にデプロイされたポッドは、実行成功後 15 分間保持されます。その後、それらを作成した対応するジョブによって削除されます。この期間を過ぎてもPodのログにアクセスできるようにするには、クラスターのログ記録を有効にする必要があります。Rancherでこれを行う方法の詳細については、https://ranchermanager.docs.rancher.com/v2.15/integrations-in-rancher/logging[Rancher Integration with Logging Services]を参照してください。

20.3.1 Upgrade Controllerプランの監視 - Rancher UI

特定のSUCプランのPodログを確認するには:

  1. 左上隅にある*☰ → <your-cluster-name>*

  2. [Workloads] → > [Pods]を選択します。

  3. `Only User Namespaces`ドロップダウンメニューを選択し、`cattle-system`ネームスペースを追加します。

  4. Podフィルターバーに、SUCプランPodの名前を入力します。名前は次のテンプレート形式になります:apply-<plan_name>-on-<node_name>

    注記
    注記

    特定のSUCプランに対して、`Completed`と`Unknown`の両方のPodが存在する場合があります。これは想定される動作であり、一部のアップグレードの性質上発生します。

  5. ログを確認するPodを選択し、*⋮ → View Logs*に移動します。

20.3.2 Upgrade Controllerプランの監視 - 手動

注記
注記

以下の手順では、`kubectl`が*SUC Plans*がデプロイされているクラスターに接続するように構成されていることを前提としています。

  1. デプロイされた*SUC*プランを一覧表示します:

    kubectl get plans -n cattle-system
  2. *SUC*プランのPodを取得します:

    kubectl get pods -l upgrade.cattle.io/plan=<plan_name> -n cattle-system
    注記
    注記

    特定のSUCプランに対して、`Completed`と`Unknown`の両方のPodが存在する場合があります。これは想定される動作であり、一部のアップグレードの性質上発生します。

  3. Podのログを取得します:

    kubectl logs <pod_name> -n cattle-system

21 Upgrade Controller

以下のSUSE Telco Cloudプラットフォームコンポーネントのアップグレードを実行できるKubernetesコントローラー:

  • オペレーティングシステム(SUSE Linux Micro)

  • Kubernetes(K3sおよびRKE2)

  • 追加コンポーネント(Rancher、Elemental、SUSE Securityなど)

Upgrade Controllerは、上記のコンポーネントの複雑さを単一の`user-facing`リソースにカプセル化することで、アップグレードプロセスを効率化し、そのリソースがアップグレードの*トリガー*として機能します。ユーザーはこのリソースを構成するだけで、残りは`Upgrade Controller`が処理します。

注記
注記

`Upgrade Controller`は現在、SUSE Telco Cloudプラットフォームのアップグレードを、*エアギャップされていない管理クラスター*向けにのみサポートしています。詳細については、21.8項 「既知の制限事項」セクションを参照してください。

21.1 SUSE Telco Cloudはどのようにアップグレードコントローラーを使用しますか?

*アップグレードコントローラー*は、管理クラスターをあるSUSE Telco Cloudリリースバージョンから次のバージョンへアップグレードするために必要な(以前は手動だった)「Day 2」運用を自動化する上で不可欠です。

この自動化を実現するために、アップグレードコントローラーはSystem Upgrade Controller (第20章 「System Upgrade Controller」)やHelm Controllerといったツールを利用します。

アップグレードコントローラーの仕組みの詳細については、21.5項 「Upgrade Controllerはどのように機能しますか?」を参照してください。

アップグレードコントローラーの既知の制限事項については、21.8項 「既知の制限事項」を参照してください。

アップグレードコントローラーとSystem Upgrade Controllerの違いに関する情報については、21.2項 「Upgrade Controller vs System Upgrade Controller」を参照してください。

21.2 Upgrade Controller vs System Upgrade Controller

System Upgrade Controller (SUC) (第20章 「System Upgrade Controller」)は、特定のKubernetesノードにアップグレード手順を伝播させる汎用ツールです。

SUSE Telco Cloudプラットフォーム向けの「Day 2」運用の一部はサポートしていますが、すべてをカバーしているわけ*ではありません*。さらに、サポートされている運用であっても、ユーザーは複数の`SUC Plans`を手動で構成、維持、デプロイする必要があり、これはエラーが発生しやすく、予期しない問題につながる可能性があります。

これにより、SUSE Telco Cloudプラットフォームのさまざまな「Day 2」運用管理の複雑さを自動化し、抽象化するツールの必要性が生じました。こうして、`Upgrade Controller`が開発されました。これは、アップグレードを駆動する単一の`user-facing resource`を導入することで、アップグレードプロセスを簡素化します。ユーザーはこのリソースを管理するだけでよく、残りは`Upgrade Controller`が処理します。

21.3 Upgrade Controllerのインストール

21.3.1 前提条件

21.3.2 手順

  1. 管理クラスターにUpgrade ControllerのHelmチャートをインストールします:

    helm install upgrade-controller oci://registry.suse.com/edge/charts/upgrade-controller --version 307.0.4+up0.1.3 --create-namespace --namespace upgrade-controller-system
  2. Upgrade Controllerのデプロイメントを検証します:

    kubectl get deployment -n upgrade-controller-system
  3. Upgrade Controllerのポッドを検証します:

    kubectl get pods -n upgrade-controller-system
  4. Upgrade Controllerのポッドログを検証します:

    kubectl logs <pod_name> -n upgrade-controller-system

21.4 Edge Image Builderを使用したUpgrade Controllerのインストール

上記の手動インストールに代わる方法として、Edge Image Builder (第12章 「Edge Image Builder」)によって調整される初期デプロイの一部としてUpgrade Controllerをインストールすることも可能です。

この場合、EIB設定ファイルに以下のHelmチャート設定を追加する必要があります:

kubernetes:
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: {version-cert-manager}
        targetNamespace: cert-manager
        valuesFile: certmanager-values.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: upgrade-controller
        version: {version-upgrade-controller-chart}
        repositoryName: suse-edge-charts
        targetNamespace: upgrade-controller-system
        createNamespace: true
        installationNamespace: kube-system

21.5 Upgrade Controllerはどのように機能しますか?

Edgeリリースのアップグレードを実行するために、Upgrade Controllerは2つの新しいKubernetes カスタムリソースを導入します:

  • UpgradePlan (21.6.1項 「UpgradePlan」) - ユーザーによって作成されます。Edgeリリースのアップグレードに関する設定を保持します。

  • ReleaseManifest (21.6.2項 「ReleaseManifest」) - Upgrade Controllerによって作成されます。特定のEdgeリリースバージョンに固有のコンポーネントバージョンを保持します。このファイルはユーザーが編集してはいけません。

Upgrade Controllerは、ユーザーが`UpgradePlan`リソースの`releaseVersion`プロパティで指定したEdgeリリースバージョンのコンポーネントデータを保持する`ReleaseManifest`リソースの作成に進みます。

`ReleaseManifest`のコンポーネントデータを使用して、アップグレードコントローラは以下の順序でEdgeリリースコンポーネントのアップグレードに進みます。

注記
注記

アップグレードプロセス中、アップグレードコントローラは作成された`UpgradePlan`にアップグレード情報を継続的に出力します。アップグレードプロセスの追跡方法の詳細については、アップグレードプロセスの追跡 (21.7項 「アップグレードプロセスの追跡」)を参照してください。

21.5.1 オペレーティングシステムのアップグレード

オペレーティングシステムをアップグレードするために、Upgrade Controllerは以下の命名テンプレートを持つSUC (第20章 「System Upgrade Controller」)プランを作成します。

  • コントロールプレーンノードのオペレーティングシステムアップグレードに関連するSUCプランの場合 - control-plane-<os-name>-<os-version>-<suffix>。

  • ワーカーノードのオペレーティングシステムアップグレードに関連するSUCプランの場合 - workers-<os-name>-<os-version>-<suffix>。

これらのプランに基づいて、SUCはクラスターの各ノード上に実際のオペレーティングシステムアップグレードを実行するワークロードを作成します。

`ReleaseManifest`に応じて、オペレーティングシステムのアップグレードには以下が含まれる場合があります。

  • パッケージのみの更新 - Edgeリリース間でオペレーティングシステムのバージョンが変更されないユースケース用。

  • 完全なオペレーティングシステムの移行 - Edgeリリース間でオペレーティングシステムのバージョンが変更されるユースケース用。

アップグレードは、コントロールプレーンノードから開始して、*1*ノードずつ実行されます。コントロールプレーンノードのアップグレードが完了した場合にのみ、ワーカーノードのアップグレードが開始されます。

注記
注記

Upgrade Controllerは、クラスターに指定されたタイプのノードが*1*つより多い場合、クラスターのノードに対してドレインを実行するようにオペレーティングシステムのSUCプランを設定します。

コントロールプレーンノードが*1*つより多く、ワーカーノードが*1つのみ*であるクラスターの場合、コントロールプレーンノードに対してのみドレインが実行され、その逆も同様です。

ノードのドレインを完全に無効にする方法については、UpgradePlan (21.6.1項 「UpgradePlan」)セクションを参照してください。

21.5.2 Kubernetesのアップグレード

クラスターのKubernetesディストリビューションをアップグレードするために、Upgrade Controllerは次の命名テンプレートを持つSUC (第20章 「System Upgrade Controller」)プランを作成します。

  • コントロールプレーンノードのKubernetesアップグレードに関連するSUCプランの場合 - control-plane-<k8s-version>-<suffix>。

  • ワーカーノードのKubernetesアップグレードに関連するSUCプランの場合 - workers-<k8s-version>-<suffix>。

これらのプランに基づいて、SUCはクラスターの各ノード上で実際のKubernetesアップグレードを実行するワークロードを作成します。

Kubernetesのアップグレードは、コントロールプレーンノードから開始され、*1*ノードずつ実行されます。コントロールプレーンノードのアップグレードが完了した場合にのみ、ワーカーノードのアップグレードが開始されます。

注記
注記

Upgrade Controllerは、指定されたタイプのノードが*1*つより多いクラスターの場合、クラスターのノードに対してドレインを実行するようにKubernetes SUCプランを構成します。

コントロールプレーンノードが*1より大きい*かつワーカーノードが*1つのみ*の場合、コントロールプレーンノードに対してのみドレインが実行され、反対の場合はワーカーノードに対してのみ実行されます。

ノードのドレインを完全に無効にする方法については、21.6.1項 「UpgradePlan」を参照してください。

21.5.3 追加コンポーネントのアップグレード

現在、すべての追加コンポーネントはHelmチャートを介してインストールされています。特定のリリースに含まれるコンポーネントの完全なリストについては、リリースノート (第78章 「リリースノート」)を参照してください。

EIB (第12章 「Edge Image Builder」)を通じてデプロイされたHelmチャートの場合、Upgrade Controllerは各コンポーネントの既存のHelmChart CRを更新します。

EIB以外でデプロイされたHelmチャートの場合、Upgrade Controllerは各コンポーネントに対して`HelmChart`リソースを作成します。

`HelmChart`リソースの作成/更新後、Upgrade Controllerはhelm-controllerに依存してこの変更を検知し、実際のコンポーネントのアップグレードを進めます。

チャートは、`ReleaseManifest`内の順序に基づいて順番にアップグレードされます。追加の値は、`UpgradePlan`を介して渡すこともできます。新しいSUSE Telco Cloudリリースでチャートのバージョンが変更されない場合、アップグレードは行われません。詳細については、21.6.1項 「UpgradePlan」を参照してください。

21.6 Kubernetes API拡張機能

Upgrade Controllerによって導入されたKubernetes APIへの拡張機能。

21.6.1 UpgradePlan

Upgrade Controllerは、カスタムリソースと呼ばれる新しいKubernetes `UpgradePlan`を導入します。

`UpgradePlan`はUpgrade Controllerの指示メカニズムとして機能し、以下の構成をサポートします。

  • releaseVersion - クラスターのアップグレード先となるEdgeリリースバージョン。リリースバージョンはセマンティックバージョニングに従う必要があり、リリースノート (第78章 「リリースノート」)から取得する必要があります。

  • disableDrain - オプション。ノードドレインを無効にするかどうかをUpgrade Controllerに指示します。中断バジェットを持つワークロードがある場合に便利です。

    • コントロールプレーンノードのドレインを無効にする例:

      spec:
        disableDrain:
          controlPlane: true
    • コントロールプレーンおよびワーカーノードのドレインを無効にする例:

      spec:
        disableDrain:
          controlPlane: true
          worker: true
  • helm - オプション。Helm経由でインストールされたコンポーネントの追加値を指定します。

    警告
    警告

    このフィールドは、アップグレードに不可欠な値に対してのみ使用することをお勧めします。標準的なチャート値の更新は、それぞれのチャートが次のバージョンにアップグレードされた後に行う必要があります。

    • 例:

      spec:
        helm:
        - chart: foo
          values:
            bar: baz

21.6.2 ReleaseManifest

Upgrade Controllerは、カスタムリソースと呼ばれる新しいKubernetes `ReleaseManifest`を導入します。

`ReleaseManifest`リソースはUpgrade Controllerによって作成され、*1つ*の特定のEdgeリリースバージョンに関するコンポーネントデータを保持します。つまり、各Edgeリリースバージョンのアップグレードは、異なる`ReleaseManifest`リソースによって表されます。

警告
警告

Release Manifestは常にUpgrade Controllerによって作成される必要があります。

`ReleaseManifest`リソースを手動で作成または編集することは推奨されません。そうすることを決定したユーザーは、*自己責任*で行う必要があります。

Release Manifestが提供するコンポーネントデータには、以下が含まれますが、これらに限定されません。

  • オペレーティングシステムデータ - バージョン、サポートされているアーキテクチャ、追加のアップグレードデータなど。

  • Kubernetesディストリビューションデータ - RKE2/K3s サポート対象バージョン

  • 追加コンポーネントデータ - SUSE Helmチャートデータ(場所、バージョン、名前など)

Release Manifestの例については、https://github.com/suse-edge/upgrade-controller/blob/main/config/samples/lifecycle_v1alpha1_releasemanifest.yaml[アップストリーム]ドキュメントを参照してください。これはあくまで例であり、有効な ReleaseManifest リソースとして作成することを意図したものではありませんのでご注意ください。

21.7 アップグレードプロセスの追跡

このセクションは、ユーザーが UpgradePlan リソースを作成した後にUpgrade Controllerが開始するアップグレードプロセスを追跡およびデバッグするための手段です。

21.7.1 全般

アップグレードプロセスの状態に関する一般的な情報は、Upgrade Planのステータス条件で確認できます。

Upgrade Planリソースのステータスは、以下の方法で確認できます。

kubectl get upgradeplan <upgradeplan_name> -n upgrade-controller-system -o yaml
例 21.1: Upgrade Plan実行の例:
apiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
  name: upgrade-plan-mgmt
  namespace: upgrade-controller-system
spec:
  releaseVersion: 3.7
status:
  conditions:
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Control plane nodes are being upgraded
    reason: InProgress
    status: "False"
    type: OSUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Kubernetes upgrade is not yet started
    reason: Pending
    status: Unknown
    type: KubernetesUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Rancher upgrade is not yet started
    reason: Pending
    status: Unknown
    type: RancherUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Longhorn upgrade is not yet started
    reason: Pending
    status: Unknown
    type: LonghornUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: MetalLB upgrade is not yet started
    reason: Pending
    status: Unknown
    type: MetalLBUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: CDI upgrade is not yet started
    reason: Pending
    status: Unknown
    type: CDIUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: KubeVirt upgrade is not yet started
    reason: Pending
    status: Unknown
    type: KubeVirtUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: NeuVector upgrade is not yet started
    reason: Pending
    status: Unknown
    type: NeuVectorUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: EndpointCopierOperator upgrade is not yet started
    reason: Pending
    status: Unknown
    type: EndpointCopierOperatorUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Elemental upgrade is not yet started
    reason: Pending
    status: Unknown
    type: ElementalUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: SRIOV upgrade is not yet started
    reason: Pending
    status: Unknown
    type: SRIOVUpgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: Metal3 upgrade is not yet started
    reason: Pending
    status: Unknown
    type: Metal3Upgraded
  - lastTransitionTime: "2024-10-01T06:26:27Z"
    message: RancherTurtles upgrade is not yet started
    reason: Pending
    status: Unknown
    type: RancherTurtlesUpgraded
  observedGeneration: 1
  sucNameSuffix: 90315a2b6d

ここでは、Upgrade Controllerがアップグレードのスケジュールを試みるすべてのコンポーネントを確認できます。各条件は以下のテンプレートに従います。

  • lastTransitionTime - このコンポーネントの条件が最後にステータスを変更した日時。

  • message - 特定のコンポーネント条件の現在のアップグレード状態を示すメッセージ。

  • reason - 特定のコンポーネント条件の現在のアップグレード状態。可能な reasons は以下の通りです。

    • Succeeded - 特定のコンポーネントのアップグレードが成功しました。

    • Failed - 特定のコンポーネントのアップグレードが失敗しました。

    • InProgress - 特定のコンポーネントのアップグレードが現在進行中です。

    • Pending - 特定のコンポーネントのアップグレードはまだスケジュールされていません。

    • Skipped - 特定のコンポーネントがクラスター上で見つからないため、そのアップグレードはスキップされます。

    • Error - 特定のコンポーネントで一時的なエラーが発生しました。

  • status - 現在の条件 type のステータス。True、False、Unknown のいずれかです。

  • type - 現在アップグレード中のコンポーネントのインジケーター。

Upgrade Controller は、タイプ OSUpgraded および KubernetesUpgraded のコンポーネント条件に対して SUC プランを作成します。これらのコンポーネントに対して作成された SUC プランをさらに追跡するには、20.3項 「System Upgrade Controllerプランの監視」 を参照してください。

他のすべてのコンポーネント条件タイプは、helm-controller によって作成されたリソースを表示することでさらに追跡できます。詳細については、21.7.2項 「Helm Controller」 を参照してください。

Upgrade Controller によってスケジュールされたアップグレード計画は、次の場合に successful としてマークされます:

  1. Pending または InProgress のコンポーネント条件はありません。

  2. lastSuccessfulReleaseVersion プロパティは、アップグレード計画の設定で指定されている releaseVersion を指します。このプロパティは、アップグレードプロセスが成功すると、Upgrade Controller によってアップグレード計画のステータスに追加されます。

例 21.2: 成功した UpgradePlan の例:
apiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
  name: upgrade-plan-mgmt
  namespace: upgrade-controller-system
spec:
  releaseVersion: 3.7
status:
  conditions:
  - lastTransitionTime: "2024-10-01T06:26:48Z"
    message: All cluster nodes are upgraded
    reason: Succeeded
    status: "True"
    type: OSUpgraded
  - lastTransitionTime: "2024-10-01T06:26:59Z"
    message: All cluster nodes are upgraded
    reason: Succeeded
    status: "True"
    type: KubernetesUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart rancher upgrade succeeded
    reason: Succeeded
    status: "True"
    type: RancherUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart longhorn is not installed
    reason: Skipped
    status: "False"
    type: LonghornUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Specified version of chart metallb is already installed
    reason: Skipped
    status: "False"
    type: MetalLBUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart cdi is not installed
    reason: Skipped
    status: "False"
    type: CDIUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart kubevirt is not installed
    reason: Skipped
    status: "False"
    type: KubeVirtUpgraded
  - lastTransitionTime: "2024-10-01T06:27:13Z"
    message: Chart neuvector-crd is not installed
    reason: Skipped
    status: "False"
    type: NeuVectorUpgraded
  - lastTransitionTime: "2024-10-01T06:27:14Z"
    message: Specified version of chart endpoint-copier-operator is already installed
    reason: Skipped
    status: "False"
    type: EndpointCopierOperatorUpgraded
  - lastTransitionTime: "2024-10-01T06:27:14Z"
    message: Chart elemental-operator upgrade succeeded
    reason: Succeeded
    status: "True"
    type: ElementalUpgraded
  - lastTransitionTime: "2024-10-01T06:27:15Z"
    message: Chart sriov-crd is not installed
    reason: Skipped
    status: "False"
    type: SRIOVUpgraded
  - lastTransitionTime: "2024-10-01T06:27:19Z"
    message: Chart metal3 is not installed
    reason: Skipped
    status: "False"
    type: Metal3Upgraded
  - lastTransitionTime: "2024-10-01T06:27:27Z"
    message: Chart rancher-turtles is not installed
    reason: Skipped
    status: "False"
    type: RancherTurtlesUpgraded
  lastSuccessfulReleaseVersion: 3.7
  observedGeneration: 1
  sucNameSuffix: 90315a2b6d

21.7.2 Helm Controller

このセクションでは、helm-controller によって作成されたリソースを追跡する方法について説明します。

注記
注記

以下の手順では、kubectl が Upgrade Controller がデプロイされているクラスターに接続するように構成されていることを前提としています。

  1. 特定のコンポーネントの HelmChart リソースを見つけます:

    kubectl get helmcharts -n kube-system
  2. HelmChart リソースの名前を使用して、helm-controller によって作成されたアップグレード Pod を見つけます:

    kubectl get pods -l helmcharts.helm.cattle.io/chart=<helmchart_name> -n kube-system
    
    # Example for Rancher
    kubectl get pods -l helmcharts.helm.cattle.io/chart=rancher -n kube-system
    NAME                         READY   STATUS      RESTARTS   AGE
    helm-install-rancher-tv9wn   0/1     Completed   0          16m
  3. コンポーネント固有の Pod のログを表示します:

    kubectl logs <pod_name> -n kube-system

21.8 既知の制限事項

  • Upgrade Controllerは、EIB (第12章 「Edge Image Builder」)を通じてデプロイされる追加の SUSE Telco Cloud Helmチャートについて、その HelmChart CR が kube-system ネームスペースにデプロイされていることを前提としています。これを行うには、EIB定義ファイルで installationNamespace プロパティを設定してください。詳細については、アップストリームのドキュメントを参照してください。

  • 現在、Upgrade Controllerには、管理クラスター上で現在実行されているEdgeリリースバージョンを特定する方法はありません。クラスター上で現在実行されているEdgeリリースバージョンよりも新しいEdgeリリースバージョンを必ず指定してください。

  • 現在、Upgrade Controllerは 非エアギャップ(された) 環境のアップグレードのみをサポートしています。エアギャップ(された) 環境でのアップグレードはまだできません。

パート IV 要件と前提

  • 22 Hardware (ハードウェア)
  • SUSE Telco Cloudのハードウェア要件は以下の通りです。

  • 23 ネットワーク
  • ネットワークアーキテクチャの参考として、次の図にTelco環境の一般的なネットワークアーキテクチャを示します。

  • 24 ポートの要件
  • 適切に動作させるために、SUSE Telco Cloudのデプロイメントでは、管理ノードおよびダウンストリームKubernetesクラスターノードで多数のポートに到達できる必要があります。

  • 25 サービス(DHCP、DNSなど)
  • デプロイ先の環境の種類によっては、DHCP、`DNS`などの外部サービスが必要になる場合があります。

  • 26 systemdサービスの無効化
  • Telcoワークロードの場合、ノード上で実行されているワークロードのパフォーマンス(レイテンシ)への影響を回避するために、ノード上で実行されている一部のサービスを無効にするか、適切に設定することが重要です。

22 Hardware (ハードウェア)

SUSE Telco Cloudのハードウェア要件は以下の通りです。

  • 管理クラスタ:管理クラスタには`SUSE Linux Micro`、RKE2、SUSE Rancher Prime、`Metal3`などのコンポーネントが含まれており、複数のダウンストリームクラスタを管理するために使用されます。管理するダウンストリームクラスタの数に応じて、サーバーのハードウェア要件は異なる場合があります。

    • サーバー(VM`または`bare-metal)の最小要件は以下の通りです。

      • RAM:最小8 GB(16 GB以上を推奨)

      • CPU:最小2(4 CPU以上を推奨)

  • ダウンストリームクラスタ:ダウンストリームクラスタは、Telcoワークロードを実行するためにデプロイされるクラスタです。SR-IOV、`CPU Performance Optimization`などの特定のTelco機能を有効にするには、特定の要件が必要です。

    • SR-IOV: パススルーモードでVF(仮想機能)をCNF/VNFに接続するには、NICがSR-IOVをサポートし、BIOSでVT-d/AMD-Viが有効になっている必要があります。

    • CPUプロセッサ:特定のTelcoワークロードを実行するには、この参照テーブル (パートVI「Telco機能の設定」)で利用可能な機能のほとんどを有効にするために、CPUプロセッサモデルを適合させる必要があります。

    • 仮想メディアを使用してインストールするためのファームウェア要件:

      サーバハードウェアBMCモデル管理

      Dellハードウェア

      第15世代

      iDRAC9

      Supermicroハードウェア

      01.00.25

      Supermicro SMC - redfish

      HPEハードウェア

      1.50

      iLO6

23 ネットワーク

ネットワークアーキテクチャの参考として、次の図にTelco環境の一般的なネットワークアーキテクチャを示します。

product atip requirements1

ネットワークアーキテクチャは、以下のコンポーネントに基づいています。

  • 管理ネットワーク:このネットワークは、ダウンストリームクラスターノードの管理に使用されます。これは帯域外管理に使用されます。通常、このネットワークは別の管理スイッチにも接続されますが、VLANを使用してトラフィックを分離することで、同じサービススイッチに接続することも可能です。

  • コントロールプレーンネットワーク:このネットワークは、ダウンストリームクラスターノード間およびそれらで実行されているサービス間の通信に使用されます。このネットワークは、ノードと`DHCP`や`DNS`サーバーなどの外部サービスとの間の通信にも使用されます。接続環境によっては、スイッチ/ルーターがインターネット経由のトラフィックを処理できる場合があります。

  • その他のネットワーク:特定の目的のために、ノードが他のネットワークに接続される場合があります。

注記
注記

ダイレクトネットワークプロビジョニングワークフローを使用するには、ホストの準備とプロビジョニングを自動化できるように、管理クラスタがダウンストリームクラスタサーバーのベースボード管理コントローラー(BMC)へのネットワーク接続を備えている必要があります。

24 ポートの要件

適切に動作させるために、SUSE Telco Cloudのデプロイメントでは、管理ノードおよびダウンストリームKubernetesクラスターノードで多数のポートに到達できる必要があります。

注記
注記

正確なリストは、デプロイされたオプションコンポーネントおよび選択されたデプロイメントオプション(CNIプラグインなど)によって異なります。

24.1 管理ノード

次の表は、管理クラスタを実行しているノードで開かれているポートの一覧です。

注記
注記

CNIプラグイン関連のポートについては、CNI固有のポート要件 (24.3項 「CNI固有のポート要件」)を参照してください。

表 24.1: 管理ノードのインバウンドネットワークルール
プロトコルポートソース説明

TCP

22

SSHアクセスを必要とするすべてのソース

管理クラスタのノードへのSSHアクセス

TCP

80

外部TLS終端を行うロードバランサー/プロキシ

外部TLS終端が使用されている場合のRancher UI/API

TCP

443

Rancher UI/APIへのTLSアクセスを必要とするすべてのソース

Rancherエージェント、Rancher UI/API

TCP

2379

RKE2(管理クラスタ)サーバーノード

etcd クライアントポート

TCP

2380

RKE2(管理クラスタ)サーバーノード

etcd ピアポート

TCP

6180

この公開ポート(非TLS)からIPA(2)ラムディスクイメージをプルするように`Metal3/ironic`から以前に指示されたすべてのBMC(1)

仮想メディアベースのブート用にIPA(2) ISOイメージを提供する`Ironic` httpd非TLS Webサーバー

このポートが有効な場合、機能的に同等なTLS対応ポート(下記参照)は開かれません

TCP

6185

この公開ポート(TLS)からIPA(2)ラムディスクイメージをプルするように`Metal3/ironic`から以前に指示されたすべてのBMC(1)

仮想メディアベースのブート用にIPA(2) ISOイメージを提供する`Ironic` httpd TLS対応Webサーバー

このポートが有効な場合、機能的に同等なTLS非対応ポート(上記参照)は開かれません

TCP

6385

「登録済み」インスタンスでデプロイおよび実行されている任意の Metal3/ironic IPA(1) ラムディスクイメージ`BareMetalHost`

Ironic API

TCP

6443

任意の管理クラスタのノード、任意の(管理クラスタ外の)Kubernetes クライアント

Kubernetes API

TCP

6545

任意の管理クラスタのノード

OCI 準拠レジストリ(Hauler)からアーティファクトをプルする

TCP

9345

RKE2 サーバーおよびエージェントノード(管理クラスタ)

ノード登録用の RKE2 スーパーバイザー API(すべての RKE2 サーバーノードでポートを開放)

TCP

10250

任意の管理クラスタのノード

kubelet メトリクス

TCP/UDP/SCTP

30000-32767

spec.type: NodePort または spec.type: LoadBalancer Service API オブジェクト を介してプライマリネットワーク上で公開されたサービスにアクセスする任意の(管理クラスタ外の)外部ソース

利用可能な NodePort ポート範囲

(1) BMC:ベースボード管理コントローラー
(2) IPA:Ironic Python Agent

24.2 ダウンストリーム ノード

SUSE Telco Cloud では、任意の(ダウンストリーム)サーバーが実行中のダウンストリーム Kubernetes クラスタの一部になる(またはそれ自体がシングルノードのダウンストリーム Kubernetes クラスタを実行する)前に、 BaremetalHost プロビジョニング状態 のいくつかを通過する必要があります。

  • 宣言されたばかりのダウンストリームサーバーのベースボード管理コントローラー(BMC)は、帯域外ネットワーク経由でアクセス可能である必要があります。BMC は(管理クラスタ上で実行されている ironic サービスから)実行すべき初期ステップについて指示を受けます:

    1. BMC が提供する virtual media に、指定された IPA ラムディスクイメージをプルしてロードします。

    2. サーバーの電源を入れます。

BMCから公開されることが想定されるポートは以下の通りです(正確なハードウェアによって異なる場合があります)。

表 24.2: ベースボード管理コントローラーのインバウンドネットワークルール
プロトコルポートソース説明

TCP

80

Ironicコンダクター(管理クラスタから)

Redfish APIアクセス(HTTP)

TCP

443

Ironicコンダクター(管理クラスタから)

Redfish APIアクセス(HTTPS)

  • BMC virtual media に読み込まれた IPA RAMディスクイメージを使用してダウンストリームサーバーイメージを起動すると、ハードウェア検査フェーズが開始されます。次の表は、実行中の IPA RAMディスクイメージによって公開されるポートの一覧です。

表 24.3: ダウンストリームノードのインバウンドネットワークルール - Metal3/Ironic プロビジョニングフェーズ
プロトコルポートソース説明

TCP

22

IPA RAMディスクイメージへのSSHアクセスを必要とするすべてのソース

検査中のダウンストリームクラスタのノードへのSSHアクセス

TCP

9999

Ironicコンダクター(管理クラスタから)

実行中のRAMディスクイメージに対するIronicコマンド

  • ベアメタルホストが適切にプロビジョニングされ、ダウンストリームのKubernetesクラスタに参加すると、以下のポートが公開されます。

注記
注記

CNIプラグイン関連のポートについては、CNI固有のポート要件 (24.3項 「CNI固有のポート要件」)を参照してください。

表 24.4: ダウンストリームノードのインバウンドネットワークルール
プロトコルポートソース説明

TCP

22

SSHアクセスを必要とするすべてのソース

ダウンストリームクラスターノードへのSSHアクセス

TCP

80

外部TLS終端を行うロードバランサー/プロキシ

外部TLS終端が使用されている場合のRancher UI/API

TCP

443

Rancher UI/APIへのTLSアクセスを必要とするすべてのソース

Rancherエージェント、Rancher UI/API

TCP

2379

RKE2(ダウンストリームクラスタ)サーバーノード

etcd クライアントポート

TCP

2380

RKE2(ダウンストリームクラスタ)サーバーノード

etcd ピアポート

TCP

6443

任意のダウンストリームクラスターノード、任意の外部(ダウンストリームクラスタ外の)Kubernetesクライアント。

Kubernetes API

TCP

9345

RKE2サーバーおよびエージェントノード(ダウンストリームクラスタ)

ノード登録用の RKE2 スーパーバイザー API(すべての RKE2 サーバーノードでポートを開放)

TCP

10250

任意のダウンストリームクラスターノード

kubelet メトリクス

TCP

10255

任意のダウンストリームクラスターノード

kubelet 読み込み専用アクセス

TCP/UDP/SCTP

30000-32767

spec.type: NodePort`または`spec.type: LoadBalancer Service APIオブジェクトを通じてプライマリネットワーク上で公開されているサービスにアクセスする(ダウンストリームクラスタ外の)外部ソース

利用可能な NodePort ポート範囲

24.3 CNI固有のポート要件

サポートされている各CNIバリアントには、独自のポート要件セットがあります。詳細については、RKE2ドキュメントの CNI固有のインバウンドネットワークルールを参照してください。

`cilium`がデフォルト/プライマリCNIプラグインとして設定されている場合、`cilium-operator`ワークロードがデプロイ先のKubernetesクラスタ外にメトリクスを公開するように構成されていると、以下のTCPポートが追加で公開されます。これにより、そのKubernetesクラスタ外で実行されている外部`Prometheus`サーバインスタンスが、引き続きこれらのメトリクスを収集できるようになります。

注記
注記

これは、rke2-cilium Helmチャートを介して`cilium`をデプロイする場合のデフォルトオプションです。

表 24.5: 管理/ダウンストリームノードのインバウンドネットワークルール - `cilium-operator`が有効な場合の外部メトリクス公開
プロトコルポートソース説明

TCP

9963

外部(Kubernetesクラスタ外の)メトリクスコレクタ

cilium-operatorメトリクスの公開

25 サービス(DHCP、DNSなど)

デプロイ先の環境の種類によっては、DHCP、`DNS`などの外部サービスが必要になる場合があります。

  • 接続環境:この場合、ノードは(L3ルーティングプロトコルを介して)インターネットに接続され、外部サービスはお客様によって提供されます。

  • 切断環境 / エアギャップ環境:この場合、ノードはインターネットIP接続を持たず、ダイレクトネットワークプロビジョニングワークフローで必要とされるコンテンツをローカルにミラーリングするために追加のサービスが必要となります。

  • ファイルサーバ:ファイルサーバは、ダイレクトネットワークプロビジョニングワークフロー中にダウンストリームクラスターノードにプロビジョニングされるOSイメージを保存するために使用されます。Metal3 HelmチャートはOSイメージを保存するためのメディアサーバをデプロイできます。次のセクション (注記)を確認してください。ただし、既存のローカルWebサーバを使用することも可能です。

26 systemdサービスの無効化

Telcoワークロードの場合、ノード上で実行されているワークロードのパフォーマンス(レイテンシ)への影響を回避するために、ノード上で実行されている一部のサービスを無効にするか、適切に設定することが重要です。

  • `rebootmgr`は、システムに保留中の更新がある場合に再起動の戦略を設定できるようにするサービスです。 Telcoワークロードの場合、システムによってスケジュールされた更新によるノードの再起動を回避し、ノード上で実行されているサービスへの影響を避けるために、`rebootmgr`サービスを無効にするか、適切に設定することが非常に重要です。

注記
注記

`rebootmgr`の詳細については、 rebootmgr GitHubリポジトリを参照してください。

使用されている戦略を確認するには、次を実行します。

cat /etc/rebootmgr.conf
[rebootmgr]
window-start=03:30
window-duration=1h30m
strategy=best-effort
lock-group=default

また、次を実行して無効にすることもできます。

sed -i 's/strategy=best-effort/strategy=off/g' /etc/rebootmgr.conf

または、`rebootmgrctl`コマンドを使用します。

rebootmgrctl strategy off
注記
注記

`rebootmgr`戦略を設定するためのこの構成は、ダイレクトネットワークプロビジョニングワークフローを使用して自動化できます。詳細については、自動プロビジョニングのドキュメント (パートVII「完全自動化されたダイレクトネットワークプロビジョニング」)を確認してください。

  • `transactional-update`は、システムによって制御される自動更新を可能にするサービスです。Telcoワークロードの場合、ノード上で実行されているサービスへの影響を回避するために、自動更新を無効にすることが重要です。

自動更新を無効にするには、次のコマンドを実行します。

systemctl --now disable transactional-update.timer
systemctl --now disable transactional-update-cleanup.timer
  • `fstrim`は、毎週自動的にファイルシステムをトリムできるようにするサービスです。Telcoワークロードの場合、ノード上で実行されているサービスへの影響を回避するために、自動トリムを無効にすることが重要です。

自動トリムを無効にするには、次のコマンドを実行します。

systemctl --now disable fstrim.timer

パート V 管理クラスタのセットアップ

  • 27 概要
  • 管理クラスタは、ランタイムスタックのプロビジョニングとライフサイクルを管理するために使用されるSUSE Telco Cloudの一部です。 技術的な観点から、管理クラスタには以下のコンポーネントが含まれています。

  • 28 管理クラスタをセットアップする手順
  • 管理クラスタをセットアップするには(単一ノードを使用)、以下の手順が必要です。

  • 29 接続環境向けのイメージ準備
  • Edge Image Builderは管理クラスター用のイメージを作成するために使用されます。本書では、管理クラスターをセットアップするために必要な最小限の設定について説明します。

  • 30 エアギャップ環境向けのイメージ準備
  • このセクションでは、前のセクションとの違いのみを示し、エアギャップ環境向けにイメージを準備する方法について説明します。エアギャップ環境向けにイメージを準備するには、前のセクション(接続環境向けのイメージ準備 (第29章 「接続環境向けのイメージ準備」))に対して以下の変更が必要です。

  • 31 イメージの作成
  • (接続環境とエアギャップ環境の両方について)前のセクションに従ってディレクトリ構造を準備したら、次のコマンドを実行してイメージをビルドします。

  • 32 管理クラスターのプロビジョニング
  • 前のイメージには上記で説明したすべてのコンポーネントが含まれており、仮想マシンまたはベアメタルサーバー(仮想メディア機能を使用)を使用して管理クラスターをプロビジョニングするために使用できます。

  • 33 デュアルスタックに関する考慮事項と構成
  • 前のセクションで示した例は、シングルスタック IPv4 管理クラスターをセットアップする方法に関するガイダンスと例を提供しています。このような管理クラスターは、ダウンストリームクラスターの動作状態とは独立しており、ダウンストリームクラスターはデプロイ後に IPv4/IPv6 シングルスタックまたはデュアルスタック構成のいずれかで動作するように個別に構成できます。ただし、管理クラスターの構成方法は、プロビジョニングフェーズで使用できる通信プロトコルに直接影響します。インバンド通信とアウト・オブ・バンド通信の両方が、管理クラスターとダウンストリームホストがサポートするプロトコルに従って行われる必要…

27 概要

管理クラスタは、ランタイムスタックのプロビジョニングとライフサイクルを管理するために使用されるSUSE Telco Cloudの一部です。 技術的な観点から、管理クラスタには以下のコンポーネントが含まれています。

  • OSとしての`SUSE Linux Micro`。ユースケースに応じて、ネットワーク、ストレージ、ユーザー、カーネル引数などの一部の構成をカスタマイズできます。

  • Kubernetesクラスタとしての`RKE2`。ユースケースに応じて、Multus、Cilium、`Calico`などの特定のCNIプラグインを使用するように構成できます。

  • クラスタのライフサイクルを管理するための管理プラットフォームとしての`Rancher`。

  • ベアメタルノードのライフサイクルを管理するためのコンポーネントとしての`Metal3`。

  • Kubernetesクラスタ(ダウンストリームクラスタ)のライフサイクルを管理するためのコンポーネントとしての`CAPI`。`RKE2 CAPI Provider`は、RKE2クラスタのライフサイクルを管理するために使用されます。

上記のすべてのコンポーネントにより、管理クラスタは、宣言的なアプローチを使用してインフラストラクチャおよびアプリケーションを管理し、ダウンストリームクラスタのライフサイクルを管理できます。

注記
注記

`SUSE Linux Micro`の詳細については、以下を参照してください。SUSE Linux Micro (第10章 「SUSE Linux Micro」)

`RKE2`の詳細については、以下を参照してください。RKE2 (第14章 「RKE2」)

`Rancher`の詳細については、以下を参照してください。Rancher (第6章 「Rancher」)

`Metal3`の詳細については、以下を参照してください。Metal3 (第11章 「Metal3」)

28 管理クラスタをセットアップする手順

管理クラスタをセットアップするには(単一ノードを使用)、以下の手順が必要です。

product atip mgmtcluster1

宣言的なアプローチを使用して管理クラスタをセットアップするための主な手順は以下のとおりです。

  1. 接続環境向けのイメージ準備 (第29章 「接続環境向けのイメージ準備」):最初のステップは、接続環境で使用するために必要なすべての構成を含むマニフェストとファイルを準備することです。

    • 接続環境のディレクトリ構造 (29.1項 「ディレクトリ構造」):このステップでは、Edge Image Builderが設定ファイルとイメージ自体を保存するために使用するディレクトリ構造を作成します。

    • 管理クラスター定義ファイル (29.2項 「管理クラスター定義ファイル」):`mgmt-cluster.yaml`ファイルは、管理クラスターのメイン定義ファイルです。これには、作成されるイメージに関する以下の情報が含まれています。

      • イメージ情報:ベースイメージを使用して作成されるイメージに関連する情報。

      • オペレーティングシステム:イメージで使用されるオペレーティングシステムの構成。

      • Kubernetes:Helmチャートとリポジトリ、Kubernetesバージョン、ネットワーク設定、およびクラスターで使用されるノード。

    • カスタムフォルダ (29.3項 「カスタムフォルダ」):`custom`フォルダには、Edge Image Builderが完全に機能する管理クラスターをデプロイするために使用する設定ファイルとスクリプトが含まれています。

      • ファイル:管理クラスターで使用される設定ファイルが含まれています。

      • スクリプト:管理クラスターで使用されるスクリプトが含まれています。

    • Kubernetesフォルダ (29.4項 「Kubernetes フォルダ」):`kubernetes`フォルダには、管理クラスターで使用される設定ファイルが含まれています。

      • マニフェスト:管理クラスターで使用されるマニフェストが含まれています。

      • Helm:管理クラスターで使用するHelm値ファイルが含まれています。

      • Config:管理クラスターで使用される設定ファイルが含まれています。

    • ネットワークフォルダ (29.5項 「Networkingフォルダ」):`network`フォルダには、管理クラスターノードで使用するネットワーク設定ファイルが含まれています。

  2. エアギャップ環境向けのイメージ準備 (第30章 「エアギャップ環境向けのイメージ準備」):このステップでは、エアギャップシナリオで使用するマニフェストとファイルの準備における違いを示します。

    • 定義ファイルの変更 (30.1項 「定義ファイルの変更」):EIB出力イメージに含めるすべてのコンテナイメージに対して`images`フィールドが設定された`embeddedArtifactRegistry`セクションを含めるように、`mgmt-cluster.yaml`ファイルを変更する必要があります。

    • カスタムフォルダの変更 (30.2項 「カスタムフォルダーの変更」):エアギャップ環境で管理クラスターを実行するために必要なリソースを含めるように、`custom`フォルダを変更する必要があります。

      • 登録スクリプト:エアギャップ環境を使用する場合は、`custom/scripts/99-register.sh`スクリプトを削除する必要があります。

  3. イメージの作成 (第31章 「イメージの作成」):このステップでは、Edge Image Builderツールを使用したイメージの作成について説明します(接続環境とエアギャップ環境の両方に対応)。システムでEdge Image Builderツールを実行するための前提条件 (第12章 「Edge Image Builder」)を確認してください。

  4. 管理クラスターのプロビジョニング (第32章 「管理クラスターのプロビジョニング」):このステップでは、前のステップで作成したイメージを使用した管理クラスターのプロビジョニングについて説明します(接続環境とエアギャップ環境の両方に対応)。このステップは、ラップトップ、サーバー、VM、またはUSBポートを備えたその他のAMD64/Intel 64システムを使用して実行できます。

注記
注記

Edge Image Builderの詳細については、Edge Image Builder (第12章 「Edge Image Builder」)およびEdge Image Builder クイックスタート (第5章 「Edge Image Builderを使用したスタンドアロンクラスター」)を参照してください。

29 接続環境向けのイメージ準備

Edge Image Builderは管理クラスター用のイメージを作成するために使用されます。本書では、管理クラスターをセットアップするために必要な最小限の設定について説明します。

Edge Image Builderはコンテナ内で実行されるため、 Podmanや Rancher Desktopなどのコンテナランタイムが必要です。このガイドでは、podmanが利用可能であると想定しています。

また、高可用性管理クラスターをデプロイするための前提条件として、ネットワーク内に3つのIPを予約する必要があります。

  • `apiVIP`はAPI VIPアドレス用(Kubernetes APIサーバーへのアクセスに使用)。

  • `ingressVIP`はIngress VIPアドレス用(例えば、Rancher UIによって消費される)。

  • `metal3VIP`はMetal3 VIPアドレス用。

29.1 ディレクトリ構造

EIBを実行する際、ホストからディレクトリがマウントされるため、最初に行うことは、EIBが設定ファイルとイメージ自体を保存するために使用するディレクトリ構造を作成することです。 このディレクトリには、次の構造があります。

eib
├── mgmt-cluster.yaml
├── network
│ └── mgmt-cluster-node1.yaml
├── os-files
│ └── var
│   └── lib
│     └── rancher
│       └── rke2
│         └── server
│           └── manifests
│             └── rke2-ingress-config.yaml
├── kubernetes
│ ├── manifests
│ │ ├── neuvector-namespace.yaml
│ │ ├── ingress-l2-adv.yaml
│ │ └── ingress-ippool.yaml
│ ├── helm
│ │ └── values
│ │     ├── rancher.yaml
│ │     ├── neuvector.yaml
│ │     ├── longhorn.yaml
│ │     ├── metal3.yaml
│ │     └── certmanager.yaml
│ └── config
│     └── server.yaml
├── custom
│ ├── scripts
│ │ ├── 99-register.sh
│ │ ├── 99-mgmt-setup.sh
│ │ └── 99-alias.sh
│ └── files
│     ├── rancher.sh
│     ├── mgmt-stack-setup.service
│     ├── metal3.sh
│     └── basic-setup.sh
└── base-images
注記
注記

イメージ`SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso`は、 SUSE Customer Centerまたは SUSEダウンロードページからダウンロードする必要があり、`base-images`フォルダの下に配置する必要があります。

イメージが改ざんされていないことを確認するために、SHA256チェックサムを確認する必要があります。チェックサムは、イメージをダウンロードしたのと同じ場所で確認できます。

ディレクトリ構造の例は、 SUSE Telco Cloud GitHubリポジトリの「telco-examples」フォルダにあります。

29.2 管理クラスター定義ファイル

`mgmt-cluster.yaml`ファイルは、管理クラスターのメイン定義ファイルです。この章は次の項目で構成されています。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
  outputImageName: eib-mgmt-cluster-image.iso
operatingSystem:
  isoConfiguration:
    installDevice: /dev/sda
  users:
  - username: root
    encryptedPassword: $ROOT_PASSWORD
  packages:
    packageList:
    - jq
    - open-iscsi
    sccRegistrationCode: $SCC_REGISTRATION_CODE
kubernetes:
  version: v1.36.3+rke2r1
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: 1.20.1
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: suse-storage
        releaseName: longhorn
        version: 1.12.1
        repositoryName: rancher-application-collection
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: longhorn.yaml
      - name: metallb
        version: 307.0.3+up0.16.1
        targetNamespace: metallb-system
        createNamespace: true
        repositoryName: suse-edge-charts
        installationNamespace: kube-system
      - name: metal3
        version: 307.0.31+up0.16.0
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: rancher-turtles-providers
        version: 307.0.8+up0.27.0
        repositoryName: suse-edge-charts
        targetNamespace: cattle-turtles-system
        createNamespace: true
        installationNamespace: kube-system
      - name: neuvector-crd
        version: 110.0.1+up2.11.1
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 110.0.1+up2.11.1
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.15.1
        repositoryName: rancher-prime
        targetNamespace: cattle-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: rancher.yaml
    repositories:
      - name: jetstack
        url: https://charts.jetstack.io
      - name: rancher-charts
        url: https://charts.rancher.io/
      - name: suse-edge-charts
        url: oci://registry.suse.com/edge/charts
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
      - name: rancher-application-collection
        url: oci://dp.apps.rancher.io/charts
        authentication:
          username: $\{APPS.RANCHER.IO_USERNAME\}
          password: $\{APPS.RANCHER.IO_ACCESS_TOKEN\}
  network:
    apiHost: $API_HOST
    apiVIP: $API_VIP
  nodes:
    - hostname: mgmt-cluster-node1
      initializer: true
      type: server
#   - hostname: mgmt-cluster-node2
#     type: server
#   - hostname: mgmt-cluster-node3
#     type: server

`mgmt-cluster.yaml`定義ファイルのフィールドと値を説明するために、以下のセクションに分割しました。

  • イメージセクション(定義ファイル):

image:
  imageType: iso
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
  outputImageName: eib-mgmt-cluster-image.iso

`baseImage`は、SUSE Customer CenterまたはSUSEダウンロードページからダウンロードした元のイメージです。`outputImageName`は、管理クラスターのプロビジョニングに使用される新しいイメージの名前です。

  • オペレーティングシステムセクション(定義ファイル):

operatingSystem:
  isoConfiguration:
    installDevice: /dev/sda
  users:
  - username: root
    encryptedPassword: $ROOT_PASSWORD
  packages:
    packageList:
    - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE

installDevice`はオペレーティングシステムのインストールに使用するデバイス、`username`と`encryptedPassword`はシステムへのアクセスに使用する資格情報、`packageList`はインストールするパッケージのリスト(`jq`はインストールプロセス中に内部的に必要)、`sccRegistrationCode`はビルド時にパッケージと依存関係を取得するために使用される登録コードであり、SUSE Customer Centerから入手できます。 暗号化されたパスワードは、`openssl コマンドを使用して次のように生成できます。

openssl passwd -6 MyPassword!123

これは次のような出力を生成します。

$6$UrXB1sAGs46DOiSq$HSwi9GFJLCorm0J53nF2Sq8YEoyINhHcObHzX2R8h13mswUIsMwzx4eUzn/rRx0QPV4JIb0eWCoNrxGiKH4R31
  • Kubernetes セクション(定義ファイル):

kubernetes:
  version: v1.36.3+rke2r1
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: 1.20.1
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: suse-storage
        releaseName: longhorn
        version: 1.12.1
        repositoryName: rancher-application-collection
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: longhorn.yaml
      - name: metal3
        version: 307.0.31+up0.16.0
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: metallb
        version: 307.0.3+up0.16.1
        targetNamespace: metallb-system
        createNamespace: true
        repositoryName: suse-edge-charts
        installationNamespace: kube-system
      - name: rancher-turtles-providers
        version: 307.0.8+up0.27.0
        repositoryName: suse-edge-charts
        targetNamespace: cattle-turtles-system
        createNamespace: true
        installationNamespace: kube-system
      - name: neuvector-crd
        version: 110.0.1+up2.11.1
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 110.0.1+up2.11.1
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.15.1
        repositoryName: rancher-prime
        targetNamespace: cattle-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: rancher.yaml
    repositories:
      - name: jetstack
        url: https://charts.jetstack.io
      - name: rancher-charts
        url: https://charts.rancher.io/
      - name: suse-edge-charts
        url: oci://registry.suse.com/edge/charts
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
      - name: rancher-application-collection
        url: oci://dp.apps.rancher.io/charts
        authentication:
          username: $\{APPS.RANCHER.IO_USERNAME\}
          password: $\{APPS.RANCHER.IO_ACCESS_TOKEN\}
    network:
      apiHost: $API_HOST
      apiVIP: $API_VIP
    nodes:
    - hostname: mgmt-cluster-node1
      initializer: true
      type: server
#   - hostname: mgmt-cluster-node2
#     type: server
#   - hostname: mgmt-cluster-node3
#     type: server

helm セクションには、インストールする Helm チャートのリスト、使用するリポジトリ、およびそれらすべてのバージョン構成が含まれています。

network セクションには、RKE2 コンポーネントで使用される apiHost や apiVIP などのネットワーク構成が含まれています。 apiVIP は、ネットワーク内で使用されていない IP アドレスである必要があり、(DHCP を使用する場合)DHCP プールの一部であってはなりません。また、マルチノードクラスターで apiVIP を使用する場合、これは Kubernetes API サーバーへのアクセスに使用されます。 apiHost は、RKE2 コンポーネントで使用される apiVIP への名前解決です。

nodes セクションには、クラスターで使用されるノードのリストが含まれています。この例ではシングルノードクラスターが使用されていますが、リストにノードを追加する(行のコメントを解除する)ことで、マルチノードクラスターに拡張できます。

注記
注記
  • クラスター内のノード名は一意である必要があります。

  • オプションで initializer フィールドを使用してブートストラップホストを指定できます。指定しない場合は、リストの最初のノードが使用されます。

  • ネットワーク構成が必要な場合、ノード名は Network Folder (29.5項 「Networkingフォルダ」) で定義されたホスト名と同じである必要があります。

29.3 カスタムフォルダ

custom フォルダには、次のサブフォルダが保管されています。

...
├── custom
│ ├── scripts
│ │ ├── 99-register.sh
│ │ ├── 99-mgmt-setup.sh
│ │ └── 99-alias.sh
│ └── files
│     ├── rancher.sh
│     ├── mgmt-stack-setup.service
│     ├── metal3.sh
│     └── basic-setup.sh
...
  • custom/files フォルダには、管理クラスターで使用される設定ファイルが保管されています。

  • custom/scripts フォルダには、管理クラスターで使用されるスクリプトが含まれています。

custom/files フォルダには、次のファイルが収められます。

  • basic-setup.sh: Metal3、Rancher、および MetalLB の構成パラメータが含まれています。使用する名前空間を変更する場合にのみ、このファイルを変更してください。

    #!/bin/bash
    # Pre-requisites. Cluster already running
    export KUBECTL="/var/lib/rancher/rke2/bin/kubectl"
    export KUBECONFIG="/etc/rancher/rke2/rke2.yaml"
    
    ##################
    # METAL3 DETAILS #
    ##################
    export METAL3_CHART_TARGETNAMESPACE="metal3-system"
    
    ###########
    # METALLB #
    ###########
    export METALLBNAMESPACE="metallb-system"
    
    ###########
    # RANCHER #
    ###########
    export RANCHER_CHART_TARGETNAMESPACE="cattle-system"
    export RANCHER_FINALPASSWORD="adminadminadmin"
    
    die(){
      echo ${1} 1>&2
      exit ${2}
    }
  • metal3.sh: 使用する Metal3 コンポーネントの構成が含まれています(変更は不要です)。将来のバージョンでは、このスクリプトは Rancher Turtles を使用するように置き換えられ、簡素化される予定です。

    #!/bin/bash
    set -euo pipefail
    
    BASEDIR="$(dirname "$0")"
    source ${BASEDIR}/basic-setup.sh
    
    METAL3LOCKNAMESPACE="default"
    METAL3LOCKCMNAME="metal3-lock"
    
    trap 'catch $? $LINENO' EXIT
    
    catch() {
      if [ "$1" != "0" ]; then
        echo "Error $1 occurred on $2"
        ${KUBECTL} delete configmap ${METAL3LOCKCMNAME} -n ${METAL3LOCKNAMESPACE}
      fi
    }
    
    # Get or create the lock to run all those steps just in a single node
    # As the first node is created WAY before the others, this should be enough
    # TODO: Investigate if leases is better
    if [ $(${KUBECTL} get cm -n ${METAL3LOCKNAMESPACE} ${METAL3LOCKCMNAME} -o name | wc -l) -lt 1 ]; then
      ${KUBECTL} create configmap ${METAL3LOCKCMNAME} -n ${METAL3LOCKNAMESPACE} --from-literal foo=bar
    else
      exit 0
    fi
    
    # Wait for metal3
    while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_CHART_TARGETNAMESPACE} $(${KUBECTL} get pods -n ${METAL3_CHART_TARGETNAMESPACE} -l app.kubernetes.io/name=metal3-ironic -o name) --timeout=10s; do sleep 2 ; done
    
    # Get the ironic IP
    IRONICIP=$(${KUBECTL} get cm -n ${METAL3_CHART_TARGETNAMESPACE} ironic -o jsonpath='{.data.IRONIC_IP}')
    
    # If LoadBalancer, use metallb, else it is NodePort
    if [ $(${KUBECTL} get svc -n ${METAL3_CHART_TARGETNAMESPACE} metal3-metal3-ironic -o jsonpath='{.spec.type}') == "LoadBalancer" ]; then
      # Wait for metallb
      while ! ${KUBECTL} wait --for condition=ready -n ${METALLBNAMESPACE} $(${KUBECTL} get pods -n ${METALLBNAMESPACE} -l app.kubernetes.io/component=controller -o name) --timeout=10s; do sleep 2 ; done
    
      # Do not create the ippool if already created
      ${KUBECTL} get ipaddresspool -n ${METALLBNAMESPACE} ironic-ip-pool -o name || cat <<-EOF | ${KUBECTL} apply -f -
      apiVersion: metallb.io/v1beta1
      kind: IPAddressPool
      metadata:
        name: ironic-ip-pool
        namespace: ${METALLBNAMESPACE}
      spec:
        addresses:
        - ${IRONICIP}/32
        serviceAllocation:
          priority: 100
          serviceSelectors:
          - matchExpressions:
            - {key: app.kubernetes.io/name, operator: In, values: [metal3-ironic]}
        EOF
    
      # Same for L2 Advs
      ${KUBECTL} get L2Advertisement -n ${METALLBNAMESPACE} ironic-ip-pool-l2-adv -o name || cat <<-EOF | ${KUBECTL} apply -f -
      apiVersion: metallb.io/v1beta1
      kind: L2Advertisement
      metadata:
        name: ironic-ip-pool-l2-adv
        namespace: ${METALLBNAMESPACE}
      spec:
        ipAddressPools:
        - ironic-ip-pool
        EOF
    fi
    
    # Clean up the lock cm
    
    ${KUBECTL} delete configmap ${METAL3LOCKCMNAME} -n ${METAL3LOCKNAMESPACE}
    • rancher.sh: 使用する Rancher コンポーネントの構成が含まれています(変更は不要です)。

      #!/bin/bash
      set -euo pipefail
      
      BASEDIR="$(dirname "$0")"
      source ${BASEDIR}/basic-setup.sh
      
      RANCHERLOCKNAMESPACE="default"
      RANCHERLOCKCMNAME="rancher-lock"
      
      if [ -z "${RANCHER_FINALPASSWORD}" ]; then
        # If there is no final password, then finish the setup right away
        exit 0
      fi
      
      trap 'catch $? $LINENO' EXIT
      
      catch() {
        if [ "$1" != "0" ]; then
          echo "Error $1 occurred on $2"
          ${KUBECTL} delete configmap ${RANCHERLOCKCMNAME} -n ${RANCHERLOCKNAMESPACE}
        fi
      }
      
      # Get or create the lock to run all those steps just in a single node
      # As the first node is created WAY before the others, this should be enough
      # TODO: Investigate if leases is better
      if [ $(${KUBECTL} get cm -n ${RANCHERLOCKNAMESPACE} ${RANCHERLOCKCMNAME} -o name | wc -l) -lt 1 ]; then
        ${KUBECTL} create configmap ${RANCHERLOCKCMNAME} -n ${RANCHERLOCKNAMESPACE} --from-literal foo=bar
      else
        exit 0
      fi
      
      # Wait for rancher to be deployed
      while ! ${KUBECTL} wait --for condition=ready -n ${RANCHER_CHART_TARGETNAMESPACE} $(${KUBECTL} get pods -n ${RANCHER_CHART_TARGETNAMESPACE} -l app=rancher -o name) --timeout=10s; do sleep 2 ; done
      until ${KUBECTL} get ingress -n ${RANCHER_CHART_TARGETNAMESPACE} rancher > /dev/null 2>&1; do sleep 10; done
      
      RANCHERBOOTSTRAPPASSWORD=$(${KUBECTL} get secret -n ${RANCHER_CHART_TARGETNAMESPACE} bootstrap-secret -o jsonpath='{.data.bootstrapPassword}' | base64 -d)
      RANCHERHOSTNAME=$(${KUBECTL} get ingress -n ${RANCHER_CHART_TARGETNAMESPACE} rancher -o jsonpath='{.spec.rules[0].host}')
      
      # Skip the whole process if things have been set already
      if [ -z $(${KUBECTL} get settings.management.cattle.io first-login -ojsonpath='{.value}') ]; then
        # Add the protocol
        RANCHERHOSTNAME="https://${RANCHERHOSTNAME}"
        TOKEN=""
        while [ -z "${TOKEN}" ]; do
          # Get token
          sleep 2
          TOKEN=$(curl -sk -X POST ${RANCHERHOSTNAME}/v3-public/localProviders/local?action=login -H 'content-type: application/json' -d "{\"username\":\"admin\",\"password\":\"${RANCHERBOOTSTRAPPASSWORD}\"}" | jq -r .token)
        done
      
        # Set password
        curl -sk ${RANCHERHOSTNAME}/v3/users?action=changepassword -H 'content-type: application/json' -H "Authorization: Bearer $TOKEN" -d "{\"currentPassword\":\"${RANCHERBOOTSTRAPPASSWORD}\",\"newPassword\":\"${RANCHER_FINALPASSWORD}\"}"
      
        # Create a temporary API token (ttl=60 minutes)
        APITOKEN=$(curl -sk ${RANCHERHOSTNAME}/v3/token -H 'content-type: application/json' -H "Authorization: Bearer ${TOKEN}" -d '{"type":"token","description":"automation","ttl":3600000}' | jq -r .token)
      
        curl -sk ${RANCHERHOSTNAME}/v3/settings/server-url -H 'content-type: application/json' -H "Authorization: Bearer ${APITOKEN}" -X PUT -d "{\"name\":\"server-url\",\"value\":\"${RANCHERHOSTNAME}\"}"
        curl -sk ${RANCHERHOSTNAME}/v3/settings/telemetry-opt -X PUT -H 'content-type: application/json' -H 'accept: application/json' -H "Authorization: Bearer ${APITOKEN}" -d '{"value":"out"}'
      fi
      
      # Clean up the lock cm
      ${KUBECTL} delete configmap ${RANCHERLOCKCMNAME} -n ${RANCHERLOCKNAMESPACE}
    • mgmt-stack-setup.service: 初回起動時にスクリプトを実行するための systemd サービスを作成する構成が含まれています(変更は不要です)。

      [Unit]
      Description=Setup Management stack components
      Wants=network-online.target
      # It requires rke2 or k3s running, but it will not fail if those services are not present
      After=network.target network-online.target rke2-server.service k3s.service
      # At least, the basic-setup.sh one needs to be present
      ConditionPathExists=/opt/mgmt/bin/basic-setup.sh
      
      [Service]
      User=root
      Type=forking
      # Metal3 can take A LOT to download the IPA image
      TimeoutStartSec=1800
      
      ExecStartPre=/bin/sh -c "echo 'Setting up Management components...'"
      # Scripts are executed in StartPre because Start can only run a single one
      ExecStartPre=/opt/mgmt/bin/rancher.sh
      ExecStartPre=/opt/mgmt/bin/metal3.sh
      ExecStart=/bin/sh -c "echo 'Finished setting up Management components'"
      RemainAfterExit=yes
      KillMode=process
      # Disable & delete everything
      ExecStartPost=rm -f /opt/mgmt/bin/rancher.sh
      ExecStartPost=rm -f /opt/mgmt/bin/metal3.sh
      ExecStartPost=rm -f /opt/mgmt/bin/basic-setup.sh
      ExecStartPost=/bin/sh -c "systemctl disable mgmt-stack-setup.service"
      ExecStartPost=rm -f /etc/systemd/system/mgmt-stack-setup.service
      
      [Install]
      WantedBy=multi-user.target

custom/scripts フォルダには、次のファイルが収められます。

  • 99-alias.sh スクリプト: 初回起動時に kubeconfig ファイルを読み込むために管理クラスターが使用するエイリアスが含まれています(変更は不要です)。

    #!/bin/bash
    echo "alias k=kubectl" >> /etc/profile.local
    echo "alias kubectl=/var/lib/rancher/rke2/bin/kubectl" >> /etc/profile.local
    echo "export KUBECONFIG=/etc/rancher/rke2/rke2.yaml" >> /etc/profile.local
  • 99-mgmt-setup.sh スクリプト: 初回起動時にスクリプトをコピーするための設定が含まれています(変更は不要です)。

    #!/bin/bash
    
    # Copy the scripts from combustion to the final location
    mkdir -p /opt/mgmt/bin/
    for script in basic-setup.sh rancher.sh metal3.sh; do
        cp ${script} /opt/mgmt/bin/
    done
    
    # Copy the systemd unit file and enable it at boot
    cp mgmt-stack-setup.service /etc/systemd/system/mgmt-stack-setup.service
    systemctl enable mgmt-stack-setup.service
  • 99-register.sh スクリプト: SCC 登録コードを使用してシステムを登録するための設定が含まれています。システムをアカウントに登録するには、${SCC_ACCOUNT_EMAIL} と ${SCC_REGISTRATION_CODE} を適切に設定する必要があります。

    #!/bin/bash
    set -euo pipefail
    
    # Registration https://www.suse.com/support/kb/doc/?id=000018564
    if ! which SUSEConnect > /dev/null 2>&1; then
        zypper --non-interactive install suseconnect-ng
    fi
    SUSEConnect --email "${SCC_ACCOUNT_EMAIL}" --url "https://scc.suse.com" --regcode "${SCC_REGISTRATION_CODE}"

29.4 Kubernetes フォルダ

kubernetes フォルダには、次のサブフォルダが保管されています。

...
├── kubernetes
│ ├── manifests
│ │ ├── rke2-ingress-config.yaml
│ │ ├── neuvector-namespace.yaml
│ │ ├── ingress-l2-adv.yaml
│ │ └── ingress-ippool.yaml
│ ├── helm
│ │ └── values
│ │     ├── rancher.yaml
│ │     ├── neuvector.yaml
│ │     ├── metal3.yaml
│ │     └── certmanager.yaml
│ └── config
│     └── server.yaml
...

kubernetes/config フォルダには、次のファイルが収められます。

  • server.yaml:デフォルトでインストールされる CNI プラグインは Cilium であるため、それを設定するためにこのフォルダやファイルを作成する必要はありません。CNI プラグインをカスタマイズする必要がある場合に備えて、kubernetes/config フォルダ内の server.yaml ファイルを使用できます。この章は次の項目で構成されています。

    cni:
    - multus
    - cilium
    write-kubeconfig-mode: '0644'
    selinux: true
    system-default-registry: registry.rancher.com
注記
注記

これは、使用する CNI プラグインや 公式ドキュメント で確認できるその他の多くのオプションなど、特定の Kubernetes のカスタマイズを定義するためのオプションファイルです。

os-files/var/lib/rancher/rke2/server/manifests フォルダには、次のファイルが保管されています。

  • rke2-ingress-config.yaml:管理クラスター用の(Traefikベースの)Ingress`サービスを作成するための設定が含まれています(.providers`スタンザ以外は変更不要です。Ingress`アノテーションを含む`ingress-nginx`APIオブジェクトをデプロイしない、またはデプロイする予定がない場合は、その.metadata`スタンザを削除してください)。

    apiVersion: helm.cattle.io/v1
    kind: HelmChartConfig
    metadata:
      name: rke2-traefik
      namespace: kube-system
    spec:
      valuesContent: |-
        ingressClass:
          isDefaultClass: true
        ports:
          web:
            hostPort: null    # disallow hostPort
            exposedPort: 80
          websecure:
            hostPort: null    # disallow hostPort
            exposedPort: 443
        service:
          enabled: true
          spec:
            type: LoadBalancer
            externalTrafficPolicy: Local
            allocateLoadBalancerNodePorts: false
        providers:
          kubernetesIngressNGINX:  # this provider allows traefik to "understand" most of the ingress-nginx annotations
            enabled: true
            ingressClass: "rke2-ingress-nginx-migration"
            controllerClass: "rke2.​cattle.​io/ingress-nginx-migration"
注記
注記

HelmChartConfig は、以前のリリースで説明されていた kubernetes/manifests 経由ではなく、os-files を介して /var/lib/rancher/rke2/server/manifests ディレクトリに追加する必要があります。

kubernetes/manifests フォルダには、次のファイルが収められます。

  • neuvector-namespace.yaml: NeuVector ネームスペースを作成するための設定が含まれています(変更は不要です)。

    apiVersion: v1
    kind: Namespace
    metadata:
      labels:
        pod-security.kubernetes.io/enforce: privileged
      name: neuvector
  • ingress-l2-adv.yaml:L2Advertisement コンポーネント用の MetalLB を作成するための設定が含まれています(変更は不要です)。

    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: ingress-l2-adv
      namespace: metallb-system
    spec:
      ipAddressPools:
        - ingress-ippool
  • ingress-ippool.yaml:IPAddressPool コンポーネント用の MetalLB rke2-traefik オブジェクトを作成するための設定が含まれています。`${INGRESS_VIP}`は、`rke2-traefik`LoadBalancerサービス用に予約された外部(仮想)IPアドレスに設定する必要があります。

    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
      name: ingress-ippool
      namespace: metallb-system
    spec:
      addresses:
        - ${INGRESS_VIP}/32
      serviceAllocation:
        priority: 100
        serviceSelectors:
          - matchExpressions:
              - {key: app.kubernetes.io/name, operator: In, values: [rke2-traefik]}

kubernetes/helm/values フォルダには、次のファイルが収められます。

  • rancher.yaml:Rancher`コンポーネントを作成するための設定が含まれています。${INGRESS_VIP}`は、Rancher`コンポーネントによって消費されるIPアドレスを定義するために、適切に設定する必要があります。`Rancher`コンポーネントにアクセスするためのURLはhttps://rancher-${INGRESS_VIP}.sslip.io`になります。

    hostname: rancher-${INGRESS_VIP}.sslip.io
    bootstrapPassword: "foobar"
    replicas: 1
    global:
      cattle:
        systemDefaultRegistry: "registry.rancher.com"
  • neuvector.yaml:`NeuVector`コンポーネントを作成するための設定が含まれています(変更は不要です)。

    controller:
      replicas: 1
      ranchersso:
        enabled: true
    manager:
      enabled: false
    cve:
      scanner:
        enabled: false
        replicas: 1
    k3s:
      enabled: true
    crdwebhook:
      enabled: false
    registry: "registry.rancher.com"
    global:
      cattle:
        systemDefaultRegistry: "registry.rancher.com"
  • longhorn.yaml:`Longhorn`コンポーネントを作成するための設定が含まれています。起動時に必要なコンテナイメージが確実にダウンロードされるように、Rancher Application Collectionの資格情報を追加してください。

    privateRegistry:
      createSecret: true
      registryUrl: dp.apps.rancher.io
      registryUser: $\{APPS.RANCHER.IO_USERNAME\}
      registryPasswd: $\{APPS.RANCHER.IO_ACCESS_TOKEN\}
      registrySecret: rancher-app-collection
  • metal3.yaml:Metal3`コンポーネントを作成するための設定が含まれています。${METAL3_VIP}`は、`Metal3`コンポーネントによって消費されるIPアドレスを定義するために、適切に設定する必要があります。

    global:
      ironicIP: ${METAL3_VIP}
      enable_vmedia_tls: false
      predictableNicNames: "true"
      # trustedCAs: tls-ca-bundle  # Optional: Uncomment and set to ConfigMap name for additional trusted CAs
    metal3-ironic:
      ipa:
        useHauler: false
      persistence:
        ironic:
          size: "5Gi"
    重要
    重要

    エアギャップ(された)環境では、metal3-ironic.ipa.useHauler Helmチャートパラメータmustを`true`(ブール値)に設定する必要があります。これにより、Metal3はインターネットからのダウンロードを試みる代わりに、埋め込みアーティファクトレジストリから`ironic-python-agent`(IPA)コンテナイメージを取得するようになります。このIPAコンテナイメージは、エアギャップ(された)環境用のEIBイメージ定義ファイル (30.1項 「定義ファイルの変更」)の`embeddedArtifactRegistry.images`リストにも追加する必要があります。

注記
注記

メディアサーバーは、Metal3に含まれるオプション機能です(デフォルトでは無効になっています)。Metal3機能を使用するには、前のマニフェストで設定する必要があります。 Metal3メディアサーバーを使用するには、次の変数を指定してください:

  • グローバルセクションでメディアサーバー機能を有効にするには、`enable_metal3_media_server`を`true`に追加してください。

  • メディアサーバーに関する以下の設定を含めてください。ここで、${MEDIA_VOLUME_PATH}はメディア内のメディアボリュームへのパスです(例:/home/metal3/bmh-image-cache)。

    metal3-media:
      mediaVolume:
        hostPath: ${MEDIA_VOLUME_PATH}

外部メディアサーバーを使用してイメージを保存できます。TLSで使用する場合は、Metal3用の信頼されたCAバンドルを提供する必要があります。

CAバンドルの準備:

まず、Metal3が必要とするすべての証明書を含むCAバンドルファイルを準備してください。これには、外部メディアサーバーのCA証明書が含まれます。

+ *オプション - システムCAバンドル:*Metal3がパブリックCAも信頼する必要がある場合(外部のHTTPSリソースにアクセスする場合など)、システムCAバンドルを含めることができます。コンテナイメージから抽出して、カスタム証明書と連結してください:

+

# Extract system CAs from a container image
podman run --rm registry.suse.com/bci/bci-base:latest cat /etc/ssl/certs/ca-certificates.crt > system-cas.pem

# Concatenate system CAs with your custom CA
cat system-cas.pem your-custom-ca.crt > ca-bundle.pem

+ または、カスタムCAのみが必要な場合は、次のとおりです。

+

cp your-custom-ca.crt ca-bundle.pem

+

システムCAバンドルを含める場合は、それを最新の状態に保つ責任が生じます。コンテナイメージ内のシステムCAは、証明書の期限切れや失効に伴い、古くなる可能性があります。更新されたコンテナイメージから再抽出して、バンドルを定期的に更新してください。

ConfigMapを作成します:

ConfigMapを作成するには、次の2つの方法があります。

  1. マニフェストファイルを使用する(EIBで推奨):`kubernetes/manifests/metal3-cacert-configmap.yaml`ファイルを作成し、CAバンドルの内容をインラインで含めます。証明書の各行を4つのスペースで適切にインデントする必要があります。

    apiVersion: v1
    kind: Namespace
    metadata:
      name: metal3-system
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: tls-ca-bundle
      namespace: metal3-system
    data:
      ca-bundle.pem: |
        -----BEGIN CERTIFICATE-----
        MIIDXTCCAkWgAwIBAgIJAKJ... (your certificate content here)
        ...
        -----END CERTIFICATE-----
        -----BEGIN CERTIFICATE-----
        MIIEkjCCA3qgAwIBAgIQCgF... (additional certificates if any)
        ...
        -----END CERTIFICATE-----

    このファイルを`ca-bundle.pem`から自動的に入力するには、次を使用できます。

    cat > kubernetes/manifests/metal3-cacert-configmap.yaml <<EOF
    apiVersion: v1
    kind: Namespace
    metadata:
      name: metal3-system
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: tls-ca-bundle
      namespace: metal3-system
    data:
      ca-bundle.pem: |
    $(sed 's/^/    /' ca-bundle.pem)
    EOF
  2. *kubectlを直接使用する(手動デプロイ用):*EIBを使用しておらず、クラスタ上で直接ConfigMapを作成したい場合は、次のとおりです。

    kubectl -n metal3-system create configmap tls-ca-bundle --from-file=ca-bundle.pem=./ca-bundle.pem
    • `metal3.yaml`ファイルの`global.trustedCAs`値を設定して、ConfigMap名を参照します。

      global:
        trustedCAs: tls-ca-bundle
  • certmanager.yaml:`Cert-Manager`コンポーネントを作成するための設定が含まれています(変更は不要です)。

    installCRDs: true

29.5 Networkingフォルダ

`network`フォルダには、管理クラスター内のノード数と同じ数のファイルが含まれています。今回のケースではノードが1つしかないため、`mgmt-cluster-node1.yaml`というファイルが1つだけ存在します。 ファイル名は、前述のnetwork/nodeセクションで定義された`mgmt-cluster.yaml`定義ファイルのホスト名と一致している必要があります。

ネットワーク構成をカスタマイズする必要がある場合(例:特定の静的IPアドレスを使用するDHCPなしのシナリオ)、`network`フォルダ下の`mgmt-cluster-node1.yaml`ファイルを使用できます。この章は次の項目で構成されています。

  • ${MGMT_GATEWAY}:ゲートウェイのIPアドレス。

  • ${MGMT_DNS}:DNSサーバのIPアドレス。

  • ${MGMT_MAC}:ネットワークインタフェースのMACアドレス。

  • ${MGMT_NODE_IP}:管理クラスターのIPアドレス。

routes:
  config:
  - destination: 0.0.0.0/0
    metric: 100
    next-hop-address: ${MGMT_GATEWAY}
    next-hop-interface: eth0
    table-id: 254
dns-resolver:
  config:
    server:
    - ${MGMT_DNS}
    - 8.8.8.8
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: ${MGMT_MAC}
  ipv4:
    address:
    - ip: ${MGMT_NODE_IP}
      prefix-length: 24
    dhcp: false
    enabled: true
  ipv6:
    enabled: false

DHCPを使用してIPアドレスを取得する場合は、次の構成を使用できます(MAC`アドレスは${MGMT_MAC}`変数を使用して適切に設定する必要があります)。

## This is an example of a dhcp network configuration for a management cluster
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: ${MGMT_MAC}
  ipv4:
    dhcp: true
    enabled: true
  ipv6:
    enabled: false
注記
注記
  • 管理クラスター内のノード数に応じて、mgmt-cluster-node2.yaml、`mgmt-cluster-node3.yaml`などのファイルを作成して、残りのノードを構成するために使用できます。

  • `routes`セクションは、管理クラスターのルーティングテーブルを定義するために使用されます。

30 エアギャップ環境向けのイメージ準備

このセクションでは、前のセクションとの違いのみを示し、エアギャップ環境向けにイメージを準備する方法について説明します。エアギャップ環境向けにイメージを準備するには、前のセクション(接続環境向けのイメージ準備 (第29章 「接続環境向けのイメージ準備」))に対して以下の変更が必要です。

  • `mgmt-cluster.yaml`ファイルを変更して、EIB出力イメージに含めるすべてのコンテナイメージを`images`フィールドに指定した`embeddedArtifactRegistry`セクションを含める必要があります。

  • エアギャップ環境を使用する場合は、`custom/scripts/99-register.sh`スクリプトを削除する必要があります。

将来のダウンストリームデプロイメントのために管理クラスターにSUSE Private Registryを含めるには、以下の変更も必要です。

  • `mgmt-cluster.yaml`ファイルを変更して、Helmチャートセクションおよび新しいイメージを含む埋め込みアーティファクトを含め、それらをEIB出力イメージに含める必要があります。

  • 管理クラスターでSUSE Private Registryを適切に構成するには、`kubernetes/values`フォルダーと`kubernetes/manifests`フォルダーにマニフェストファイルを追加する必要があります。

注記
注記

特定の資格情報が必要になります。これは、公式の SUSE Private Registryドキュメントに従うことで取得できます。

30.1 定義ファイルの変更

`mgmt-cluster.yaml`ファイルを変更して、`embeddedArtifactRegistry`セクションを含める必要があります。 このセクションでは、`images`フィールドに、出力イメージに含めるすべてのコンテナイメージのリストが含まれている必要があります。

注記
注記

以下の`mgmt-cluster.yaml`ファイルの例には、`embeddedArtifactRegistry`セクションとSUSE Private Registry機能の両方が含まれています。 リストされているイメージに、必要なコンポーネントバージョンが含まれていることを確認してください。

注記
注記

このイメージリストは、この例で示されている管理クラスターコンポーネントの検証済みベースラインであり、網羅的なカタログではありません。このベースライン上でデプロイされる追加のワークロードや動的にプロビジョニングされるワークロード(例:追加のRancherカタログアプリケーションや、SR-IOVデバイスプラグインなどのハードウェア固有のコンポーネント)は、ランタイムに独自のコンテナイメージをプルします。完全にエアギャップ(された)環境にデプロイする前に、それらのイメージを特定し、個別に`embeddedArtifactRegistry.images`リストに追加してください。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
  outputImageName: eib-mgmt-cluster-image.iso
operatingSystem:
  isoConfiguration:
    installDevice: /dev/sda
  users:
  - username: root
    encryptedPassword: $ROOT_PASSWORD
  packages:
    packageList:
    - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE
kubernetes:
  version: v1.36.3+rke2r1
  helm:
    charts:
      - name: private-registry-helm
        createNamespace: true
        installationNamespace: kube-system
        repositoryName: privateregistry
        targetNamespace: suse-private-registry
        valuesFile: privateregistry.yaml
        version: 1.1.1
      - name: cert-manager
        repositoryName: jetstack
        version: 1.20.1
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: suse-storage
        releaseName: longhorn
        version: 1.12.1
        repositoryName: rancher-application-collection
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: longhorn.yaml
      - name: metallb
        version: 307.0.3+up0.16.1
        targetNamespace: metallb-system
        createNamespace: true
        repositoryName: suse-edge-charts
        installationNamespace: kube-system
      - name: metal3
        version: 307.0.31+up0.16.0
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: rancher-turtles-providers
        version: 307.0.8+up0.27.0
        repositoryName: suse-edge-charts
        targetNamespace: cattle-turtles-system
        createNamespace: true
        installationNamespace: kube-system
      - name: neuvector-crd
        version: 110.0.1+up2.11.1
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 110.0.1+up2.11.1
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.15.1
        repositoryName: rancher-prime
        targetNamespace: cattle-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: rancher.yaml
    repositories:
      - name: jetstack
        url: https://charts.jetstack.io
      - name: rancher-charts
        url: https://charts.rancher.io/
      - name: suse-edge-charts
        url: oci://registry.suse.com/edge/charts
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
      - name: rancher-application-collection
        url: oci://dp.apps.rancher.io/charts
        authentication:
          username: $\{APPS.RANCHER.IO_USERNAME\}
          password: $\{APPS.RANCHER.IO_ACCESS_TOKEN\}
      - name: privateregistry
        authentication:
          username: ${PRIVATE_REGISTRY_USERNAME}
          password: ${PRIVATE_REGISTRY_PASSWORD}
        plainHTTP: false
        skipTLSVerify: false
        url: oci://registry.suse.com/private-registry
    network:
      apiHost: $API_HOST
      apiVIP: $API_VIP
    nodes:
    - hostname: mgmt-cluster-node1
      initializer: true
      type: server
#   - hostname: mgmt-cluster-node2
#     type: server
#   - hostname: mgmt-cluster-node3
#     type: server
embeddedArtifactRegistry:
  registries:
    - uri: dp.apps.rancher.io
      authentication:
        username: $\{APPS.RANCHER.IO_USERNAME\}
        password: $\{APPS.RANCHER.IO_ACCESS_TOKEN\}
    - uri: registry.suse.com
      authentication:
        username: ${PRIVATE_REGISTRY_USERNAME}
        password: ${PRIVATE_REGISTRY_PASSWORD}
  images:
    - name: registry.suse.com/private-registry/harbor-core:1.1.1-1.19
    - name: registry.suse.com/private-registry/harbor-jobservice:1.1.1-1.19
    - name: registry.suse.com/private-registry/harbor-portal:1.1.1-1.20
    - name: registry.suse.com/private-registry/harbor-registry:1.1.1-1.19
    - name: registry.suse.com/private-registry/harbor-registryctl:1.1.1-1.19
    - name: registry.suse.com/private-registry/harbor-trivy-adapter:1.1.1-1.24
    - name: registry.rancher.com/rancher/hardened-cluster-autoscaler:v1.10.3-build20260717
    - name: registry.rancher.com/rancher/hardened-cni-plugins:v1.9.1-build20260717
    - name: registry.rancher.com/rancher/hardened-coredns:v1.14.6-build20260722
    - name: registry.rancher.com/rancher/hardened-k8s-metrics-server:v0.9.0-build20260722
    - name: registry.rancher.com/rancher/hardened-multus-cni:v4.3.0-build20260722
    - name: registry.rancher.com/rancher/hardened-traefik:v3.7.8-build20260717
    - name: registry.rancher.com/rancher/klipper-helm:v0.13.3-build20260727
    - name: registry.rancher.com/rancher/mirrored-cilium-cilium:v1.19.6
    - name: registry.rancher.com/rancher/mirrored-cilium-operator-generic:v1.19.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-attacher:4.12.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-provisioner:5.3.0-17.8
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-resizer:2.2.1-10.8
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-snapshotter:8.6.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-livenessprobe:2.19.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-node-driver-registrar:2.17.0-17.6
    - name: dp.apps.rancher.io/containers/longhorn-backing-image-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-engine:1.12.1-1.6
    - name: dp.apps.rancher.io/containers/longhorn-instance-manager:1.12.1-1.7
    - name: dp.apps.rancher.io/containers/longhorn-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-share-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-ui:1.12.1-1.3
    - name: dp.apps.rancher.io/containers/rancher-support-bundle-kit:0.0.92-13.12
    - name: registry.rancher.com/rancher/mirrored-sig-storage-snapshot-controller:v8.2.0
    - name: registry.rancher.com/rancher/neuvector-compliance-config:1.0.16
    - name: registry.rancher.com/rancher/neuvector-controller:5.6.1
    - name: registry.rancher.com/rancher/neuvector-enforcer:5.6.1
    - name: registry.rancher.com/rancher/neuvector-updater:0.0.14
    - name: registry.rancher.com/rancher/nginx-ingress-controller:v1.14.5-hardened2
    - name: registry.suse.com/rancher/cluster-api-addon-provider-fleet:v0.15.0
    - name: registry.rancher.com/rancher/fleet-agent:v0.16.1
    - name: registry.rancher.com/rancher/fleet:v0.16.1
    - name: registry.rancher.com/rancher/rancher-webhook:v0.11.1
    - name: registry.rancher.com/rancher/turtles:v0.27.1
    - name: registry.rancher.com/rancher/rancher:v2.15.1
    - name: registry.rancher.com/rancher/rancher-agent:v2.15.1
    - name: registry.rancher.com/rancher/shell:v0.8.1
    - name: registry.rancher.com/rancher/system-upgrade-controller:v0.20.1
    - name: registry.rancher.com/rancher/cluster-api-controller:v1.13.3
    - name: registry.suse.com/rancher/cluster-api-provider-metal3:v1.13.2
    - name: registry.suse.com/rancher/cluster-api-provider-rke2-bootstrap:v0.25.0
    - name: registry.suse.com/rancher/cluster-api-provider-rke2-controlplane:v0.25.0
    - name: registry.rancher.com/rancher/ip-address-manager:v1.13.2
    - name: registry.rancher.com/rancher/kubectl:v1.35.2
    - name: registry.rancher.com/rancher/scc-operator:v0.5.1
    - name: registry.suse.com/edge/3.7/ironic-python-agent:3.0.10
    - name: registry.suse.com/edge/3.7/node-feature-discovery:v0.18.2
    - name: registry.suse.com/edge/3.7/ib-sriov-cni:v1.3.0

30.2 カスタムフォルダーの変更

  • エアギャップ環境を使用する場合は、`custom/scripts/99-register.sh`スクリプトを削除する必要があります。ディレクトリ構造で確認できるように、`99-register.sh`スクリプトは`custom/scripts`フォルダーに含まれていません。

30.3 kubernetesフォルダーの変更

  • kubernetes/helm/values/metal3.yaml`ファイルを更新して、`metal3-ironic.ipa.useHauler Helmチャートパラメーターを`true`(ブール値)に設定します。

    global:
      ironicIP: ${METAL3_VIP}
      enable_vmedia_tls: false
      predictableNicNames: "true"
      # trustedCAs: tls-ca-bundle  # Optional: Uncomment and set to ConfigMap name for additional trusted CAs
    metal3-ironic:
      ipa:
        useHauler: true
      persistence:
        ironic:
          size: "5Gi"
  • `kubernetes/helm/values/rancher.yaml`ファイルを更新して、`hostname`パラメーターを変更します。エアギャップ環境では、`sslip.io`のような外部DNS解決サービスにはアクセスできません。2つのオプションがあります。

    1. オプション 1:内部DNSを使用する(推奨):内部DNSサーバーを構成してRancherホスト名を解決し、それに応じてファイルを更新します。

      hostname: rancher.yourdomain.internal
      bootstrapPassword: "foobar"
      replicas: 1
      global:
        cattle:
          systemDefaultRegistry: "registry.rancher.com"
    2. オプション 2:/etc/hosts インジェクションを使用する:内部DNSサーバーがない場合は、EIBを介して静的な`/etc/hosts`エントリを注入できます。EIBディレクトリ構造内の`eib/os-files/etc/hosts`に、以下のような内容のファイルを作成します。

      # Static DNS resolution for Rancher in air-gapped environment
      ${INGRESS_VIP} rancher-${INGRESS_VIP}.sslip.io

      次に、`rancher.yaml`ファイルを更新してこのホスト名を使用するようにします。

      hostname: rancher-${INGRESS_VIP}.sslip.io
      bootstrapPassword: "foobar"
      replicas: 1
      global:
        cattle:
          systemDefaultRegistry: "registry.rancher.com"
      重要
      重要

      オプション2を使用する場合、`/etc/hosts`ファイルは管理クラスターのノードだけでなく、Rancher UIにアクセスする必要があるすべてのシステム上に存在する必要があることに注意してください。

  • 以下のファイルで、SUSE Private Registry用に予約された静的IPを使用して`${MGMT_CLUSTER_REGISTRY_IP}`を変更する必要があります。

    1. kubernetes/manifests/metallb-registry.yaml

      apiVersion: metallb.io/v1beta1
      kind: L2Advertisement
      metadata:
        name: private-registry
        namespace: metallb-system
      spec:
        ipAddressPools:
        - private-registry-pool
      ---
      apiVersion: metallb.io/v1beta1
      kind: IPAddressPool
      metadata:
        name: private-registry-pool
        namespace: metallb-system
      spec:
        addresses:
        - ${MGMT_CLUSTER_REGISTRY_IP}/32
        serviceAllocation:
          namespaces:
          - suse-private-registry
    2. kubernetes/helm/values/privateregistry.yaml

      core:
        secretName: suse-registry-tls
      expose:
        tls:
          certSource: secret
          enabled: true
          secret:
            secretName: suse-registry-tls
        type: loadBalancer
      externalURL: https://${MGMT_CLUSTER_REGISTRY_IP}
      persistence:
        persistentVolumeClaim:
          registry:
            size: 20Gi
  • `kubernetes/manifests/suse-private-registry-creds.yaml`は、以下の内容で作成する必要があります。

apiVersion: v1
kind: Secret
metadata:
  name: suse-registry
  namespace: suse-private-registry
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ${DOCKER_CONFIG_JSON_BASE64}
---
apiVersion: v1
kind: Secret
metadata:
    name: suse-registry-tls
    namespace: suse-private-registry
type: kubernetes.io/tls
data:
    tls.crt: ${TLS_CRT_BASE64}
    tls.key: ${TLS_KEY_BASE64}

${DOCKER_CONFIG_JSON_BASE64}、${TLS_CRT_BASE64}、および`${TLS_KEY_BASE64}`を変更する必要があります。docker config json (base64) を正しく構成するには、以下を実行します。

# ${DOCKER_CONFIG_JSON_BASE64} CONTENT
echo -n '{"auths":{"<MGMT_CLUSTER_REGISTRY_IP>":{"username":"<USERNAME>","password":"<PASSWORD>","auth":"<AUTH>"}}}' | base64 -w 0

ここで、IPは以前に構成した`${MGMT_CLUSTER_REGISTRY_IP}`と同じであり、<USERNAME>`および<PASSWORD>`の値は SUSE Private Registry公式ドキュメントから取得できます。auth`フィールドに設定される<AUTH>`値は、`<USERNAME>:<PASSWORD>`連結のbase64エンコーディングです。

上記の suse-registry-tls Secret マニフェスト内の tls.crt フィールドと tls.key フィールドの内容を設定するには、以下のコマンドを実行して、独自の TLS 自己署名証明書と関連する秘密鍵を生成します。

# Generate a self-signed certificate and key
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes

# Convert them to base64 for the suse-private-registry-creds.yaml file
cat cert.pem | base64 -w 0
cat key.pem | base64 -w 0

31 イメージの作成

(接続環境とエアギャップ環境の両方について)前のセクションに従ってディレクトリ構造を準備したら、次のコマンドを実行してイメージをビルドします。

podman run --rm --privileged -it -v $PWD:/eib \
 registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
 build --definition-file mgmt-cluster.yaml

これにより、ISO 出力イメージファイルが作成されます。このファイルは、今回の場合、上記で説明したイメージ定義に基づいて eib-mgmt-cluster-image.iso となります。

32 管理クラスターのプロビジョニング

前のイメージには上記で説明したすべてのコンポーネントが含まれており、仮想マシンまたはベアメタルサーバー(仮想メディア機能を使用)を使用して管理クラスターをプロビジョニングするために使用できます。

33 デュアルスタックに関する考慮事項と構成

前のセクションで示した例は、シングルスタック IPv4 管理クラスターをセットアップする方法に関するガイダンスと例を提供しています。このような管理クラスターは、ダウンストリームクラスターの動作状態とは独立しており、ダウンストリームクラスターはデプロイ後に IPv4/IPv6 シングルスタックまたはデュアルスタック構成のいずれかで動作するように個別に構成できます。ただし、管理クラスターの構成方法は、プロビジョニングフェーズで使用できる通信プロトコルに直接影響します。インバンド通信とアウト・オブ・バンド通信の両方が、管理クラスターとダウンストリームホストがサポートするプロトコルに従って行われる必要があるためです。BMC やダウンストリームの一部またはすべてで IPv6 を使用することが想定される場合は、管理クラスターのデュアルスタック設定が必要になります。

注記
注記

シングルスタック IPv6 管理クラスターは、現時点ではサポートされていません。

デュアルスタック機能を実現するには、Kubernetes に POD およびサービス用の IPv4 CIDR と IPv6 CIDR の両方を提供する必要があります。ただし、EIB を使用して管理クラスターイメージをビルドする前に、他のコンポーネントも特定の調整を行う必要があります。Metal3 プロビジョニングサービス (Ironic) は、インフラストラクチャや要件に応じて、さまざまな方法で構成できます。

  • Ironic サービスは、単一の IP アドレスではなく、システム上のすべてのインターフェースでリスン(する)ように構成できます。したがって、管理クラスターホストが関連するインターフェースに IPv4 アドレスと IPv6 アドレスの両方を割り当てられている限り、プロビジョニング中にそれらのいずれかを使用できる可能性があります。現時点では、URL 生成(他のサービス、例えば Baremetal Operator や BMC などによる消費用)にはこれらのアドレスのうち 1 つしか選択できないことに注意してください。その結果、BMC との IPv6 通信を有効にするには、IPv6 アドレスを含む BMH 定義を扱う際に、IPv6 URL を公開して渡すように Baremetal Operator に指示することができます。言い換えれば、BMC が IPv6 対応であると識別された場合、プロビジョニングは IPv6 経由でのみ実行され、それ以外の場合は IPv4 経由で実行されます。

  • IPv4 と IPv6 の両方に解決される単一のホスト名を Metal3 で使用することで、Ironic がバインディングと URL 作成にそれらのアドレスを使用できるようにすることができます。このアプローチにより、構成が容易になり、柔軟な動作が可能になります(各プロビジョニングステップで IPv4 と IPv6 の両方が有効なままになります)が、既存の DNS サーバー、IP 割り当て、およびレコードがすでに配置されているインフラストラクチャが必要になります。

いずれの場合も、Kubernetes は IPv4 と IPv6 の両方に使用する CIDR を認識する必要があるため、EIB ディレクトリ内の`kubernetes/config/server.yaml`に以下の行を追加します。その際、IPv4 を先に記述するようにしてください。

service-cidr: 10.96.0.0/12,fd12:4567:789c::/112
cluster-cidr: 193.168.0.0/18,fd12:4567:789b::/48

一部のコンテナはホストネットワークを利用するため、`network`ディレクトリ配下のホストのネットワーク設定を変更し、IPv6接続を有効にします。

routes:
  config:
  - destination: 0.0.0.0/0
    next-hop-address: ${MGMT_GATEWAY_V4}
    next-hop-interface: eth0
  - destination: ::/0
    next-hop-address: ${MGMT_GATEWAY_V6}
    next-hop-interface: eth0
dns-resolver:
  config:
    server:
    - ${MGMT_DNS}
    - 8.8.8.8
    - 2001:4860:4860::8888
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: ${MGMT_MAC}
  ipv4:
    address:
    - ip: ${MGMT_CLUSTER_IP_V4}
      prefix-length: 24
    dhcp: false
    enabled: true
  ipv6:
    address:
    - ip: ${MGMT_CLUSTER_IP_V6}
      prefix-length: 128
    dhcp: false
    autoconf: false
    enabled: true

プレースホルダーを、ゲートウェイのIPアドレス、追加のDNSサーバー(必要な場合)、ネットワークインタフェースのMACアドレス、および管理クラスターのIPアドレスに置き換えてください。アドレスの自動設定を使用する場合は、以下の抜粋を参照し、`${MGMT_MAC}`変数を設定してください。

interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: ${MGMT_MAC}
  ipv4:
    enabled: true
    dhcp: true
  ipv6:
    enabled: false
    dhcp: true
    autoconf: true

次に、最初のオプションから始めて、シングルノード構成の残りのファイルを定義します。`kubernetes/helm/values/metal3.yaml`を以下のように作成してください。

global:
  ironicIP: ${MGMT_CLUSTER_IP_V4}
  enable_vmedia_tls: false
  # trustedCAs: tls-ca-bundle  # Optional: Uncomment and set to ConfigMap name for trusted CA bundle
metal3-ironic:
  global:
    predictableNicNames: true
  listenOnAll: true
  persistence:
    ironic:
      size: "5Gi"
  service:
    type: NodePort
metal3-baremetal-operator:
  baremetaloperator:
    externalHttpIPv6: ${MGMT_CLUSTER_IP_V6}

さらに、`kubernetes/helm/values/rancher.yaml`を以下のように作成します。

hostname: rancher-${MGMT_CLUSTER_IP_V4}.sslip.io
bootstrapPassword: "foobar"
replicas: 1
global:
  cattle:
    systemDefaultRegistry: "registry.rancher.com"

ここで、${MGMT_CLUSTER_IP_V4}`と${MGMT_CLUSTER_IP_V6}`は、以前にホストに割り当てられたIPアドレスです。

あるいは、IPアドレスの代わりにホスト名を使用する場合は、`kubernetes/helm/values/metal3.yaml`を以下のように変更します。

global:
  provisioningHostname: `${MGMT_CLUSTER_HOSTNAME}`
  enable_vmedia_tls: false
  # trustedCAs: tls-ca-bundle  # Optional: Uncomment and set to ConfigMap name for trusted CA bundle
metal3-ironic:
  global:
    predictableNicNames: true
  persistence:
    ironic:
      size: "5Gi"
  service:
    type: NodePort

さらに、`kubernetes/helm/values/rancher.yaml`を以下のように変更します。

hostname: rancher-${MGMT_CLUSTER_HOSTNAME}.sslip.io
bootstrapPassword: "foobar"
replicas: 1
global:
  cattle:
    systemDefaultRegistry: "registry.rancher.com"

ここで、`${MGMT_CLUSTER_HOSTNAME}`にはホストのIPアドレスに解決される完全修飾ドメイン名を指定する必要があります。

詳細については、 SUSE Telco Cloud GitHubリポジトリの「dual-stack」フォルダを参照してください。そこにディレクトリ構造の例が記載されています。

パート VI Telco機能の設定

このセクションでは、SUSE Telco Cloud経由でデプロイされたクラスターにおけるTelco固有機能の設定について説明します。

自動プロビジョニング (パートVII「完全自動化されたダイレクトネットワークプロビジョニング」)セクションで説明されているように、ダイレクトネットワークプロビジョニングのデプロイメント方法が使用されます。

このセクションの構成は次のとおりです。

  • 34 リアルタイム用カーネルイメージ
  • リアルタイムカーネルイメージが標準カーネルより優れているとは限りません。 これは特定のユースケースに合わせて調整された別のカーネルです。リアルタイムカーネルは、スループットを犠牲にして低遅延を実現するように調整されています。リアルタイムカーネルは汎用用途には推奨されませんが、Telcoワークロードにおいて遅延が重要な要因となる場合には、推奨されるカーネルです。

  • 35 低レイテンシおよび高性能のためのカーネル引数
  • 適切なカーネル引数を設定することは、パフォーマンスの最適化、低レイテンシの実現、およびTelcoワークロード向けのクラスタ展開を成功させるために不可欠です。一部のパラメータはリアルタイムカーネルが最適に機能するように特別に設計されていますが、このセクションはRTカーネルとデフォルトカーネルの両方の構成に適用されます。さらに、Directed Network Provisioning方式を使用してダウンストリームのクラスタノードを正常に展開するには、特定の引数が必須となります。

  • 36 ホストでのCPU固定
  • CPUピニング(プロセッサアフィニティとも呼ばれます)は、プロセスやスレッドを特定のCPUコアにバインドし、オペレーティングシステムのスケジューラによる移動を防ぐ手法です。プロセスが常に同じコアで実行されるようにすることで、そのコアのキャッシュメモリに残っているデータへのアクセスが高速になるという利点があります。この手法は、ハイパフォーマンスコンピューティング環境で一般的であり、パフォーマンスを劇的に向上させ、オーバーヘッドを削減します。

  • 37 KubernetesにおけるCPUピニング
  • RKE2設定ファイルを編集して、RKE2クラスターでCPUピニングを有効にします。`/etc/rancher/rke2/config.yaml`ファイルに以下のkubelet引数を追加します。`kubelet-reserved`および`system-reserved`引数でハウスキーピングCPUコアを必ず指定してください:

  • 38 ネットワークパラメータ
  • ネットワークのチューニングは、通信ワークロードで最適なパフォーマンスを実現するために不可欠です。performance-settings.shスクリプトには、バッファサイズ、パケット処理、およびUDPパフォーマンスを最適化するために、さまざまなカーネルネットワークパラメータを設定する`configure_network_tuning`関数が含まれています。

  • 39 CNI構成
  • Cilium`は、SUSE Telco CloudのデフォルトのCNIプラグインです。 RKE2クラスターでCiliumをデフォルトのプラグインとして有効にするには、/etc/rancher/rke2/config.yaml`ファイルに以下の構成が必要です。

  • 40 SR-IOV
  • SR-IOV(Single Root I/O Virtualization)を使用すると、ネットワークアダプターなどの単一の物理デバイスが、そのリソースを複数の`PCIe`ハードウェア関数に分離できます。これにより、さまざまなアプリケーションがリソースに直接アクセスできるようになります。

  • 41 DPDK
  • DPDK(Data Plane Development Kit)は、高速なパケット処理のためのライブラリおよびドライバーのセットです。これは、さまざまなCPUアーキテクチャで実行されるパケット処理ワークロードを高速化するために使用されます。 DPDKには、データプレーンライブラリと、以下に対する最適化されたネットワークインタフェースコントローラ(NIC)ドライバーが含まれています。

  • 42 vRANアクセラレーション(Intel ACC100/VRB1/VRB2)
  • 通信サービスプロバイダーが4Gから5Gネットワークへ移行するにつれ、多くのプロバイダーが、より高いチャネル容量と、エッジベースのサービスやアプリケーションの容易な展開を実現するために、仮想化無線アクセスネットワーク(vRAN)アーキテクチャを採用しています。vRANソリューションは、リアルタイムトラフィックの量やネットワーク上の需要に基づいて容量を増減できる柔軟性を備え、低遅延サービスを提供するのに理想的な位置にあります。

  • 43 ヒュージページ
  • プロセスが`RAM`を使用する場合、`CPU`はそのプロセスによって利用される正確な部分をマークします。効率を達成するために、`CPU`は`RAM`を`pages`と呼ばれるブロックで割り当てます。多くのプラットフォームでのデフォルトの`page`サイズは`4 KB`です。ページはディスクにスワップされることがあります(他の操作の中でも)。

  • 44 NUMA対応スケジューリング
  • Non-Uniform Memory Access(不均一メモリアクセス)またはNon-Uniform Memory Architecture(NUMA)は、SMP(マルチプロセッサ)アーキテクチャで使用される物理メモリ設計であり、メモリへのアクセス時間はプロセッサに対するメモリの場所によって異なります。`NUMA`では、プロセッサは非ローカルメモリ(別のプロセッサのローカルメモリやプロセッサ間で共有されるメモリ)よりも、自身のローカルメモリに高速にアクセスできます。

  • 45 Metal LB
  • `MetalLB`は、`L2`や`BGP`などの標準的なルーティングプロトコルをアドバタイズメントプロトコルとして使用する、ベアメタルKubernetesクラスター向けのロードバランサー実装です。これは、ベアメタル環境でKubernetesサービスのタイプ`LoadBalancer`を使用する必要があるため、Kubernetesクラスター内のサービスを外部に公開するために使用できるネットワークロードバランサーです。

  • 46 プライベートレジストリの設定
  • `Containerd`は、プライベートレジストリに接続し、それを使用して各ノードでプライベートイメージをプルするように設定できます。

  • 47 高精度時刻同期プロトコル (PTP)
  • IEEE 1588標準で定義されている高精度時刻同期プロトコル (PTP) は、パケットネットワーク上で高精度の時刻を配信します。ネットワークインタフェース (NIC) がハードウェアでPTPパケットにタイムスタンプを付与すると、NTPが提供できる範囲をはるかに超えるサブマイクロ秒の精度に達します。通信事業者の環境において、PTPは5G無線アクセスネットワーク (RAN) の中核となる構成要素であり、無線ユニットが正しく送信を行うには厳密な位相と時刻の同期が必要です。SUSE Telco Cloudは、`linuxptp`パッケージを通じてPTPを実装しており、以下に説明する通信事業者向けプロ…

  • 48 SCTP - ストリーム制御伝送プロトコル
  • ストリーム制御伝送プロトコル - Wikipediaより

34 リアルタイム用カーネルイメージ

リアルタイムカーネルイメージが標準カーネルより優れているとは限りません。 これは特定のユースケースに合わせて調整された別のカーネルです。リアルタイムカーネルは、スループットを犠牲にして低遅延を実現するように調整されています。リアルタイムカーネルは汎用用途には推奨されませんが、Telcoワークロードにおいて遅延が重要な要因となる場合には、推奨されるカーネルです。

主な機能は4つあります。

  • 決定論的実行:

    予測可能性を高め、システム負荷が高い場合でも、毎回、重要なビジネスプロセスを期限内に確実に完了させ、高品質のサービスを提供します。重要なシステムリソースを高優先度プロセス用に保護することで、時間的制約のあるアプリケーションの予測可能性を高めることができます。

  • 低ジッタ:

    高度に決定論的な技術に基づく低ジッタは、アプリケーションを現実世界と同期させるのに役立ちます。これは、継続的かつ反復的な計算を必要とするサービスに役立ちます。

  • プライオリティの継承:

    プライオリティの継承とは、優先度の高いプロセスがタスクを完了するために優先度の低いプロセスの終了を必要とする場合に、優先度の低いプロセスが高い優先度を引き継ぐ機能を指します。SUSE Linux Enterprise Real Timeは、ミッションクリティカルなプロセスにおけるこれらの優先度の逆転問題を解決します。

  • スレッド割り込み:

    汎用OSにおいて割り込みモードで動作しているプロセスは、プリエンプトされることがありません。SUSE Linux Enterprise Real Timeでは、これらの割り込みがカーネルスレッドによってカプセル化され、これらのカーネルスレッドは割り込み可能なため、ユーザが定義した優先度の高いプロセスによってハード割り込みやソフト割り込みがプリエンプトされるようになります。

    この場合、`SUSE Linux Micro RT`のようなリアルタイムイメージをインストール済みであれば、カーネルリアルタイムはすでにインストールされています。 SUSE Customer Centerから、リアルタイムカーネルイメージをダウンロードできます。

    注記
    注記

    リアルタイムカーネルの詳細については、 SUSE Real Timeを参照してください。

35 低レイテンシおよび高性能のためのカーネル引数

適切なカーネル引数を設定することは、パフォーマンスの最適化、低レイテンシの実現、およびTelcoワークロード向けのクラスタ展開を成功させるために不可欠です。一部のパラメータはリアルタイムカーネルが最適に機能するように特別に設計されていますが、このセクションはRTカーネルとデフォルトカーネルの両方の構成に適用されます。さらに、Directed Network Provisioning方式を使用してダウンストリームのクラスタノードを正常に展開するには、特定の引数が必須となります。

  • SUSEリアルタイムカーネルを使用する場合は、`kthread_cpus`を削除してください。このパラメータは、どのCPU上でカーネルスレッドが作成されるかを制御します。また、PID 1やカーネルモジュール(kmodユーザスペースヘルパー)の読み込みに使用できるCPUを制御します。このパラメータは認識されず、何の効果もありません。

  • isolcpus、nohz_full、rcu_nocbs、および`irqaffinity`を使用してCPUコアを分離します。CPUピン留め技術の包括的な一覧については、CPU Pinning on Host (第36章 「ホストでのCPU固定」)の章を参照してください。

  • `isolcpus`カーネル引数に`domain,nohz,managed_irq`フラグを追加します。フラグを指定しない場合、`isolcpus`は`domain`フラグのみを指定した場合と同等になります。これにより、カーネルタスクを含むスケジューリングから指定されたCPUが分離されます。`nohz`フラグは指定されたCPUでのスケジューラティックを停止し(CPU上で実行可能なタスクが1つだけの場合)、`managed_irq`フラグは指定されたCPUへの管理対象の外部(デバイス)割り込みのルーティングを回避します。NVMeデバイスのIRQラインはカーネルによって完全に管理されており、その結果、分離されていない(ハウスキーピング)コアにルーティングされることに注意してください。例えば、このセクションの最後に記載されているコマンドラインを実行すると、システムには4つのキュー(および管理/制御キュー)のみが割り当てられます。

    for I in $(grep nvme0 /proc/interrupts | cut -d ':' -f1); do cat /proc/irq/${I}/effective_affinity_list; done | column
    39      0       19      20      39

    この動作により、分離されたコア上で実行される時間に敏感なアプリケーションがディスクI/Oによる中断を回避できる一方で、ストレージ向けのワークロードでは慎重な設計が求められる場合があります。

  • ティック(カーネルの周期的なタイマー割り込み)を調整します。

    • skew_tick=1: ティックが同時に発生することがあります。すべてのCPUが同時にタイマーティックを受け取るのではなく、`skew_tick=1`を使用すると、わずかに時間をずらして発生させることができます。これはシステムジッターの低減に役立ち、より一貫した低い割り込み応答時間を実現します(これはレイテンシに敏感なアプリケーションにとって不可欠な要件です)。

    • nohz=on: アイドル状態のCPUでの周期的なタイマーティックを停止します。

    • nohz_full=<cpu-cores>:リアルタイムアプリケーション専用の指定されたCPUでの周期的なタイマーティックを停止します。

  • `mce=off`を指定して、マシンチェック例外(MCE)処理を無効にします。MCEはプロセッサによって検出されるハードウェアエラーであり、これらを無効にすることで、不要なログ出力を回避できます。

  • `nowatchdog`を追加して、タイマーハード割り込みコンテキストで実行されるタイマーとして実装されているソフトロックアップウォッチドッグを無効にします。期限が切れると(つまり、ソフトロックアップが検出されると)、警告が出力され(ハード割り込みコンテキストで)、レイテンシターゲットが実行されます。期限が切れない場合でも、タイマーリストに追加されるため、すべてのタイマー割り込みのオーバーヘッドがわずかに増加します。このオプションはNMIウォッチドッグも無効にするため、NMIが干渉することはありません。

  • `nmi_watchdog=0`はNMI(ノンマスカブル割り込み)ウォッチドッグを無効にします。`nowatchdog`が使用されている場合、これは省略可能です。

  • RCU(Read-Copy-Update)は、共有データへの同時かつロックフリーなアクセスを多くのリーダーに対して可能にするカーネルメカニズムです。RCUコールバックは「猶予期間」の後にトリガーされる関数であり、以前のすべてのリーダーが終了したことを確認して、古いデータを安全に再利用できるようにします。私たちは、特に機密性の高いワークロードに対してRCUを微調整し、これらのコールバックを専用(固定)CPUからオフロードすることで、カーネル操作が重要で時間的制約のあるタスクに干渉するのを防ぎます。

    • RCUコールバックが実行されないように、`rcu_nocbs`で固定CPUを指定します。これは、リアルタイムワークロードのジッターとレイテンシを低減するのに役立ちます。

    • `rcu_nocb_poll`は、コールバック処理が必要かどうかを確認するために、ノーコールバックCPUに定期的にポーリングを行わせます。これにより、割り込みオーバーヘッドを削減できます。

    • `rcupdate.rcu_cpu_stall_suppress=1`は、負荷の高いリアルタイムシステムで誤検知となることがあるRCU CPUストール警告を抑制します。

    • `rcupdate.rcu_expedited=1`はRCU操作の猶予期間を短縮し、読み取り側のクリティカルセクションの応答性を高めます。

    • rcupdate.rcu_normal_after_boot=1 rcu_expeditedと併用すると、システム起動後にRCUを通常(非高速化)の動作に戻すことができます。

    • `rcupdate.rcu_task_stall_timeout=0`はRCUタスクストール検出器を無効にし、長時間実行されるRCUタスクによる潜在的な警告やシステム停止を防ぎます。

    • `rcutree.kthread_prio=99`はRCUコールバックカーネルスレッドの優先度を最高値(99)に設定し、必要に応じてコールバックを迅速に処理するために確実にスケジュールされるようにします。

  • Metal3およびCluster APIがクラスターのプロビジョニング/デプロビジョニングを正常に行えるように、`ignition.platform.id=openstack`を追加します。これは、OpenStack Ironicに由来するMetal3 Pythonエージェントによって使用されます。

  • `net.ifnames=1`を介して ネットワークインタフェースの予測可能な命名を有効にします。SUSE Linux Micro 6.2以降では、これがデフォルトで有効になっており、明示的な設定は不要です。6.2より前のバージョンでは、これをカーネル引数として明示的に設定する必要があります。これは、Management ClusterのMetal3 Helmチャートの`predictableNicNames`設定と一致しており、ダイレクトネットワークプロビジョニングが正しく機能するために必要です。SR-IOVを利用する場合、一貫したインターフェース命名も重要です。

  • intel_pstate=passive`を削除する。このオプションは、`intel_pstate`が汎用cpufreqガバナーと連携するように設定しますが、これを機能させるために、副作用としてハードウェア管理のP-state(`HWP)を無効にします。ハードウェアのレイテンシを削減するため、リアルタイムワークロードにはこのオプションは推奨されません。

  • `intel_idle.max_cstate=0 processor.max_cstate=1`を`idle=poll`に置き換えます。C-State遷移を回避するために、`idle=poll`オプションを使用してC-State遷移を無効にし、CPUを最高のC-Stateに維持します。`intel_idle.max_cstate=0`オプションは`intel_idle`を無効にするため、`acpi_idle`が使用され、その後`acpi_idle.max_cstate=1`がacpi_idleの最大C-stateを設定します。 AMD64/Intel 64アーキテクチャでは、最初のACPI C-Stateは常に`POLL`ですが、`poll_idle()`関数を使用します。この関数は、定期的にクロックを読み取り、タイムアウト後に`do_idle()`でメインループを再起動するため、わずかなレイテンシが発生する可能性があります(これには`TIF_POLL`タスクフラグのクリアと設定も含まれます)。 対照的に、`idle=poll`はタイトなループで実行され、タスクが再スケジュールされるのをビジーウェイトで待機します。これによりアイドル状態からの復帰レイテンシは最小限に抑えられますが、アイドルスレッドでCPUをフルスピードで動作させ続けるという代償が伴います。

  • BIOSでC1Eを無効にします。このオプションは、BIOSでC1E状態を無効にし、アイドル時にCPUがC1E状態に入るのを防ぐために重要です。C1E状態は、CPUがアイドル状態のときにレイテンシを引き起こす可能性のある低電力状態です。

このドキュメントの残りの部分では、ヒュージページやIOMMUを含む追加のパラメータについて説明します。

以下は、前述の調整を含む、32コアIntelサーバーのカーネル引数の例です。

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll

以下は、64コアAMDサーバーの別の設定例です。128個の論理プロセッサ(0-127)のうち、最初の8コア(0-7)はハウスキーピング用に指定され、残りの120コア(8-127)はアプリケーション用に固定されています。

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=575291cf-74e8-42cf-8f2c-408a20dc00b8 skew_tick=1 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 amd_iommu=on iommu=pt irqaffinity=0-7 isolcpus=domain,nohz,managed_irq,8-127 nohz_full=8-127 rcu_nocbs=8-127 mce=off nohz=on nowatchdog nmi_watchdog=0 nosoftlockup quiet rcu_nocb_poll rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll

36 ホストでのCPU固定

CPUピニング(プロセッサアフィニティとも呼ばれます)は、プロセスやスレッドを特定のCPUコアにバインドし、オペレーティングシステムのスケジューラによる移動を防ぐ手法です。プロセスが常に同じコアで実行されるようにすることで、そのコアのキャッシュメモリに残っているデータへのアクセスが高速になるという利点があります。この手法は、ハイパフォーマンスコンピューティング環境で一般的であり、パフォーマンスを劇的に向上させ、オーバーヘッドを削減します。

36.1 TuneDによるCPUの分離

`tuned`は、さまざまな定義済みプロファイルを使用してパフォーマンスを最適化するためにシステムの状態を監視するシステムチューニングツールです。重要な機能として、リアルタイムアプリケーションなどの特定のワークロードに対してCPUコアを分離する機能があります。これにより、OSがこれらのコアを使用することを防ぎ、レイテンシが増加する可能性を抑えます。

この機能を有効にして設定するには、まず分離したいCPUコア用のプロファイルを作成する必要があります。この例では、64個のコアのうち、60個のコア(1-30,33-62)をアプリケーション専用とし、残りの4個のコアをハウスキーピング用に使用します。分離されたCPUの設計は、リアルタイムアプリケーションに大きく依存することに注意してください。

$ echo "export tuned_params" >> /etc/grub.d/00_tuned

$ echo "isolated_cores=1-30,33-62" >> /etc/tuned/cpu-partitioning-variables.conf

$ tuned-adm profile cpu-partitioning
Tuned (re)started, changes applied.

36.2 カーネル引数によるCPUの分離

次に、CPUコアを分離し、CPU使用率に関するその他の重要なパラメータを設定するために、GRUBオプションを変更する必要があります。 以下のオプションは、現在のハードウェア仕様に合わせてカスタマイズすることが重要です。

パラメータ」値description

isolcpus

domain,nohz,managed_irq,1-30,33-62

コア1~30および33~62を分離します。`domain`は、これらのCPUが分離ドメインの一部であることを示します。`nohz`は、これらの分離されたCPUがアイドル状態のときにティックレス動作を有効にし、割り込みを削減します。`managed_irq`は、固定されたCPUがIRQのターゲットにならないように分離します。これは、すでにほとんどのIRQをハウスキーピングコアに振り向けている`irqaffinity=0-7`を考慮に入れています。

skew_tick

1

このオプションにより、カーネルは分離されたCPU間でタイマー割り込みをスキュー(ずらすこと)できます。

nohz

on

有効にすると、カーネルの周期的なタイマー割り込み(「ティック」)が、アイドル状態になった任意のCPUコアで停止します。これは主にハウスキーピングCPU(0,31,32,63)にメリットがあり、電力を節約し、それらの汎用コアでの不要なウェイクアップを削減します。

nohz_full

1-30,33-62

分離されたコアの場合、これはCPUが単一のアクティブなタスクを実行しているときでもティックを停止します。これは、CPUをフルティックレスモード(または「dyntick」)で実行することを意味します。カーネルは、実際に必要な場合にのみタイマー割り込みを発生させます。

rcu_nocbs

1-30,33-62

このオプションは、指定されたCPUコアからRCUコールバック処理をオフロードします。

rcu_nocb_poll

 

このオプションが設定されている場合、no-RCU-callback CPUは、他のCPUによって明示的にウェイクアップされるのではなく、コールバック処理が必要かどうかを定期的にポーリングして確認します。これにより、割り込みオーバーヘッドを削減できます。

irqaffinity

0,31,32,63

このオプションにより、カーネルはハウスキーピングコアに対して割り込みを実行できるようになります。

アイドル

ポーリング

これによりアイドル状態からの復帰レイテンシは最小限に抑えられますが、アイドルスレッドでCPUをフルスピードで動作させ続けるという代償が伴います。

nmi_watchdog

0

このオプションはNMIウォッチドッグのみを無効にします。`nowatchdog`が設定されている場合は、これを省略できます。

nowatchdog

 

このオプションは、タイマーハード割り込みコンテキストで実行されるタイマーとして実装されているソフトロックアップウォッチドッグを無効にします。

次のコマンドはGRUB設定を変更し、前述の変更を次回の起動時に適用します。

`/etc/default/grub`ファイルを上記のパラメータで編集すると、ファイルは次のようになります。

GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"

GRUB設定を更新します。

$ transactional-update grub.cfg
$ reboot

再起動後にパラメータが適用されたことを確認するには、次のコマンドを使用してカーネルコマンドラインを確認できます。

$ cat /proc/cmdline

CPU構成とネットワークパラメータを調整するために使用できる別のスクリプトがあり、基本的には次の手順を実行します。

  • CPUガバナーを`performance`に設定します。

  • 分離されたCPUへのタイマー移行を解除します。

  • kdaemonスレッドをハウスキーピングCPUに移行します。

  • 分離されたCPUのレイテンシを可能な限り低い値に設定します。

  • vmstatの更新を300秒に遅延させます。

  • 最適なパフォーマンスを得るためにネットワークチューニングパラメータを構成します。

スクリプトは SUSE Telco Cloud Examplesリポジトリで入手できます。

37 KubernetesにおけるCPUピニング

37.1 RKE2 Versions < v1.32

RKE2設定ファイルを編集して、RKE2クラスターでCPUピニングを有効にします。`/etc/rancher/rke2/config.yaml`ファイルに以下のkubelet引数を追加します。`kubelet-reserved`および`system-reserved`引数でハウスキーピングCPUコアを必ず指定してください:

kubelet-arg:
- "cpu-manager-policy=static"
- "cpu-manager-policy-options=full-pcpus-only=true"
- "cpu-manager-reconcile-period=0s"
- "kubelet-reserved=cpu=0,31,32,63"
- "system-reserved=cpu=0,31,32,63"

37.2 RKE2 Versions >= v1.32

RKE2のバージョンがv1.32以上の場合、アップストリームのKubernetesの慣行に従い、コマンドライン引数を使用してkubeletを設定することはできません。CPUピニングを設定するには、kubelet設定ファイルを作成する必要があります。 RKE2ドキュメントを参照してください。

01-cpu-pinning.conf`のような新しいkubelet設定ファイルを作成し、/var/lib/rancher/rke2/agent/etc/kubelet.conf.d/`ディレクトリに配置します:

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cpuManagerPolicy: static
reservedSystemCPUs: 0,31,32,63
topologyManagerPolicy: single-numa-node

設定変更を有効にするには、適切なRKE2サービス(サーバーまたはエージェント)の再起動が必要です。この操作により、ホスト上のRKE2サービスが一時的に中断されます。ノードタイプに応じて、以下のコマンドのいずれかのみを実行してください:

# If the node is RKE2 agent
systemctl restart rke2-agent
# Else if the node is RKE2 server
systemctl restart rke2-server

37.3 CPUピニングを活用したワークロードのデプロイ

ワークロードで定義するリクエストと制限に応じて、kubeletで定義された`Static Policy`を使用してこの機能を使用する方法は3つあります。

  1. BestEffort QoSクラス:`CPU`のリクエストまたは制限を定義しない場合、ポッドはシステムで使用可能な最初の`CPU`にスケジュールされます。

    BestEffort QoSクラスを使用する例は次のとおりです。

    spec:
      containers:
      - name: nginx
        image: nginx
  2. Burstable QoSクラス:CPUのリクエストを定義したが制限と等しくない場合、またはCPUリクエストがない場合。

    Burstable QoSクラスを使用する例は次のとおりです。

    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            memory: "200Mi"
          requests:
            memory: "100Mi"

    または

    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            memory: "200Mi"
            cpu: "2"
          requests:
            memory: "100Mi"
            cpu: "1"
  3. Guaranteed QoSクラス:CPUのリクエストを定義し、それが制限と等しい場合。

    Guaranteed QoSクラスを使用する例は次のとおりです。

    spec:
      containers:
        - name: nginx
          image: nginx
          resources:
            limits:
              memory: "200Mi"
              cpu: "2"
            requests:
              memory: "200Mi"
              cpu: "2"

38 ネットワークパラメータ

ネットワークのチューニングは、通信ワークロードで最適なパフォーマンスを実現するために不可欠です。performance-settings.shスクリプトには、バッファサイズ、パケット処理、およびUDPパフォーマンスを最適化するために、さまざまなカーネルネットワークパラメータを設定する`configure_network_tuning`関数が含まれています。

注記
注記

提供されているネットワークチューニング値は、テストおよび検証済みの例です。ただし、これらは特定のユースケース、ワークロード要件、およびハードウェア構成に合わせて調整する必要があります。

次のネットワークパラメータがスクリプトによって構成されます。

38.1 コアネットワークパラメータ

  • net.core.rmem_max (1342177280バイト):最大受信ソケットバッファサイズ。このパラメータは、任意のソケットでデータを受信するために割り当て可能なメモリの最大量を設定します。

  • net.core.wmem_max (516777216バイト):送信ソケットバッファの最大サイズ。このパラメータは、任意のソケットでデータを送信するために割り当てることができるメモリの最大量を設定します。

  • net.core.rmem_default (10000000バイト):受信ソケットバッファのデフォルトサイズ。これは、新しいソケットでデータを受信するための初期バッファサイズです。

  • net.core.wmem_default (10000000バイト):送信ソケットバッファのデフォルトサイズ。これは、新しいソケットでデータを送信するための初期バッファサイズです。

  • net.core.netdev_max_backlog (416384パケット):インターフェースがカーネルの処理能力を超える速度でパケットを受信したときに、入力側でキューに入れられるパケットの最大数。この値を増やすと、トラフィックのバースト時にパケットがドロップするのを防ぐのに役立ちます。

  • net.core.optmem_max (25165824 bytes):ソケットごとに許可される補助バッファの最大サイズ。これは、オプションメモリバッファのサイズに影響します。

  • net.core.netdev_budget (1024パケット):1回のsoftirq実行で処理できるパケットの最大数。これは、パケット処理中のCPU使用率を制御するのに役立ちます。

38.2 UDP固有のパラメータ

  • net.ipv4.udp_mem (11416320 15221760 22832640 ページ):UDPによって使用されるメモリ量(ページ単位)を制御します。3つの値は以下を表します:

    • 最小しきい値これより下では、UDPに負荷はかかりません

    • 負荷しきい値:UDPがメモリ負荷の適用を開始します

    • 最大しきい値UDPの最大メモリページ数

  • net.ipv4.udp_rmem_min (16384バイト):UDPソケットの最小受信バッファサイズ。UDP受信のベースラインバッファサイズを確保します。

  • net.ipv4.udp_wmem_min (16384バイト):UDPソケットの最小送信バッファサイズ。UDP送信のベースラインバッファサイズを確保します。

38.3 リアルタイムスケジューリング

  • kernel.sched_rt_runtime_us (-1):リアルタイムスロットリングメカニズムを無効にします。これを-1に設定すると、リアルタイムタスクに無制限のCPU時間が許可されます。これは、決定論的なレイテンシを必要とする通信ワークロードに不可欠です。

重要
重要

これらのパラメータは、SUSE Telco Cloud Examplesリポジトリのperformance-settings.shスクリプトを使用すると自動的に構成されます。このスクリプトは、Automated Provisioning (パートVII「完全自動化されたダイレクトネットワークプロビジョニング」)セクションで説明されているように、イメージビルドプロセスに統合する必要があります。

39 CNI構成

39.1 Cilium

Cilium`は、SUSE Telco CloudのデフォルトのCNIプラグインです。 RKE2クラスターでCiliumをデフォルトのプラグインとして有効にするには、/etc/rancher/rke2/config.yaml`ファイルに以下の構成が必要です。

cni:
- cilium

これはコマンドライン引数でも指定できます。つまり、/etc/systemd/system/rke2-server`ファイルのサーバー行に--cni=cilium`を追加します。

40.2項 「オプション2(推奨):SR-IOV Network Operator」で説明されている`SR-IOV`ネットワークをCiliumと共に使用するには、`multus`メタプラグインをデプロイします。`multus`が他のCNIよりも前にリストされていることを確認してください。

cni:
- multus
- cilium

39.2 Calico

Calico`は、Telco向けSUSE Telco Cloudのもう1つのCNIプラグインです。 RKE2クラスターでCalicoをデフォルトのプラグインとして有効にするには、/etc/rancher/rke2/config.yaml`ファイルに以下の設定が必要です。

cni:
- calico

これはコマンドライン引数でも指定できます。つまり、/etc/systemd/system/rke2-server`ファイルのサーバー行に--cni=calico`を追加します。

40.2項 「オプション2(推奨):SR-IOV Network Operator」で説明されている`SR-IOV`ネットワークをCalicoと共に使用するには、`multus`メタプラグインをデプロイします。`multus`が他のCNIよりも前にリストされていることを確認してください。

cni:
- multus
- calico
注記
注記

CNIプラグインの詳細については、 Network Optionsを参照してください。

39.3 Bond CNI

一般的に、ボンディングは複数のネットワークインタフェースを単一の論理的な「ボンドインタフェース」に集約する方法を提供します。これは通常、冗長なネットワークパスを導入してサービスの可用性を高めるために使用されますが、特定のボンドモードでは帯域幅を増やすためにも使用できます。 Bond CNIプラグインとMultusを組み合わせて使用する場合、以下のCNIプラグインがサポートされています。

  • MACVLAN

  • ホストデバイス

  • SR-IOV

39.3.1 MACVLANを使用したBond CNI

MACVLANでBond CNIプラグインを使用するには、コンテナ内に2つの空きネットワークインタフェースが必要です。以下の例では「enp8s0」と「enp9s0」を使用します。まず、それらのネットワークアタッチメント定義を作成します。

NetworkAttachmentDefinition enp8s0

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: enp8s0-conf
spec:
  config: '{
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "macvlan",
          "capabilities": { "ips": true },
          "master": "enp8s0",
          "mode": "bridge",
          "ipam": {}
        }, {
          "capabilities": { "mac": true },
          "type": "tuning"
        }
      ]
    }'

NetworkAttachmentDefinition enp9s0

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: enp9s0-conf
spec:
  config: '{
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "macvlan",
          "capabilities": { "ips": true },
          "master": "enp9s0",
          "mode": "bridge",
          "ipam": {}
        }, {
          "capabilities": { "mac": true },
          "type": "tuning"
        }
      ]
    }'

次に、ボンド自体のネットワークアタッチメント定義を追加します。

NetworkAttachmentDefinition bond

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: bond-net1
spec:
  config: '{
  "type": "bond",
  "cniVersion": "0.3.1",
  "name": "bond-net1",
  "mode": "active-backup",
  "failOverMac": 1,
  "linksInContainer": true,
  "miimon": "100",
  "mtu": 1500,
  "links": [
     {"name": "net1"},
     {"name": "net2"}
  ],
  "ipam": {
    "type": "static",
    "addresses": [
      {
        "address": "192.168.200.100/24",
        "gateway": "192.168.200.1"
      }
    ],
    "subnet": "192.168.200.0/24",
    "routes": [{
      "dst": "0.0.0.0/0"
    }]
  }
}'

ここでのIPアドレス割り当ては静的であり、ボンドのアドレスを/24ネットワーク上の「192.168.200.100」と定義し、ゲートウェイはネットワークの最初に使用可能なアドレスに配置されます。ボンドのネットワークアタッチメントでは、必要なボンドのタイプも定義します。この場合はアクティブバックアップです。

このボンドを使用するには、Podがすべてのネットワークインタフェースを認識している必要があります。Pod定義の例は次のようになります。

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  annotations:
        k8s.v1.cni.cncf.io/networks: '[
{"name": "enp8s0-conf",
"interface": "net1"
},
{"name": "enp9s0-conf",
"interface": "net2"
},
{"name": "bond-net1",
"interface": "bond0"
}]'
spec:
  restartPolicy: Never
  containers:
  - name: bond-test
    image: alpine:latest
    command:
      - /bin/sh
      - "-c"
      - "sleep 60m"
    imagePullPolicy: IfNotPresent

アノテーションがどのようにすべてのネットワークを参照し、インターフェース「enp8s0 → net1」と「enp9s0→net2」の間のマッピングを定義しているかに注目してください。

39.3.2 ホストデバイスでのBond CNI

ホストデバイスでBond CNIプラグインを使用するには、ホスト上に2つの空きネットワークインタフェースが必要です。これらのネットワークインタフェースは、コンテナにマッピングされます。次の例では、「enp8s0」と「enp9s0」を使用します。まず、それらのネットワークアタッチメント定義を作成します。

NetworkAttachmentDefinition enp8s0

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: enp8s0-hostdev
spec:
  config: '{
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "host-device",
          "name": "host0",
          "device": "enp8s0",
          "ipam": {}
        }]
    }'

NetworkAttachmentDefinition enp9s0

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: enp9s0-hostdev
spec:
  config: '{
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "host-device",
          "name": "host0",
          "device": "enp9s0",
          "ipam": {}
        }]
    }'

この後、ボンド自体のネットワークアタッチメント定義を追加します。これはMACVLANのユースケースと似ています。

NetworkAttachmentDefinition bond

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: bond-net1
spec:
  config: '{
  "type": "bond",
  "cniVersion": "0.3.1",
  "name": "bond-net1",
  "mode": "active-backup",
  "failOverMac": 1,
  "linksInContainer": true,
  "miimon": "100",
  "mtu": 1500,
  "links": [
     {"name": "net1"},
     {"name": "net2"}
  ],
  "ipam": {
    "type": "static",
    "addresses": [
      {
        "address": "192.168.200.100/24",
        "gateway": "192.168.200.1"
      }
    ],
    "subnet": "192.168.200.0/24",
    "routes": [{
      "dst": "0.0.0.0/0"
    }]
  }
}'

ここでのIPアドレスの割り当ては静的であり、ボンドのアドレスを/24ネットワーク上の「192.168.200.100」として定義し、ゲートウェイはネットワークの最初に使用可能なアドレスに配置されます。ボンドのネットワークアタッチメントで、ボンドのタイプを定義します。この場合はアクティブ-バックアップです。

このボンドを使用するには、podがすべてのインターフェースを認識している必要があります。ホストデバイスを使用したボンドのpod定義の例は、次のようになります。

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  annotations:
        k8s.v1.cni.cncf.io/networks: '[
{"name": "enp8s0-hostdev",
"interface": "net1"
},
{"name": "enp9s0-hostdev",
"interface": "net2"
},
{"name": "bond-net1",
"interface": "bond0"
}]'
spec:
  restartPolicy: Never
  containers:
  - name: bond-test
    image: alpine:latest
    command:
      - /bin/sh
      - "-c"
      - "sleep 60m"
    imagePullPolicy: IfNotPresent

39.3.3 SR-IOVでのボンドCNI

SR-IOVでボンドCNIを使用するのは非常に簡単です。SR-IOVのセットアップ方法の詳細については、第40章 「SR-IOV」を参照してください。そこに記載されているように、`SriovNetworkNodePolicies`を作成して、`resourceNames`や仮想関数の数などを定義する必要があります。`resourceNames`は、ポッド定義でインターフェースとして使用される`SriovNetwork`によって使用されます。ボンドの定義は、MACVLANおよびホストデバイスの場合とまったく同じです。

注記
注記

SR-IOVでのボンドCNIは、カーネルドライバーを使用するSR-IOV仮想関数(VF)にのみ適用されます。DPDKワークロードで使用されるようなユーザースペースドライバーVFは、ボンドCNIでボンディングすることはできません。

40 SR-IOV

SR-IOV(Single Root I/O Virtualization)を使用すると、ネットワークアダプターなどの単一の物理デバイスが、そのリソースを複数の`PCIe`ハードウェア関数に分離できます。これにより、さまざまなアプリケーションがリソースに直接アクセスできるようになります。

クラスターに`SR-IOV`をデプロイするために、2つの異なる方法を提供しています。

ネットワークデバイスにNetwork Operatorを使用し、vRANアクセラレータにDevice Pluginを使用するというように、両方のソリューションが必要な稀なケースでは、それらを別々のKubernetesネームスペースにデプロイする必要があります。この分離は、2つのデプロイメント間の競合を防ぐために不可欠です。

40.1 オプション1:SR-IOV Network Device Plugin DaemonsetおよびconfigMap

SR-IOV Network Device Pluginは、PCI物理機能(PF)やその仮想機能(VF)などのネットワークリソースをKubernetesホスト上で検出し、アドバタイズします。

  • デバイスプラグイン用のconfig mapを準備します

SR-IOVリソースプールを定義するconfig mapを作成する必要があります。`lspci`コマンドを実行して情報を取得します。

$ lspci | grep -i acc
07:00.0 Processing accelerators: Intel Corporation Device 57c2
07:00.1 Processing accelerators: Intel Corporation Device 57c3
07:00.2 Processing accelerators: Intel Corporation Device 57c3
07:00.3 Processing accelerators: Intel Corporation Device 57c3
07:00.4 Processing accelerators: Intel Corporation Device 57c3
07:00.5 Processing accelerators: Intel Corporation Device 57c3
07:00.6 Processing accelerators: Intel Corporation Device 57c3
07:00.7 Processing accelerators: Intel Corporation Device 57c3
07:01.0 Processing accelerators: Intel Corporation Device 57c3
07:01.1 Processing accelerators: Intel Corporation Device 57c3
07:01.2 Processing accelerators: Intel Corporation Device 57c3
07:01.3 Processing accelerators: Intel Corporation Device 57c3
07:01.4 Processing accelerators: Intel Corporation Device 57c3
07:01.5 Processing accelerators: Intel Corporation Device 57c3
07:01.6 Processing accelerators: Intel Corporation Device 57c3
07:01.7 Processing accelerators: Intel Corporation Device 57c3
07:02.0 Processing accelerators: Intel Corporation Device 57c3
0a:00.0 Processing accelerators: Intel Corporation Device 57c2

$ lspci | grep -i net
19:00.0 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.1 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.2 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
19:00.3 Ethernet controller: Broadcom Inc. and subsidiaries BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet (rev 11)
51:00.0 Ethernet controller: Intel Corporation Ethernet Controller E810-C for QSFP (rev 02)
51:00.1 Ethernet controller: Intel Corporation Ethernet Controller E810-C for QSFP (rev 02)
51:01.0 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.1 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.2 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:01.3 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.0 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.1 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.2 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)
51:11.3 Ethernet controller: Intel Corporation Ethernet Adaptive Virtual Function (rev 02)

SR-IOV Device Pluginは、Kubernetesが公開すべきハードウェアリソースを定義するJSONファイルを含むconfigMapを使用します。この構成は、2つのコアとなる概念、selectors(ハードウェア検出用)と`resources`(Kubernetes公開用)に基づいています。

resource`とは、Podが消費する名前付きエンティティです(例: `rancher.io/intel_fec_5g)。リソースは、次の2つのタイプのいずれかとして定義できます。

  • accelerator:vRANアクセラレータカード(ACC100/vRAN Boostなど)に使用されます。

  • netdevice:標準のネットワークインタフェース(NIC)に使用されます。

ノード上のハードウェアをフィルタリングするために`selectors`を使用してターゲットデバイスを定義します。

  • vendors:`8086` (Intel)

  • devices:`57c3` (FEC VF)、1889 (NIC VF)

  • drivers: vfio-pci

  • pfNames: eno16595np0 (物理インターフェイス名)

ネットワークカードの場合、物理機能(PF)から仮想機能(VF)のサブセットを選択することもできます。

  • pfNames: ["eth1#1,2,3,4,5,6"] または [eth1#1-6]

ポッドがデバイスを要求できるようにするには、各リソースに名前を付ける必要があります。この名前は、プレフィックスと名前で構成されます。

  • resourceName: pci_sriov_net_bh_dpdk

  • resourcePrefix: rancher.io

ポッドは、結合されたリソース名 rancher.io/pci_sriov_net_bh_dpdk を要求します。

注記
注記

このドキュメントには、すべての可能なセレクターが記載されているわけではありません。リソースの種類によって、使用するセレクターのセットが異なります。詳細については、 SR-IOV Network Device Pluginリポジトリを参照してください。

以下のConfigMapは、vRANアクセラレータカード(FEC)用に1つ、2つの異なるNICポート用に2つ、合計3つのリソースを作成する例です。

FECカードの場合は、まずデバイスIDとVFIOトークンを取得する必要があります。前提条件については、第42章 「vRANアクセラレーション(Intel ACC100/VRB1/VRB2)」の章の手順に従ってください。

apiVersion: v1
kind: ConfigMap
metadata:
  name: sriovdp-config
  namespace: kube-system
data:
  config.json: |
    {
        "resourceList": [
            {
                "resourcePrefix": "rancher.io",
                "resourceName": "intel_fec_5g",
                "deviceType": "accelerator",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["57c3"]
                },
                "additionalInfo": {
                      "*": {
                        "VFIO_TOKEN": "00112233-4455-6677-8899-aabbccddeeff"
                      }
                  }
            },
            {
                "resourcePrefix": "rancher.io",
                "resourceName": "intel_sriov_odu",
                "deviceType": "netdevice",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["1889"],
                    "drivers": ["vfio-pci"],
                    "pfNames": ["eno16595np0"]
                }
            },
            {
                "resourcePrefix": "rancher.io",
                "resourceName": "intel_sriov_oru",
                "deviceType": "netdevice",
                "selectors": {
                    "vendors": ["8086"],
                    "devices": ["1889"],
                    "drivers": ["vfio-pci"],
                    "pfNames": ["eno16605np1"]
                }
            }
        ]
    }
  • デバイスプラグインをデプロイするために`daemonset`ファイルを準備します。

デバイスプラグインは複数のアーキテクチャ(arm、amd、ppc64le)をサポートしているため、アーキテクチャごとに複数の`daemonset`をデプロイすることで、同じファイルを異なるアーキテクチャに使用できます。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: sriov-device-plugin
  namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-sriov-device-plugin-amd64
  namespace: kube-system
  labels:
    tier: node
    app: sriovdp
spec:
  selector:
    matchLabels:
      name: sriov-device-plugin
  template:
    metadata:
      labels:
        name: sriov-device-plugin
        tier: node
        app: sriovdp
    spec:
      hostNetwork: true
      nodeSelector:
        kubernetes.io/arch: amd64
      tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      serviceAccountName: sriov-device-plugin
      containers:
      - name: kube-sriovdp
        image: registry.suse.com/edge/3.7/sriov-network-device-plugin:v3.10.0
        imagePullPolicy: IfNotPresent
        args:
        - --log-dir=sriovdp
        - --log-level=10
        securityContext:
          privileged: true
        resources:
          requests:
            cpu: "250m"
            memory: "40Mi"
          limits:
            cpu: 1
            memory: "200Mi"
        volumeMounts:
        - name: devicesock
          mountPath: /var/lib/kubelet/
          readOnly: false
        - name: log
          mountPath: /var/log
        - name: config-volume
          mountPath: /etc/pcidp
        - name: device-info
          mountPath: /var/run/k8s.cni.cncf.io/devinfo/dp
      volumes:
        - name: devicesock
          hostPath:
            path: /var/lib/kubelet/
        - name: log
          hostPath:
            path: /var/log
        - name: device-info
          hostPath:
            path: /var/run/k8s.cni.cncf.io/devinfo/dp
            type: DirectoryOrCreate
        - name: config-volume
          configMap:
            name: sriovdp-config
            items:
            - key: config.json
              path: config.json
  • configMapと`daemonset`を適用すると、デバイスプラグインがデプロイされ、インターフェースが検出されてポッドで使用可能になります。

    $ kubectl get pods -n kube-system | grep sriov
    kube-system  kube-sriov-device-plugin-amd64-twjfl  1/1  Running  0  2m
  • すべてのノードで、インターフェースが検出され、ポッドで使用可能になったかどうかを確認します。

    $ kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, allocatable: .status.allocatable}'
    {
      "name": "node1.suse.edge.com",
      "allocatable": {
          "cpu": "64",
          "ephemeral-storage": "256196109726",
          "hugepages-1Gi": "40Gi",
          "hugepages-2Mi": "0",
          "rancher.io/intel_fec_5g": "16",
          "rancher.io/intel_sriov_odu": "4",
          "rancher.io/intel_sriov_oru": "4",
          "memory": "221396384Ki",
          "pods": "110"
      }
    }
  • `FEC`アクセラレータのresourceNameは`rancher.io/intel_fec_5g`であり、16個のVFが使用可能です。

  • NICカードのresourceNameは`rancher.io/intel_sriov_odu`および`rancher.io/intel_sriov_oru`です。各リソースは4個のVFを提供します。

重要
重要

Kubernetesノードでインターフェースが割り当て可能なリソースとして検出されない場合は、この問題を解決することが不可欠です。一般的な原因の1つはconfigMapの仕様が正しくないことであるため、configMapとそのセレクターを確認することをお勧めします。

40.2 オプション2(推奨):SR-IOV Network Operator

  • Helmが存在しない場合は取得します。

$ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
  • `sriov-network-operator`ネームスペースにSR-IOV Network Operatorをインストールします。

helm install sriov-crd oci://registry.suse.com/edge/charts/sriov-crd -n sriov-network-operator
helm install sriov-network-operator oci://registry.suse.com/edge/charts/sriov-network-operator -n sriov-network-operator
  • デプロイされたCRDとポッドを確認します。

$ kubectl get crd
$ kubectl -n sriov-network-operator get pods
  • SR-IOVラベルがノードに適用されているかどうかを確認します。

すべてのリソースが実行されると、ラベルがノードに自動的に表示されます。

$ kubectl get nodes -oyaml | grep feature.node.kubernetes.io/network-sriov.capable

feature.node.kubernetes.io/network-sriov.capable: "true"
  • daemonset を確認して、新しい sriov-network-config-daemon と sriov-rancher-nfd-worker がアクティブで準備完了になっていることを確認します。

$ kubectl get daemonset -n sriov-network-operator
NAMESPACE             NAME                            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                                           AGE
sriov-network-operator   sriov-network-config-daemon     1         1         1       1            1           feature.node.kubernetes.io/network-sriov.capable=true   45m
sriov-network-operator   sriov-rancher-nfd-worker        1         1         1       1            1           <none>                                                  45m

数分でノードが検出され、SR-IOV 機能で完全に構成されます。更新には最大10分かかる場合があります。

$ kubectl get sriovnetworknodestates -A
NAMESPACE             NAME     AGE
sriov-network-operator   xr11-2   83s
  • インターフェイスが検出されたかどうかを確認します。

検出されたインターフェイスは、ネットワークデバイスのPCIアドレスである必要があります。ホストで lspci コマンドを使用して、この情報を確認します。

$ kubectl get sriovnetworknodestates -n sriov-network-operator -oyaml
apiVersion: v1
items:
- apiVersion: sriovnetwork.openshift.io/v1
  kind: SriovNetworkNodeState
  metadata:
    creationTimestamp: "2023-06-07T09:52:37Z"
    generation: 1
    name: xr11-2
    namespace: sriov-network-operator
    ownerReferences:
    - apiVersion: sriovnetwork.openshift.io/v1
      blockOwnerDeletion: true
      controller: true
      kind: SriovNetworkNodePolicy
      name: default
      uid: 80b72499-e26b-4072-a75c-f9a6218ec357
    resourceVersion: "356603"
    uid: e1f1654b-92b3-44d9-9f87-2571792cc1ad
  spec:
    dpConfigVersion: "356507"
  status:
    interfaces:
    - deviceID: "1592"
      driver: ice
      eSwitchMode: legacy
      linkType: ETH
      mac: 40:a6:b7:9b:35:f0
      mtu: 1500
      name: eno16595np0
      pciAddress: "0000:51:00.0"
      totalvfs: 128
      vendor: "8086"
    - deviceID: "1592"
      driver: ice
      eSwitchMode: legacy
      linkType: ETH
      mac: 40:a6:b7:9b:35:f1
      mtu: 1500
      name: eno16605np1
      pciAddress: "0000:51:00.1"
      totalvfs: 128
      vendor: "8086"
    syncStatus: Succeeded
kind: List
metadata:
  resourceVersion: ""
注記
注記

インターフェイスがここで検出されない場合は、次のConfigMapに存在することを確認してください。

$ kubectl get cm supported-nic-ids -oyaml -n sriov-network-operator

デバイスがリストにない場合は、ConfigMapを編集して、検出される正しい値を追加してください。次に、各ノードの sriov-network-config-daemon ポッドを再起動して、更新を有効にします。

  • SriovNetworkNodePolicy を構成するために VFs を作成します。

このポリシーは、ポッドで使用するためのリソース intelnicsDpdk を作成します。また、vfio-pci ドライバーを指定されたPCIデバイスにバインドし、MTUサイズ1500の8つのVFを作成します。

注記
注記

resourceName フィールドには特殊文字を含めることはできず、クラスター全体で一意である必要があります。 この例では、DPDKがSR-IOVと組み合わせて使用されるため、deviceType: vfio-pci を使用します。DPDKを使用しない場合は、deviceType: netdevice(デフォルト値)を設定してください。

apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-dpdk
  namespace: sriov-network-operator
spec:
  nodeSelector:
    feature.node.kubernetes.io/network-sriov.capable: "true"
  resourceName: intelnicsDpdk
  deviceType: vfio-pci
  numVfs: 8
  mtu: 1500
  nicSelector:
    deviceID: "1592"
    vendor: "8086"
    rootDevices:
    - 0000:51:00.0
  • すべてのノードで構成を検証します。

定義済みの resourcePrefix rancher.io を使用すると、8つのVFを持つリソース rancher.io/intelnicsDpdk が検出されるはずです。

$ kubectl get nodes -o jsonpath='{"items": [ { "name": @.metadata.name, "allocatable": @.status.allocatable } ]}' | jq
{
  "name": "node1.suse.edge.com",
  "allocatable": {
      "cpu": "64",
      "ephemeral-storage": "256196109726",
      "hugepages-1Gi": "60Gi",
      "hugepages-2Mi": "0",
      "rancher.io/intel_fec_5g": "16",
      "memory": "200424836Ki",
      "pods": "110",
      "rancher.io/intelnicsDpdk": "8"
  }
}
  • (オプション)sriovnetwork を作成します。

この手順はオプションであり、カスタムネットワーク定義の場合にのみ必要です。以前に作成したノードポリシーにバインドする resourceName を指定します。

networkNamespace が設定されている場合、ネットワークはそのネームスペース内のポッドに公開されます。それ以外の場合、ネットワークはNetwork Operatorのインストールネームスペースで使用可能になります。

apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
  name: network-dpdk
  namespace: sriov-network-operator        # where SRIOV Operator is installed
spec:
  ipam: |
    {
      "type": "host-local",
      "subnet": "192.168.0.0/24",
      "rangeStart": "192.168.0.20",
      "rangeEnd": "192.168.0.60",
      "routes": [{
        "dst": "0.0.0.0/0"
      }],
      "gateway": "192.168.0.1"
    }
  vlan: 500
  resourceName: intelnicsDpdk
  networkNamespace: default         # where workloads are deployed
  • 更新が成功すると、ターゲットクラスターにNetworkAttachmentDefinition(NAD)が作成されます。

$ kubectl get net-attach-def -A -oyaml

apiVersion: v1
items:
- apiVersion: k8s.cni.cncf.io/v1
  kind: NetworkAttachmentDefinition
  metadata:
    annotations:
      k8s.v1.cni.cncf.io/resourceName: rancher.io/intelnicsDpdk
    creationTimestamp: "2023-06-08T11:22:27Z"
    generation: 1
    name: network-dpdk
    namespace: default
    resourceVersion: "13124"
    uid: df7c89f5-177c-4f30-ae72-7aef3294fb15
  spec:
    config: '{ "cniVersion":"0.4.0", "name":"network-dpdk","type":"sriov","vlan":500,"vlanQoS":0,"ipam":{"type":"host-local","subnet":"192.168.0.0/24","rangeStart":"192.168.0.10","rangeEnd":"192.168.0.60","routes":[{"dst":"0.0.0.0/0"}],"gateway":"192.168.0.1"}
      }'
kind: List
metadata:
  resourceVersion: ""

ワークロードポッドは、リソース名 rancher.io/intelnicsDpdk を使用してネットワークインターフェイスのVFを利用できます。

41 DPDK

DPDK(Data Plane Development Kit)は、高速なパケット処理のためのライブラリおよびドライバーのセットです。これは、さまざまなCPUアーキテクチャで実行されるパケット処理ワークロードを高速化するために使用されます。 DPDKには、データプレーンライブラリと、以下に対する最適化されたネットワークインタフェースコントローラ(NIC)ドライバーが含まれています。

  1. キューマネージャーは、ロックレスキューを実装します。

  2. バッファーマネージャーは、固定サイズのバッファーを事前割り当てします。

  3. メモリーマネージャーは、メモリー内のオブジェクトプールを割り当て、リングを使用して空きオブジェクトを格納します。また、オブジェクトがすべての DRAM チャネルに均等に分散されるようにします。

  4. ポーリングモードドライバー(PMD)は、非同期通知なしで動作するように設計されており、オーバーヘッドを削減します。

  5. パケットフレームワークは、パケット処理の開発を支援するライブラリのセットです。

以下の手順では、`DPDK`を有効にする方法と、`DPDK`インターフェイスで使用する`NICs`から`VFs`を作成する方法を説明します。

  • `DPDK`パッケージをインストールします。

$ transactional-update pkg install dpdk dpdk-tools libdpdk-25
$ reboot
  • カーネルパラメータ:

DPDKを使用するには、いくつかのドライバーを使用してカーネル内の特定のパラメーターを有効にします。

パラメータ」値description

iommu

pt

このオプションは、DPDKインターフェイス用の`vfio`ドライバーの使用を有効にします。

intel_iommu or amd_iommu

on

このオプションは、`vfio`用の`VFs`の使用を有効にします。

パラメーターを有効にするには、それらを`/etc/default/grub`ファイルに追加します。

GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"

GRUB構成を更新し、システムを再起動して変更を適用します。

$ transactional-update grub.cfg
$ reboot
  • `vfio-pci`カーネルモジュールをロードし、NICで`SR-IOV`を有効にします。最初の引数はSR-IOVをサポートする`vfio-pci`ドライバーを示し、2番目の引数はPCIデバイスがアイドル状態のときに低電力状態になるのを防ぎます。

$ modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
  • NICs`からいくつかの仮想機能(`VFs)を作成します。

`VFs`用に、例えば2つの異なる`NICs`用に作成するには、以下のコマンドが必要です。

$ echo 4 > /sys/bus/pci/devices/0000:51:00.0/sriov_numvfs
$ echo 4 > /sys/bus/pci/devices/0000:51:00.1/sriov_numvfs
  • 新しいVFを`vfio-pci`ドライバーにバインドします。

$ dpdk-devbind.py -b vfio-pci 0000:51:01.0 0000:51:01.1 0000:51:01.2 0000:51:01.3 \
                              0000:51:11.0 0000:51:11.1 0000:51:11.2 0000:51:11.3
  • 構成が正しく適用されていることを確認します。

$ dpdk-devbind.py -s

Network devices using DPDK-compatible driver
============================================
0000:51:01.0 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.1 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.2 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.3 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:01.0 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:11.1 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:21.2 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio
0000:51:31.3 'Ethernet Adaptive Virtual Function 1889' drv=vfio-pci unused=iavf,igb_uio

Network devices using kernel driver
===================================
0000:19:00.0 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=eno8303np0 drv=bnxt_en unused=igb_uio,vfio-pci *Active*
0000:19:00.1 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=eno8403np1 drv=bnxt_en unused=igb_uio,vfio-pci
0000:19:00.2 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=eno8503np2 drv=bnxt_en unused=igb_uio,vfio-pci
0000:19:00.3 'BCM57504 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb/200Gb Ethernet 1751' if=eno8603np3 drv=bnxt_en unused=igb_uio,vfio-pci
0000:51:00.0 'Ethernet Controller E810-C for QSFP 1592' if=eth13 drv=ice unused=igb_uio,vfio-pci
0000:51:00.1 'Ethernet Controller E810-C for QSFP 1592' if=rename8 drv=ice unused=igb_uio,vfio-pci

42 vRANアクセラレーション(Intel ACC100/VRB1/VRB2)

通信サービスプロバイダーが4Gから5Gネットワークへ移行するにつれ、多くのプロバイダーが、より高いチャネル容量と、エッジベースのサービスやアプリケーションの容易な展開を実現するために、仮想化無線アクセスネットワーク(vRAN)アーキテクチャを採用しています。vRANソリューションは、リアルタイムトラフィックの量やネットワーク上の需要に基づいて容量を増減できる柔軟性を備え、低遅延サービスを提供するのに理想的な位置にあります。

最も計算集約的な4Gおよび5Gワークロードの1つが、RAN階層1(L1)`FEC`であり、これは信頼性の低い、またはノイズの多い通信チャネルでのデータ伝送エラーを解決します。`FEC`テクノロジーは、4Gまたは5Gデータ内の限られた数のエラーを検出および修正し、再送信の必要性を排除します。`FEC`アクセラレーショントランザクションにはセル状態情報が含まれていないため、簡単に仮想化でき、プーリングの利点と容易なセル移行が可能になります。

歴史的に、Intelはレイヤー1 FECアルゴリズムを迅速に実行し、メインCPUのホスト処理能力を解放するために、ACC100 vRANアクセラレータカードを提供してきました。Intelはその後、Sapphire Rapidsを皮切りに、このテクノロジーを`Intel vRAN Boost`(VRB)という名称で新しいCPUに直接統合しました。Intel vRAN BoostはCPU自体でオフロードアクセラレーターとして機能し、個別のハードウェアカードを不要にします。本セクションでは、ワークロードがACC100またはIntel vRAN Boostを活用するためのSUSE Telco Cloudの構成について詳しく説明します。

42.1 カーネルパラメータ

`vRAN`アクセラレーションを有効にするには、以下のカーネルパラメータを有効にする必要があります(まだ存在しない場合)。

パラメータ」値description

iommu

pt

このオプションは、DPDKインターフェースでのvfioの使用を有効にします。

intel_iommu or amd_iommu

on

このオプションは、VFでのvfioの使用を有効にします。

GRUBファイル`/etc/default/grub`を変更して、カーネルコマンドラインに追加します。

GRUB_CMDLINE_LINUX="BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll"

GRUB構成を更新し、システムを再起動して変更を適用します。

$ transactional-update grub.cfg
$ reboot

再起動後にパラメータが適用されていることを確認するには、コマンドラインを確認します。

$ cat /proc/cmdline

42.2 FECアクセラレータでのSR-IOVの構成

  • vRANアクセラレーションを有効にするために`vfio-pci`カーネルモジュールをロードします。最初の引数はSR-IOVをサポートするための`vfio-pci`モジュールを示し、2番目の引数はPCIデバイスがアイドル状態のときに低電力状態になるのを防ぎます。

$ modprobe vfio-pci enable_sriov=1 disable_idle_d3=1
  • FECアクセラレータのPCIデバイスアドレスを取得します。

$ lspci -DPPnn | grep -i acc
0000:07:00.0 Processing accelerators [1200]: Intel Corporation Device [8086:57c2]
0000:0a:00.0 Processing accelerators [1200]: Intel Corporation Device [8086:57c2]
  • 物理インターフェース(PF)を`vfio-pci`ドライバーにバインドします。

$ dpdk-devbind.py -b vfio-pci 0000:07:00.0
  • 物理インターフェース(PF)から仮想関数(VFs)を作成します。

アクセラレータカードの最大`VF`容量を確認します。次に、最大数を超えない範囲で、希望する数のVFを公開するようにカードを構成します。この例では、カードを16 VFのフル容量で構成します。

$ cat /sys/bus/pci/devices/0000:07:00.0/sriov_totalvfs
64
$ echo 16 > /sys/bus/pci/devices/0000:07:00.0/sriov_numvfs
  • アクセラレータカードとその仮想関数を4Gまたは5Gプロファイルで構成します。その際、正確なIntelプロセッサ世代に応じて適切な`vRAN Boost`デバイスタイプを選択してください。Sapphire Rapids Edge Enhanced(SPR-EE)の場合は`VRB1`(旧称ACC200)、Granite Rapids-D(GNR-D)の場合は`VRB2`を選択します。一意のVFトークン(UUID)を提供する必要があります(ワークロードは、このVFトークンを使用してカードのFECアクセラレータ機能を利用します)。

警告
警告

pf-bb-config`からの非推奨事項:VRB2デバイスタイプをサポートする新しいRPMリリースでは、設定例ファイルが/usr/share/pf-bb-config/examples`の場所にインストールされるようになりました。古い`/opt/pf-bb-config/`パスも引き続きサポートされますが、将来のリリースで削除される予定です。新しいパスを反映するようにスクリプトとドキュメントを更新してください(以下の例のように実行してください)。

$ pf_bb_config VRB2 -c /usr/share/pf-bb-config/examples/vrb2/vrb2_config_vf_5g.cfg -f /usr/share/pf-bb-config/examples/vrb2/srs_fft_windows_coefficient.bin -v 00112233-4455-6677-8899-aabbccddeeff -p 0000:07:00.0
== pf_bb_config Version 25.11 ==
VRB2 PF [0000:07:00.0] configuration complete!
Log file = /var/log/pf_bb_cfg_0000:07:00.0.log
  • FEC PFから作成された新しいVFを確認します。VFは 0d5d デバイスIDを取得したことに注意してください。この情報は、これらのVFをKubernetesリソースとして公開するための次のステップで必要になります。

$ # dpdk-devbind.py -s | grep -A18 Baseband
Baseband devices using DPDK-compatible driver
=============================================
0000:07:00.0 'Device 57c2' numa_node=0 drv=vfio-pci unused=
0000:07:00.1 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:00.2 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:00.3 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:00.4 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:00.5 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:00.6 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:00.7 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:01.0 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:01.1 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:01.2 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:01.3 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:01.4 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:01.5 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:01.6 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:01.7 'Device 57c3' numa_node=0 drv=vfio-pci unused=
0000:07:02.0 'Device 57c3' numa_node=0 drv=vfio-pci unused=
--
Other Baseband devices
======================
0000:0a:00.0 'Device 57c2' numa_node=0 unused=vfio-pci

Other Crypto devices
====================
0000:01:00.0 '420xx Series QAT 4946' numa_node=0 unused=vfio-pci
0000:03:00.0 'Device 2714' numa_node=0 unused=vfio-pci

DMA devices using kernel driver
===============================
0000:00:01.0 'Device 11fb' numa_node=0 drv=idxd unused=vfio-pci

Other Eventdev devices
======================
0000:03:00.0 'Device 2714' numa_node=0 unused=vfio-pci

No 'Mempool' devices detected
=============================

42.3 FECアクセラレーション用にKubernetesを構成する

最後のステップは、SR-IOVデバイスプラグインを使用してVFをKubernetesに公開することです。前のステップで収集したVFのdeviceIDを使用してConfigMapを作成し、SR-IOVデバイスプラグインをインストールします。KubernetesノードがFEC VFを Allocatable リソースとして表示すれば、クラスターはワークロードがFECアクセラレーションを利用できる状態になります。

第40章 「SR-IOV」 章のオプション1の手順に従ってください。SRIOV Network OperatorはFECアクセラレータには適用できないため、オプション2は適用できません。

43 ヒュージページ

プロセスが`RAM`を使用する場合、`CPU`はそのプロセスによって利用される正確な部分をマークします。効率を達成するために、`CPU`は`RAM`を`pages`と呼ばれるブロックで割り当てます。多くのプラットフォームでのデフォルトの`page`サイズは`4 KB`です。ページはディスクにスワップされることがあります(他の操作の中でも)。

プロセスのアドレス空間は仮想であるため、CPU`とオペレーティングシステムは、どの`pages`が各プロセスに属し、それぞれがどこに格納されているかを追跡する必要があります。`pages`の数が多いほど、メモリマッピングの検索に時間がかかります。例えば、`1 GB`のメモリを使用するプロセスでは、262,144個のエントリを確認する必要があります(1 GB / 4 KB)。各`page table entry`が8バイトを占める場合、参照するデータの合計は`2 MB(262,144 * 8)になります。

現在のほとんどの`CPU`アーキテクチャでは、デフォルトの`4 KB`値よりも大きいサイズの`pages`ブロックを定義できます(`1 GB`や`2 MB`が一般的なサポート値です)。これは`huge pages`として知られており、`CPU/Operating System`が参照しなければならないエントリの数を減らします。

  • カーネルパラメータ

`huge pages`を有効にするには、以下のカーネルパラメータを追加する必要があります。この例では、`1 GB`サイズのページを40ページ、`2 MB`サイズのページを0ページ設定しますが、サポートする巨大なページサイズと各ページの正確な数は、アプリケーションのメモリ要件に応じて調整してください。

パラメータ」値description

hugepagesz

1G

このオプションを使用すると、「ヒュージページ」のサイズを1 GBに設定できます。

ヒュージページ

40

これは、直前に定義されたサイズ (1 GB) に対して、起動時に割り当てるよう要求される「ヒュージページ」の数です。

hugepagesz

2M

このオプションを使用すると、「ヒュージページ」のサイズを2 MBに設定できます。

ヒュージページ

0

これは、直前に定義されたサイズ (2 MB) に対して、起動時に割り当てるよう要求される「ヒュージページ」の数です。

default_hugepagesz

1G

これは、「ヒュージページ」サイズのデフォルト値です。

GRUBファイル`/etc/default/grub`を変更し、`GRUB_CMDLINE_LINUX`にこれらのパラメーターを追加します。

default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0

GRUB設定を更新し、システムを再起動して変更を適用します。

$ transactional-update grub.cfg
$ reboot

再起動後にパラメーターが適用されたことを確認するには、コマンドラインを確認します。

$ cat /proc/cmdline
  • ヒュージページの使用

ヒュージページを使用するには、それらをマウントする必要があります。

$ mkdir -p /hugepages
$ mount -t hugetlbfs nodev /hugepages

Kubernetesワークロードをデプロイし、リソースとボリュームを作成します。

...
 resources:
   requests:
     memory: "24Gi"
     hugepages-1Gi: 16Gi
     intel.com/intel_sriov_oru: '4'
   limits:
     memory: "24Gi"
     hugepages-1Gi: 16Gi
     intel.com/intel_sriov_oru: '4'
...
...
volumeMounts:
  - name: hugepage
    mountPath: /hugepages
...
volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages
...

44 NUMA対応スケジューリング

Non-Uniform Memory Access(不均一メモリアクセス)またはNon-Uniform Memory Architecture(NUMA)は、SMP(マルチプロセッサ)アーキテクチャで使用される物理メモリ設計であり、メモリへのアクセス時間はプロセッサに対するメモリの場所によって異なります。`NUMA`では、プロセッサは非ローカルメモリ(別のプロセッサのローカルメモリやプロセッサ間で共有されるメモリ)よりも、自身のローカルメモリに高速にアクセスできます。

44.1 NUMAノードの特定

`NUMA`ノードを特定するには、システム上で次のコマンドを使用します。

$ lscpu | grep NUMA
NUMA node(s):                       1
NUMA node0 CPU(s):                  0-63
注記
注記

この例では、64個の`CPUs`を表示する`NUMA`ノードが1つだけあります。

`NUMA`は`BIOS`で有効にする必要があります。`dmesg`に起動時のNUMA初期化の記録がない場合、カーネルリングバッファ内の`NUMA`関連のメッセージが上書きされている可能性があります。

45 Metal LB

`MetalLB`は、`L2`や`BGP`などの標準的なルーティングプロトコルをアドバタイズメントプロトコルとして使用する、ベアメタルKubernetesクラスター向けのロードバランサー実装です。これは、ベアメタル環境でKubernetesサービスのタイプ`LoadBalancer`を使用する必要があるため、Kubernetesクラスター内のサービスを外部に公開するために使用できるネットワークロードバランサーです。

`RKE2`クラスターで`MetalLB`を有効にするには、次の手順が必要です。

  • 次のコマンドを使用して`MetalLB`をインストールします。

$ kubectl apply <<EOF -f
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: metallb
  namespace: kube-system
spec:
  chart: oci://registry.suse.com/edge/charts/metallb
  targetNamespace: metallb-system
  version: 307.0.3+up0.16.1
  createNamespace: true
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: endpoint-copier-operator
  namespace: kube-system
spec:
  chart: oci://registry.suse.com/edge/charts/endpoint-copier-operator
  targetNamespace: endpoint-copier-operator
  version: 307.0.1+up0.3.0
  createNamespace: true
EOF
  • `IpAddressPool`と`L2advertisement`の設定を作成します。

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: kubernetes-vip-ip-pool
  namespace: metallb-system
spec:
  addresses:
    - 10.168.200.98/32
  serviceAllocation:
    priority: 100
    namespaces:
      - default
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: ip-pool-l2-adv
  namespace: metallb-system
spec:
  ipAddressPools:
    - kubernetes-vip-ip-pool
  • `VIP`を公開するためのエンドポイントサービスを作成します。

apiVersion: v1
kind: Service
metadata:
  name: kubernetes-vip
  namespace: default
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: rke2-api
    port: 9345
    protocol: TCP
    targetPort: 9345
  - name: k8s-api
    port: 6443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: LoadBalancer
  • `VIP`が作成され、`MetalLB`ポッドが実行されていることを確認します。

$ kubectl get svc -n default
$ kubectl get pods -n default

46 プライベートレジストリの設定

`Containerd`は、プライベートレジストリに接続し、それを使用して各ノードでプライベートイメージをプルするように設定できます。

起動時に、RKE2`は/etc/rancher/rke2/`に`registries.yaml`ファイルが存在するかどうかを確認し、ファイルで定義されているレジストリを使用するように`containerd`に指示します。プライベートレジストリを使用する場合は、レジストリを使用する各ノードでルートユーザーとしてこのファイルを作成してください。

プライベートレジストリを追加するには、次の内容でファイル`/etc/rancher/rke2/registries.yaml`を作成します。

mirrors:
  docker.io:
    endpoint:
      - "https://registry.example.com:5000"
configs:
  "registry.example.com:5000":
    auth:
      username: xxxxxx # this is the registry username
      password: xxxxxx # this is the registry password
    tls:
      cert_file:            # path to the cert file used to authenticate to the registry
      key_file:             # path to the key file for the certificate used to authenticate to the registry
      ca_file:              # path to the ca file used to verify the registry's certificate
      insecure_skip_verify: # may be set to true to skip verifying the registry's certificate

または認証なしの場合:

mirrors:
  docker.io:
    endpoint:
      - "https://registry.example.com:5000"
configs:
  "registry.example.com:5000":
    tls:
      cert_file:            # path to the cert file used to authenticate to the registry
      key_file:             # path to the key file for the certificate used to authenticate to the registry
      ca_file:              # path to the ca file used to verify the registry's certificate
      insecure_skip_verify: # may be set to true to skip verifying the registry's certificate

レジストリの変更を有効にするには、ノードでRKE2を開始する前にこのファイルを設定するか、構成済みの各ノードでRKE2を再起動する必要があります。

注記
注記

これに関する詳細については、 containerd registry configuration rke2を確認してください。

47 高精度時刻同期プロトコル (PTP)

47.1 概要

IEEE 1588標準で定義されている高精度時刻同期プロトコル (PTP) は、パケットネットワーク上で高精度の時刻を配信します。ネットワークインタフェース (NIC) がハードウェアでPTPパケットにタイムスタンプを付与すると、NTPが提供できる範囲をはるかに超えるサブマイクロ秒の精度に達します。通信事業者の環境において、PTPは5G無線アクセスネットワーク (RAN) の中核となる構成要素であり、無線ユニットが正しく送信を行うには厳密な位相と時刻の同期が必要です。SUSE Telco Cloudは、`linuxptp`パッケージを通じてPTPを実装しており、以下に説明する通信事業者向けプロファイルITU-T G.8275.1およびITU-T G.8275.2を対象としています。

PTPドメインは、少数のクロック役割で構成されます。

  • グランドマスター (GM): ドメインの主要な時刻源です。通常、GNSS受信機によって駆動されるプライマリリファレンスタイムクロック (PRTC) に同期し、下流のノードに時刻を送信します。GMの精度が、ドメイン全体の品質上限を決定します。

  • オーディナリークロック (OC): 単一のPTPポートを持つエンドノードです。通信事業者のデプロイメントでは、タイムレシーバーとして機能し、上流のグランドマスターまたはバウンダリークロックからローカルクロックを調整します。無線ワークロードを実行するコンピュートノードは、典型的なOCです。

  • バウンダリークロック (BC): 1つのポートで時刻を受信し (タイムレシーバー)、残りのポートで他のノードに向けて時刻を再生成する (タイムトランスミッター) マルチポートノードです。パス上にバウンダリークロックを挿入することで、各OCとリファレンス間のチェーンが短縮され、ネットワークでホップごとに蓄積される誤差が制限されます。

トポロジーを設計する際、オーディナリークロックとバウンダリークロックの区別が重要になります。

  • *オーディナリークロック (OC)*は、*単一*のPTPポートを持ち、ドメインの端に配置されます。 自身のクロックを制御するためにのみ時刻を消費し、他のノードに時刻を転送することはありません。

  • *バウンダリークロック (BC)*は、*複数*のPTPポートを持ちます。Time Receiverポートで時刻を消費し、Time Transmitterポートでそれを*再生成*することで、アップストリームのタイミングチェーンを終端し、ダウンストリームで新しいタイミングチェーンを開始します。この再生成により、長いノードチェーン全体で誤差が蓄積されるのを防ぎます。

以下のハードウェアおよびシグナリング要素がこれらの役割をサポートします。

  • PTP Hardware Clock (PHC):PTPが実際に同期を行う、NICに組み込まれたクロックです。オペレーティングシステムのクロックをPHCに合わせることは、専用のデーモンによって処理される別のステップです。

  • Synchronous Ethernet (SyncE):物理層の周波数同期です。PTPはパケット内で位相と時刻を伝送しますが、SyncEはイーサネット信号から直接安定した周波数を復元します。SyncEは*オプションの拡張機能*です。PTP単体でもすでに位相と時刻を提供しており、SyncEは、ノードがより強力な周波数安定性を必要とする場合や、PTP時刻ソースが一時的に失われた場合に備えてより長いホールドオーバーが必要な場合に追加されます。

  • Digital Phase-Locked Loop (DPLL):基準信号に同期し、それをフィルタリングして安定したクリーンなクロックを出力するハードウェアタイミングブロックです。これは、利用可能な入力からPHCを制御し、複数のNICを持つプラットフォームでは、異なるNICクロックを調整する役割を果たします。

各ノードにおいて、これらの機能は`linuxptp`デーモンによって実行されます。`ptp4l`はPTPプロトコルを実行してPHCを制御し、`phc2sys`はシステムクロックをPHCに合わせます。グランドマスターでは、`ts2phc`がさらにGNSS基準からPHCを制御します。それらの役割とインストールについては47.2項 「前提条件」で説明されています。

ハードウェアクロック自体は、LinuxカーネルのDPLLサブシステムとネットワークドライバによって処理されます。タイミング制御の度合い、およびマルチNICノード内でのタイミングの分散方法は、管理可能なDPLLがどこに配置されているかによって異なります。

  • NIC with an integrated DPLL:DPLLはNICに組み込まれており、Linux DPLLサブシステムを通じて構成されます。選択されたリファレンスにロックし、PHCを制御することで、周波数とホールドオーバーを完全に管理します。

  • 統合DPLLのないNIC:NICは構成可能なDPLLを備えておらず、`ptp4l`はPHCを直接制御します。サブシステムはロックステータスを(読み取り専用で)報告するにとどまり、高度な周波数処理は外部のタイミングソースに依存します。

  • 複数のNIC間で共有されるオンボードDPLL:DPLLは単一のNICに組み込まれているのではなく、NICの外部にあるプラットフォーム上に配置されています。これは、共通のリファレンスから複数のNICのPHCを制御して同期を維持するため、ノード内のすべてのNICが同じ時刻を共有します。この構成は、外部ケーブルに頼らずに内部でタイミングを配信するマルチNICプラットフォームで使用されます。

管理可能なDPLLを統合したNICを持つノード
図 47.1: 管理可能なDPLLを統合したNICを持つノード上のPTPソフトウェア
管理可能なDPLLを持たないNICを持つノード
図 47.2: 管理可能なDPLLを持たないNICを持つノード上のPTPソフトウェア
NIC間で共有されるオンボードDPLLを備えたノード
図 47.3: NIC間で共有されるオンボードDPLLを備えたノード上のPTPソフトウェア

通信事業者ネットワークは2つのITU-Tプロファイルを標準としており、これらは主に、使用されるトランスポートと、基盤となるネットワークのどれだけがPTP対応である必要があるかという点で異なります。

  • ITU-T G.8275.1(フルタイミングサポート):マルチキャストを使用してイーサネット(レイヤー2)上で直接実行されます。パス上のすべてのノードはPTPに対応し、<em>バウンダリークロック</em>として機能する必要があり、これにより最高の精度が得られます。特に明記されていない限り、このガイドのシナリオではこのプロファイルを使用します。

  • ITU-T G.8275.2(部分的なタイミングサポート):ユニキャストを使用してIP(レイヤー3)上で実行されます。 中間ノードはPTPをサポートする必要がないため、タイミングはタイミング非対応のネットワークセグメントを通過できますが、その代償として精度が低下します。

以下の図は、PTPのみの場合と、オプションの周波数拡張としてSyncEを追加した場合の時刻配信を示しています。どちらの場合も、グランドマスターはPRTC/GNSSソースからリファレンスを取得し、バウンダリクロックはエンドポイントに向けてタイミングを再生成します。

グランドマスターによるPTP専用配信
図 47.4: PTPのみによる時刻配信
グランドマスターによるPTPおよびSyncE配信
図 47.5: PTPおよびSyncEによる時刻と周波数の配信(オプションの拡張機能)

本ガイドでは、以下のシナリオについて説明します。各シナリオには、そのCluster API(CAPI)自動化へのリンクが含まれています。

注記
注記

シナリオ1a (47.3項 「シナリオ1a - オーディナリークロック(PTPのみ)」)のみが、ITU-T G.8275.1およびITU-T G.8275.2の両方の通信事業者固有のプロファイルの構成を示しています。残りのシナリオは、簡潔にするためITU-T G.8275.1のケースのみに焦点を当てています。展開は同一であり、2つのプロファイル間で変更されるのは`ptp4l`設定ファイルのみです。

47.2 前提条件

本ガイドでは通信事業者固有のプロファイルのみを扱うため、ハードウェアタイムスタンプおよびNIC内のPTPハードウェアクロック(PHC)が前提となります。通信事業者グレードのNICはハードウェアでPTPをサポートしています。特定のインターフェースの機能は、`ethtool -T`で確認できます。

# ethtool -T eno16495np0
Time stamping parameters for eno16495np0:
Capabilities:
        hardware-transmit
        software-transmit
        hardware-receive
        software-receive
        software-system-clock
        hardware-raw-clock
PTP Hardware Clock: 0
Hardware Transmit Timestamp Modes:
        off
        on
Hardware Receive Filter Modes:
        none
        all

hardware-transmit、hardware-receive、hardware-raw-clock`の機能と、0以上の`PTP Hardware Clock`インデックスを確認してください(-1`という値は、インターフェースにPHCがないことを意味します)。`eno16495np0`を、PTPに使用する予定のインターフェースに置き換えてください。

PTPは、linuxptp`パッケージによって提供されます。これには、`systemd`によって管理される長時間実行デーモンとして実行される3つのユーザスペースプログラム(`ptp4l、phc2sys、ts2phc)が含まれています(それぞれ専用のサービス:ptp4l.service、phc2sys.service、ts2phc.service)。これらは集合的にプロトコルを実行し、クロックを同期させ続けます。

  • ptp4l: PTPデーモン。これは、構成されたインターフェース上でIEEE 1588プロトコルを実行し、Best Master Clock Algorithm (BMCA) を適用して各ポートの役割を決定し、NICのPHCを調整します。単一の ptp4l インスタンスは複数のポートを管理でき、これによってノードがバウンダリクロックとして機能できるようになります。

  • phc2sys: 2つのクロックを同期させます。これは通常、システム(オペレーティングシステム)クロックを ptp4l が同期し続けるPHCに合わせるために使用され、システム時刻もPTPに従うようにします。

  • ts2phc: 「PHCへのタイムスタンプ」。これは、GNSS受信機によって配信されるPPSなどの外部時刻信号からPHCを調整します。これは、グランドマスターで使用され、同じノード内の複数のPHCを同期させるために使用されます。

ダウンストリームクラスターにPTPをインストールする推奨される方法は、Edge Image Builder (EIB) 定義ファイルの packageList に linuxptp パッケージを追加し、プロビジョニング中に自動的にデプロイされるようにすることです。パッケージのインストールに関する詳細については、EIB documentation (5.3.6項 「RPMパッケージの設定」) を参照してください。

apiVersion: 1.3
image:
  imageType: RAW
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.2-Base-RT-GM.raw
  outputImageName: eibimage-slmicrort-telco.raw
operatingSystem:
  systemd:
    enable:
      - ptp4l
      - phc2sys
  packages:
    packageList:
      - linuxptp
    sccRegistrationCode: $SCC_REGISTRATION_CODE
注記
注記

linuxptp`パッケージは、デフォルトでは `ptp4l、phc2sys、または ts2phc を有効にしません。 設定ファイルをデプロイした後、マニフェストの systemd セクションを使用して、必要なノードデーモンを有効にします(以下のシナリオを参照してください)。

最後に、使用するPTPプロファイルによって、ノード間のネットワークスイッチをPTP対応デバイスとして構成する必要があるかどうかが決まります。

  • ITU-T G.8275.1 (full timing support): マルチキャストを使用してイーサネット(レイヤー2)上で直接実行されます。パス上のすべてのノードはPTP対応であり、バウンダリクロックとして機能する必要があります。これにより最高の精度が得られます。したがって、介在するスイッチはPTP用に構成する必要があります。特に明記されていない限り、このガイドのシナリオではこのプロファイルを使用します。

  • ITU-T G.8275.2 (partial timing support): ユニキャストを使用してIP(レイヤー3)上で実行されます。 中間ノードはPTPをサポートする必要がないため、タイミングはタイミング非対応のネットワーク セグメントを通過でき、スイッチにPTP設定は不要ですが、その代償として精度が低下します。

47.3 シナリオ1a - オーディナリークロック(PTPのみ)

説明

これは最も単純なPTPデプロイメントです。単一のクラスタノードがアップストリームソースから時刻を取得し、ローカルクロックを調整しますが、別のノードに時刻を転送することはありません。このノードは、タイムレシーバーの役割を持つ単一のPTPポートを備えたオーディナリークロック(OC)として動作します。

OCノードでは、使用するプロファイルに関係なく、タイミングはすべて`linuxptp`デーモンによって処理されます。ノードは単一のNICを使用し、`ptp4l`が直接PHCを調整するため、DPLL設定や`ts2phc`は不要です。

  • `ptp4l`は受信インターフェース上でPTPプロトコルを実行します。ベストマスタークロックアルゴリズム(BMCA)がアップストリームノードをマスターとして選択し、ローカルポートが`SLAVE`状態に遷移し、`ptp4l`がNICのPTPハードウェアクロック(PHC)を調整します。 `clientOnly 1`を設定すると、ノードはタイムレシーバーの役割に制限されるため、マスターとして選択されることはありません。

  • phc2sys`はシステムクロック(`CLOCK_REALTIME)を`ptp4l`が同期を維持するPHCに合わせるため、オペレーティングシステムの時刻もPTPに従います。

このシナリオはどちらかの通信事業者向けプロファイルで実装可能です。これらはトランスポート や介在するネットワークが提供すべき内容が異なり、以下に2つの独立したモデルとして文書化されています。

重要
重要

オーディナリークロックは、一度に1つのPTPプロファイルのみを実行します。これら2つのモデルは相互排他的です。特定のノードには、どちらか一方のみを設定してください。選択したプロファイルの設定ファイルのみを作成し、/etc/sysconfig/ptp4l`ではそのファイルのみを参照してください。/etc/ptp4l-G.8275.1.conf`と`/etc/ptp4l-G.8275.2.conf`の両方を作成しないでください。また、`OPTIONS=`行に両方のファイルを渡さないでください。

モデル1 — ITU-T G.8275.1(レイヤー2マルチキャスト)

G.8275.1はイーサネット上で直接実行され、そのメッセージを転送不可能なマルチキャストMAC `01:80:C2:00:00:0E`に送信します。標準的なブリッジはこれを転送しないため、パス上のすべてのデバイスがPTPを終端および再生成する必要があります。コンポーネントは以下の通りです。

  • Grandmaster (GM): PTPドメイン(G.8275.1の場合はドメイン 24)のアップストリームリファレンスで、通常はGNSS/PRTCソースにロックされています。

  • PTP-aware switch: Boundary Clockとして機能します。GMに向かうポートはTime Receiverであり、OCに向かうポートはTime Transmitterです。両方のポートでPTPを有効にする必要があります。

  • Ordinary Clock (OC): クラスターノードであり、単一のPTPポートで時刻を受信します。

シナリオ1a - G.8275.1を使用したオーディナリークロック(PTPのみ)
図 47.6: Ordinary Clock (OC) — G.8275.1 (レイヤー2マルチキャスト)

ノードを以下のように設定します。

  1. PTPに使用するインターフェースのPHCインデックス <N>(ここでは eno8403np1)を特定します。出力されたフィールド PTP Hardware Clock(Hardware timestamp provider index`と表示される場合もあります)の値は、/dev/ptp<N>`デバイスを示し、`ptp4l`がこれを調整し、`phc2sys`がソースとして読み取るものです。

    # ethtool -T eno8403np1
    Time stamping parameters for eno8403np1:
    Capabilities:
            hardware-transmit
            hardware-receive
            hardware-raw-clock
    PTP Hardware Clock: 1
    ...

    この例では、eno8403np1`のPHCは `/dev/ptp1 です。

  2. ptp4l`設定ファイル/etc/ptp4l-G.8275.1.conf`を作成します。インターフェースはセクション([eno8403np1])として宣言されるため、デーモンに`-i`フラグは不要です。

    例 47.1: オーディナリークロック設定 — ITU-T G.8275.1
    # Telecom G.8275.1 — Ordinary Clock (Time Receiver)
    [global]
    domainNumber                    24
    priority2                       255
    dataset_comparison              G.8275.x
    G.8275.portDS.localPriority     128
    G.8275.defaultDS.localPriority  128
    maxStepsRemoved                 255
    logAnnounceInterval             -3
    logSyncInterval                 -4
    logMinDelayReqInterval          -4
    announceReceiptTimeout          3
    clientOnly                      1
    ptp_dst_mac                     01:80:C2:00:00:0E
    network_transport               L2
    summary_interval                3
    message_tag                     "ptp4l"
    uds_address                     /var/run/ptp4l
    uds_ro_address                  /var/run/ptp4lro
    
    [eno8403np1]

    `ptp_dst_mac`の値はG.8275.1で固定されています。これは、PTPを単一のリンクに限定する転送不可能なマルチキャストアドレス`01:80:C2:00:00:0E`であり、これがパス上のすべてのデバイスがPTP対応でなければならない理由です。`uds_address`は、`phc2sys`がポート状態を追跡するために使用する管理ソケットを公開します。

  3. ptp4l`で/etc/sysconfig/ptp4l`がこのファイルを指すようにします。

    OPTIONS="-f /etc/ptp4l-G.8275.1.conf"
  4. /etc/sysconfig/phc2sys`で`phc2sys`を設定し、PTPインターフェース(/dev/ptp1`)のPHCからシステムクロックを制御します。--uds_address`と--domainNumber`の値は、`ptp4l`の設定と一致している必要があります。

    OPTIONS="-s /dev/ptp1 -w -m --uds_address /var/run/ptp4l --domainNumber 24"

    -s /dev/ptp1`はPHCをソースクロックとして選択し、-w`は`ptp4l`が同期するのを待ってからシステムクロックをステップし、`-m`はサーボステータスをログに出力します。

  5. 両方のサービスを有効にして開始します。

    # systemctl enable --now ptp4l phc2sys
  6. ptp4l`がアップストリームマスターにロックされていることを確認します。ポートは`SLAVE`に移行し、報告されたオフセット(`rms)は低く安定した値に収束します。

    # journalctl -u ptp4l -f
    ptp4l[...]: "ptp4l" port 1 (eno8403np1): UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
    ptp4l[...]: "ptp4l" rms 1502498567 max 8499416372 freq  -3977 +/- 43609 delay  11 +/- 607
    ptp4l[...]: "ptp4l" rms   40 max   99 freq +10129 +/-   30 delay 211 +/-   3
    ptp4l[...]: "ptp4l" rms    7 max   15 freq +10125 +/-   13 delay 211 +/-   2
    ptp4l[...]: "ptp4l" rms    6 max   16 freq +10118 +/-   12 delay 213 +/-   2
  7. phc2sys`がシステムクロックを制御していることを確認します。サーボ状態は`s0(ロック解除)から`s1`(初期ステップ)、そして`s2`(ロック)へと進み、オフセットはゼロ付近で安定します。

    # journalctl -u phc2sys -f
    phc2sys[...]: CLOCK_REALTIME phc offset 45583145631 s0 freq   -1673 delay   0
    phc2sys[...]: CLOCK_REALTIME phc offset 45583157513 s1 freq  +10207 delay   0
    phc2sys[...]: CLOCK_REALTIME phc offset          4 s2 freq  +10211 delay   0
    phc2sys[...]: CLOCK_REALTIME phc offset         13 s2 freq  +10221 delay   0

    小さなオフセットを伴う安定した`s2`状態は、ノードがロックされ、システムクロックがPTPに従っていることを確認するものです。

モデル2 — ITU-T G.8275.2(レイヤー3ユニキャスト)

G.8275.2はユニキャストを使用してIP(レイヤー3)上で実行されます。OCはマスターのIPアドレスと直接メッセージを交換するため、介在するネットワークがPTP対応である必要はなく、PTP対応スイッチも不要です。コンポーネントは以下の通りです。

  • マスター(GMまたは境界クロック):G.8275.2ドメイン(ドメイン`44`)上でIP経由で到達可能なアップストリームマスターです。

  • IPネットワーク:標準的なルーティングまたはスイッチングネットワークです。PTP設定なしでユニキャストPTPパケットを転送します。

  • オーディナリークロック(OC):クラスターノードであり、単一のPTPポートからマスターへユニキャストリクエストを送信します。

シナリオ1a - G.8275.2を使用したオーディナリークロック(PTPのみ)
図 47.7: オーディナリークロック(OC) — G.8275.2(レイヤー3ユニキャスト)

ノードを以下のように設定します。

  1. モデル1(ethtool -T eno8403np1)と同様にPTPインターフェースのPHCを特定します。この例では、eno8403np1`のPHCは/dev/ptp1`です。

  2. ptp4l`設定ファイル/etc/ptp4l-G.8275.2.conf`を作成します。マスターには`ptp_dst_mac`経由のIPで到達するため、`unicast_master_table`は存在しません。 `$MASTER_IP_ADDRESS`をアップストリームマスターのIPアドレスに置き換えます。

    例 47.2: オーディナリークロック設定 — ITU-T G.8275.2
    # Telecom G.8275.2 — Ordinary Clock (Time Receiver)
    [global]
    domainNumber                    44
    priority2                       255
    dataset_comparison              G.8275.x
    G.8275.portDS.localPriority     128
    G.8275.defaultDS.localPriority  128
    maxStepsRemoved                 255
    logAnnounceInterval             0
    logSyncInterval                 -5
    logMinDelayReqInterval          -4
    announceReceiptTimeout          2
    clientOnly                      1
    network_transport               UDPv4
    hybrid_e2e                      1
    inhibit_multicast_service       1
    unicast_listen                  1
    unicast_req_duration            60
    message_tag                     "ptp4l"
    uds_address                     /var/run/ptp4l
    uds_ro_address                  /var/run/ptp4lro
    
    [unicast_master_table]
    table_id                        1
    logQueryInterval                2
    UDPv4                           $MASTER_IP_ADDRESS
    
    [eno8403np1]
    unicast_master_table            1
  3. `/etc/sysconfig/ptp4l`で`ptp4l`をこのファイルを指すように設定します。

    OPTIONS="-f /etc/ptp4l-G.8275.2.conf"
  4. G.8275.2ドメイン番号(44)を使用して`/etc/sysconfig/phc2sys`の`phc2sys`を設定します。ソースPHCと`--uds_address`は変更されません。

    OPTIONS="-s /dev/ptp1 -w -m --uds_address /var/run/ptp4l --domainNumber 44"
  5. 両方のサービスを有効にして開始します。

    # systemctl enable --now ptp4l phc2sys
  6. モデル1と同様に同期を確認します。ptp4l`はポートを`SLAVE(journalctl -u ptp4l)に移動し、phc2sys`は`s2(ロック)状態に達し、オフセットはゼロに近い(journalctl -u phc2sys)です。

CAPI自動化

自動プロビジョニングワークフローを使用してこのシナリオを展開するには、完全に自動化されたダイレクトネットワークプロビジョニング (55.1項 「高精度時刻同期プロトコル (PTP)」)で説明されている汎用Cluster APIテンプレートを使用し、そのプレースホルダーを以下に示すこのシナリオの値で上書きします。

表 47.1: モデル1 — ITU-T G.8275.1
Placeholder値

${PTP4L_CONF_PATH}

/etc/ptp4l-G.8275.1.conf

${PTP4L_CONF_CONTENTS}

上記のG.8275.1設定 (例47.1「オーディナリークロック設定 — ITU-T G.8275.1」)からコンテンツをコピーします。

${PTP4L_OPTIONS}

-f /etc/ptp4l-G.8275.1.conf

${PHC2SYS_OPTIONS}

-s /dev/ptp1 -w -m --uds_address /var/run/ptp4l --domainNumber 24

表 47.2: モデル2 — ITU-T G.8275.2
Placeholder値

${PTP4L_CONF_PATH}

/etc/ptp4l-G.8275.2.conf

${PTP4L_CONF_CONTENTS}

上記のG.8275.2設定 (例47.2「オーディナリークロック設定 — ITU-T G.8275.2」)からコンテンツをコピーします。

${PTP4L_OPTIONS}

-f /etc/ptp4l-G.8275.2.conf

${PHC2SYS_OPTIONS}

-s /dev/ptp1 -w -m --uds_address /var/run/ptp4l --domainNumber 44

47.4 シナリオ1b - オーディナリクロック (ハイブリッドモード:PTPおよびSyncE)

このシナリオはまだサポートされていません。将来のSUSE Telco Cloudリリースで含まれる予定です。

47.5 シナリオ2a - バウンダリクロック (PTPのみ)、マルチポートシングルNICを使用し、オーディナリクロックサーバーへの伝搬を含む

説明

このシナリオでは、ITU-T G.8275.1 (PTPのみ、レイヤー2) を介して、ダウンストリームのオーディナリクロック(OC) に向けてPTPを再生成するバウンダリクロック(BC)を用いてタイミングチェーンを拡張します。BCは単一のマルチポートNICを使用します。1つの`ptp4l`インスタンスが同じNIC上の複数のポートを管理するため、`ts2phc`もDPLLルーティングも必要ありません (マルチNICシナリオとは異なります)。

このシナリオには、以下のコンポーネントが含まれます。

  • グランドマスター (GM): PTPドメイン (ドメイン`24`) のリファレンスであり、通常はGNSS/PRTCソースにロックされています (ここで使用するテストベンチにはGNSSがないため、後述する`gm.ClockClass`の劣化が生じます)。アップストリームセグメントに時刻を送信します。

  • PTP対応スイッチ: タイミングパス上でバウンダリクロック (T-BC) として機能します。PTPを伝送するすべてのポートには`ptp enable`が設定されています。

  • バウンダリクロック (BCサーバー): 2つのPTPセグメントをブリッジする、単一NIC上のマルチポートノードです。その`eno8403np1`ポートはタイムレシーバー (SLAVE) として*アップストリーム*セグメントに向き、NICのPHCを制御します。eno8503np2 (および`eno8603np3`) はタイムトランスミッターとして*ダウンストリーム*セグメントに向き、PTPを再生成します。BCはアップストリームのタイミングチェーンを終端し、ダウンストリーム側で新しいタイミングチェーンを開始します。

  • オーディナリークロック(OCサーバー):*ダウンストリーム*セグメント上にあるシングルポートノード(ens6f0np0)であり、その唯一のPTPマスターはBCです。BCが再生成した時点からローカルクロックを調整します。

タイミングは、各ノードの`linuxptp`デーモンによって処理されます。

  • *BCサーバー*では、単一の`ptp4l`インスタンスがすべてのポートを管理します。BMCAは`eno8403np1`上でGMをマスターとして選択し、それが`SLAVE`に移行してPHCを調整します。`eno8503np2`と`eno8603np3`は`serverOnly 1`に強制されるため、タイムトランスミッターとしてのみ機能します。 すべてのポートが同じNIC PHCを共有しているため、受信した時刻は送信ポートですぐに利用可能です。ポートが複数構成されている場合はバウンダリクロックが自動的に暗示されるため、`clock_type`や`ts2phc`の設定は不要です。

  • *OCサーバー*では、`ptp4l`が`clientOnly 1`上の`ens6f0np0`で実行されるため、ポートは常にタイムレシーバーとしてのみ機能します。`phc2sys`はシステムクロックをPHCに合わせます。

  • OCサーバーにおいて、`clientOnly 1`はそれがマスターになることを決して許さないための保証となります。`localPriority`属性(G.8275.x BMCAにおいて、clockClass、clockAccuracy、variance、priority2が等しい場合のタイブレーカーとしてのみ使用され、値が小さい方が優先される)は、この順序付けを強化します。BCサーバーはデフォルトの`128`を維持し、OCサーバーは優先度の低い`250`を使用します。

BCは、GMと`eno8403np1`ポート間の*アップストリーム*セグメントと、`eno8503np2`ポートとOC間の*ダウンストリーム*セグメントという、2つの独立したPTPセグメントをブリッジします。これらは、例えばスイッチの異なるVLAN上や別々のネットワーク上で、分離された状態に保たれます。BCはダウンストリームセグメントにおける唯一のマスターであるため、OCはBCから同期し、GMから直接同期することはありません。

シナリオ1a (47.3項 「シナリオ1a - オーディナリークロック(PTPのみ)」)と同様に、このシナリオでは転送不可能なマルチキャストMAC`01:80:C2:00:00:0E`を使用します。標準的なブリッジはこれを転送しないため、すべてのPTP対応デバイスがPTPを終端および再生成します。タイミングパスのすべてのノードで同じアドレスを設定する必要があります。

図

シナリオ2a - バウンダリクロック(PTPのみ)、マルチポートシングルNIC、オーディナリークロックサーバーへの伝搬を含む
図 47.8: バウンダリクロック(PTPのみ)、シングルNIC、オーディナリークロックへの伝搬あり

設定

タイミングパス上のすべてのスイッチポート(GM、BC、OCに向かうポート)でPTPを有効にする必要があります。2つのクラスターノードは、次のように構成されます。

バウンダリクロック(BCサーバー)

  1. PTP NICのPHC (ethtool -T eno8403np1) を特定します。単一のNICでは、すべてのポートが同じPHCを共有します。この例では、`/dev/ptp1`です。

  2. /etc/ptp4l-G.8275.1.conf`を作成します。受信ポート[eno8403np1]にはロールフラグがないため、BMCAはそれをTime Receiverとして選択します。[eno8503np2]と[eno8603np3]`は、Time Transmitterとして機能するように`serverOnly 1`に設定されます。複数のポートを宣言すると、Boundary Clockであることを意味します。

    例 47.3: バウンダリクロックの設定
    # Telecom G.8275.1 — Boundary Clock (multi-port, single NIC)
    [global]
    domainNumber                    24
    priority2                       255
    dataset_comparison              G.8275.x
    G.8275.portDS.localPriority     128
    G.8275.defaultDS.localPriority  128
    maxStepsRemoved                 255
    logAnnounceInterval             -3
    logSyncInterval                 -4
    logMinDelayReqInterval          -4
    announceReceiptTimeout          3
    ptp_dst_mac                     01:80:C2:00:00:0E
    network_transport               L2
    summary_interval                3
    message_tag                     "ptp4l"
    uds_address                     /var/run/ptp4l
    uds_ro_address                  /var/run/ptp4lro
    
    [eno8403np1]
    
    [eno8503np2]
    serverOnly                      1
    
    [eno8603np3]
    serverOnly                      1
  3. ptp4l`で/etc/sysconfig/ptp4l`をこのファイルを指すように設定します。

    OPTIONS="-f /etc/ptp4l-G.8275.1.conf"
  4. オプションとして、共有NIC PHCをソースとして使用し、`/etc/sysconfig/phc2sys`内の`phc2sys`とシステムクロックを同期させます。

    OPTIONS="-s /dev/ptp1 -w -m --uds_address /var/run/ptp4l --domainNumber 24"
  5. サービスを有効にして開始し、eno8403np1`がGMにロックされていることを確認します。受信ポートは`SLAVE`に移行し、オフセット (`rms) は低い値に収束します。

    # systemctl enable --now ptp4l phc2sys
    # journalctl -u ptp4l -f
    ptp4l[...]: "ptp4l" selected best master clock d0460c.ffff.05c130
    ptp4l[...]: "ptp4l" port 1 (eno8403np1): UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
    ptp4l[...]: "ptp4l" rms    8 max   24 freq +10092 +/-  18 delay   211 +/-   2
    ptp4l[...]: "ptp4l" rms    4 max   11 freq +10069 +/-   7 delay   210 +/-   2
    ptp4l[...]: "ptp4l" rms    3 max    9 freq +10070 +/-   6 delay   213 +/-   3

Ordinary Clock (OCサーバー)

  1. PTPインターフェースのPHC (ethtool -T ens6f0np0) を特定します。この例では、`/dev/ptp1`です。

  2. 単一ポートと`clientOnly 1`を持つ`/etc/ptp4l-G.8275.1.conf`を作成します。これにより、ノードは常にTime Receiverとしてのみ機能します。より高い`localPriority` (250) により、BMCAにおいてBCの下位に維持されます。

    例 47.4: Ordinary Clockの設定
    # Telecom G.8275.1 — Ordinary Clock (Time Receiver)
    [global]
    domainNumber                    24
    priority2                       255
    dataset_comparison              G.8275.x
    G.8275.portDS.localPriority     250
    G.8275.defaultDS.localPriority  250
    maxStepsRemoved                 255
    logAnnounceInterval             -3
    logSyncInterval                 -4
    logMinDelayReqInterval          -4
    announceReceiptTimeout          3
    clientOnly                      1
    ptp_dst_mac                     01:80:C2:00:00:0E
    network_transport               L2
    summary_interval                3
    message_tag                     "ptp4l"
    uds_address                     /var/run/ptp4l
    uds_ro_address                  /var/run/ptp4lro
    
    [ens6f0np0]
  3. BCの場合と同様に`/etc/sysconfig/ptp4l`と`/etc/sysconfig/phc2sys`を設定し (`phc2sys`ソースは`ens6f0np0`のPHC)、サービスを有効にして開始します。

    # /etc/sysconfig/ptp4l
    OPTIONS="-f /etc/ptp4l-G.8275.1.conf"
    
    # /etc/sysconfig/phc2sys
    OPTIONS="-s /dev/ptp1 -w -m --uds_address /var/run/ptp4l --domainNumber 24"
  4. ens6f0np0`がBCから再生成された時刻にロックされていることを確認します。ポートは`SLAVE`に移行し、オフセット (`rms) は安定します。

    # journalctl -u ptp4l -f
    ptp4l[...]: "ptp4l" selected best master clock d0460c.ffff.05c130
    ptp4l[...]: "ptp4l" port 1 (ens6f0np0): UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
    ptp4l[...]: "ptp4l" rms   15 max   34 freq +11699 +/-  25 delay   468 +/-   5
    ptp4l[...]: "ptp4l" rms   13 max   30 freq +11701 +/-  23 delay   468 +/-   4
    ptp4l[...]: "ptp4l" rms   14 max   30 freq +11697 +/-  24 delay   467 +/-   4

    OCは、直近のマスターであるアップストリームの境界クロックから時刻を取得します。 ただし、selected best master clock`行はBoundary Clockの識別子ではなく、*Grandmaster*の識別子 (`d0460c.ffff.05c130、GM) を報告します。Boundary ClockはGrandmasterの識別子を変更せずに転送し、自身のポートを親としてアドバタイズするため、チェーンはGrandmasterまで追跡可能です。両方の識別子を明示的に確認するには、OCで親データセットを照会します (出力例):

    # pmc -f /etc/ptp4l-G.8275.1.conf -u -b 0 'GET PARENT_DATA_SET'
    sending: GET PARENT_DATA_SET
        507c6f.fffe.4ae178-0 seq 0 RESPONSE MANAGEMENT PARENT_DATA_SET
            parentPortIdentity                    000000.fffe.001101-2
            parentStats                           0
            observedParentOffsetScaledLogVariance 0xffff
            observedParentClockPhaseChangeRate    0x7fffffff
            grandmasterPriority1                  128
            gm.ClockClass                         165
            gm.ClockAccuracy                      0xfe
            gm.OffsetScaledLogVariance            0xffff
            grandmasterPriority2                  120
            grandmasterIdentity                   d0460c.ffff.05c130

    2つの識別子は異なりますが、これはまさに境界クロック・デプロイメントが示すべきものです。

    • parentPortIdentity (000000.fffe.001101-2) — 直接のマスター:境界クロックの送信ポートであり、OCが実際に時刻を受信するクロックです。

    • grandmasterIdentity (d0460c.ffff.05c130) — タイミングツリーのルート:グランドマスターであり、境界クロックを介して変更されずに転送されます。

      gm.ClockClass、gm.ClockAccuracy、および`grandmasterPriority`の値は、BMCAによって使用されるグランドマスターのアドバタイズされた品質を示しています。もし2つの識別子が等しい場合、OCはパス上に境界クロックが存在せず、グランドマスターから直接同期することになります。

CAPI自動化

自動プロビジョニングワークフローを使用してこのシナリオを展開するには、各ノードで完全に自動化されたダイレクトネットワークプロビジョニング (55.1項 「高精度時刻同期プロトコル (PTP)」)に記載されている汎用Cluster APIテンプレートを使用し、そのプレースホルダーを以下の値で上書きしてください。

表 47.3: 境界クロック(BCサーバー)
Placeholder値

${PTP4L_CONF_PATH}

/etc/ptp4l-G.8275.1.conf

${PTP4L_CONF_CONTENTS}

上記の境界クロック設定 (例47.3「バウンダリクロックの設定」)から内容をコピーしてください。

${PTP4L_OPTIONS}

-f /etc/ptp4l-G.8275.1.conf

${PHC2SYS_OPTIONS}

-s /dev/ptp1 -w -m --uds_address /var/run/ptp4l --domainNumber 24

表 47.4: Ordinary Clock(OCサーバー)
Placeholder値

${PTP4L_CONF_PATH}

/etc/ptp4l-G.8275.1.conf

${PTP4L_CONF_CONTENTS}

上記のOrdinary Clock設定 (例47.4「Ordinary Clockの設定」)から内容をコピーしてください。

${PTP4L_OPTIONS}

-f /etc/ptp4l-G.8275.1.conf

${PHC2SYS_OPTIONS}

-s /dev/ptp1 -w -m --uds_address /var/run/ptp4l --domainNumber 24

47.6 シナリオ2b - 境界クロック(ハイブリッドモード:PTPおよびSyncE)マルチポートシングルNIC構成(Ordinary Clockサーバーへの伝搬を含む)

このシナリオはまだサポートされていません。将来のSUSE Telco Cloudリリースで含まれる予定です。

47.7 シナリオ3a - 境界クロック(PTPのみ)マルチNIC構成(内部タイミングモジュール付き、DPLL GNR-Dベース)

説明

SUSE Telco Cloudは、最新のIntel Granite Rapids-Dベースの設計(GNR-D)を含む、さまざまなプラットフォームで高精度なタイミングをサポートしています。これらのサーバーには通常、組み込みの高速イーサネットコントローラーと、追加ポート用のイーサネットコントローラーを備えた1つ以上の追加カード(AIC)が含まれています。以前のプラットフォーム世代とは異なり、システム全体および異なるNIC間でタイミング信号を内部的にルーティングできる専用のDPLLも装備されており、すべてのNIC PHCを同期させるための外部ケーブル接続は不要になりました。 したがって、全体的な展開は簡素化されますが、起動時のDPLLや内部信号設定など、特定の手順とソフトウェアコンポーネントが必要になります。

このシナリオは、シナリオ2a (47.5項 「シナリオ2a - バウンダリクロック (PTPのみ)、マルチポートシングルNICを使用し、オーディナリクロックサーバーへの伝搬を含む」)を拡張したもので、ITU-T G.8275.1(PTPのみ、レイヤー2)に完全に準拠した、複数のNIC上に構築される境界クロック(BC)を対象としています。統合コントローラーの1つのポートがグランドマスターからPTPを受信し、追加カードがダウンストリームでPTPを再生成します。シングルNICの場合とは異なり、各NICは独自のPHCを備えています。オンボードのDPLLと`ts2phc`がそれらを調整し、PHCごとに1つの`ptp4l`インスタンスが実行されます。

重要
重要

この SUSE Telco Cloud リリースでは、このシナリオは「デフォルト」(つまり「PREEMPT_RT」ではない)カーネルフレーバーでのみサポートされています。 「RT」カーネルフレーバーのサポートは、今後のリリースで追加される予定です。

前提条件
  • _Intel 800シリーズネットワークデバイス_用の最新のカーネルドライバーを、 IntelのWebサイトからダウンロードしてインストールしてください。

  • 「ice_RPM_Files」を含むzipファイルを選択し、アーカイブを解凍して`ice-kmp-default-*sles16sp0.x86_64.rpm`をインストールしてください。このRPMには、例えば ice-kmp-default-2.4.5_k6.12.0_160000.5-1.sles16sp0.x86_64.rpm が含まれています。

    # transactional-update pkg install ice-kmp-default-2.4.5_k6.12.0_160000.5-1.sles16sp0.x86_64.rpm

    変更を永続的かつ有効にするために、サーバーを再起動してください。

注記
注記
  • 例を通してDell PowerEdge XR8720tシステムをリファレンスシステムとして使用しますが、カーネルインターフェイスとポート構成は、別のGNR-Dサーバーでは異なる場合があります。デバイス名は適宜調整してください。

  • Telcoデプロイメントが想定されており、以下のセクション全体でTelcoプロファイルG.8275.1が使用されます。

このシナリオには、以下のコンポーネントが含まれます。

  • Grandmaster (GM): アップストリームセグメント上の、PTPドメイン(ドメイン 24)のリファレンス。

  • PTP対応スイッチ: タイミングパス上でバウンダリクロック (T-BC) として機能します。PTPを伝送するすべてのポートには`ptp enable`が設定されています。アップストリームセグメントとダウンストリームセグメントは、スイッチの異なるVLAN上で分離されています(各セグメントに専用のVLANを使用)。

  • Boundary Clock (BC server): GNR-Dノード。その統合コントローラーは eno8403np1 上のGMからPTPを受信し、統合PHC (/dev/ptp1) を制御します。オンボードDPLLはそのタイミングをアドインカードに分配し、ts2phc はそれらのPHC (/dev/ptp2、/dev/ptp3) を /dev/ptp1 に同期させ続けます。各アドインカードはPTPをダウンストリーム側で再生成し(例えば eno16495np0 上で)、タイムトランスミッターとして機能します。

  • Ordinary Clock (OC server): ダウンストリームセグメント上のシングルポートノード (ens6f0np0) で、その唯一のPTPマスターはBCです。

BC server のタイミングは、PHCが物理的に分離されているため、連携して動作する複数の linuxptp デーモンによって処理されます。

  • 統合コントローラー (/dev/ptp1) 上の ptp4l インスタンスが eno8403np1 でPTPプロトコルを実行します。BMCAがGMをマスターとして選択し、ポートは`SLAVE`に移行し、ptp4l`が/dev/ptp1`を同期させます。

  • オンボードDPLLは、統合PHCがSDPピンを介してそれを駆動し、DPLLが今度はアドインカードのクロックを駆動するように配線されています。これは、以前のプラットフォームで使用されていた外部1PPSケーブル配線の内部的な代替手段です。

  • ts2phc`は、DPLLが分配する信号から、アドインカードのPHCを/dev/ptp1`に同期させ続けます。

  • アドインカードごとの個別の`ptp4l`インスタンス(/dev/ptp2、/dev/ptp3)が、そのポート上でPTPを再生成し、すべて`serverOnly 1`(タイムトランスミッター)に強制されます。

  • バウンダリクロックは、時刻に加えて、グランドマスターの補助属性(クロッククラス、精度など)を転送する必要があります。これは単一の`ptp4l`インスタンス内でのみ自動的に行われるため、統合インスタンスからアドインインスタンスへそれらの値を転送するために`pmc`が使用されます(ステップ5を参照)。pmc(PTP管理クライアント)は、管理ソケットを介して実行中の`ptp4l`インスタンスのランタイム状態を照会および更新する`linuxptp`ツールです。

注記
注記

統合コントローラーでは、そのポートのうち*1つ*のみがPHCを管理する管理ポートです。/sys/class/ptp/ptp1/device/net/`を調べてそれを見つけます(例: `eno8703np0)。これはDPLL信号の設定に使用されるポートであり、必ずしもPTP(eno8403np1)を伝送するポートではありません。

注記
注記

ここで説明する設定は完全に静的なものです。GMが利用できなくなった場合、ダウンストリームの同期はホストのホールドオーバー機能のみに依存します。別の時刻参照ソースへの自動切り替えは実行されません。

図

シナリオ3a - バウンダリクロック(PTPのみ)、内部タイミングモジュール(DPLL GNR-Dベース)を備えたマルチNIC
図 47.9: バウンダリクロック(PTPのみ)、オンボードDPLLを備えたマルチNIC GNR-Dノード、オーディナリークロックへの伝搬あり

設定

タイミングパス上のすべてのスイッチポートでPTPを有効にする必要があります。BCサーバーは、以下の順序で起動されます。各ランタイムステップは`systemd`ユニットにもマッピングされるため、設定が再起動後も保持され、Cluster API(GNR-D CAPI自動化 (55.1.2項 「GNR-DマルチNICシナリオ(DPLL)」)を参照)を使用して自動化できます。OCサーバーは、シナリオ2a (47.5項 「シナリオ2a - バウンダリクロック (PTPのみ)、マルチポートシングルNICを使用し、オーディナリクロックサーバーへの伝搬を含む」)とまったく同じように設定されます。

  1. PTPデバイスと統合コントローラーを特定します。

    1. PTPクロックと、それぞれがバインドされているPCIデバイスを一覧表示します。

      # ls -l /sys/class/ptp/
      lrwxrwxrwx 1 root root 0 ... ptp1 -> ../../devices/pci0000:12/0000:12:04.0/0000:13:00.0/ptp/ptp1
      lrwxrwxrwx 1 root root 0 ... ptp2 -> ../../devices/pci0000:6b/0000:6b:02.0/0000:6c:00.0/ptp/ptp2
      lrwxrwxrwx 1 root root 0 ... ptp3 -> ../../devices/pci0000:6b/0000:6b:06.0/0000:6e:00.0/ptp/ptp3
    2. `lspci`を実行して各デバイスタイプを特定し、統合コントローラーとアドインカードを区別できるようにします。

      # lspci -s 0000:13:00.0
      13:00.0 Ethernet controller: Intel Corporation Ethernet Connection E825-C for SFP (rev 04)
      # lspci -s 0000:6c:00.0
      6c:00.0 Ethernet controller: Intel Corporation Ethernet Controller E830-CC for SFP
      # lspci -s 0000:6e:00.0
      6e:00.0 Ethernet controller: Intel Corporation Ethernet Controller E830-CC for SFP

      このリファレンスサーバーには、_Intel E825-C_統合コントローラー(/dev/ptp1)と、2枚の_E830-CC_アドインカード(/dev/ptp2、/dev/ptp3)が搭載されています。

    3. PHCを管理する統合コントローラーの管理ポートを特定します。

      # ls /sys/class/ptp/ptp1/device/net/
      eno8703np0
      # ethtool -i eno8703np0
      driver: ice
      version: 2.4.5
      [...]
  2. 内部タイミング信号(DPLL)を設定します。

    統合PHCをDPLLに接続し、前述の管理ポート(eno8703np0)と正しい`ptpN`インデックスを使用して、DPLLがアドインカードに信号を供給できるようにします。

    例 47.5: 01-gnrd-startup-setup.sh
    #!/bin/bash
    
    # The admin port that manages the PHC is under /sys/class/ptp/ptp1/device/net/ (e.g. eno8703np0).
    # Only one port of the integrated E825-C NIC exposes it.
    
    # Let the DPLL drive the Ethernet clock on the integrated controller
    echo 4 1 > /sys/class/net/eno8703np0/device/tspll_cfg
    
    # Feed the DPLL from the integrated PHC through the SDP pins:
    # SDP0 -> 1 pulse per second (1PPS, 1 Hz): enable the pin, then set a 1 s period
    echo 2 2 > /sys/class/ptp/ptp1/pins/SDP0
    echo 2 0 0 1 0 > /sys/class/ptp/ptp1/period
    
    # SDP2 -> 1000 pulses per second (1kPPS, 1 kHz): enable the pin, then set a 1 ms period
    echo 2 1 > /sys/class/ptp/ptp1/pins/SDP2
    echo 1 0 0 0 1000000 > /sys/class/ptp/ptp1/period
    
    # Propagate the pulses from the DPLL to the add-in cards (SDP1 on each add-in PHC)
    echo 1 1 > /sys/class/ptp/ptp2/pins/SDP1
    echo 1 1 > /sys/class/ptp/ptp3/pins/SDP1

    これらの設定は再起動時に失われるため、`ts2phc`および`ptp4l`の前に順序付けられたoneshot型の`systemd`ユニットから起動時にスクリプトを実行してください。

    # /etc/systemd/system/gnrd-ptp-dpll-setup.service
    [Unit]
    Description=GNR-D PTP DPLL and internal signal setup
    Before=ts2phc.service ptp4l@nac.service ptp4l@aic1.service ptp4l@aic2.service
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/local/bin/01-gnrd-startup-setup.sh
    
    [Install]
    WantedBy=multi-user.target
  3. アドインカードのPHCを`ts2phc`に合わせます。

    ts2phc(「PHCへのタイムスタンプ」)は、アドインカードのPHCを基準クロックに合わせます。ここでは、基準は統合NICのPHC(/dev/ptp1、GMによってその`ptp4l`インスタンスを通じてすでに調整済み)であり、コマンドラインで`-s /dev/ptp1`とともに渡されます。オンボードのDPLLは、その基準から導出された1PPSを各アドインカードの`SDP1`ピンに供給します。`ts2phc`はそれらの入力パルス(EXTTS)をタイムスタンプし、それに応じて各アドインPHCをステップさせるため、ノード内のすべてのPHCが最終的に同じ時間を共有することになります。

    注記
    注記

    アドインPHCの調整には、異なるレベルでの2つの補完的な設定が必要です。

    • ハードウェア: オンボードのDPLLが1PPSパルスを供給できるように、各アドインPHCの`SDP1`入力ピンを有効にする必要があります。これは、前のステップ(echo 1 1 > /sys/class/ptp/ptpN/pins/SDP1)のDPLLセットアップスクリプトで行われます。

    • ソフトウェア: ts2phc`に対して、その入力をタイムスタンプし、PHCをステップさせるよう指示する必要があります。これは、以下の構成(`ts2phc.channel、ts2phc.pin_index、ts2phc.extts_polarity)で行われます。

    ピンを有効にしないとパルスはPHCに到達せず、`ts2phc`構成を行わないとパルスは適用されません。両方が必要です。

    設定ファイルを作成します。

    例 47.6: /etc/ts2phc-cf-all.cfg — `ts2phc`設定ファイル
    [global]
    use_syslog              0
    verbose                 1
    logging_level           7
    ts2phc.pulsewidth       100000000
    
    [eno16495np0]
    ts2phc.channel          1
    ts2phc.extts_polarity   rising
    ts2phc.pin_index        1
    
    [eno16595np0]
    ts2phc.channel          1
    ts2phc.extts_polarity   rising
    ts2phc.pin_index        1

    各アドインカードは、その最初のポート([eno16495np0]、[eno16595np0])にちなんで名付けられたセクションを通じて構成され、これにより調整対象のPHCが識別されます。パラメータは、DPLLパルスをそのカードにマッピングします。

    • ts2phc.pin_index`および`ts2phc.channel: DPLLが1PPSを供給するピンとチャネル(このセットアップでは`SDP1`、したがって`pin_index 1`)。

    • ts2phc.extts_polarity: タイムスタンプするパルスエッジ(rising)。

    • ts2phc.pulsewidth: 期待される入力パルス幅(ナノ秒単位、ここでは100 ms)。

      手動で`ts2phc -f /etc/ts2phc-cf-all.cfg -s /dev/ptp1 -m`を実行するか、または`systemd`に`/etc/sysconfig/ts2phc`を通じて管理させるようにしてください。

      # /etc/sysconfig/ts2phc
      OPTIONS="-f /etc/ts2phc-cf-all.cfg -s /dev/ptp1 -m"
  4. PHCごとに`ptp4l`インスタンスを1つ実行してください。

    統合コントローラーはBMCA駆動のインスタンス(レシーバー)を実行し、各アドインカードはすべてのポートが`serverOnly 1`に強制されたインスタンスを実行します。各インスタンスは、異なる制御ソケットと読み取り専用ソケットを使用する必要があります。3つの設定ファイルを作成してください:

    例 47.7: /etc/ptp4l-nac.conf — 統合コントローラー (/dev/ptp1)
    # Telecom G.8275.1 — integrated controller (receiver)
    [global]
    domainNumber                    24
    priority2                       255
    dataset_comparison              G.8275.x
    G.8275.portDS.localPriority     128
    G.8275.defaultDS.localPriority  128
    maxStepsRemoved                 255
    logAnnounceInterval             -3
    logSyncInterval                 -4
    logMinDelayReqInterval          -4
    announceReceiptTimeout          3
    ptp_dst_mac                     01:80:C2:00:00:0E
    network_transport               L2
    summary_interval                3
    message_tag                     "ptp4l-nac"
    uds_address                     /var/run/ptp4l-nac
    uds_ro_address                  /var/run/ptp4lro-nac
    
    [eno8403np1]

    統合インスタンスは、GMからPTPを受信するポートである`eno8403np1`のみを宣言し、それに対して`serverOnly`や`clientOnly`を設定しません。役割の割り当てはBMCAに依存します。eno8403np1`でGMに到達可能な場合、BMCAはそれをタイムレシーバー(`SLAVE)として選択し、`/dev/ptp1`を制御します。統合コントローラーの他のポートは宣言されません。なぜなら、このノードではダウンストリームの再生成は統合コントローラーではなくアドインカードによって実行されるからです。対照的に、アドインカードは常にタイムトランスミッターである必要があるため、`serverOnly 1`を強制します。これらはPTPを受信して時刻を取得するのではなく、DPLLと`ts2phc`から時刻を取得するため、レシーバーとして選出されてはなりません。より厳密な制御が必要な場合は、インターフェースの下に`serverOnly`または`clientOnly`フラグを明示的に追加してください。

    G.8275.portDS.localPriority`および`G.8275.defaultDS.localPriority`の値(統合インスタンスでは`128、アドインカードでは`250`)は、G.8275.x BMCAのタイブレーカーとして機能します。これらは`clockClass`、clockAccuracy、分散、priority2`の後にのみ比較され、値が小さい方が優先されます。統合インスタンスでデフォルトの`128`を維持すると、アドインインスタンス(`250)よりも優先順位が高くなります。これにより、ノード内のタイムトランスミッター/タイムレシーバーの順序が決定論的に保たれ、`ptp4l`によって報告されるポート状態に反映されるように、BMCAがどのポートを選択するかが決まります。

    例 47.8: /etc/ptp4l-aic1.conf — アドインカード 1 (/dev/ptp2)
    # Telecom G.8275.1 — add-in card (Time Transmitter)
    [global]
    domainNumber                    24
    priority2                       255
    dataset_comparison              G.8275.x
    G.8275.portDS.localPriority     250
    G.8275.defaultDS.localPriority  250
    maxStepsRemoved                 255
    logAnnounceInterval             -3
    logSyncInterval                 -4
    logMinDelayReqInterval          -4
    announceReceiptTimeout          3
    ptp_dst_mac                     01:80:C2:00:00:0E
    network_transport               L2
    summary_interval                3
    message_tag                     "ptp4l-aic1"
    uds_address                     /var/run/ptp4l-aic1
    uds_ro_address                  /var/run/ptp4lro-aic1
    
    [eno16495np0]
    serverOnly                      1
    例 47.9: /etc/ptp4l-aic2.conf — アドインカード 2 (/dev/ptp3)
    # Telecom G.8275.1 — add-in card (Time Transmitter)
    [global]
    domainNumber                    24
    priority2                       255
    dataset_comparison              G.8275.x
    G.8275.portDS.localPriority     250
    G.8275.defaultDS.localPriority  250
    maxStepsRemoved                 255
    logAnnounceInterval             -3
    logSyncInterval                 -4
    logMinDelayReqInterval          -4
    announceReceiptTimeout          3
    ptp_dst_mac                     01:80:C2:00:00:0E
    network_transport               L2
    summary_interval                3
    message_tag                     "ptp4l-aic2"
    uds_address                     /var/run/ptp4l-aic2
    uds_ro_address                  /var/run/ptp4lro-aic2
    
    [eno16595np0]
    serverOnly                      1
    注記
    注記

    シナリオ 2a (47.5項 「シナリオ2a - バウンダリクロック (PTPのみ)、マルチポートシングルNICを使用し、オーディナリクロックサーバーへの伝搬を含む」)と同様に、タイミングパス上のすべてのノードは、ダウンストリームOCを含め、同じ転送不可のG.8275.1マルチキャストMAC `01:80:C2:00:00:0E`を使用します。

    テンプレート化された`systemd`ユニットで`/etc/ptp4l-<instance>.conf`を読み取り、インスタンスを管理してください:

    # /etc/systemd/system/ptp4l@.service
    [Unit]
    Description=PTP Boundary Clock instance %i
    After=gnrd-ptp-dpll-setup.service
    Requires=gnrd-ptp-dpll-setup.service
    
    [Service]
    ExecStart=/usr/sbin/ptp4l -f /etc/ptp4l-%i.conf
    
    [Install]
    WantedBy=multi-user.target

    3つのインスタンスを有効にして開始してください:

    # systemctl enable --now ptp4l@nac ptp4l@aic1 ptp4l@aic2
  5. グランドマスターのパラメータを`ptp4l`インスタンス間で転送してください。

    境界クロックは、時刻だけでなく、グランドマスターの補助パラメータ(クロッククラス、精度、UTCオフセットなど)も転送しなければなりません。これは*同じ*ptp4l`インスタンスのポート間で自動的に行われますが、異なるPHCを管理する個別のインスタンス間では行われません。値は、各インスタンスのUDSソケット(`SET GRANDMASTER_SETTINGS_NP)を介して、ランタイムで`pmc`を使って適用されます。

    重要
    重要

    pmc`で適用された値は実行中の`ptp4l`プロセス内にのみ保持されます。これらは*書き込まれず*、.conf`ファイルには保存されず、再起動しても保持され*ません*。`ptp4l`インスタンスが再起動されると、ファイルデフォルト値に戻るため、値を再度転送する必要があります。手動で一度実行するのではなく、転送を自動化してください(下記参照)。

    統合コントローラーがGMにロックされたら、グランドマスターの値をクエリします。以下のヘルパーは、クエリするインスタンスの設定ファイルを引数として受け取ります。

    例 47.10: get_pmc_values.sh — `ptp4l`インスタンスからグランドマスターの値をクエリする
    #!/bin/bash
    # Retrieve Grandmaster information via pmc for the given ptp4l config file
    set -euo pipefail
    
    echo "PARENT_DATA_SET (Grandmaster clock values):"
    pmc -f "$1" -u -b 0 'GET PARENT_DATA_SET' | grep gm
    
    echo "TIME_PROPERTIES_DATA_SET:"
    pmc -f "$1" -u -b 0 'GET TIME_PROPERTIES_DATA_SET'

    次に、それらの値をアドインインスタンスに転送します。以下のスクリプトは、統合インスタンスから値を読み取り、各アドインインスタンスに適用します。「Input variables」セクションを編集して設定ファイル名と一致させ、システムがGMに同期されたら実行してください。

    例 47.11: 04-ptp-forward-GM.sh — グランドマスターの値をアドインインスタンスに転送する
    #!/bin/bash
    
    set -euo pipefail
    
    ################## Input variables ##################
    VERBOSE=1
    
    CONFIG_FILE_NAC=/etc/ptp4l-nac.conf
    CONFIG_FILES_AICS=(/etc/ptp4l-aic1.conf /etc/ptp4l-aic2.conf)
    
    #####################################################
    
    
    # Check the system is synchronized to a GM
    GM_PRESENT=$(pmc -f ${CONFIG_FILE_NAC} -u -b 0 'GET TIME_STATUS_NP' | awk '/gmPresent/ {print $2}')
    
    if [ -z "$GM_PRESENT" ]; then
        echo "Failed to get GM value from ptp4l instance for NAC, exiting..."
        exit 1
    elif [ "${GM_PRESENT}" != "true" ]; then
        echo "No GM present, exiting..."
        exit 1
    fi
    
    # Get the "upstream" Grandmaster values
    PDS_GM_VALUES=$(pmc -f ${CONFIG_FILE_NAC} -u -b 0 'GET PARENT_DATA_SET' | awk 'BEGIN {ORS=" "} /gm./ {print $2}')
    TPDS_GM_VALUES=$(pmc -f ${CONFIG_FILE_NAC} -u -b 0 'GET TIME_PROPERTIES_DATA_SET' | awk 'BEGIN {ORS=" "} NR>2 {print $2}')
    
    if [ -z "$PDS_GM_VALUES" ]; then
        echo "No PARENT_DATA_SET values retrieved, exiting ..."
        exit 2
    elif [ -z "$TPDS_GM_VALUES" ]; then
        echo "No TIME_PROPERTIES_DATA_SET values retrieved, exiting ..."
        exit 2
    fi
    
    # Unpack from PARENT_DATA_SET
    read CLOCK_CLASS CLOCK_ACCURACY VARIANCE <<< $PDS_GM_VALUES
    
    # Unpack from TIME_PROPERTIES_DATA_SET
    read UTC_OFFSET LEAP_61 LEAP_59 UTC_OFFSET_VALID PTP_TIMESCALE T_TRACEABLE F_TRACEABLE T_SOURCE <<< $TPDS_GM_VALUES
    
    if [ "$VERBOSE" -eq 1 ]; then
        echo "Read from PARENT_DATA_SET: clockClass=${CLOCK_CLASS} clockAccuracy=${CLOCK_ACCURACY} offsetScaledLogVariance=${VARIANCE}"
        echo "Read from TIME_PROPERTIES_DATA_SET: currentUtcOffset=${UTC_OFFSET} leap61=${LEAP_61} leap59=${LEAP_59}" \
             "currentUtcOffsetValid=${UTC_OFFSET_VALID} ptpTimescale=${PTP_TIMESCALE} timeTraceable=${T_TRACEABLE}" \
             "frequencyTraceable=${F_TRACEABLE} timeSource=${T_SOURCE}"
    fi
    
    
    # Forward these values to the "downstream" Time Receivers, updating the ptp4l instances
    for FILE in "${CONFIG_FILES_AICS[@]}"; do
        if [ "$VERBOSE" -eq 1 ]; then
            echo "Updating GRANDMASTER_SETTINGS_NP (${FILE})"
        fi
    
        pmc -f ${FILE} -u -b 0 'SET GRANDMASTER_SETTINGS_NP
           clockClass              '${CLOCK_CLASS}'
           clockAccuracy           '${CLOCK_ACCURACY}'
           offsetScaledLogVariance '${VARIANCE}'
           currentUtcOffset        '${UTC_OFFSET}'
           leap61                  '${LEAP_61}'
           leap59                  '${LEAP_59}'
           currentUtcOffsetValid   '${UTC_OFFSET_VALID}'
           ptpTimescale            '${PTP_TIMESCALE}'
           timeTraceable           '${T_TRACEABLE}'
           frequencyTraceable      '${F_TRACEABLE}'
           timeSource              '${T_SOURCE}'' &> /dev/null
    
        if [ $? -ne 0 ]; then
            echo "Failed to update ptp4l instance using config file \"${FILE}\", exiting ..."
            exit 1
        fi
    done

    値は永続的ではないため、このスクリプトを`systemd`タイマーから実行し、定期的に、またインスタンスの再起動後に値が更新されるようにしてください。

    # /etc/systemd/system/ptp-forward-gm.service
    [Unit]
    Description=Forward Grandmaster parameters to the add-in ptp4l instances
    Wants=ptp4l@nac.service ptp4l@aic1.service ptp4l@aic2.service
    After=ptp4l@nac.service ptp4l@aic1.service ptp4l@aic2.service
    
    [Service]
    Type=oneshot
    SELinuxContext=system_u:system_r:unconfined_t:s0
    ExecStart=/usr/local/bin/04-ptp-forward-GM.sh
    # /etc/systemd/system/ptp-forward-gm.timer
    [Unit]
    Description=Refresh forwarded Grandmaster parameters
    
    [Timer]
    OnBootSec=2min
    OnUnitActiveSec=5min
    
    [Install]
    WantedBy=timers.target

    その効果は、BC上のアドイン`ptp4l`インスタンスにクエリを実行することで確認できます。転送前は、ノードはファイルデフォルト値をアドバタイズしますが、転送開始後は、グランドマスターの実際の値(その後、ダウンストリームのOCに伝播されます)をアドバタイズします。例えば、`gm.ClockClass`の変更点:

    # ./get_pmc_values.sh /etc/ptp4l-aic1.conf     # before forwarding
            gm.ClockClass                         165
            gm.ClockAccuracy                      0xfe
            gm.OffsetScaledLogVariance            0xffff
    # ./get_pmc_values.sh /etc/ptp4l-aic1.conf     # after forwarding
            gm.ClockClass                         8
            gm.ClockAccuracy                      0xfe
            gm.OffsetScaledLogVariance            0xffff
  6. オプションとして、統合PHCをソース(/etc/sysconfig/phc2sys)として使用し、`phc2sys`でPTPからシステムクロックを導出します。

    OPTIONS="-f /etc/ptp4l-nac.conf -s /dev/ptp1 -c CLOCK_REALTIME -w"

CAPI自動化

自動プロビジョニングワークフローでこのシナリオをデプロイするには、完全に自動化されたダイレクトネットワークプロビジョニング — GNR-Dシナリオ (55.1.2項 「GNR-DマルチNICシナリオ(DPLL)」)で説明されているGNR-D固有のCluster APIテンプレートを使用してください。標準的なシナリオとは異なり、複数の`ptp4l`インスタンス、`ts2phc`サービス、DPLL起動時セットアップ、およびグランドマスター転送タイマーをデプロイするため、上記に記載された追加の設定ファイルと`systemd`ユニットが必要です。 そのプレースホルダーを以下の値で上書きしてください。

表 47.5: GNR-Dバウンダリクロック
Placeholder値

${GNRD_DPLL_SETUP_CONTENTS}

01-gnrd-startup-setup.sh (例47.5「01-gnrd-startup-setup.sh」)からコンテンツをコピーしてください。

${GNRD_FORWARD_GM_CONTENTS}

04-ptp-forward-GM.sh (例47.11「04-ptp-forward-GM.sh — グランドマスターの値をアドインインスタンスに転送する」)からコンテンツをコピーしてください。

${TS2PHC_CONF_CONTENTS}

/etc/ts2phc-cf-all.cfg (例47.6「/etc/ts2phc-cf-all.cfg — `ts2phc`設定ファイル」)からコンテンツをコピーしてください。

${TS2PHC_OPTIONS}

-f /etc/ts2phc-cf-all.cfg -s /dev/ptp1 -m

${PTP4L_NAC_CONTENTS}

/etc/ptp4l-nac.conf (例47.7「/etc/ptp4l-nac.conf — 統合コントローラー (/dev/ptp1)」)からコンテンツをコピーしてください。

${PTP4L_AIC1_CONTENTS}

/etc/ptp4l-aic1.conf (例47.8「/etc/ptp4l-aic1.conf — アドインカード 1 (/dev/ptp2)」)からコンテンツをコピーしてください。

${PTP4L_AIC2_CONTENTS}

/etc/ptp4l-aic2.conf (例47.9「/etc/ptp4l-aic2.conf — アドインカード 2 (/dev/ptp3)」)からコンテンツをコピーしてください。

47.8 シナリオ 3b - バウンダリクロック (ハイブリッドモード:PTP & SyncE) 内部タイミングモジュール付きマルチNIC (DPLL GNR-Dベース)

このシナリオはまだサポートされていません。将来のSUSE Telco Cloudリリースで含まれる予定です。

48 SCTP - ストリーム制御伝送プロトコル

ストリーム制御伝送プロトコル - Wikipediaより

ストリーム制御伝送プロトコル(SCTP)は、インターネットプロトコルスイートのトランスポート層におけるコンピュータネットワーク通信プロトコルです。 もともとは電気通信における信号システム7(SS7)のメッセージ転送を目的としていましたが、このプロトコルは、伝送制御プロトコル(TCP)のような輻輳制御を備えた信頼性の高い順序通りのメッセージ転送を保証しつつ、ユーザーデータグラムプロトコル(UDP)のメッセージ指向機能を提供します。 UDPやTCPとは異なり、このプロトコルはマルチホーミングと冗長パスをサポートしており、回復力と信頼性を向上させます。

SCTPは、インターネット技術標準化委員会(IETF)によってRFC 9260で標準化されています。SCTPの参照実装はFreeBSDバージョン7の一部としてリリースされ、それ以来、他のプラットフォームにも広く移植されています。

3GPP 4G(LTE)仕様において、SCTP(ストリーム制御伝送プロトコル)は、無線アクセスネットワーク(RAN)ドメインとの信号接続を含む、Evolved Packet Core(EPC)全体での制御プレーン信号メッセージの基盤となるレイヤー4トランスポートとして機能します。3GPP 5G仕様では、Diameter-over-SCTPベースのすべての信号インターフェースをHTTP/2に置き換えるサービスベースアーキテクチャ(SBA)の導入により、コアネットワーク内でのSCTPの必要性が排除されました。しかし、5G RANドメイン内では依然として必要とされています:

  • 「分離された」gNodeBインスタンスを構成するネットワーク要素間の信号インターフェース(DUとCU-CP間のF1-Cインターフェース、およびCU-CPとCU-UP間のE1インターフェース)において。

  • 信号目的でgNodeBインスタンスを接続するXn-Cインターフェースにおいて。

  • 信号目的でgNodeBインスタンス(RANドメイン)とAMFインスタンス(コアネットワークドメイン)を接続するために使用されるN2(別名NG-C)参照ポイントにおいて。

次に、それを利用するSCTP対応のTelcoワークロードをホストするダウンストリームクラスターノードで、sctp Linux カーネルモジュール(lksctp)を有効にする必要があります。

  • Linuxノードで`sctp`カーネルモジュールを手動でロードするには、次の手順を実行します。

$ sudo modprobe sctp
  • ノードの起動時に毎回`sctp`カーネルモジュールを自動的にロードするには、`/etc/modules-load.d/`ディレクトリに`sctp.conf`というファイル名のファイルを作成し、その中に単に`sctp`という文字列( systemd-modules-load.serviceユニットが起動時にロードすべきカーネルモジュールの名前)を記述します。

$ echo "sctp" > /etc/modules-load.d/sctp.conf
$ reboot

ノードの起動時に毎回`sctp`カーネルモジュールを確実にロードするための最も簡単で最適な方法は、ダウンストリームノードのプロビジョニングに使用されるEdge Image Builder (EIB) で構築された raw イメージにその`/etc/modules-load.d/sctp.conf`ファイルを追加することです。その方法の詳細については、EIB documentation (5.3.5項 「オペレーティングシステムファイルの追加」)を参照してください。

パート VII 完全自動化されたダイレクトネットワークプロビジョニング

49 概要

この章では、SUSE Telco Cloudでサポートされているプロビジョニング方法であるダイレクトネットワークプロビジョニングを使用して、ダウンストリームクラスターをプロビジョニングする方法について説明します。イメージベースのプロビジョニングとは異なり、このワークフローではOSイメージを汎用的に保ち、すべてのクラスター固有の構成を管理クラスターから実行するため、分散サイト全体で一貫した完全自動化された大規模なデプロイメントが可能になります。

ダイレクトネットワークプロビジョニングは、管理クラスターによって実行される完全自動化されたゼロタッチワークフローです。各ベアメタルホストは、まずBMC資格情報とハードウェア詳細を登録することにより、管理クラスターからMetal3に事前登録されます。ホストがラックに搭載され、必要なネットワークに接続され、電源がオンになると、管理クラスターが引き継ぎます。管理クラスターは、帯域外管理インターフェイスを介してEIBで生成されたベースイメージを使用してOSをプロビジョニングし、それ以上の手動介入なしで、すべてのtelcoプロファイルが適用された完全なKubernetesスタックをデプロイします。

管理クラスターは、各ダウンストリームクラスターノードへの以下のコンポーネントのデプロイメントを自動化します。

  • オペレーティングシステムとしてSUSE Linux Micro (第10章 「SUSE Linux Micro」)(またはリアルタイムカーネルの場合は`SUSE Linux Micro RT`)。ネットワーキング、ストレージ、ユーザー、およびカーネル引数は、ユースケースに応じてカスタマイズできます。

  • RKE2 (第14章 「RKE2」)(Kubernetesディストリビューションとして)。デフォルトのCNIプラグインは`Cilium`です。ユースケースに応じて、`Cilium+Multus`などの他のCNIの組み合わせを使用できます。

  • (オプション)SUSE Storage (第15章 「SUSE Storage」)

  • (オプション)SUSE Security (第16章 「SUSE Security」)

  • (オプション)MetalLB(高可用性マルチノードクラスターのロードバランサーとして)。

以下のセクションでは、さまざまなダイレクトネットワークプロビジョニングワークフローと、プロビジョニングプロセスに追加できるいくつかの追加機能について説明します。

注記
注記

以下のセクションでは、SUSE Telco Cloudを使用してダイレクトネットワークプロビジョニングワークフローのさまざまなシナリオを準備する方法を示します。 デプロイメントのさまざまな構成オプション(エアギャップ環境、DHCPおよびDHCPなしネットワーク、プライベートコンテナレジストリなどを含む)の例については、https://github.com/suse-edge/telco-cloud-examples/tree/release-3.7/telco-examples/downstream-clusters[SUSE Telco Cloudリポジトリ]を参照してください。

50 接続されたシナリオ向けのダウンストリームクラスターイメージの準備

Edge Image Builder (第12章 「Edge Image Builder」)は、ダウンストリームクラスター ホストにプロビジョニングされる変更済みのSLEMicroベースイメージを準備するために使用されます。

Edge Image Builderによる構成の多くは可能ですが、本ガイドでは、ダウンストリームクラスターをセットアップするために必要な最小限の構成について説明します。

50.1 接続されたシナリオの前提条件

注記
注記

ビルドするイメージと同じアーキテクチャのビルドホストを使用する必要があります。つまり、`aarch64`イメージをビルドするには`aarch64`ビルドホストを使用する必要があり、`x86-64`の場合も同様です(現時点ではクロスビルドはサポートされていません)。

50.2 接続されたシナリオのイメージ構成

Edge Image Builderを実行する際、ホストからディレクトリがマウントされるため、ターゲットイメージの定義に使用する設定ファイルを保存するためのディレクトリ構造を作成する必要があります。

  • `downstream-cluster-config.yaml`はイメージ定義ファイルです。詳細については第5章 「Edge Image Builderを使用したスタンドアロンクラスター」を参照してください。

  • ベースイメージフォルダーには、ガイド第65章 「Kiwiを使用して更新されたSUSE Linux Microイメージを構築する」に従いプロファイル`Base`(またはリアルタイムカーネルの場合は`Base-RT`)を使用して生成された出力RAWイメージが含まれます。これを`base-images`フォルダーの下にコピーまたは移動する必要があります。

  • `custom/files`ディレクトリには、イメージ作成プロセス中にイメージにコピーされる`performance-settings.sh`ファイルと`sriov-auto-filler.sh`ファイルが含まれています。

  • `custom/scripts`ディレクトリには、初回起動時に実行されるスクリプトが含まれています。

    1. `01-fix-growfs.sh`スクリプトは、デプロイ時にOSルートパーティションのサイズを変更するために必要です。

    2. `02-performance.sh`スクリプトはオプションであり、パフォーマンスチューニング用にシステムを構成するために使用できます。

    3. `03-sriov.sh`スクリプトはオプションであり、SR-IOV用にシステムを構成するために使用できます。

  • `network`フォルダーはオプションです。詳細については50.2.6項 「高度なネットワーク構成用の追加スクリプト」を参照してください。

  • `os-files`フォルダーには、各ノードの起動時に必要なオプションを指定して`sctp`カーネルモジュールと`vfio-pci`カーネルモジュールをロードするために必要な設定ファイルが含まれています。

├── downstream-cluster-config.yaml
├── base-images
│   └── SL-Micro.x86_64-6.2-Base-GM.raw
├── custom
│   ├── files
│   │   ├── performance-settings.sh
│   │   └── sriov-auto-filler.sh
│   └── scripts
│       ├── 01-fix-growfs.sh
│       ├── 02-performance.sh
│       └── 03-sriov.sh
├── network
│   └── configure-network.sh
└── os-files
    └── etc
        ├── modprobe.d
        │   └── vfio-pci-options.conf
        └── modules-load.d
            ├── sctp.conf
            └── vfio-pci.conf

50.2.1 ダウンストリームクラスターイメージ定義ファイル

`downstream-cluster-config.yaml`ファイルは、ダウンストリームクラスターイメージのメイン設定ファイルです。Metal3を介したデプロイメントの最小限の例を次に示します。

apiVersion: 1.3
image:
  imageType: raw
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.2-Base-GM.raw
  outputImageName: eibimage-output-telco.raw
operatingSystem:
  kernelArgs:
    - ignition.platform.id=openstack
  systemd:
    disable:
      - rebootmgr
      - transactional-update.timer
      - transactional-update-cleanup.timer
      - fstrim
      - time-sync.target
  users:
    - username: root
      encryptedPassword: $ROOT_PASSWORD
      sshKeys:
      - $USERKEY1
      createHomeDir: true
  packages:
    packageList:
      - jq
    sccRegistrationCode: $SCC_REGISTRATION_CODE

`$SCC_REGISTRATION_CODE`は SUSE Customer Centerからコピーした登録コードであり、パッケージリストには必要な`jq`が含まれています。

`$ROOT_PASSWORD`はルートユーザの暗号化されたパスワードであり、テストやデバッグに役立ちます。 これは`openssl passwd -6 PASSWORD`コマンドで生成できます。

本番環境では、`$USERKEY1`を実際のSSHキーに置き換えてusersブロックに追加できるSSHキーを使用することをお勧めします。

注記
注記

`arch: x86_64`はイメージのアーキテクチャです。arm64アーキテクチャの場合は、`arch: aarch64`を使用してください。

`ignition.platform.id=openstack`は必須であることに注意してください。この引数がないと、Metal3の自動フローによるSLEMicroの設定は失敗します。

SUSE Linux Micro 6.2より前のバージョンでは、 Predictable Network Interface Namingを有効にするために、`net.ifnames=1`をカーネル引数として明示的に設定する必要があります。これは6.2以降ではデフォルトで適用されるため、明示的な設定は不要です。これは、管理クラスターのMetal3 Helmチャートの`predictableNicNames`設定と一致しており、ダイレクトネットワークプロビジョニングが正しく機能するために必要です。SR-IOVを利用する場合、一貫したインターフェース命名も不可欠です。

50.2.2 Growfsスクリプト

現在、プロビジョニング後の初回起動時にディスクサイズに合わせてファイルシステムを拡張するには、カスタムスクリプト(custom/scripts/01-fix-growfs.sh)が必要です。`01-fix-growfs.sh`スクリプトには、次の情報が含まれています。

#!/bin/bash
growfs() {
  mnt="$1"
  dev="$(findmnt --fstab --target ${mnt} --evaluate --real --output SOURCE --noheadings)"
  # /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1
  parent_dev="/dev/$(lsblk --nodeps -rno PKNAME "${dev}")"
  # Last number in the device name: /dev/nvme0n1p42 -> 42
  partnum="$(echo "${dev}" | sed 's/^.*[^0-9]\([0-9]\+\)$/\1/')"
  ret=0
  growpart "$parent_dev" "$partnum" || ret=$?
  [ $ret -eq 0 ] || [ $ret -eq 1 ] || exit 1
  /usr/lib/systemd/systemd-growfs "$mnt"
}
growfs /

50.2.3 パフォーマンススクリプト

次のオプションのスクリプト(custom/scripts/02-performance.sh)を使用して、パフォーマンスチューニング用にシステムを設定できます。

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/performance-settings

# copy the artifacts
cp performance-settings.sh /opt/performance-settings/

custom/files/performance-settings.sh の内容は、パフォーマンスチューニング用にシステムを設定するために使用できるスクリプトであり、次の https://github.com/suse-edge/telco-cloud-examples/blob/release-3.7/telco-examples/downstream-clusters/dhcp/eib/custom/files/performance-settings.sh [link] からダウンロードできます。

50.2.4 SR-IOVスクリプト

次のオプションのスクリプト(custom/scripts/03-sriov.sh)を使用して、SR-IOV用にシステムを設定できます。

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/sriov
# copy the artifacts
cp sriov-auto-filler.sh /opt/sriov/sriov-auto-filler.sh

custom/files/sriov-auto-filler.sh の内容は、SR-IOV 用にシステムを構成するために使用できるスクリプトであり、以下の link からダウンロードできます。

注記
注記

同じアプローチを使用して、プロビジョニングプロセス中に実行される独自のカスタムスクリプトを追加します。 詳細については、第5章 「Edge Image Builderを使用したスタンドアロンクラスター」を参照してください。

50.2.5 通信ワークロードの追加構成

dpdk、sr-iov、または FEC などの通信機能を有効にするには、次の例に示すように追加のパッケージが必要になる場合があります。

apiVersion: 1.3
image:
  imageType: raw
  arch: x86_64
  baseImage: SL-Micro.x86_64-6.2-Base-GM.raw
  outputImageName: eibimage-output-telco.raw
operatingSystem:
  kernelArgs:
    - ignition.platform.id=openstack
  systemd:
    disable:
      - rebootmgr
      - transactional-update.timer
      - transactional-update-cleanup.timer
      - fstrim
      - time-sync.target
  users:
    - username: root
      encryptedPassword: $ROOT_PASSWORD
      sshKeys:
      - $user1Key1
      createHomeDir: true
  packages:
    packageList:
      - jq            # Non Telco specific - category: testing/utils
      - dpdk          # TelCo Core-Network UserPlane (5G UPF) and RAN UserPlane (gNB: DU and CU-UP) - category: runtime
      - dpdk-tools    # TelCo Core-Network UserPlane (5G UPF) and RAN UserPlane (gNB: DU and CU-UP) - category: testing/utils
      - libdpdk-25    # TelCo Core-Network UserPlane (5G UPF) and RAN UserPlane (gNB: DU and CU-UP) - category: runtime
      - pf-bb-config  # TelCo RAN (gNB: DU) - category: config.
      - open-iscsi    # Non Telco specific (required by SUSE Storage/Longhorn) - category: runtime
      - tuned         # Non Telco specific (linux tuning) - category: config.
      - cpupower      # Non Telco specific (linux tuning - CPU power related settings) - category: config.
      - rt-tests      # Non Telco specific (RT scheduler-latency testing) - category: testing/utils
      - linuxptp      # TelCo RAN; time sync (gNB: DU) - category: runtime
      - synce4l       # TelCo RAN; time sync (gNN: DU) - category: runtime
      - pciutils      # Non Telco specific (provides "lspci" command) - category: testing/utils
      - numactl       # Non Telco specific (provides "numactl" command) - category: testing/utils
    sccRegistrationCode: $SCC_REGISTRATION_CODE

ここで $SCC_REGISTRATION_CODE は SUSE Customer Center からコピーされた登録コードであり、パッケージリストには通信プロファイルに使用される最小限のパッケージが含まれています。

注記
注記

`arch: x86_64`はイメージのアーキテクチャです。arm64アーキテクチャの場合は、`arch: aarch64`を使用してください。

50.2.6 高度なネットワーク構成用の追加スクリプト

第54章 「高度なネットワーク設定」 で説明されているように、静的 IP やより高度なネットワークシナリオを構成する必要がある場合は、以下の追加構成が必要です。

network フォルダーに次の configure-network.sh 設定ファイルを作成します。これは初回起動時に構成ドライブデータを消費し、 NM Configurator tool を使用してホストネットワークを構成します。

#!/bin/bash

set -eux

# Attempt to statically configure a NIC in the case where we find a network_data.json
# In a configuration drive

CONFIG_DRIVE=$(blkid --label config-2 || true)
if [ -z "${CONFIG_DRIVE}" ]; then
  echo "No config-2 device found, skipping network configuration"
  exit 0
fi

mount -o ro $CONFIG_DRIVE /mnt

META_DATA_FILE="/mnt/openstack/latest/meta_data.json"
if [ ! -f "${META_DATA_FILE}" ]; then
  umount /mnt
  echo "No meta_data.json found, skipping hostname configuration"
  exit 0
fi

DESIRED_HOSTNAME=$(cat /mnt/openstack/latest/meta_data.json | tr ',{}' '\n' | grep '"metal3-name"' | sed 's/.*\"metal3-name\": \"\(.*\)\"/\1/')
echo "${DESIRED_HOSTNAME}" > /etc/hostname

NETWORK_DATA_FILE="/mnt/openstack/latest/network_data.json"

if [ ! -f "${NETWORK_DATA_FILE}" ]; then
  umount /mnt
  echo "No network_data.json found, skipping network configuration"
  exit 0
fi

mkdir -p /tmp/nmc/{desired,generated}
cp ${NETWORK_DATA_FILE} /tmp/nmc/desired/_all.yaml
umount /mnt

./nmc generate --config-dir /tmp/nmc/desired --output-dir /tmp/nmc/generated
./nmc apply --config-dir /tmp/nmc/generated

50.2.7 通信に必要なカーネルモジュール

通信ワークロードに必要なカーネルモジュールが各ノードの起動時に読み込まれるようにするには、以下の設定ファイルを os-files EIB フォルダーに追加する必要があります。

50.2.7.1 sctp.conf

os-files/etc/modules-load.d/ パスに配置し、 systemd-modules-load.service に対してノード起動時に sctp カーネルモジュールを読み込むよう指示します。

$ cat os-files/etc/modules-load.d/sctp.conf
# Request "systemd-modules-load.service" to load sctp module at boot time
sctp

50.2.7.2 vfio-pci.conf

os-files/etc/modules-load.d/ パスに配置し、 systemd-modules-load.service に対してノード起動時に vfio-pci カーネルモジュールを読み込むよう指示します。

$ cat os-files/etc/modules-load.d/vfio-pci.conf
# Request "systemd-modules-load.service" to load vfio-pci module at boot time
# NOTE: The (SRIOV & DPDK related) required load-module options settings are defined in related "/etc/modprobe.d/vfio-pci-options.conf" file
vfio_pci

50.2.7.3 vfio-pci-options.conf

os-files/etc/modprobe.d/ パスに配置し、カーネルモジュールの読み込み時に適用される必要な vfio-pci カーネルモジュールパラメーターを設定します。

$ cat os-files/etc/modprobe.d/vfio-pci-options.conf
# Enable SR-IOV and disable idle D3 state for vfio-pci driver
options vfio_pci enable_sriov=1 disable_idle_d3=1

50.3 イメージの作成

前のセクションに従ってディレクトリ構造が準備できたら、次のコマンドを実行してイメージをビルドします。

podman run --rm --privileged -it -v $PWD:/eib \
 registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
 build --definition-file downstream-cluster-config.yaml

これにより、上記で説明した定義に基づいて、`eibimage-output-telco.raw`という名前の出力RAWイメージファイルが作成されます。

出力されたイメージは、Management Cluster Documentation (注記)で有効化されたメディアサーバーコンテナ、またはローカルでアクセス可能なその他のサーバーなど、Webサーバー経由で利用できるようにする必要があります。 以下の例では、このサーバーを imagecache.local:8080 と呼びます。

51 エアギャップシナリオ用のダウンストリームクラスターイメージの準備

Edge Image Builder (第12章 「Edge Image Builder」)は、ダウンストリームクラスターのホストにプロビジョニングされる変更済みのSLEMicroベースイメージを準備するために使用されます。

設定の多くは Edge Image Builder で可能ですが、このガイドでは、エアギャップシナリオ用にダウンストリームクラスターをセットアップするために必要な最小限の設定について説明します。

51.1 エアギャップシナリオの前提条件

  • Edge Image Builderを実行するには、 Podmanや Rancher Desktopなどのコンテナランタイムが必要です。

  • ベースイメージは、次のガイド第65章 「Kiwiを使用して更新されたSUSE Linux Microイメージを構築する」を使用して、プロファイル`Base`(またはリアルタイムカーネルの場合は`Base-RT`)でビルドされます。このプロセスは、両方のアーキテクチャ(x86-64およびaarch64)で同じです。

  • SR-IOVやコンテナイメージを必要とするその他のワークロードを使用する場合は、ローカルのプライベートレジストリをデプロイし、あらかじめ設定(TLSや認証の有無を問わず)しておく必要があります。このレジストリは、イメージおよびHelmチャートOCIイメージを保存するために使用されます。

注記
注記

ビルドするイメージと同じアーキテクチャのビルドホストを使用する必要があります。つまり、aarch64 イメージをビルドするには aarch64 ビルドホストを使用する必要があり、x86-64 の場合も同様です(現時点ではクロスビルドはサポートされていません)。

51.2 エアギャップシナリオのイメージ設定

Edge Image Builderを実行する際、ホストからディレクトリがマウントされるため、ターゲットイメージの定義に使用する設定ファイルを保存するためのディレクトリ構造を作成する必要があります。

  • `downstream-cluster-airgap-config.yaml`はイメージ定義ファイルです。詳細については第5章 「Edge Image Builderを使用したスタンドアロンクラスター」を参照してください。

  • ベースイメージフォルダーには、ガイド第65章 「Kiwiを使用して更新されたSUSE Linux Microイメージを構築する」に従いプロファイル`Base`(またはリアルタイムカーネルの場合は`Base-RT`)を使用して生成された出力RAWイメージが含まれます。これを`base-images`フォルダーの下にコピーまたは移動する必要があります。

  • network フォルダーはオプションです。詳細については 50.2.6項 「高度なネットワーク構成用の追加スクリプト」 を参照してください。

  • custom/scripts ディレクトリには、初回起動時に実行されるスクリプトが含まれています。

    1. デプロイ時にOSルートパーティションのサイズを変更するには、01-fix-growfs.sh スクリプトが必要です。

    2. エアギャップ環境のイメージ作成プロセス中に、イメージを適切な場所にコピーするには、02-airgap.sh スクリプトが必要です。

    3. 03-performance.sh スクリプトはオプションであり、パフォーマンスチューニング用にシステムを構成するために使用できます。

    4. 04-sriov.sh スクリプトはオプションであり、SR-IOV用にシステムを構成するために使用できます。

  • custom/files ディレクトリには、イメージ作成プロセス中にイメージにコピーされる rke2 および cni イメージが含まれています。また、オプションの performance-settings.sh および sriov-auto-filler.sh ファイルを含めることもできます。

  • os-files フォルダーには、各ノードの起動時に必要なオプションを指定して sctp カーネルモジュールと vfio-pci カーネルモジュールをロードするために必要な設定ファイルが含まれています。

├── downstream-cluster-airgap-config.yaml
├── base-images
│   └── SL-Micro.x86_64-6.2-Base-GM.raw
├── custom
│   ├── files
│   │   ├── install.sh
│   │   ├── rke2-images-cilium.linux-amd64.tar.zst
│   │   ├── rke2-images-core.linux-amd64.tar.zst
│   │   ├── rke2-images-multus.linux-amd64.tar.zst
│   │   ├── rke2-images.linux-amd64.tar.zst
│   │   ├── rke2.linux-amd64.tar.zst
│   │   ├── sha256sum-amd64.txt
│   │   ├── performance-settings.sh
│   │   └── sriov-auto-filler.sh
│   └── scripts
│       ├── 01-fix-growfs.sh
│       ├── 02-airgap.sh
│       ├── 03-performance.sh
│       └── 04-sriov.sh
├── network
│   └── configure-network.sh
└── os-files
    └── etc
        ├── modprobe.d
        │   └── vfio-pci-options.conf
        └── modules-load.d
            ├── sctp.conf
            └── vfio-pci.conf

51.2.1 ダウンストリームクラスターイメージ定義ファイル

downstream-cluster-airgap-config.yaml ファイルはダウンストリームクラスターイメージのメイン設定ファイルであり、その内容は前のセクション (50.2.5項 「通信ワークロードの追加構成」)で説明されています。

51.2.2 Growfsスクリプト

現在、プロビジョニング後の初回起動時にディスクサイズに合わせてファイルシステムを拡張するには、カスタムスクリプト(custom/scripts/01-fix-growfs.sh)が必要です。01-fix-growfs.sh スクリプトには、次の情報が含まれています。

#!/bin/bash
growfs() {
  mnt="$1"
  dev="$(findmnt --fstab --target ${mnt} --evaluate --real --output SOURCE --noheadings)"
  # /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1
  parent_dev="/dev/$(lsblk --nodeps -rno PKNAME "${dev}")"
  # Last number in the device name: /dev/nvme0n1p42 -> 42
  partnum="$(echo "${dev}" | sed 's/^.*[^0-9]\([0-9]\+\)$/\1/')"
  ret=0
  growpart "$parent_dev" "$partnum" || ret=$?
  [ $ret -eq 0 ] || [ $ret -eq 1 ] || exit 1
  /usr/lib/systemd/systemd-growfs "$mnt"
}
growfs /

51.2.3 エアギャップスクリプト

イメージ作成プロセス中にイメージを適切な場所にコピーするには、以下のスクリプト(custom/scripts/02-airgap.sh)が必要です。

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/rke2-artifacts
mkdir -p /var/lib/rancher/rke2/agent/images

# copy the artifacts
cp install.sh /opt/
cp rke2-images*.tar.zst rke2.linux-amd64.tar.gz sha256sum-amd64.txt /opt/rke2-artifacts/

51.2.4 パフォーマンススクリプト

次のオプションのスクリプト(custom/scripts/03-performance.sh)を使用して、パフォーマンスチューニング用にシステムを設定できます。

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/performance-settings

# copy the artifacts
cp performance-settings.sh /opt/performance-settings/

custom/files/performance-settings.sh の内容は、パフォーマンスチューニング用にシステムを設定するために使用できるスクリプトであり、次の https://github.com/suse-edge/telco-cloud-examples/blob/release-3.7/telco-examples/downstream-clusters/dhcp/eib/custom/files/performance-settings.sh [link] からダウンロードできます。

51.2.5 SR-IOVスクリプト

次のオプションのスクリプト(custom/scripts/04-sriov.sh)を使用して、SR-IOV用にシステムを設定できます。

#!/bin/bash

# create the folder to extract the artifacts there
mkdir -p /opt/sriov
# copy the artifacts
cp sriov-auto-filler.sh /opt/sriov/sriov-auto-filler.sh

custom/files/sriov-auto-filler.sh の内容は、SR-IOV用にシステムを設定するために使用できるスクリプトであり、以下の リンク からダウンロードできます。

51.2.6 通信に必要なカーネルモジュール

非エアギャップシナリオについてセクション (50.2.7項 「通信に必要なカーネルモジュール」)で説明した通りです。

51.2.7 エアギャップアーティファクトの準備

リリースコンテナイメージを使用してエアギャップアーティファクトを準備し、特定のバージョンのアーティファクトでリポジトリを構成するには、以下の手順が必要です。 RKE2 tarballの生成、HelmチャートOCIのミラーリング、コンテナイメージのミラーリングを単一のコマンドで処理するため、個別のスクリプトは不要です。

  1. プライベートレジストリで認証が必要な場合は、base64エンコードされた認証情報を使用してレジストリ認証ファイルを作成してください。

    $ echo -n "$(echo -n 'myusername' | base64 -w 0):$(echo -n 'mypassword' | base64 -w 0)" > registry-auth.txt
  2. Rancher Appsチャートリポジトリ(LonghornおよびRancherソースのチャートに必要)を使用する場合は、Rancher Apps認証ファイルを作成してください。

    $ echo -n "$(echo -n 'myusername@apps.rancher.io' | base64 -w 0):$(echo -n 'mypassword' | base64 -w 0)" > rancher-apps-auth.txt
  3. (オプション)SUSEプライベートレジストリのアーティファクト(Harborチャート/イメージ)をミラーリングする場合は、 SUSEプライベートレジストリのドキュメントに従って取得した`SCC mirroring credentials`を使用して、SUSEプライベートレジストリ認証ファイルを作成してください。

    $ echo -n "$(echo -n 'SUSE_REGISTRY_USERNAME' | base64 -w 0):$(echo -n 'SUSE_REGISTRY_PASSWORD' | base64 -w 0)" > suse-private-registry-auth.txt
  4. リリースコンテナイメージを使用して`mirror`コマンドを実行し、特定のリリースバージョンに必要なすべてのアーティファクト(RKE2イメージ、HelmチャートOCIイメージ、コンテナイメージ)をプライベートリポジトリに格納します。 認証ファイルや証明書は、`-v ./:/opt:z`バインドマウントを介してコンテナ内からアクセスできるように、現在のディレクトリに配置してください。

    SUSE Private Registryを使用しない場合(Harborチャート/イメージはスキップされます):

    $ podman run --rm \
      -v ./:/opt:z \
      registry.suse.com/edge/3.7/release-manifest:3.7.0 \
      mirror \
      -o /opt/output \
      -a /opt/registry-auth.txt \
      -c /opt/cert.pem \
      -r ${REGISTRY_IP}:5000 \
      --rancher-apps-authfile /opt/rancher-apps-auth.txt \
      --debug

    ここで、`${REGISTRY_IP}`はデータを格納するレジストリインスタンスのIPアドレスです。

    SUSE Private Registryを使用する場合:

    $ podman run --rm \
      -v ./:/opt:z \
      registry.suse.com/edge/3.7/release-manifest:3.7.0 \
      mirror \
      -o /opt/output \
      -a /opt/registry-auth.txt \
      -c /opt/cert.pem \
      -r ${MGMT_CLUSTER_REGISTRY_IP}:5000 \
      --rancher-apps-authfile /opt/rancher-apps-auth.txt \
      --suse-private-registry-authfile /opt/suse-private-registry-auth.txt \
      --debug

    ここで、`${MGMT_CLUSTER_REGISTRY_IP}`は、前のセクション (30.3項 「kubernetesフォルダーの変更」)で説明したように、管理クラスターにデプロイされたSUSE Private Registryインスタンスに割り当てられた予約済み静的IPアドレスです。

  5. 生成されたRKE2アーティファクトを出力ディレクトリ(例では`/opt/output`)から`custom/files`ディレクトリにコピーし、ビルドプロセス中にEIBがダウンストリームクラスター用にそれらを使用できるようにします。

    $ cp output/rke2-images*.tar.zst custom/files/
    $ cp output/rke2.linux-amd64.tar.gz custom/files/
    $ cp output/sha256sum-amd64.txt custom/files/
注記
注記

リリースコンテナイメージにはすでに`/release_manifest.yaml`と`/release_images.yaml`が内部的にバンドルされているため、追加のマニフェストファイルを提供する必要はありません。 フラグの完全なリファレンスと高度な使用方法については、 seactlドキュメントを参照してください。

51.3 エアギャップシナリオ向けのイメージ作成

前のセクションに従ってディレクトリ構造が準備できたら、次のコマンドを実行してイメージをビルドします。

podman run --rm --privileged -it -v $PWD:/eib \
 registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
 build --definition-file downstream-cluster-airgap-config.yaml

これにより、上記で説明した定義に基づいて、`eibimage-output-telco.raw`という名前の出力RAWイメージファイルが作成されます。

出力されたイメージは、Management Cluster Documentation (注記)で有効化されたメディアサーバーコンテナ、またはローカルでアクセス可能なその他のサーバーなど、Webサーバー経由で利用できるようにする必要があります。 以下の例では、このサーバーを`imagecache.local:8080`と呼びます。

52 ダイレクトネットワークプロビジョニング(シングルノード)によるダウンストリームクラスターのプロビジョニング

このセクションでは、ダイレクトネットワークプロビジョニングを使用してシングルノードのダウンストリームクラスターのプロビジョニングを自動化するワークフローについて説明します。 これは、ダウンストリームクラスターのプロビジョニングを自動化する最も簡単な方法です。

要件

のワークフロー

次の図は、ダイレクトネットワークプロビジョニングを使用してシングルノードのダウンストリームクラスターのプロビジョニングを自動化するワークフローを示しています。

atip automated singlenode1

ダイレクトネットワークプロビジョニングを使用してシングルノードのダウンストリームクラスターのプロビジョニングを自動化するには、2 つの異なるステップがあります。

  1. ベアメタルホストを登録して、プロビジョニング処理で使用できるようにします。

  2. ベアメタルホストをプロビジョニングして、オペレーティングシステムとKubernetesクラスターをインストールおよび構成します。

ベアメタルホストの登録

最初のステップは、新しいベアメタルホストを管理クラスターに登録し、プロビジョニング可能な状態にすることです。 そのためには、管理クラスターで次のファイル(bmh-example.yaml)を作成し、使用する`BMC`資格情報と登録する`BaremetalHost`オブジェクトを指定する必要があります。

apiVersion: v1
kind: Secret
metadata:
  name: example-demo-credentials
type: Opaque
data:
  username: ${BMC_USERNAME}
  password: ${BMC_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: example-demo
  labels:
    cluster-role: control-plane
spec:
  architecture: x86_64
  online: true
  bootMACAddress: ${BMC_MAC}
  rootDeviceHints:
    deviceName: /dev/nvme0n1
  bmc:
    address: ${BMC_ADDRESS}
    disableCertificateVerification: true
    credentialsName: example-demo-credentials

各要素の説明

  • ${BMC_USERNAME} — 新しいベアメタルホストの`BMC`のユーザー名。

  • ${BMC_PASSWORD} — 新しいベアメタルホストの`BMC`のパスワード。

  • ${BMC_MAC} — 使用する新しいベアメタルホストの`MAC`アドレス。

  • ${BMC_ADDRESS} — ベアメタルホスト`BMC`の`URL`(例:redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/)。ハードウェアプロバイダーに応じて利用可能なさまざまなオプションの詳細については、次の リンクを確認してください。

注記
注記
  • アーキテクチャは、登録するベアメタルホストのアーキテクチャに応じて、`x86_64`または`aarch64`のいずれかである必要があります。

  • ホストのネットワーク設定が、イメージビルド時または`BareMetalHost`定義のいずれにおいても指定されていない場合は、自動構成メカニズム(DHCP、DHCPv6、SLAAC)が使用されます。詳細や複雑な設定については、第54章 「高度なネットワーク設定」を確認してください。

ファイルが作成されたら、管理クラスターで次のコマンドを実行して、新しいベアメタルホストの管理クラスターへの登録を開始する必要があります。

$ kubectl apply -f bmh-example.yaml

新しいベアメタルホストオブジェクトが登録され、その状態がregisteringからinspectingおよびavailableに変更されます。変更内容は、次のコマンドを使用して確認できます。

$ kubectl get bmh
注記
注記

BaremetalHost`オブジェクトは、`BMC`資格情報が検証されるまで`registering`状態になります。資格情報が検証されると、`BaremetalHost`オブジェクトの状態は`inspecting`に変更されます。このステップは、ハードウェアによっては時間がかかる場合があります(最大20分)。インスペクションフェーズ中に、ハードウェア情報が取得され、Kubernetesオブジェクトが更新されます。次のコマンドを使用して情報を確認してください:`kubectl get bmh -o yaml。

プロビジョニングステップ

ベアメタルホストが登録され、利用可能になったら、次のステップはベアメタルホストをプロビジョニングして、オペレーティングシステムとKubernetesクラスターをインストールおよび構成することです。 そのためには、管理クラスターで次のファイル(capi-provisioning-example.yaml)を作成し、以下の情報を指定する必要があります(`capi-provisioning-example.yaml`は、次のブロックを結合することで生成できます)。

注記
注記

`$\{…​\}`の間の値のみを実際の値に置き換える必要があります。

次のブロックはクラスター定義であり、`pods`ブロックと`services`ブロックを使用してネットワークを設定できます。また、使用するコントロールプレーンとインフラストラクチャ(`Metal3`プロバイダーを使用)オブジェクトへの参照も含まれています。

apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
  name: single-node-cluster
  namespace: default
  labels:
    cluster-api.cattle.io/rancher-auto-import: "true"
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
        - fd00:bad:cafe::/48
    services:
      cidrBlocks:
        - 10.96.0.0/12
        - fd00:bad:bad:cafe::/112
  controlPlaneRef:
    apiGroup: controlplane.cluster.x-k8s.io
    kind: RKE2ControlPlane
    name: single-node-cluster
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3Cluster
    name: single-node-cluster
注記
注記
  • シングルスタックとデュアルスタックの両方のデプロイメントが可能です。IPv4のみのクラスターにする場合は、上記の定義からIPv6 CIDRを削除してください。

  • シングルスタックIPv6デプロイメントは技術プレビュー段階であり、正式にはまだサポートされていません。

  • `cluster.x-k8s.io`オブジェクトにラベル`cluster-api.cattle.io/rancher-auto-import: "true"`を追加すると、クラスターがRancherにインポートされます(対応する`clusters.management.cattle.io`オブジェクトが作成されます)。 詳細については、 Cluster APIドキュメントを参照してください。

Metal3Cluster`オブジェクトは、構成対象のコントロールプレーンのエンドポイント(${DOWNSTREAM_CONTROL_PLANE_IPV4}`の代わりに)と、ベアメタルが使用されるため`false`に設定された`cloudProviderEnabled`フラグを示します。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3Cluster
metadata:
  name: single-node-cluster
  namespace: default
spec:
  controlPlaneEndpoint:
    host: ${DOWNSTREAM_CONTROL_PLANE_IPV4}
    port: 6443
  cloudProviderEnabled: false

RKE2ControlPlane`オブジェクトは使用するコントロールプレーン設定を指定し、`Metal3MachineTemplate`オブジェクトは使用するコントロールプレーンイメージを指定します。 また、必要なレプリカ数(この場合は1)に関する情報と、使用する`CNI`プラグイン(この場合は`Cilium)に関する情報も含まれています。 agentConfigブロックには、使用する`Ignition`形式と、systemdユニットサービス(名前は`rke2-preinstall.service`)などの情報を使って`RKE2`ノードを構成するために使用する`additionalUserData`、およびIronic情報を利用してプロビジョニング処理中に`PROVIDERID`と`node-name`を自動的に置き換えるための情報が含まれています。RKE2(Traefikベース)Ingressコントローラーに必要な設定も含まれており、${INGRESS_IPV4}`および${INGRESS_IPV6}`仮想IPを通じてIngressサービスを外部に公開するために必要な`MetalLB`カスタムリソース(IPAddressPool`および`L2Advertisement)インスタンスマニフェストも含まれています。 情報の最後のブロックには、使用するKubernetesバージョンが含まれています。${RKE2_VERSION}`は、この値を置き換えるために使用する`RKE2`のバージョンです(例:v1.36.3+rke2r1`)。

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
  annotations: {
    rke2.controlplane.cluster.x-k8s.io/load-balancer-exclusion: "true"
  }
spec:
  machineTemplate:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  serverConfig:
    cni: cilium
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
          - name: rke2-preinstall.service
            enabled: true
            contents: |
              [Unit]
              Description=rke2-preinstall
              Wants=network-online.target
              Before=rke2-install.service
              ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
              [Service]
              Type=oneshot
              User=root
              ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
              # Note we use _ as a delimiter for sed here because the providerid includes / characters
              ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStartPost=/bin/sh -c "umount /mnt"
              [Install]
              WantedBy=multi-user.target
        storage:
          directories:
          - path: /var/lib/rancher/rke2/server/manifests
            overwrite: true
          files:
          - path: /var/lib/rancher/rke2/server/manifests/rke2-traefik-config.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: helm.cattle.io/v1
                kind: HelmChartConfig
                metadata:
                  name: rke2-traefik
                  namespace: kube-system
                spec:
                  valuesContent: |-
                    ingressClass:
                      isDefaultClass: true
                    ports:
                      web:
                        hostPort: null    # disallow hostPort
                        exposedPort: 80
                      websecure:
                        hostPort: null    # disallow hostPort
                        exposedPort: 443
                    service:
                      enabled: true
                      spec:
                        type: LoadBalancer
                        externalTrafficPolicy: Local
                        allocateLoadBalancerNodePorts: false
            mode: 0644
            user:
              name: root
            group:
              name: root
          - path: /var/lib/rancher/rke2/server/manifests/metallb-traefik-cr.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: metallb.io/v1beta1
                kind: IPAddressPool
                metadata:
                  name: ingress-ippool
                  namespace: metallb-system
                spec:
                  addresses:
                    - ${INGRESS_IPV4}/32
                    - ${INGRESS_IPV6}/128
                  serviceAllocation:
                    priority: 100
                    serviceSelectors:
                    - matchExpressions:
                      - {key: app.kubernetes.io/name, operator: In, values: [rke2-traefik]} # assign to rke2-traefik LB svc
                ---
                apiVersion: metallb.io/v1beta1
                kind: L2Advertisement
                metadata:
                  name: ingress-l2-adv
                  namespace: metallb-system
                spec:
                  ipAddressPools:
                    - ingress-ippool
            mode: 0644
            user:
              name: root
            group:
              name: root
    kubelet:
      extraArgs:
      - provider-id=metal3://PROVIDERID
    nodeName: "localhost.localdomain"

`Metal3MachineTemplate`オブジェクトは、以下の情報を指定します。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3MachineTemplate
metadata:
  name: single-node-cluster-controlplane
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: single-node-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/eibimage-output-telco.raw.sha256
        checksumType: sha256
        diskFormat: raw
        url: http://imagecache.local:8080/eibimage-output-telco.raw

`Metal3DataTemplate`オブジェクトは、ダウンストリームクラスターの`metaData`を指定します。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3DataTemplate
metadata:
  name: single-node-cluster-controlplane-template
  namespace: default
spec:
  clusterName: single-node-cluster
  metaData:
    objectNames:
    - key: name
      object: machine
    - key: local-hostname
      object: machine
    - key: local_hostname
      object: machine

前のブロックを結合してファイルを作成したら、新しいベアメタルホストのプロビジョニングを開始するために、管理クラスターで次のコマンドを実行する必要があります。

$ kubectl apply -f capi-provisioning-example.yaml

53 ダイレクトネットワークプロビジョニング(マルチノード)によるダウンストリームクラスターのプロビジョニング

本セクションでは、ダイレクトネットワークプロビジョニングとロードバランサ戦略として`MetalLB`を使用し、マルチノードダウンストリームクラスターのプロビジョニングを自動化するワークフローについて説明します。 これは、ダウンストリームクラスターのプロビジョニングを自動化する最も簡単な方法です。次の図は、ダイレクトネットワークプロビジョニングと`MetalLB`を使用して、マルチノードダウンストリームクラスターのプロビジョニングを自動化するワークフローを示しています。

要件

のワークフロー

次の図は、ダイレクトネットワークプロビジョニングを使用して、マルチノードダウンストリームクラスターのプロビジョニングを自動化するワークフローを示しています。

atip automate multinode1
  1. 3台のベアメタルホストを登録し、プロビジョニングプロセスで使用できるようにします。

  2. 3台のベアメタルホストをプロビジョニングし、`MetalLB`を使用してオペレーティングシステムとKubernetesクラスターをインストールおよび構成します。

ベアメタルホストを登録する

最初のステップは、3台のベアメタルホストを管理クラスターに登録し、プロビジョニングできるようにすることです。 そのためには、管理クラスターで使用する`BMC`の認証情報と、管理クラスターに登録する`BaremetalHost`オブジェクトを指定するために、以下のファイル(bmh-example-node1.yaml、bmh-example-node2.yaml、bmh-example-node3.yaml)を作成する必要があります。

注記
注記
  • `$\{…​\}`の間の値のみを実際の値に置き換える必要があります。

  • ここでは、1台のホストを対象としたプロセスについて説明します。他の2つのノードについても同様の手順が適用されます。

apiVersion: v1
kind: Secret
metadata:
  name: node1-example-credentials
type: Opaque
data:
  username: ${BMC_NODE1_USERNAME}
  password: ${BMC_NODE1_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: node1-example
  labels:
    cluster-role: control-plane
spec:
  architecture: x86_64
  online: true
  bootMACAddress: ${BMC_NODE1_MAC}
  bmc:
    address: ${BMC_NODE1_ADDRESS}
    disableCertificateVerification: true
    credentialsName: node1-example-credentials

各要素の内容は次のとおりです。

  • ${BMC_NODE1_USERNAME} — 最初のベアメタルホストのBMCのユーザー名。

  • ${BMC_NODE1_PASSWORD} — 最初のベアメタルホストのBMCのパスワード。

  • ${BMC_NODE1_MAC} — 使用する最初のベアメタルホストのMACアドレス。

  • ${BMC_NODE1_ADDRESS} — 最初のベアメタルホストのBMCのURL(例: redfish-virtualmedia://192.168.200.75/redfish/v1/Systems/1/)。URLのホスト部分は、既存のインフラストラクチャで許可されている場合、IPアドレス(v4またはv6)またはドメイン名にすることができます。ハードウェアプロバイダーに応じて利用可能なさまざまなオプションの詳細については、次の リンクを確認してください。

注記
注記
  • ホストのネットワーク構成が、イメージビルド時または`BareMetalHost`定義のいずれにおいても指定されていない場合は、自動構成メカニズム(DHCP、DHCPv6、SLAAC)が使用されます。詳細や複雑な構成については、第54章 「高度なネットワーク設定」を確認してください。

  • シングルスタックIPv6クラスターには、デュアルスタック管理クラスターが必要です。

  • アーキテクチャは、登録するベアメタルホストのアーキテクチャに応じて、`x86_64`または`aarch64`のいずれかである必要があります。

  • すべての最新サーバーにはデュアルスタック対応のBMCが搭載されていますが、デュアルスタック環境で本番稼働させる前に、IPv6のサポート(およびVirtualMedia機能にホスト名を使用するオプションの有無)を確認する必要があります。

ファイルが作成されたら、管理クラスターで次のコマンドを実行して、ベアメタルホストを管理クラスターに登録する必要があります。

$ kubectl apply -f bmh-example-node1.yaml
$ kubectl apply -f bmh-example-node2.yaml
$ kubectl apply -f bmh-example-node3.yaml

新しいベアメタルオブジェクトが登録され、状態がregisteringからinspectingおよびavailableに変更されます。変更内容は、次のコマンドを使用して確認できます。

$ kubectl get bmh -o wide
注記
注記

BaremetalHost`オブジェクトは、`BMC`資格情報が検証されるまで`registering`状態になります。資格情報が検証されると、`BaremetalHost`オブジェクトの状態は`inspecting`に変更されます。このステップは、ハードウェアによっては時間がかかる場合があります(最大20分)。インスペクションフェーズ中に、ハードウェア情報が取得され、Kubernetesオブジェクトが更新されます。次のコマンドを使用して情報を確認してください:`kubectl get bmh -o yaml。

プロビジョニングステップ

3つのベアメタルホストが登録され利用可能になったら、次のステップはベアメタルホストをプロビジョニングしてオペレーティングシステムとKubernetesクラスターをインストールおよび構成し、それらを管理するためのロードバランサーを作成することです。 そのためには、管理クラスターで次の情報を使用して次のファイル(capi-provisioning-example.yaml)を作成する必要があります(`capi-provisioning-example.yamlは、以下のブロックを結合することで生成できます)。

注記
注記
  • `$\{…​\}`の間の値のみを実際の値に置き換える必要があります。

  • `VIP`アドレスは、どのノードにも割り当てられていない予約済みIPアドレスであり、ロードバランサーの構成に使用されます。デュアルスタッククラスターではIPv4とIPv6の両方を指定できますが、以下の例ではIPv4アドレスが優先されます。

以下はクラスター定義であり、クラスターネットワークは`pods`ブロックと`services`ブロックを使用して構成できます。また、使用するコントロールプレーンとインフラストラクチャ(`Metal3`プロバイダーを使用)オブジェクトへの参照も含まれています。

apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
  name: multinode-cluster
  namespace: default
  labels:
    cluster-api.cattle.io/rancher-auto-import: "true"
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 192.168.0.0/18
        - fd00:1234:4321::/48
    services:
      cidrBlocks:
        - 10.96.0.0/12
        - fd00:5678:8765:4321::/112
  controlPlaneRef:
    apiGroup: controlplane.cluster.x-k8s.io
    kind: RKE2ControlPlane
    name: multinode-cluster
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3Cluster
    name: multinode-cluster
注記
注記
  • シングルスタックとデュアルスタックの両方のデプロイメントが可能です。IPv4のみのクラスターにする場合は、(以降のセクションで)IPv6 CIDRとIPv6 VIPアドレスを削除してください。

  • `cluster.x-k8s.io`オブジェクトにラベル`cluster-api.cattle.io/rancher-auto-import: "true"`を追加すると、クラスターがRancherにインポートされます(対応する`clusters.management.cattle.io`オブジェクトが作成されます)。 詳細については、 Cluster APIドキュメントを参照してください。

Metal3Cluster`オブジェクトは、すでに予約されている`VIP`アドレス(${EDGE_VIP_ADDRESS_IPV4}`の代わりに)を使用して構成されるコントロールプレーンエンドポイントと、3つのベアメタルノードが使用されるため`false`に設定された`cloudProviderEnabled`フラグを指定します。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3Cluster
metadata:
  name: multinode-cluster
  namespace: default
spec:
  controlPlaneEndpoint:
    host: ${EDGE_VIP_ADDRESS_IPV4}
    port: 6443
  cloudProviderEnabled: false

`RKE2ControlPlane`オブジェクトは使用するコントロールプレーン設定を指定し、`Metal3MachineTemplate`オブジェクトは使用するコントロールプレーンイメージを指定します。

  • ダウンストリームクラスターのアップグレードなどのライフサイクル操作中にノードがドレインされることを、MetalLBのような外部ロードバランサーに通知するロードバランサー除外アノテーション。詳細については、60.1項 「ロードバランサーの除外」を参照してください。

  • 使用するレプリカの数(この場合は3)。

  • ロードバランサーが使用するアドバタイズメントモード(address`はL2実装を使用)、および使用するアドレス(${EDGE_VIP_ADDRESS}`を`VIP`アドレスに置き換えます)。

  • 使用する`CNI`プラグインを備えた`serverConfig`(この場合は`Cilium`)、および`tlsSan`の下にリストされる追加の`VIP`アドレスや名前。

  • agentConfigブロックには、使用する`Ignition`形式と、次のような情報で`additionalUserData`ノードを設定するために使用する`RKE2`が含まれています。

    • Ironic情報を使用してプロビジョニングプロセス中に`PROVIDERID`と`node-name`を自動的に置き換え、BareMetalHost UUIDを持つノードオブジェクトに`metal3.io/uuid`ラベルを追加するための、`rke2-preinstall.service`という名前のsystemdサービスです。

    • MetalLB`および`endpoint-copier-operator Helmチャートをインストールするために必要なマニフェストを含む`storage`ブロック。

    • このダウンロードクラスターのAPIサーバーを、構成済みの`VIP`アドレス(`${EDGE_VIP_ADDRESS_IPV4}`を、選択した`VIP`アドレスに置き換えます)を通じて外部に公開するために使用される`IPaddressPool`および`L2Advertisement`を含む`metalLB`カスタムリソースファイル。

    • `MetalLB`によって公開される`kubernetes-vip`サービスを、構成済みの`VIP`アドレスを通じて構成するために使用される`endpoint-svc.yaml`設定ファイル。

    • RKE2`ビルトイン`rke2-traefik Helmチャートのデプロイメント構成を提供する`rke2-traefik-config.yaml`ファイル。

    • ${INGRESS_IPV4}`および${INGRESS_IPV6}`仮想IPを通じてIngressサービスを外部に公開するために必要な`MetalLB`カスタムリソース(IPAddressPool`および`L2Advertisement)インスタンスマニフェストを含む`metallb-traefik-cr.yaml`設定ファイル。

  • 情報の最後のブロックには、使用するKubernetesバージョンが含まれています。${RKE2_VERSION}`は、この値を置き換えるために使用される`RKE2`のバージョンです(例: `v1.36.3+rke2r1)。

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: multinode-cluster
  namespace: default
  annotations: {
    rke2.controlplane.cluster.x-k8s.io/load-balancer-exclusion: "true"
  }
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: multinode-cluster-controlplane
  replicas: 3
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  registrationMethod: "control-plane-endpoint"
  registrationAddress: ${EDGE_VIP_ADDRESS}
  serverConfig:
    cni: cilium
    tlsSan:
      - ${EDGE_VIP_ADDRESS_IPV4}
      - ${EDGE_VIP_ADDRESS_IPV6}
      - https://${EDGE_VIP_ADDRESS_IPV4}.sslip.io
      - https://${EDGE_VIP_ADDRESS_IPV6}.sslip.io
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
          - name: rke2-preinstall.service
            enabled: true
            contents: |
              [Unit]
              Description=rke2-preinstall
              Wants=network-online.target
              Before=rke2-install.service
              ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
              [Service]
              Type=oneshot
              User=root
              ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
              # Note we use _ as a delimiter for sed here because the providerid includes / characters
              ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStartPost=/bin/sh -c "umount /mnt"
              [Install]
              WantedBy=multi-user.target
        storage:
          directories:
          - path: /var/lib/rancher/rke2/server/manifests
            overwrite: true
          files:
            # https://docs.rke2.io/networking/multus_sriov#using-multus-with-cilium
            - path: /var/lib/rancher/rke2/server/manifests/rke2-cilium-config.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChartConfig
                  metadata:
                    name: rke2-cilium
                    namespace: kube-system
                  spec:
                    valuesContent: |-
                      cni:
                        exclusive: false
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /var/lib/rancher/rke2/server/manifests/endpoint-copier-operator.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: endpoint-copier-operator
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/endpoint-copier-operator
                    targetNamespace: endpoint-copier-operator
                    version: 307.0.1+up0.3.0
                    createNamespace: true
            - path: /var/lib/rancher/rke2/server/manifests/metallb.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: metallb
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/metallb
                    targetNamespace: metallb-system
                    version: 307.0.3+up0.16.1
                    createNamespace: true

            - path: /var/lib/rancher/rke2/server/manifests/metallb-cr.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: metallb.io/v1beta1
                  kind: IPAddressPool
                  metadata:
                    name: kubernetes-vip-ip-pool
                    namespace: metallb-system
                  spec:
                    addresses:
                      - ${EDGE_VIP_ADDRESS_IPV4}/32
                      - ${EDGE_VIP_ADDRESS_IPV6}/128
                    serviceAllocation:
                      priority: 100
                      namespaces:
                        - default
                      serviceSelectors:
                        - matchExpressions:
                          - {key: "serviceType", operator: In, values: [kubernetes-vip]}
                  ---
                  apiVersion: metallb.io/v1beta1
                  kind: L2Advertisement
                  metadata:
                    name: ip-pool-l2-adv
                    namespace: metallb-system
                  spec:
                    ipAddressPools:
                      - kubernetes-vip-ip-pool
            - path: /var/lib/rancher/rke2/server/manifests/endpoint-svc.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  kind: Service
                  metadata:
                    name: kubernetes-vip
                    namespace: default
                    labels:
                      serviceType: kubernetes-vip
                  spec:
                    ipFamilyPolicy: PreferDualStack
                    ports:
                    - name: rke2-api
                      port: 9345
                      protocol: TCP
                      targetPort: 9345
                    - name: k8s-api
                      port: 6443
                      protocol: TCP
                      targetPort: 6443
                    type: LoadBalancer
          - path: /var/lib/rancher/rke2/server/manifests/rke2-traefik-config.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: helm.cattle.io/v1
                kind: HelmChartConfig
                metadata:
                  name: rke2-traefik
                  namespace: kube-system
                spec:
                  valuesContent: |-
                    ingressClass:
                      isDefaultClass: true
                    ports:
                      web:
                        hostPort: null    # disallow hostPort
                        exposedPort: 80
                      websecure:
                        hostPort: null    # disallow hostPort
                        exposedPort: 443
                    service:
                      enabled: true
                      spec:
                        type: LoadBalancer
                        externalTrafficPolicy: Local
                        allocateLoadBalancerNodePorts: false
            mode: 0644
            user:
              name: root
            group:
              name: root
            mode: 0644
            user:
              name: root
            group:
              name: root
          - path: /var/lib/rancher/rke2/server/manifests/metallb-traefik-cr.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: metallb.io/v1beta1
                kind: IPAddressPool
                metadata:
                  name: ingress-ippool
                  namespace: metallb-system
                spec:
                  addresses:
                    - ${INGRESS_IPV4}/32
                    - ${INGRESS_IPV6}/128
                  serviceAllocation:
                    priority: 100
                    serviceSelectors:
                    - matchExpressions:
                      - {key: app.kubernetes.io/name, operator: In, values: [rke2-traefik]} # assign to rke2-traefik LB svc
                ---
                apiVersion: metallb.io/v1beta1
                kind: L2Advertisement
                metadata:
                  name: ingress-l2-adv
                  namespace: metallb-system
                spec:
                  ipAddressPools:
                    - ingress-ippool
            mode: 0644
            user:
              name: root
            group:
              name: root
    kubelet:
      extraArgs:
      - provider-id=metal3://PROVIDERID
    nodeName: "Node-multinode-cluster"

`Metal3MachineTemplate`オブジェクトは、以下の情報を指定します。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3MachineTemplate
metadata:
  name: multinode-cluster-controlplane
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: multinode-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/eibimage-output-telco.raw.sha256
        checksumType: sha256
        diskFormat: raw
        url: http://imagecache.local:8080/eibimage-output-telco.raw

`Metal3DataTemplate`オブジェクトは、ダウンストリームクラスターの`metaData`を指定します。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3DataTemplate
metadata:
  name: multinode-cluster-controlplane-template
  namespace: default
spec:
  clusterName: multinode-cluster
  metaData:
    objectNames:
    - key: name
      object: machine
    - key: local-hostname
      object: machine
    - key: local_hostname
      object: machine

以下のyamlファイルは、ワーカーノードの設定例です。

MachineDeployment:

apiVersion: cluster.x-k8s.io/v1beta2
kind: MachineDeployment
metadata:
  labels:
    cluster.x-k8s.io/cluster-name: multinode-cluster
    nodepool: nodepool-0
  name: multinode-cluster-workers
  namespace: default
spec:
  clusterName: multinode-cluster
  replicas: 3
  selector:
    matchLabels:
      cluster.x-k8s.io/cluster-name: multinode-cluster
      nodepool: nodepool-0
  template:
    metadata:
      labels:
        cluster.x-k8s.io/cluster-name: multinode-cluster
        nodepool: nodepool-0
    spec:
      bootstrap:
        configRef:
          apiGroup: bootstrap.cluster.x-k8s.io
          kind: RKE2ConfigTemplate
          name: multinode-cluster-workers
      clusterName: multinode-cluster
      infrastructureRef:
        apiGroup: infrastructure.cluster.x-k8s.io
        kind: Metal3MachineTemplate
        name: multinode-cluster-workers
      deletion:
        nodeDrainTimeoutSeconds: 0
      version: ${RKE2_VERSION}

RKE2ConfigTemplateオブジェクトは、マルチノードクラスターのワーカーノードに使用される構成テンプレートを指定します。

apiVersion: bootstrap.cluster.x-k8s.io/v1beta2
kind: RKE2ConfigTemplate
metadata:
  name: multinode-cluster-workers
  namespace: default
spec:
  template:
    spec:
      agentConfig:
        format: ignition
        kubelet:
          extraArgs:
          - provider-id=metal3://PROVIDERID
        nodeName: "Node-multinode-cluster-worker"
        additionalUserData:
          config: |
            variant: fcos
            version: 1.4.0
            systemd:
              units:
              - name: rke2-preinstall.service
                enabled: true
                contents: |
                  [Unit]
                  Description=rke2-preinstall
                  Wants=network-online.target
                  Before=rke2-install.service
                  ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                  [Service]
                  Type=oneshot
                  User=root
                  ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                  # Note we use _ as a delimiter for sed here because the providerid includes / characters
                  ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
                  ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                  ExecStartPost=/bin/sh -c "umount /mnt"
                  [Install]
                  WantedBy=multi-user.target

Metal3MachineTemplate`オブジェクトには、ワーカーノード用の`dataTemplate、hostSelector、および`image`への参照が含まれています。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3MachineTemplate
metadata:
  name: multinode-cluster-workers
  namespace: default
spec:
  template:
    spec:
      dataTemplate:
        name: multinode-cluster-workers-template
      hostSelector:
        matchLabels:
          cluster-role: worker
      image:
        checksum: http://imagecache.local:8080/eibimage-slmicro-rt-telco.raw.sha256
        checksumType: sha256
        diskFormat: raw
        url: http://imagecache.local:8080/eibimage-slmicro-rt-telco.raw

`Metal3DataTemplate`オブジェクトは、ワーカーノード用のダウンストリームクラスターの`metaData`を指定します。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3DataTemplate
metadata:
  name: multinode-cluster-workers-template
  namespace: default
spec:
  clusterName: multinode-cluster
  metaData:
    objectNames:
    - key: name
      object: machine
    - key: local-hostname
      object: machine
    - key: local_hostname
      object: machine

前のブロックを結合してファイルを作成したら、管理クラスターで次のコマンドを実行し、3つの新しいベアメタルホストのプロビジョニングを開始します。

$ kubectl apply -f capi-provisioning-example.yaml

54 高度なネットワーク設定

ダイレクトネットワークプロビジョニングワークフローにより、静的IP、ボンディング、VLAN、IPv6など、ダウンストリームクラスターでの特定のネットワーク設定が可能になります。

以下のセクションでは、高度なネットワーク設定を使用してダウンストリームクラスターのプロビジョニングを有効にするために必要な追加手順について説明します。

要件

設定

先に進む前に、ホストの登録とプロビジョニングに必要な手順のガイダンスについて、以下のいずれかのセクションを参照してください。

高度なネットワーク設定は、`BareMetalHost`ホスト定義と、`nmstate`形式の`networkData`ブロックを含む関連付けられたシークレットを通じて、登録時に適用する必要があります。次の例のファイルは、ダウンストリームクラスターホストの静的`IP`および`VLAN`を要求する必要な`networkData`を含むシークレットを定義しています。

apiVersion: v1
kind: Secret
metadata:
  name: controlplane-0-networkdata
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: ${CONTROLPLANE_INTERFACE}
      type: ethernet
      state: up
      mtu: 1500
      identifier: mac-address
      mac-address: "${CONTROLPLANE_MAC}"
      ipv4:
        address:
        - ip:  "${CONTROLPLANE_IP}"
          prefix-length: "${CONTROLPLANE_PREFIX}"
        enabled: true
        dhcp: false
    - name: floating
      type: vlan
      state: up
      vlan:
        base-iface: ${CONTROLPLANE_INTERFACE}
        id: ${VLAN_ID}
    dns-resolver:
      config:
        server:
        - "${DNS_SERVER}"
    routes:
      config:
      - destination: 0.0.0.0/0
        next-hop-address: "${CONTROLPLANE_GATEWAY}"
        next-hop-interface: ${CONTROLPLANE_INTERFACE}

ご覧のとおり、この例では、インフラストラクチャに応じて以下の変数を実際の値に置き換えた後、静的IPでインターフェイスを有効にする設定と、ベースインターフェイスを使用してVLANを有効にする設定を示しています。

  • ${CONTROLPLANE_INTERFACE} — ダウンストリームクラスターに使用するコントロールプレーンインターフェイス(例: eth0)。`identifier: mac-address`を含め、命名はMACアドレスによって自動的に検査されるため、任意のインターフェイス名を使用できます。

  • ${CONTROLPLANE_IP} — ダウンストリームクラスターのエンドポイントとして使用するIPアドレス(kubeapi-serverエンドポイントと一致する必要があります)。

  • ${CONTROLPLANE_PREFIX} — ダウンストリームクラスターに使用するCIDR(例: /24`または`255.255.255.0`が必要な場合は`24)。

  • ${CONTROLPLANE_GATEWAY} — ダウンストリームクラスターに使用するゲートウェイ(例: 192.168.100.1)。

  • ${CONTROLPLANE_MAC} — コントロールプレーンインターフェイスに使用するMACアドレス(例: 00:0c:29:3e:3e:3e)。

  • ${DNS_SERVER} — ダウンストリームクラスターに使用するDNS(例: 192.168.100.2)。

  • ${VLAN_ID} — ダウンストリームクラスターに使用するVLAN ID(例: 100)。

特定の要件に合わせてダウンストリームクラスターのネットワークを構成するために、他の`nmstate`準拠の定義を使用することもできます。例えば、静的デュアルスタック構成を指定することも可能です。

apiVersion: v1
kind: Secret
metadata:
  name: controlplane-0-networkdata
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: ${CONTROLPLANE_INTERFACE}
      type: ethernet
      state: up
      mac-address: ${CONTROLPLANE_MAC}
      ipv4:
        enabled: true
        dhcp: false
        address:
        - ip: ${CONTROLPLANE_IP_V4}
          prefix-length: ${CONTROLPLANE_PREFIX_V4}
      ipv6:
        enabled: true
        dhcp: false
        autoconf: false
        address:
        - ip: ${CONTROLPLANE_IP_V6}
          prefix-length: ${CONTROLPLANE_PREFIX_V6}
    routes:
      config:
      - destination: 0.0.0.0/0
        next-hop-address: ${CONTROLPLANE_GATEWAY_V4}
        next-hop-interface: ${CONTROLPLANE_INTERFACE}
      - destination: ::/0
        next-hop-address: ${CONTROLPLANE_GATEWAY_V6}
        next-hop-interface: ${CONTROLPLANE_INTERFACE}
    dns-resolver:
      config:
        server:
        - ${DNS_SERVER_V4}
        - ${DNS_SERVER_V6}

前の例と同様に、インフラストラクチャに合わせて以下の変数を実際の値に置き換えてください。

  • ${CONTROLPLANE_IP_V4} - ホストに割り当てるIPv4アドレス

  • ${CONTROLPLANE_PREFIX_V4} - ホストIPが属するネットワークのIPv4プレフィックス

  • ${CONTROLPLANE_IP_V6} - ホストに割り当てるIPv6アドレス

  • ${CONTROLPLANE_PREFIX_V6} - ホストIPが属するネットワークのIPv6プレフィックス

  • ${CONTROLPLANE_GATEWAY_V4} - デフォルトルートに一致するトラフィックのゲートウェイのIPv4アドレス

  • ${CONTROLPLANE_GATEWAY_V6} - デフォルトルートに一致するトラフィックのゲートウェイのIPv6アドレス

  • ${CONTROLPLANE_INTERFACE} - アドレスを割り当て、IPv4およびIPv6の両方でデフォルトルートに一致するエグレストラフィックに使用するインターフェイス名

  • ${DNS_SERVER_V4}`または${DNS_SERVER_V6}` - 使用するDNSサーバーのIPアドレス(単一または複数のエントリとして指定できます)。IPv4およびIPv6の両方のアドレスがサポートされます。

注記
注記
  • IPv6のみやデュアルスタック構成など、より複雑な例については、 SUSE Telco Cloud examples repoを参照してください。

  • シングルスタックIPv6デプロイメントは技術プレビュー段階であり、正式にはまだサポートされていません。

最後に、ネットワーク構成の詳細に関わらず、ホストを管理クラスターに正常に登録するには、`preprovisioningNetworkDataName`を`BaremetalHost`オブジェクトに追加してシークレットが参照されるようにしてください。

apiVersion: v1
kind: Secret
metadata:
  name: example-demo-credentials
type: Opaque
data:
  username: ${BMC_USERNAME}
  password: ${BMC_PASSWORD}
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: example-demo
  labels:
    cluster-role: control-plane
spec:
  architecture: x86_64
  online: true
  bootMACAddress: ${BMC_MAC}
  rootDeviceHints:
    deviceName: /dev/nvme0n1
  bmc:
    address: ${BMC_ADDRESS}
    disableCertificateVerification: true
    credentialsName: example-demo-credentials
  preprovisioningNetworkDataName: controlplane-0-networkdata
注記
注記
  • マルチノードクラスターをデプロイする必要がある場合は、各ノードに対して同じプロセスを実行する必要があります。

  • Metal3DataTemplate、networkData、および`Metal3 IPAM`は現在サポートされていません。静的シークレットによる構成のみが完全にサポートされています。

  • アーキテクチャは、登録するベアメタルホストのアーキテクチャに応じて、`x86_64`または`aarch64`のいずれかである必要があります。

55 Telco機能 (DPDK、SR-IOV、CPUアイソレーション、huge pages、NUMAなど)

ダイレクトネットワークプロビジョニングワークフローにより、ダウンストリームクラスターで使用されるTelco機能を自動化し、それらのサーバー上でTelcoワークロードを実行できるようになります。

要件

設定

ホストの登録およびプロビジョニングの基礎として、以下の2つのセクションを使用してください。

本セクションで扱うTelco機能は以下の通りです。

  • DPDKおよびVFの作成

  • SR-IOVおよびワークロードで使用するVFの割り当て

  • CPUの分離およびパフォーマンスチューニング

  • Huge pagesの設定

  • カーネルパラメータのチューニング

注記
注記

Telco機能の詳細については、パートVI「Telco機能の設定」を参照してください。

上記で示したTelco機能を有効にするために必要な変更は、すべてプロビジョニングファイル`capi-provisioning-example.yaml`内の`RKE2ControlPlane`ブロックに含まれています。ファイル`capi-provisioning-example.yaml`内のその他の情報は、プロビジョニングセクション (第52章 「ダイレクトネットワークプロビジョニング(シングルノード)によるダウンストリームクラスターのプロビジョニング」)で提供されている情報と同じです。

プロセスを明確にするため、Telco機能を有効にするためにそのブロック(RKE2ControlPlane)で必要な変更は以下の通りです。

  • インターフェース、ドライバー、およびワークロードに対して作成・公開する`VFs`の数を定義するために使用するイグニッションファイル`/var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml`。

    • 設定マップ sriov-custom-auto-config 内の値のみが、実際の値に置き換えられます。

      • ${RESOURCE_NAME1} — 最初の PF インターフェースに使用されるリソース名(例:sriov-resource-du1)。これはプレフィックス rancher.io に追加され、ワークロードで使用されるラベルとして使用されます(例:rancher.io/sriov-resource-du1)。

      • ${SRIOV-NIC-NAME1} — 使用する最初の PF インターフェースの名前(例:eth0)。

      • ${PF_NAME1} — 使用する最初の物理機能 PF の名前。これを使用して、より複雑なフィルターを生成します(例:eth0#2-5)。

      • ${DRIVER_NAME1} — 最初の VF インターフェースに使用されるドライバー名(例:vfio-pci)。

      • ${NUM_VFS1} — 最初の PF インターフェースに対して作成される VFs の数(例:8)。

  • /var/sriov-auto-filler.sh は、高レベルの設定マップ sriov-custom-auto-config と、低レベルのハードウェア情報を含む sriovnetworknodepolicy との間の変換器として使用されます。このスクリプトは、ユーザーが事前にハードウェア情報を把握する必要がないように、その複雑さを抽象化するために作成されました。このファイルに変更を加える必要はありませんが、sr-iov を有効にして VFs を作成する必要がある場合は、このファイルが存在している必要があります。

  • 以下の機能を有効にするために使用されるカーネル引数:

パラメータ

値

説明

isolcpus

domain,nohz,managed_irq,1-30,33-62

コア 1-30 および 33-62 を分離します。

skew_tick

1

カーネルが分離された CPU 間でタイマー割り込みを分散させることを可能にします。

nohz

on

システムがアイドル状態のときに、カーネルが単一の CPU 上でタイマーティックを実行できるようにします。

nohz_full

1-30,33-62

カーネルブートパラメータは、CPU 分離とともにフル dynticks を構成するための現在の主要なインターフェースです。

rcu_nocbs

1-30,33-62

システムがアイドル状態のときに、カーネルが単一の CPU 上で RCU コールバックを実行できるようにします。

irqaffinity

0,31,32,63

システムがアイドル状態のときに、カーネルが単一の CPU で割り込みを実行できるようにします。

アイドル

poll

アイドル状態から抜ける際のレイテンシを最小限に抑えます。

iommu

pt

dpdkインターフェースにvfioを使用できるようにします。

intel_iommu

on

VFに対してvfioの使用を有効にします。

hugepagesz

1G

「ヒュージページ」のサイズを1 GBに設定できるようにします。

ヒュージページ

40

直前に定義されたサイズ(1 GB)に対して割り当てるよう要求された「ヒュージページ」の数。

hugepagesz

2M

「ヒュージページ」のサイズを2 MBに設定できるようにします。

ヒュージページ

0

直前に定義されたサイズ(2 MB)に対して割り当てるよう要求された「ヒュージページ」の数。

default_hugepagesz

1G

「ヒュージページ」サイズのデフォルト値。

nowatchdog

 

ウォッチドッグを無効にします。

nmi_watchdog

0

NMIウォッチドッグを無効にします。

  • 以下のsystemdサービスを使用して、以下を有効にします。

    • Ironic情報を使用してプロビジョニング処理中に PROVIDERID と node-name を自動的に置き換えるための rke2-preinstall.service。

    • cpu-partitioning.service は、CPU の分離コアを有効にするために使用されます(例:1-30,33-62)。

    • performance-settings.service は、CPUパフォーマンスチューニングを有効にするために使用されます。

    • sriov-custom-auto-vfs.service を実行して sriov Helmチャートをインストールし、カスタムリソースが作成されるまで待機した後、/var/sriov-auto-filler.sh を実行して設定マップ sriov-custom-auto-config の値を置き換え、ワークロードで使用する sriovnetworknodepolicy を作成します。

  • ${RKE2_VERSION}`は、この値を置き換えるために使用する`RKE2`のバージョンです(例: `v1.36.3+rke2r1)。

前述のすべての変更を行うと、capi-provisioning-example.yaml 内の RKE2ControlPlane ブロックは次のようになります。

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  serverConfig:
    cni: calico
    cniMultusEnable: true
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        storage:
          files:
          - path: /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: v1
                kind: ConfigMap
                metadata:
                  name: sriov-custom-auto-config
                  namespace: kube-system
                data:
                  config.json: |
                    [
                        {
                          "resourceName": "${RESOURCE_NAME1}",
                          "interface": "${SRIOV-NIC-NAME1}",
                          "pfname": "${PF_NAME1}",
                          "driver": "${DRIVER_NAME1}",
                          "numVFsToCreate": ${NUM_VFS1}
                        },
                        {
                          "resourceName": "${RESOURCE_NAME2}",
                          "interface": "${SRIOV-NIC-NAME2}",
                          "pfname": "${PF_NAME2}",
                          "driver": "${DRIVER_NAME2}",
                          "numVFsToCreate": ${NUM_VFS2}
                        }
                    ]
            mode: 0644
            user:
              name: root
            group:
              name: root
          - path: /var/lib/rancher/rke2/server/manifests/sriov-crd.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: helm.cattle.io/v1
                kind: HelmChart
                metadata:
                  name: sriov-crd
                  namespace: kube-system
                spec:
                  chart: oci://registry.suse.com/edge/charts/sriov-crd
                  targetNamespace: sriov-network-operator
                  version: 307.1.0+up1.6.0
                  createNamespace: true
          - path: /var/lib/rancher/rke2/server/manifests/sriov-network-operator.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: helm.cattle.io/v1
                kind: HelmChart
                metadata:
                  name: sriov-network-operator
                  namespace: kube-system
                spec:
                  chart: oci://registry.suse.com/edge/charts/sriov-network-operator
                  targetNamespace: sriov-network-operator
                  version: 307.1.0+up1.6.0
                  createNamespace: true
        kernel_arguments:
          should_exist:
            - intel_iommu=on
            - iommu=pt
            - idle=poll
            - mce=off
            - hugepagesz=1G hugepages=40
            - hugepagesz=2M hugepages=0
            - default_hugepagesz=1G
            - irqaffinity=${NON-ISOLATED_CPU_CORES}
            - isolcpus=domain,nohz,managed_irq,${ISOLATED_CPU_CORES}
            - nohz_full=${ISOLATED_CPU_CORES}
            - rcu_nocbs=${ISOLATED_CPU_CORES}
            - rcu_nocb_poll
            - nosoftlockup
            - nowatchdog
            - nohz=on
            - nmi_watchdog=0
            - skew_tick=1
            - quiet
        systemd:
          units:
          - name: rke2-preinstall.service
            enabled: true
            contents: |
              [Unit]
              Description=rke2-preinstall
              Wants=network-online.target
              Before=rke2-install.service
              ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
              [Service]
              Type=oneshot
              User=root
              ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
              # Note we use _ as a delimiter for sed here because the providerid includes / characters
              ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStartPost=/bin/sh -c "umount /mnt"
              [Install]
              WantedBy=multi-user.target
          - name: cpu-partitioning.service
            enabled: true
            contents: |
              [Unit]
              Description=cpu-partitioning
              Wants=network-online.target
              After=network.target network-online.target
              [Service]
              Type=oneshot
              User=root
              ExecStart=/bin/sh -c "echo isolated_cores=${ISOLATED_CPU_CORES} > /etc/tuned/cpu-partitioning-variables.conf"
              ExecStartPost=/bin/sh -c "tuned-adm profile cpu-partitioning"
              ExecStartPost=/bin/sh -c "systemctl enable tuned.service"
              [Install]
              WantedBy=multi-user.target
          - name: performance-settings.service
            enabled: true
            contents: |
              [Unit]
              Description=performance-settings
              Wants=network-online.target
              After=network.target network-online.target cpu-partitioning.service
              [Service]
              Type=oneshot
              User=root
              ExecStart=/bin/sh -c "/opt/performance-settings/performance-settings.sh"
              [Install]
              WantedBy=multi-user.target
          - name: sriov-custom-auto-vfs.service
            enabled: true
            contents: |
              [Unit]
              Description=SRIOV Custom Auto VF Creation
              Wants=network-online.target  rke2-server.target
              After=network.target network-online.target rke2-server.target
              [Service]
              User=root
              Type=forking
              TimeoutStartSec=900
              ExecStart=/bin/sh -c "while ! /var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml wait --for condition=ready nodes --all ; do sleep 2 ; done"
              ExecStartPost=/bin/sh -c "while [ $(/var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml get sriovnetworknodestates.sriovnetwork.openshift.io --ignore-not-found --no-headers -A | wc -l) -eq 0 ]; do sleep 1; done"
              ExecStartPost=/bin/sh -c "/opt/sriov/sriov-auto-filler.sh"
              RemainAfterExit=yes
              KillMode=process
              [Install]
              WantedBy=multi-user.target
    kubelet:
      extraArgs:
      - provider-id=metal3://PROVIDERID
    nodeName: "localhost.localdomain"

前のブロックを結合してファイルを作成したら、管理クラスターで次のコマンドを実行し、Telco機能を使用して新しいダウンストリームクラスターのプロビジョニングを開始する必要があります。

$ kubectl apply -f capi-provisioning-example.yaml

55.1 高精度時刻同期プロトコル (PTP)

PTP同期は、EIBイメージでデーモンを有効にすることと、Cluster APIを介して設定ファイルをデプロイすることの2つのステップで、プロビジョニング時に有効になります。ターゲットプラットフォームに応じて、2つのプロビジョニングモデルが文書化されています。

55.1.1 標準シナリオ(単一のptp4l + phc2sys)

これらのPTPシナリオ間では設定ファイルのみが変更されるため、このセクションでは、単一の汎用テンプレートと、それに続く各シナリオの具体的な値を提供します。

EIBイメージでデーモンを有効にする

`linuxptp`パッケージは、すでにTelcoパッケージリストに含まれています(Telcoワークロードの追加設定 (50.2.5項 「通信ワークロードの追加構成」)を参照してください)。ただし、`ptp4l`および`phc2sys`デーモンはデフォルトでは有効になっていないため、同じEIBイメージ定義ファイルの`systemd.enable`リストに追加する必要があります。

operatingSystem:
  systemd:
    enable:
      - ptp4l
      - phc2sys
  packages:
    packageList:
      - linuxptp      # already present in the Telco package list
    sccRegistrationCode: $SCC_REGISTRATION_CODE

イメージビルド時にデーモンを有効にすると、設定ファイルがホスト上に存在すれば、両方のサービスが自動的に開始されます。

Cluster APIを介して設定ファイルをデプロイする

PTP設定は、変更された`RKE2ControlPlane`オブジェクトを介してデプロイされます。このオブジェクトは、ptp4l`プロファイルファイルと、`ptp4l`および`phc2sys`デーモンを制御する2つの/etc/sysconfig`ファイルを書き込みます。オブジェクトの残りの部分はプロビジョニングセクション (第52章 「ダイレクトネットワークプロビジョニング(シングルノード)によるダウンストリームクラスターのプロビジョニング」)で説明されているものと同じです。他のCluster APIオブジェクトで補完し、選択したシナリオの値でプレースホルダーを置き換えてください。

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  registrationMethod: "control-plane-endpoint"
  serverConfig:
    cni: canal
  agentConfig:
    format: ignition
    cisProfile: cis
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                # Note we use _ as a delimiter for sed here because the providerid includes / characters
                ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
        storage:
          files:
            - path: ${PTP4L_CONF_PATH}
              overwrite: true
              contents:
                inline: |
                  ## Replace ${PTP4L_CONF_CONTENTS} with the ptp4l configuration content of the PTP scenario to deploy
                  ${PTP4L_CONF_CONTENTS}
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /etc/sysconfig/ptp4l
              overwrite: true
              contents:
                inline: |
                  ## Path:           Network/LinuxPTP
                  ## Description:    Precision Time Protocol (PTP): ptp4l settings
                  ## Replace ${PTP4L_OPTIONS} with the ptp4l OPTIONS value of the PTP scenario to deploy
                  OPTIONS="${PTP4L_OPTIONS}"
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /etc/sysconfig/phc2sys
              overwrite: true
              contents:
                inline: |
                  ## Path:           Network/LinuxPTP
                  ## Description:    Precision Time Protocol (PTP): phc2sys settings
                  ## Replace ${PHC2SYS_OPTIONS} with the phc2sys OPTIONS value of the PTP scenario to deploy
                  OPTIONS="${PHC2SYS_OPTIONS}"
              mode: 0644
              user:
                name: root
              group:
                name: root
    kubelet:
      extraArgs:
        - provider-id=metal3://PROVIDERID
    nodeName: "localhost.localdomain"

プレースホルダーは各シナリオによって提供されます。

Placeholder説明

${PTP4L_CONF_PATH}

ptp4l`プロファイルファイルのパス(例:/etc/ptp4l-G.8275.1.conf`)。

${PTP4L_CONF_CONTENTS}

選択したシナリオから取得した、その`ptp4l`ファイルの内容。

${PTP4L_OPTIONS}

`/etc/sysconfig/ptp4l`内の`OPTIONS=`行の値。

${PHC2SYS_OPTIONS}

`/etc/sysconfig/phc2sys`内の`OPTIONS=`行の値。

各ケースで代入する具体的な値については、PTPドキュメントのPTPシナリオ (47.1項 「概要」)にある対応するシナリオの*CAPI自動化*を参照してください。

注記
注記

このアプローチは、クラスター内のハードウェアが均一であり、インターフェイス名を含めてすべてのホストで同じPTP設定が必要な場合にのみ便利です。`ts2phc`またはオンボードDPLLルーティングに依存する境界クロックシナリオでは、基本例に加えて追加のファイルとサービスが必要であり、これらについては次のセクションで説明します。

55.1.2 GNR-DマルチNICシナリオ(DPLL)

GNR-D境界クロック(シナリオ3a (47.7項 「シナリオ3a - 境界クロック(PTPのみ)マルチNIC構成(内部タイミングモジュール付き、DPLL GNR-Dベース)」))は、単一の`ptp4l`プロファイルでは記述できません。PHCごとに1つの`ptp4l`インスタンスを実行し、アドインカードを`ts2phc`と調整し、起動時にオンボードDPLLを配線し、グランドマスターパラメーターを定期的に転送します。したがって、プロビジョニングは、同じ`RKE2ControlPlane` Ignitionブロックを通じてデプロイされるいくつかの設定ファイル、スクリプト、および`systemd`ユニットで基本例を拡張します。すべてのファイルとユニットの内容は、シナリオ3a (47.7項 「シナリオ3a - 境界クロック(PTPのみ)マルチNIC構成(内部タイミングモジュール付き、DPLL GNR-Dベース)」)にリストされているものです。

重要
重要

このSUSE Telco Cloudリリースでは、このシナリオは「デフォルト」(つまり、「PREEMPT_RT」ではない)カーネルフレーバーに対してのみサポートされています。 「RT」カーネルフレーバーのサポートは、次のリリースで追加される予定です。

EIBイメージでデーモンを有効にする

GNR-Dユニットには、DPLLサービス、PHCごとに1つのテンプレート化された`ptp4l`インスタンス、およびグランドマスター転送タイマーというカスタムセットアップが必要です。その結果、EIB systemd.enable`リストを使用する代わりに、以下のIgnitionブロックを介してそれらをデプロイおよび有効化する必要があります。EIBイメージには`linuxptp`パッケージのみが必要であり、これによって`ptp4l、ts2phc、および`pmc`バイナリが提供されます。

operatingSystem:
  packages:
    packageList:
      - linuxptp      # already present in the Telco package list
    sccRegistrationCode: $SCC_REGISTRATION_CODE

Cluster APIを介してファイルとユニットをデプロイする

以下の`RKE2ControlPlane`オブジェクトは、GNR-Dファイルとユニットをデプロイします。これは標準例と同じアプローチに従っています。ファイルの内容はプレースホルダーとして提供され、シナリオ4 (47.7項 「シナリオ3a - 境界クロック(PTPのみ)マルチNIC構成(内部タイミングモジュール付き、DPLL GNR-Dベース)」)から取得されます。一方、`systemd`ユニット(このシナリオでは固定)はインラインで表示されます。標準的な例のように他のCluster APIオブジェクトで完成させ、プレースホルダーをシナリオの値に置き換えてください。

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  registrationMethod: "control-plane-endpoint"
  serverConfig:
    cni: canal
  agentConfig:
    format: ignition
    cisProfile: cis
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
            - name: rke2-preinstall.service
              enabled: true
              contents: |
                [Unit]
                Description=rke2-preinstall
                Wants=network-online.target
                Before=rke2-install.service
                ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                [Service]
                Type=oneshot
                User=root
                ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                # Note we use _ as a delimiter for sed here because the providerid includes / characters
                ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
                ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                ExecStartPost=/bin/sh -c "umount /mnt"
                [Install]
                WantedBy=multi-user.target
            - name: gnrd-ptp-dpll-setup.service
              enabled: true
              contents: |
                [Unit]
                Description=GNR-D PTP DPLL and internal signal setup
                Before=ts2phc.service ptp4l@nac.service ptp4l@aic1.service ptp4l@aic2.service
                [Service]
                Type=oneshot
                RemainAfterExit=yes
                ExecStart=/usr/local/bin/01-gnrd-startup-setup.sh
                [Install]
                WantedBy=multi-user.target
            - name: ptp4l@.service
              contents: |
                [Unit]
                Description=PTP Boundary Clock instance %i
                After=gnrd-ptp-dpll-setup.service
                Requires=gnrd-ptp-dpll-setup.service
                [Service]
                ExecStart=/usr/sbin/ptp4l -f /etc/ptp4l-%i.conf
                [Install]
                WantedBy=multi-user.target
            - name: ptp4l@nac.service
              enabled: true
            - name: ptp4l@aic1.service
              enabled: true
            - name: ptp4l@aic2.service
              enabled: true
            - name: ts2phc.service
              enabled: true
            - name: ptp-forward-gm.service
              contents: |
                [Unit]
                Description=Forward Grandmaster parameters to the add-in ptp4l instances
                Wants=ptp4l@nac.service ptp4l@aic1.service ptp4l@aic2.service
                After=ptp4l@nac.service ptp4l@aic1.service ptp4l@aic2.service
                [Service]
                Type=oneshot
                SELinuxContext=system_u:system_r:unconfined_t:s0
                ExecStart=/usr/local/bin/04-ptp-forward-GM.sh
            - name: ptp-forward-gm.timer
              enabled: true
              contents: |
                [Unit]
                Description=Refresh forwarded Grandmaster parameters
                [Timer]
                OnBootSec=2min
                OnUnitActiveSec=5min
                [Install]
                WantedBy=timers.target
        storage:
          files:
            - path: /usr/local/bin/01-gnrd-startup-setup.sh
              mode: 0755
              overwrite: true
              contents:
                inline: |
                  ${GNRD_DPLL_SETUP_CONTENTS}
            - path: /usr/local/bin/04-ptp-forward-GM.sh
              mode: 0755
              overwrite: true
              contents:
                inline: |
                  ${GNRD_FORWARD_GM_CONTENTS}
            - path: /etc/ts2phc-cf-all.cfg
              mode: 0644
              overwrite: true
              contents:
                inline: |
                  ${TS2PHC_CONF_CONTENTS}
            - path: /etc/sysconfig/ts2phc
              mode: 0644
              overwrite: true
              contents:
                inline: |
                  OPTIONS="${TS2PHC_OPTIONS}"
            - path: /etc/ptp4l-nac.conf
              mode: 0644
              overwrite: true
              contents:
                inline: |
                  ${PTP4L_NAC_CONTENTS}
            - path: /etc/ptp4l-aic1.conf
              mode: 0644
              overwrite: true
              contents:
                inline: |
                  ${PTP4L_AIC1_CONTENTS}
            - path: /etc/ptp4l-aic2.conf
              mode: 0644
              overwrite: true
              contents:
                inline: |
                  ${PTP4L_AIC2_CONTENTS}
    kubelet:
      extraArgs:
        - provider-id=metal3://PROVIDERID
    nodeName: "localhost.localdomain"

プレースホルダーはGNR-Dシナリオによって提供されます。

Placeholder説明

${GNRD_DPLL_SETUP_CONTENTS}

DPLLブート時セットアップスクリプト(01-gnrd-startup-setup.sh)の内容。

${GNRD_FORWARD_GM_CONTENTS}

グランドマスター転送スクリプト(04-ptp-forward-GM.sh)の内容。

${TS2PHC_CONF_CONTENTS}

ts2phc`環境設定ファイル(/etc/ts2phc-cf-all.cfg`)の内容。

${TS2PHC_OPTIONS}

OPTIONS=`内の/etc/sysconfig/ts2phc`行の値。

${PTP4L_NAC_CONTENTS}

統合コントローラー`ptp4l`ファイル(/etc/ptp4l-nac.conf)の内容。

${PTP4L_AIC1_CONTENTS}

アドインカード 1 ptp4l`ファイル(/etc/ptp4l-aic1.conf`)の内容。

${PTP4L_AIC2_CONTENTS}

アドインカード 2 ptp4l`ファイル(/etc/ptp4l-aic2.conf`)の内容。

代入する具体的な値については、CAPI automation の Scenario 4 (47.7項 「シナリオ3a - 境界クロック(PTPのみ)マルチNIC構成(内部タイミングモジュール付き、DPLL GNR-Dベース)」) を参照してください。

注記
注記

ptp4l@.service テンプレートは enabled なしでデプロイされます。インスタンスは ptp4l@nac、ptp4l@aic1、および ptp4l@aic2 を有効にすることで作成されます。ptp-forward-gm.service はタイマーによってトリガーされるため、タイマーのみが有効になります。ts2phc.service は linuxptp パッケージによって出荷され、/etc/sysconfig/ts2phc を読み取ります。ブート順序は Before= の gnrd-ptp-dpll-setup.service ディレクティブによって強制されます。デバイス名 (eno8703np0、ptp<N>、eno16495np0、eno16595np0) とアドインカードの数をターゲットハードウェアに合わせて調整してください。

56 プライベートレジストリ

ワークロードで使用されるイメージのミラーとしてプライベートレジストリを構成できます。

これを行うには、ダウンストリームクラスターで使用するプライベートレジストリに関する情報を含むシークレットを作成します。

apiVersion: v1
kind: Secret
metadata:
  name: private-registry-cert
  namespace: default
data:
  tls.crt: ${TLS_CERTIFICATE}
  tls.key: ${TLS_KEY}
  ca.crt: ${CA_CERTIFICATE}
type: kubernetes.io/tls
---
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-auth
  namespace: default
data:
  username: ${REGISTRY_USERNAME}
  password: ${REGISTRY_PASSWORD}

tls.crt、tls.key、および ca.crt は、プライベートレジストリの認証に使用される証明書です。username および password は、プライベートレジストリの認証に使用される資格情報です。

注記
注記

tls.crt、tls.key、ca.crt、username、および password は、シークレットで使用する前に base64 形式でエンコードする必要があります。

前述のすべての変更を行うと、capi-provisioning-example.yaml 内の RKE2ControlPlane ブロックは次のようになります。

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  privateRegistriesConfig:
    mirrors:
      "registry.example.com":
        endpoint:
          - "https://registry.example.com:5000"
    configs:
      "registry.example.com":
        authSecret:
          apiVersion: v1
          kind: Secret
          namespace: default
          name: private-registry-auth
        tls:
          tlsConfigSecret:
            apiVersion: v1
            kind: Secret
            namespace: default
            name: private-registry-cert
  serverConfig:
    cni: calico
    cniMultusEnable: true
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
          - name: rke2-preinstall.service
            enabled: true
            contents: |
              [Unit]
              Description=rke2-preinstall
              Wants=network-online.target
              Before=rke2-install.service
              ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
              [Service]
              Type=oneshot
              User=root
              ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
              # Note we use _ as a delimiter for sed here because the providerid includes / characters
              ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStartPost=/bin/sh -c "umount /mnt"
              [Install]
              WantedBy=multi-user.target
    kubelet:
      extraArgs:
      - provider-id=metal3://PROVIDERID
    nodeName: "localhost.localdomain"

registry.example.com はダウンストリームクラスターで使用するプライベートレジストリの例名であり、実際の値に置き換える必要があります。

57 エアギャップ環境でのダウンストリームクラスターのプロビジョニング

ダイレクトネットワークプロビジョニングワークフローを使用すると、エアギャップ環境でのダウンストリームクラスターのプロビジョニングを自動化できます。

57.1 エアギャップ環境の要件

  1. EIB を使用して生成された raw イメージには、エアギャップ環境でダウンストリームクラスターを実行するために必要な特定のコンテナイメージ(HelmチャートOCIおよびコンテナイメージ)が含まれている必要があります。詳細については、「このセクション (第51章 「エアギャップシナリオ用のダウンストリームクラスターイメージの準備」)」を参照してください。

  2. SR-IOV またはその他のカスタムワークロードを使用する場合、ワークロードの実行に必要なイメージを、「プライベートレジストリのプリロードセクション (51.2.7項 「エアギャップアーティファクトの準備」)」に従ってプライベートレジストリにプリロードしておく必要があります。

57.2 エアギャップ環境でのベアメタルホストの登録

管理クラスターにベアメタルホストを登録するプロセスは、「前のセクション (第52章 「ダイレクトネットワークプロビジョニング(シングルノード)によるダウンストリームクラスターのプロビジョニング」)」で説明したものと同じです。

57.3 エアギャップ環境でのダウンストリームクラスターのプロビジョニング

エアギャップ環境でダウンストリームクラスターをプロビジョニングするには、いくつかの重要な変更が必要です。

  1. `capi-provisioning-example.yaml`ファイルの`RKE2ControlPlane`ブロックには、`spec.agentConfig.airGapped: true`ディレクティブを含める必要があります。

  2. プライベートレジストリの設定は、プライベートレジストリのセクション (第56章 「プライベートレジストリ」)に続いて、`capi-provisioning-airgap-example.yaml`ファイルの`RKE2ControlPlane`ブロックに含める必要があります。

  3. SR-IOVまたはhelm-chartのインストールを必要とするその他の`AdditionalUserData`設定(combustionスクリプト)を使用している場合は、パブリックレジストリを使用する代わりに、プライベートレジストリを参照するように内容を変更する必要があります。

次の例は、プライベートレジストリを参照するために必要な変更を加えた、`capi-provisioning-airgap-example.yaml`ファイルの`AdditionalUserData`ブロックにおけるSR-IOVの設定を示しています。

  • プライベートレジストリのシークレット参照

  • パブリックOCIイメージの代わりにプライベートレジストリを使用するHelm-Chartの定義。

# secret to include the private registry certificates
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-cert
  namespace: default
data:
  tls.crt: ${TLS_BASE64_CERT}
  tls.key: ${TLS_BASE64_KEY}
  ca.crt: ${CA_BASE64_CERT}
type: kubernetes.io/tls
---
# secret to include the private registry auth credentials
apiVersion: v1
kind: Secret
metadata:
  name: private-registry-auth
  namespace: default
data:
  username: ${REGISTRY_USERNAME}
  password: ${REGISTRY_PASSWORD}
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: single-node-cluster
  namespace: default
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: single-node-cluster-controlplane
  replicas: 1
  version: ${RKE2_VERSION}
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  privateRegistriesConfig:       # Private registry configuration to add your own mirror and credentials
    mirrors:
      docker.io:
        endpoint:
          - "${PRIVATE_REGISTRY_URL}"
        rewrite:
          "^(.*)$": "mirror/$1"
      registry.suse.com:
        endpoint:
          - "${PRIVATE_REGISTRY_URL}"
        rewrite:
          "^(.*)$": "mirror/$1"
      registry.suse.de:
        endpoint:
          - "${PRIVATE_REGISTRY_URL}"
        rewrite:
          "^(.*)$": "mirror/$1"
      registry.opensuse.org:
        endpoint:
          - "${PRIVATE_REGISTRY_URL}"
        rewrite:
          "^(.*)$": "mirror/$1"
      registry.rancher.com:
        endpoint:
          - "${PRIVATE_REGISTRY_URL}"
        rewrite:
          "^(.*)$": "mirror/$1"
    configs:
      "192.168.100.22:5000":
        authSecret:
          apiVersion: v1
          kind: Secret
          namespace: default
          name: private-registry-auth
        tls:
          tlsConfigSecret:
            apiVersion: v1
            kind: Secret
            namespace: default
            name: private-registry-cert
          insecureSkipVerify: false
  serverConfig:
    cni: calico
    cniMultusEnable: true
  agentConfig:
    airGapped: true       # Airgap true to enable airgap mode
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        storage:
          files:
          - path: /var/lib/rancher/rke2/server/manifests/configmap-sriov-custom-auto.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: v1
                kind: ConfigMap
                metadata:
                  name: sriov-custom-auto-config
                  namespace: sriov-network-operator
                data:
                  config.json: |
                    [
                        {
                          "resourceName": "${RESOURCE_NAME1}",
                          "interface": "${SRIOV-NIC-NAME1}",
                          "pfname": "${PF_NAME1}",
                          "driver": "${DRIVER_NAME1}",
                          "numVFsToCreate": ${NUM_VFS1}
                        },
                        {
                          "resourceName": "${RESOURCE_NAME2}",
                          "interface": "${SRIOV-NIC-NAME2}",
                          "pfname": "${PF_NAME2}",
                          "driver": "${DRIVER_NAME2}",
                          "numVFsToCreate": ${NUM_VFS2}
                        }
                    ]
            mode: 0644
            user:
              name: root
            group:
              name: root
          - path: /var/lib/rancher/rke2/server/manifests/sriov.yaml
            overwrite: true
            contents:
              inline: |
                apiVersion: v1
                data:
                  .dockerconfigjson: ${REGISTRY_AUTH_DOCKERCONFIGJSON}
                kind: Secret
                metadata:
                  name: privregauth
                  namespace: kube-system
                type: kubernetes.io/dockerconfigjson
                ---
                apiVersion: v1
                kind: ConfigMap
                metadata:
                  namespace: kube-system
                  name: example-repo-ca
                data:
                  ca.crt: |-
                    -----BEGIN CERTIFICATE-----
                    ${CA_BASE64_CERT}
                    -----END CERTIFICATE-----
                ---
                apiVersion: helm.cattle.io/v1
                kind: HelmChart
                metadata:
                  name: sriov-crd
                  namespace: kube-system
                spec:
                  chart: oci://${PRIVATE_REGISTRY_URL}/mirror/sriov-crd
                  dockerRegistrySecret:
                    name: privregauth
                  repoCAConfigMap:
                    name: example-repo-ca
                  createNamespace: true
                  set:
                    global.clusterCIDR: 192.168.0.0/18
                    global.clusterCIDRv4: 192.168.0.0/18
                    global.clusterDNS: 10.96.0.10
                    global.clusterDomain: cluster.local
                    global.rke2DataDir: /var/lib/rancher/rke2
                    global.serviceCIDR: 10.96.0.0/12
                  targetNamespace: sriov-network-operator
                  version: 307.1.0+up1.6.0
                ---
                apiVersion: helm.cattle.io/v1
                kind: HelmChart
                metadata:
                  name: sriov-network-operator
                  namespace: kube-system
                spec:
                  chart: oci://${PRIVATE_REGISTRY_URL}/mirror/sriov-network-operator
                  dockerRegistrySecret:
                    name: privregauth
                  repoCAConfigMap:
                    name: example-repo-ca
                  createNamespace: true
                  set:
                    global.clusterCIDR: 192.168.0.0/18
                    global.clusterCIDRv4: 192.168.0.0/18
                    global.clusterDNS: 10.96.0.10
                    global.clusterDomain: cluster.local
                    global.rke2DataDir: /var/lib/rancher/rke2
                    global.serviceCIDR: 10.96.0.0/12
                  targetNamespace: sriov-network-operator
                  version: 307.1.0+up1.6.0
            mode: 0644
            user:
              name: root
            group:
              name: root
        kernel_arguments:
          should_exist:
            - intel_iommu=on
            - iommu=pt
            - idle=poll
            - mce=off
            - hugepagesz=1G hugepages=40
            - hugepagesz=2M hugepages=0
            - default_hugepagesz=1G
            - irqaffinity=${NON-ISOLATED_CPU_CORES}
            - isolcpus=domain,nohz,managed_irq,${ISOLATED_CPU_CORES}
            - nohz_full=${ISOLATED_CPU_CORES}
            - rcu_nocbs=${ISOLATED_CPU_CORES}
            - rcu_nocb_poll
            - nosoftlockup
            - nowatchdog
            - nohz=on
            - nmi_watchdog=0
            - skew_tick=1
            - quiet
        systemd:
          units:
          - name: rke2-preinstall.service
            enabled: true
            contents: |
              [Unit]
              Description=rke2-preinstall
              Wants=network-online.target
              Before=rke2-install.service
              ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
              [Service]
              Type=oneshot
              User=root
              ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
              # Note we use _ as a delimiter for sed here because the providerid includes / characters
              ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStartPost=/bin/sh -c "umount /mnt"
              [Install]
              WantedBy=multi-user.target
          - name: cpu-partitioning.service
            enabled: true
            contents: |
              [Unit]
              Description=cpu-partitioning
              Wants=network-online.target
              After=network.target network-online.target
              [Service]
              Type=oneshot
              User=root
              ExecStart=/bin/sh -c "echo isolated_cores=${ISOLATED_CPU_CORES} > /etc/tuned/cpu-partitioning-variables.conf"
              ExecStartPost=/bin/sh -c "tuned-adm profile cpu-partitioning"
              ExecStartPost=/bin/sh -c "systemctl enable tuned.service"
              [Install]
              WantedBy=multi-user.target
          - name: performance-settings.service
            enabled: true
            contents: |
              [Unit]
              Description=performance-settings
              Wants=network-online.target
              After=network.target network-online.target cpu-partitioning.service
              [Service]
              Type=oneshot
              User=root
              ExecStart=/bin/sh -c "/opt/performance-settings/performance-settings.sh"
              [Install]
              WantedBy=multi-user.target
          - name: sriov-custom-auto-vfs.service
            enabled: true
            contents: |
              [Unit]
              Description=SRIOV Custom Auto VF Creation
              Wants=network-online.target  rke2-server.target
              After=network.target network-online.target rke2-server.target
              [Service]
              User=root
              Type=forking
              TimeoutStartSec=1800
              ExecStart=/bin/sh -c "while ! /var/lib/rancher/rke2/bin/kubectl --kubeconfig=/etc/rancher/rke2/rke2.yaml wait --for condition=ready nodes --timeout=30m --all ; do sleep 10 ; done"
              ExecStartPost=/bin/sh -c "/opt/sriov/sriov-auto-filler.sh"
              RemainAfterExit=yes
              KillMode=process
              [Install]
              WantedBy=multi-user.target
    kubelet:
      extraArgs:
      - provider-id=metal3://PROVIDERID
    nodeName: "localhost.localdomain"

パート VIII Day 2運用

このセクションでは、管理者が管理クラスターとダウンストリームクラスターの両方で、さまざまな「Day 2」運用タスクを処理する方法を説明します。

  • 58 エッジ 3.7 移行
  • このセクションでは、management および downstream クラスタを SUSE Telco Cloud 3.6 から SUSE Telco Cloud 3.7.0 へマイグレーションする方法を説明します。

  • 59 管理クラスタ
  • 現在、management クラスターで「Day 2」操作を実行する方法は2つあります。

  • 60 ライフサイクルアクション
  • このセクションでは、SUSE Telco Cloud経由でデプロイされたクラスターのライフサイクル管理について説明します。

58 エッジ 3.7 移行

このセクションでは、management および downstream クラスタを SUSE Telco Cloud 3.6 から SUSE Telco Cloud 3.7.0 へマイグレーションする方法を説明します。

重要
重要

クラスタのマイグレーションは、必ず latest Z-stream の SUSE Telco Cloud 3.6 リリースから実行してください。

必ず SUSE Telco Cloud 3.7.0 リリースへマイグレーションしてください。マイグレーション後のアップグレードについては、管理 (第59章 「管理クラスタ」) を参照してください。 セクション。

次の表に、さまざまな種類のクラスタとクラスタをアップグレードする方法を示します。

表 58.1: ダウンストリームクラスタの種類とアップグレード方法
クラスタのタイプメソッド

EIBでプロビジョニングされたクラスタ

詳細については58.1.3項 「Fleet」を参照してください。

Metal3でプロビジョニングされたクラスタ

詳細は ダウンストリームクラスタのアップグレード (60.3項 「ダウンストリームクラスターのアップグレード」) を参照してください。

58.1 管理クラスタ

この章の構成は次のとおりです。

58.1.1項 「前提条件」 - マイグレーション開始前に完了すべき前提条件の手順。

58.1.2項 「Upgrade Controller」 - management を使用して 第21章 「Upgrade Controller」 クラスタマイグレーションを実行する方法。

58.1.3項 「Fleet」 - management を使用して 第9章 「Fleet」 クラスタマイグレーションを実行する方法。

58.1.1 前提条件

58.1.1.1 ベアメタル Operator CRDのアップグレード

注記
注記

第11章 「Metal3」 チャートのアップグレードが必要なCAPI/Metal3管理クラスタにのみ適用されます。

Metal3 Helmチャートには、HelmのCRDディレクトリを活用することで、ベアメタル Operator (BMO) CRDが含まれています。

ただし、このアプローチには特定の制限があり、特にこのディレクトリ内のCRDをHelmを使用してアップグレードできないという点があります。詳細については、Helmマニュアルを参照してください。

その結果、Metal3を`SUSE Telco Cloud 3.7.0`互換バージョンにアップグレードする前に、ユーザーは基盤となるBMO CRDを手動でアップグレードする必要があります。

Helm`がインストールされ、`kubectl`がmanagement`クラスタを指すように設定されているマシンで、以下を実行します。

  1. BMO CRDを手動で適用します。

    helm show crds oci://registry.suse.com/edge/charts/metal3 --version 307.0.31+up0.16.0 | kubectl apply -f -

58.1.2 Upgrade Controller

重要
重要

Upgrade Controller`は現在、*非エアギャップ(された)管理*クラスターに対するSUSE Telco Cloud`リリース移行のみをサポートしています。

このセクションでは、以下のトピックについて説明します。

58.1.2.1項 「前提条件」 - `Upgrade Controller`に固有の前提条件。

58.1.2.2項 「移行手順」 - Upgrade Controller`を使用してmanagement`クラスターを新しい`SUSE Telco Cloud`バージョンに移行する手順。

58.1.2.1 前提条件

58.1.2.1.1 SUSE Telco Cloud 3.7 Upgrade Controller

Upgrade Controller`を使用する前に、目的のSUSE Telco Cloud`リリースへの移行が可能なバージョンで実行されていることを確認する必要があります。

これには次の操作を行います。

  1. 以前の`Upgrade Controller`リリースから`SUSE Telco Cloud`が既にデプロイされている場合は、そのチャートをアップグレードしてください。

    helm upgrade upgrade-controller -n upgrade-controller-system oci://registry.suse.com/edge/charts/upgrade-controller --version 307.0.4+up0.1.3
  2. `Upgrade Controller`がデプロイされて*いない*場合は、21.3項 「Upgrade Controllerのインストール」に従ってください。

58.1.2.2 移行手順

Upgrade Controller`を使用したmanagement`クラスターの移行は、基本的にアップグレードの実行と似ています。

唯一の違いは、UpgradePlan`で3.7.0`リリースバージョンを*指定する必要がある*点です。

apiVersion: lifecycle.suse.com/v1alpha1
kind: UpgradePlan
metadata:
  name: upgrade-plan-mgmt
  # Change to the namespace of your Upgrade Controller
  namespace: CHANGE_ME
spec:
  releaseVersion: 3.7.0

上記の`UpgradePlan`を使用して移行を行う方法については、Upgrade Controller アップグレード処理 (59.1項 「Upgrade Controller」)を参照してください。

58.1.3 Fleet

注記
注記

可能な限り、移行には58.1.2項 「Upgrade Controller」を使用してください。

`Upgrade Controller`でカバーされていないユースケースについてのみ、このセクションを参照してください。

Fleet`を使用したmanagement`クラスターの移行は、基本的にアップグレードの実行と似ています。

*主な*違いは以下の通りです。

  1. Fleetは、`suse-edge/fleet-examples`リポジトリのrelease-3.7.0リリースから*使用する必要があります*。

  2. アップグレードが予定されているチャートは、SUSE Telco Cloud 3.7.0`リリースと互換性のあるバージョンに*アップグレードする必要があります*。SUSE Telco Cloud 3.7.0`コンポーネントのリストについては、78.3項 「リリース 3.7.0。」を参照してください。

重要
重要

`SUSE Telco Cloud 3.7.0`移行を確実に成功させるため、ユーザーは上記で概説した点に従うことが重要です。

58.2 ダウンストリームクラスタ

58.2.1項 「Fleet」 - downstream を使用して 第9章 「Fleet」 クラスタマイグレーションを実行する方法。

58.2.1 Fleet

`downstream`を使用した`Fleet`クラスタの移行は、基本的にアップグレードの実行と似ています。

*主な*違いは以下の通りです。

  1. Fleetは、`suse-edge/fleet-examples`リポジトリのrelease-3.7.0リリースから*使用する必要があります*。

  2. アップグレードが予定されているチャートは、SUSE Telco Cloud 3.7.0`リリースと互換性のあるバージョンに*アップグレードする必要があります*。SUSE Telco Cloud 3.7.0`コンポーネントのリストについては、78.3項 「リリース 3.7.0。」を参照してください。

重要
重要

`SUSE Telco Cloud 3.7.0`移行を確実に成功させるため、ユーザーは上記で概説した点に従うことが重要です。

59 管理クラスタ

現在、management クラスターで「Day 2」操作を実行する方法は2つあります。

59.1 Upgrade Controller

重要
重要

`Upgrade Controller`は現在、*非エアギャップ管理*クラスターに対する`Day 2`操作のみをサポートしています。

このセクションでは、Day 2`クラスターをある`management`プラットフォームバージョンから別のバージョンへアップグレードする際に関連する、さまざまなSUSE Telco Cloud`操作の実行方法について説明します。

`Day 2`操作はUpgrade Controller (第21章 「Upgrade Controller」)によって自動化されており、以下が含まれます。

59.1.1 前提条件

`management`クラスターをアップグレードする前に、以下の前提条件を満たす必要があります。

  1. SCC registered nodes - クラスターノードのOSが、アップグレード先の`SUSE Telco Cloud`リリース (第78章 「リリースノート」)で指定されているOSバージョンをサポートするサブスクリプションキーで登録されていることを確認してください。

  2. Upgrade Controller - `Upgrade Controller`が`management`クラスターにデプロイされていることを確認してください。インストール手順については、21.3項 「Upgrade Controllerのインストール」を参照してください。

59.1.2 アップグレード

  1. SUSE Telco Cloud`クラスターのアップグレード先となるリリース (第78章 「リリースノート」)バージョンを決定します。`management

  2. `management`クラスターに、目的の`UpgradePlan`を指定する`release version`をデプロイします。`UpgradePlan`は、`Upgrade Controller`のネームスペースにデプロイする必要があります。

    kubectl apply -n <upgrade_controller_namespace> -f - <<EOF
    apiVersion: lifecycle.suse.com/v1alpha1
    kind: UpgradePlan
    metadata:
      name: upgrade-plan-mgmt
      namespace: upgrade-controller-system  # replaces it if the upgrade controller has been deployed in a different namespace
    spec:
      # Version retrieved from release notes
      releaseVersion: 3.X.Y
    EOF
    注記
    注記

    `UpgradePlan`に対して追加の設定を行いたいユースケースがあるかもしれません。可能なすべての設定については、21.6.1項 「UpgradePlan」を参照してください。

  3. `UpgradePlan`を`Upgrade Controller’s`ネームスペースにデプロイすると、`upgrade process`が開始されます。

    注記
    注記

    実際の`upgrade process`の詳細については、21.5項 「Upgrade Controllerはどのように機能しますか?」を参照してください。

    `upgrade process`の追跡方法については、21.7項 「アップグレードプロセスの追跡」を参照してください。

59.1.3 アップグレード後の手順

SUSE Telco Cloud`の最新の3.6` z-streamから`3.7.0`へのアップグレードでは、Upgrade Controller`のアップグレードプロセス完了後に、SUSE Telco Cloud` 3.7.0`リリースに含まれる`rke2-traefik HelmチャートのHelmパラメータ変更に関連する最後の手動手順を実行する必要があります。

  • kube-system`ネームスペースの`helmchartconfigs.helm.cattle.io/rke2-traefik APIオブジェクトに以下の変更を適用してください(そのAPIオブジェクトが存在しない場合は、helmcharts.helm.cattle.io/rke2-traefik APIオブジェクトに適用してください)。

以下の通り`HelmChartConfig`(または`HelmChart`)マニフェストを使用してこれらの変更を適用し、将来の管理クラスターのアップグレードでも`Upgrade Controller`がそれらを保持するようにしてください。

# You can use `kubectl edit', `kubectl patch` or `kubectl apply` commands to apply the changes indicated below
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: rke2-traefik
  namespace: kube-system
spec:
  failurePolicy: reinstall
  valuesContent: |-
    ingressClass:
      isDefaultClass: true
    ports:
      web:
        hostPort: null
        exposedPort: 80
      websecure:
        hostPort: null
        exposedPort: 443
    service:
      enabled: true
      # type: LoadBalancer              # CHANGE_1: This Helm parameter has been REMOVED
      # ipFamilyPolicy: PreferDualStack # CHANGE_2: This Helm parameter has been REMOVED
      spec:
        type: LoadBalancer              # CHANGE_3: NEW Helm parameter replacing the old/removed one (above)
        ipFamilyPolicy: PreferDualStack # CHANGE_4: NEW Helm parameter replacing the old/removed one (above)
        externalTrafficPolicy: Local
        allocateLoadBalancerNodePorts: false
    providers:
      kubernetesIngressNGINX:           # CHANGE_5: NEW Helm parameter replacing the old/removed "KubernetesIngressNginx"
        enabled: true
        ingressClass: "rke2-ingress-nginx-migration"
        controllerClass: "rke2.​cattle.​io/ingress-nginx-migration"
EOF

または、kube-system`ネームスペースの`helmchartconfigs.helm.cattle.io/rke2-traefik APIオブジェクトが存在しない場合:

# You can use `kubectl edit', `kubectl patch` or `kubectl apply` commands to apply the changes indicated below
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: rke2-traefik
  namespace: kube-system
spec:
  chart: rke2-traefik
  version: {rke2-traefik Helm chart version}
  repo: https://rke2-charts.rancher.io
  bootstrap: false
  failurePolicy: reinstall
  backOffLimit: 20
  targetNamespace: kube-system
  set:
    global.cattle.systemDefaultRegistry: registry.rancher.com
    global.rke2DataDir: /var/lib/rancher/rke2
    global.systemDefaultRegistry: registry.rancher.com
  valuesContent: |-
    ingressClass:
      isDefaultClass: true
    ports:
      web:
        hostPort: null
        exposedPort: 80
      websecure:
        hostPort: null
        exposedPort: 443
    service:
      enabled: true
      # type: LoadBalancer              # CHANGE_1: This Helm parameter has been REMOVED
      # ipFamilyPolicy: PreferDualStack # CHANGE_2: This Helm parameter has been REMOVED
      spec:
        type: LoadBalancer              # CHANGE_3: NEW Helm parameter replacing the old/removed one (above)
        ipFamilyPolicy: PreferDualStack # CHANGE_4: NEW Helm parameter replacing the old/removed one (above)
        externalTrafficPolicy: Local
        allocateLoadBalancerNodePorts: false
    providers:
      kubernetesIngressNGINX:           # CHANGE_5: NEW Helm parameter replacing the old/removed "KubernetesIngressNginx"
        enabled: true
        ingressClass: "rke2-ingress-nginx-migration"
        controllerClass: "rke2.​cattle.​io/ingress-nginx-migration"
EOF

上記で示されている`{rke2-traefik Helm chart version}`は、アップグレード先の`SUSE Telco Cloud` `3.7.0`リリースで使用されるRKE2/k3sリリースによって提供されるものです(対応する RKE2リリースページ / k3sリリースページから入手できます)。

59.2 Fleet

本セクションでは、Fleet (第9章 「Fleet」)コンポーネントを使用して「Day 2」オペレーションを実行する方法について説明します。

本セクションでは、以下のトピックを扱います。

  1. 59.2.1項 「コンポーネント」 - すべての「Day 2」オペレーションで使用されるデフォルトコンポーネント。

  2. 59.2.2項 「ユースケースの特定」 - 使用されるFleetカスタムリソースの概要と、さまざまな「Day 2」オペレーションのユースケースへの適合性について説明します。

  3. 59.2.3項 「Day 2 ワークフロー」 - Fleetを使用して「Day 2」オペレーションを実行するためのワークフローガイドを提供します。

  4. 59.2.4項 「OSのアップグレード」 - Fleetを使用してOSアップグレードを実行する方法について説明します。

  5. 59.2.5項 「Kubernetesバージョンのアップグレード」 - Fleetを使用してKubernetesバージョンのアップグレードを実行する方法について説明します。

  6. 59.2.6項 「Helmチャートのアップグレード」 - Fleetを使用してHelmチャートのアップグレードを実行する方法について説明します。

59.2.1 コンポーネント

以下に、Fleetを使用して「Day 2」オペレーションを正常に実行するために、`management`クラスター上にセットアップする必要があるデフォルトコンポーネントの説明を記載します。

59.2.1.1 Rancher

オプション。`downstream clusters`の管理および`System Upgrade Controller`への`management cluster`のデプロイを担当します。

詳細については、第6章 「Rancher」を参照してください。

59.2.1.2 System Upgrade Controller (SUC)

*System Upgrade Controller*は、`Plan`と呼ばれるカスタムリソースを通じて提供される設定データに基づき、指定されたノードでタスクを実行する役割を担います。

*SUC*は、オペレーティングシステムおよびKubernetesディストリビューションのアップグレードに積極的に活用されています。

*SUC*コンポーネントの詳細およびEdgeスタックにおける位置付けについては、第20章 「System Upgrade Controller」を参照してください。

59.2.2 ユースケースの特定

Fleetは、KubernetesおよびHelmリソースの管理を可能にするために、2種類のカスタムリソースを使用します。

以下に、これらのリソースの目的と、「Day 2」オペレーションの文脈において最適なユースケースに関する情報を記載します。

59.2.2.1 GitRepo

GitRepo`は、`Fleet`が`Bundles`を作成するためのGitリポジトリを表すFleet (第9章 「Fleet」)リソースです。各 `Bundle は、GitRepo リソース内で定義された設定パスに基づいて作成されます。詳細については、 GitRepoマニュアルを参照してください。

「Day 2」運用のコンテキストでは、GitRepo リソースは通常、Fleet GitOps アプローチを利用する 非エアギャップ(された) 環境で SUC または SUC Plans をデプロイするために使用されます。

あるいは、ローカル git サーバーを介してリポジトリ設定をミラーリングすることを条件に、エアギャップ(された) 環境で SUC または SUC Plans をデプロイするために GitRepo リソースを使用することもできます。

59.2.2.2 バンドル

Bundles は、ターゲットクラスターにデプロイされる raw Kubernetes リソースを保持します。通常、これらは GitRepo リソースから作成されますが、手動でデプロイできるユースケースもあります。詳細については、 Bundleマニュアルを参照してください。

「Day 2」運用のコンテキストでは、Bundle リソースは通常、ローカル GitOps 手順(例:ローカル git サーバー)を使用しない エアギャップ(された) 環境で SUC または SUC Plans をデプロイするために使用されます。

あるいは、ユースケースで GitOps ワークフロー(Git リポジトリの使用など)が許可されない場合は、非エアギャップ(された) 環境で SUC または SUC Plans をデプロイするために Bundle リソースを使用することもできます。

59.2.3 Day 2 ワークフロー

以下は、management クラスターを特定の Edge リリースにアップグレードする際に従うべき「Day 2」ワークフローです。

59.2.4 OSのアップグレード

このセクションでは、第9章 「Fleet」と第20章 「System Upgrade Controller」を使用してオペレーティングシステムのアップグレードを実行する方法について説明します。

このセクションでは、以下のトピックについて説明します。

  1. 59.2.4.1項 「コンポーネント」 - アップグレードプロセスで使用される追加コンポーネント。

  2. 59.2.4.2項 「概要」 - アップグレードプロセスの概要。

  3. 59.2.4.3項 「要件」 - アップグレードプロセスの要件。

  4. 59.2.4.4項 「OS アップグレード - SUC プランのデプロイメント」 - アップグレードプロセスをトリガーする役割を担う`SUC plans`のデプロイ方法についての情報。

59.2.4.1 コンポーネント

このセクションでは、`OS upgrade`プロセスがデフォルトの「Day 2」コンポーネント (59.2.1項 「コンポーネント」)の代わりに使用するカスタムコンポーネントについて説明します。

59.2.4.1.1 systemd.service

特定のノードでのOSアップグレードは、systemd.serviceによって処理されます。

OSがEdgeのバージョン間で必要とするアップグレードの種類に応じて、異なるサービスが作成されます。

上記のサービスは、OSアップグレードが必要なmanagementクラスター上に配置する必要がある`SUC plan`を通じて、各ノードに配布されます。

59.2.4.2 概要

managementクラスターノードのオペレーティングシステムのアップグレードは、`Fleet`と`System Upgrade Controller (SUC)`を利用して行われます。

*Fleet*は、目的のクラスターに`SUC plans`をデプロイおよび管理するために使用されます。

注記
注記

`SUC plans`は、特定のタスクを一連のノード上で実行するために`SUC`が従うべき手順を記述するカスタムリソースです。`SUC plan`がどのようなものかの例については、アップストリームリポジトリを参照してください。

OS SUC plans`は、特定のFleet ワークスペースに GitRepoまたは Bundleリソースをデプロイすることで、各クラスターに配布されます。Fleetはデプロイされた`GitRepo/Bundle`を取得し、その内容(`OS SUC plans)を目的のクラスターにデプロイします。

注記
注記

`GitRepo/Bundle`リソースは常に`management cluster`にデプロイされます。`GitRepo`リソースと`Bundle`リソースのどちらを使用するかはユースケースによって異なります。詳細については59.2.2項 「ユースケースの特定」を確認してください。

`OS SUC plans`は次のワークフローを記述します。

  1. OSアップグレードの前に、必ずノードをcordonしてください。

  2. `control-plane`ノードの前に、必ず`worker`ノードをアップグレードしてください。

  3. 常に*one*ノードずつクラスターをアップグレードしてください。

`OS SUC plans`がデプロイされると、ワークフローは次のようになります。

  1. SUCはデプロイされた`OS SUC plans`を調整し、*各ノード*に`Kubernetes Job`を作成します。

  2. `Kubernetes Job`は、パッケージのアップグレードまたはOS移行のいずれかのためにsystemd.service (59.2.4.1.1項 「systemd.service」)を作成します。

  3. 作成された`systemd.service`は、特定のノードでOSアップグレードプロセスをトリガーします。

    重要
    重要

    OSアップグレードプロセスが完了すると、システムに更新を適用するために、対応するノードが`rebooted`されます。

上記の説明の図を以下に示します。

fleet day2 management os upgrade

59.2.4.3 要件

全般:

  1. SCC登録済みマシン - すべてのmanagementクラスターノードは、それぞれの`https://scc.suse.com/`が目的のRPMリポジトリに正常に接続できるようにするために必要な`systemd.service`に登録されている必要があります。

    重要
    重要

    OSバージョンの移行(例: 6.1 → 6.2)を必要とするEdgeリリースの場合は、SCCキーが新しいバージョンへの移行をサポートしていることを確認してください。

  2. SUCプランの許容設定がノードの許容設定と一致していることを確認してください - Kubernetesクラスターノードにカスタム*テイント*がある場合は、*SUCプラン*にそれらのテイントに対する許容設定を必ず追加してください。デフォルトでは、*SUCプラン*は*コントロールプレーン*ノードに対する許容設定のみを持っています。デフォルトの許容設定(tolerations)には以下が含まれます:

    • CriticalAddonsOnly=true:NoExecute

    • node-role.kubernetes.io/control-plane:NoSchedule

    • node-role.kubernetes.io/etcd:NoExecute

      注記
      注記

      追加の許容設定は、各プランの .spec.tolerations セクションの下に追加する必要があります。OS アップグレードに関連する SUC プラン は、fleets/day2/system-upgrade-controller-plans/os-upgrade の下の suse-edge/fleet-examples リポジトリにあります。有効なリポジトリ release タグのプランを使用していることを確認してください。

      コントロールプレーン SUC プランのカスタム許容設定を定義する例は次のようになります:

      apiVersion: upgrade.cattle.io/v1
      kind: Plan
      metadata:
        name: os-upgrade-control-plane
      spec:
        ...
        tolerations:
        # default tolerations
        - key: "CriticalAddonsOnly"
          operator: "Equal"
          value: "true"
          effect: "NoExecute"
        - key: "node-role.kubernetes.io/control-plane"
          operator: "Equal"
          effect: "NoSchedule"
        - key: "node-role.kubernetes.io/etcd"
          operator: "Equal"
          effect: "NoExecute"
        # custom toleration
        - key: "foo"
          operator: "Equal"
          value: "bar"
          effect: "NoSchedule"
      ...

エアギャップ(された):

  1. SUSE RPM リポジトリのミラーリング - OS RPM リポジトリはローカルにミラーリングし、systemd.service がそれらにアクセスできるようにする必要があります。これは、https://documentation.suse.com/sles/15-SP6/html/SLES-all/book-rmt.html[RMT]またはhttps://documentation.suse.com/multi-linux-manager/5.1/en/docs/index.html[SUSE Multi-Linux Manager Documentation]のいずれかを使用することで実現できます。

59.2.4.4 OS アップグレード - SUC プランのデプロイメント

重要
重要

この手順を使用して以前にアップグレードされた環境の場合、ユーザーは以下のいずれかの手順が完了していることを確認する必要があります:

  • Remove any previously deployed SUC Plans related to older Edge release versions from the management cluster - 既存の GitRepo/Bundle ターゲット設定 から目的のクラスターを削除するか、GitRepo/Bundle リソースを完全に削除することで実行できます。

  • Reuse the existing GitRepo/Bundle resource - リソースのリビジョンを、目的の suse-edge/fleet-examples リリース に適したフリートを保持する新しいタグに向けることで実行できます。

これは、古い Edge リリースバージョンの SUC Plans との競合を避けるために行われます。

ユーザーがアップグレードを試みる際に management クラスター上に既存の SUC Plans が存在する場合、次のようなフリートエラーが表示されます:

Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..

59.2.4.2項 「概要」 で述べたように、OS のアップグレードは、以下のいずれかの方法で目的のクラスターに SUC plans を送信することによって行われます:

どのリソースを使用すべきかを判断するには、59.2.2項 「ユースケースの特定」 を参照してください。

サードパーティの GitOps ツールから OS SUC plans をデプロイしたいユースケースについては、59.2.4.4.3項 「SUCプランのデプロイ - サードパーティのGitOpsワークフロー」 を参照してください。

59.2.4.4.1 SUC プランのデプロイメント - GitRepo リソース

必要な OS SUC plans を送信する GitRepo リソースは、以下のいずれかの方法でデプロイできます:

  1. Rancher UI - 59.2.4.4.1.1項 「GitRepoの作成 - Rancher UI」 を通じて(`Rancher`が利用可能な場合)。

  2. リソースを手動でデプロイ (59.2.4.4.1.2項 「GitRepoの作成 - 手動」) して、management cluster に適用します。

デプロイ後、ターゲットクラスターのノードのOSアップグレードプロセスを監視するには、20.3項 「System Upgrade Controllerプランの監視」 を参照してください。

59.2.4.4.1.1 GitRepoの作成 - Rancher UI

Rancher UIを通じて GitRepo リソースを作成するには、公式の ドキュメント に従ってください。

Edgeチームは、すぐに使用できる Fleet を維持管理しています。環境によっては、このFleetを直接使用することも、テンプレートとして使用することもできます。

重要
重要

必ず有効な Edge release タグからこのFleetを使用してください。

Fleetが提供する SUC plans にカスタム変更を含める必要がないユースケースでは、ユーザーは suse-edge/fleet-examples リポジトリから os-upgrade Fleetを直接参照できます。

カスタム変更が必要な場合(カスタムテイントの追加など)、ユーザーは別のリポジトリから os-upgrade Fleetを参照し、必要に応じてSUCプランに変更を追加できるようにする必要があります。

GitRepo が suse-edge/fleet-examples リポジトリのFleetを使用するように構成する方法の例は、こちらで確認できます。

59.2.4.4.1.2 GitRepoの作成 - 手動
  1. GitRepo リソースをプルします:

    curl -o os-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.7.0/gitrepos/day2/os-upgrade-gitrepo.yaml
  2. GitRepo 設定を編集します:

    • spec.targets セクションを削除します - ダウンストリームクラスターにのみ必要です。

      # Example using sed
      sed -i.bak '/^  targets:/,$d' os-upgrade-gitrepo.yaml && rm -f os-upgrade-gitrepo.yaml.bak
      
      # Example using yq (v4+)
      yq eval 'del(.spec.targets)' -i os-upgrade-gitrepo.yaml
    • GitRepo のネームスペースを fleet-local ネームスペースに向けます - これは管理クラスターにリソースをデプロイするために行います。

      # Example using sed
      sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' os-upgrade-gitrepo.yaml && rm -f os-upgrade-gitrepo.yaml.bak
      
      # Example using yq (v4+)
      yq eval '.metadata.namespace = "fleet-local"' -i os-upgrade-gitrepo.yaml
  3. `management cluster`に*GitRepo*リソースを適用します。

    kubectl apply -f os-upgrade-gitrepo.yaml
  4. `fleet-local`ネームスペースの下で、作成された*GitRepo*リソースを表示します。

    kubectl get gitrepo os-upgrade -n fleet-local
    
    # Example output
    NAME            REPO                                              COMMIT         BUNDLEDEPLOYMENTS-READY   STATUS
    os-upgrade      https://github.com/suse-edge/fleet-examples.git   release-3.7.0  0/0
59.2.4.4.2 SUCプランのデプロイメント - Bundleリソース

必要なを配布する*Bundle*`OS SUC Plans`リソースは、以下のいずれかの方法でデプロイできます。

  1. Rancher UI - 59.2.4.4.2.1項 「Bundleの作成 - Rancher UI」 を通じて(`Rancher`が利用可能な場合)。

  2. リソースを手動でデプロイ (59.2.4.4.2.2項 「バンドルの作成 - 手動」) して、management cluster に適用します。

デプロイ後、ターゲットクラスターのノードのOSアップグレードプロセスを監視するには、20.3項 「System Upgrade Controllerプランの監視」 を参照してください。

59.2.4.4.2.1 Bundleの作成 - Rancher UI

Edgeチームは、以下の手順で使用できるすぐに使えるbundleを管理しています。

重要
重要

必ず有効なEdge releaseタグのこのBundleを使用してください。

RancherのUIからBundleを作成するには:

  1. 左上隅で、*☰ → Continuous Delivery*をクリックします。

  2. Advanced > *Bundles*に移動します。

  3. *Create from YAML*を選択します。

  4. ここから、以下のいずれかの方法でBundleを作成できます。

    注記
    注記

    Bundleが配布する`SUC plans`にカスタム変更を含める必要があるユースケースがあるかもしれません(例:カスタムのtolerationを追加する場合など)。以下の手順で生成されるBundleに、それらの変更を必ず含めてください。

    1. `suse-edge/fleet-examples`からbundle contentを手動でコピーし、*Create from YAML*ページに貼り付けます。

    2. 目的のreleaseタグからsuse-edge/fleet-examplesリポジトリをクローンし、*Create from YAML*ページの*Read from File*オプションを選択します。そこからBundleの場所(bundles/day2/system-upgrade-controller-plans/os-upgrade)に移動し、Bundleファイルを選択します。これにより、*Create from YAML*ページにBundleの内容が自動的に入力されます。

  5. Rancher UIでバンドルを編集します。

    • Bundle`の*ネームスペース*を変更して、fleet-local`ネームスペースを指すようにします。

      # Example
      kind: Bundle
      apiVersion: fleet.cattle.io/v1alpha1
      metadata:
        name: os-upgrade
        namespace: fleet-local
      ...
    • Bundle`の*ターゲット*クラスターを変更して、`local(管理)クラスターを指すようにします。

      spec:
        targets:
        - clusterName: local
      注記
      注記

      `local`クラスターの名前が異なる場合があるユースケースがいくつかあります。

      `local`クラスター名を取得するには、以下のコマンドを実行します。

      kubectl get clusters.fleet.cattle.io -n fleet-local
  6. [作成]を選択します。

59.2.4.4.2.2 バンドルの作成 - 手動
  1. *バンドル*リソースをプルします。

    curl -o os-upgrade-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.7.0/bundles/day2/system-upgrade-controller-plans/os-upgrade/os-upgrade-bundle.yaml
  2. `Bundle`設定を編集します。

    • Bundle`の*ターゲット*クラスターを変更して、`local(管理)クラスターを指すようにします。

      spec:
        targets:
        - clusterName: local
      注記
      注記

      `local`クラスターの名前が異なる場合があるユースケースがいくつかあります。

      `local`クラスター名を取得するには、以下のコマンドを実行します。

      kubectl get clusters.fleet.cattle.io -n fleet-local
    • Bundle`の*ネームスペース*を変更して、fleet-local`ネームスペースを指すようにします。

      # Example
      kind: Bundle
      apiVersion: fleet.cattle.io/v1alpha1
      metadata:
        name: os-upgrade
        namespace: fleet-local
      ...
  3. *バンドル*リソースを`management cluster`に適用します。

    kubectl apply -f os-upgrade-bundle.yaml
  4. 作成された*バンドル*リソースを`fleet-local`ネームスペースの下で表示します。

    kubectl get bundles -n fleet-local
59.2.4.4.3 SUCプランのデプロイ - サードパーティのGitOpsワークフロー

ユーザーが`OS SUC plans`を独自のサードパーティGitOpsワークフロー(例: Flux)に組み込みたいというユースケースがあるかもしれません。

必要なOSアップグレードリソースを取得するには、まず使用するsuse-edge/fleet-examplesリポジトリのEdge リリースタグを特定します。

その後、リソースは`fleets/day2/system-upgrade-controller-plans/os-upgrade`にあります。ここで:

  • `plan-control-plane.yaml`は、*コントロールプレーン*ノード用のSUCプランリソースです。

  • `plan-worker.yaml`は、*ワーカー*ノード用のSUCプランリソースです。

  • `secret.yaml`は、systemd.service (59.2.4.1.1項 「systemd.service」)を作成する役割を担う`upgrade.sh`スクリプトを含むシークレットです。

  • `config-map.yaml`は、`upgrade.sh`スクリプトによって使用される設定を保持するConfigMapです。

重要
重要

これらの`Plan`リソースは`System Upgrade Controller`によって解釈されるため、アップグレードする各ダウンストリームクラスターに展開する必要があります。SUCの展開に関する情報については、20.2項 「System Upgrade Controllerのインストール」を参照してください。

OSアップグレード用の*SUC Plans*を展開するためにGitOpsワークフローをどのように使用できるかをより深く理解するには、overview (59.2.4.2項 「概要」)を参照すると役立ちます。

59.2.5 Kubernetesバージョンのアップグレード

このセクションでは、第9章 「Fleet」と第20章 「System Upgrade Controller」を使用してKubernetesのアップグレードを実行する方法について説明します。

このセクションでは、以下のトピックについて説明します。

  1. 59.2.5.1項 「コンポーネント」 - アップグレードプロセスで使用される追加コンポーネント。

  2. 59.2.5.2項 「概要」 - アップグレードプロセスの概要。

  3. 59.2.5.3項 「要件」 - アップグレードプロセスの要件。

  4. 59.2.5.4項 「K8sアップグレード - SUCプランのデプロイメント」 - アップグレードプロセスをトリガーする役割を担う`SUC plans`のデプロイ方法に関する情報。

59.2.5.1 コンポーネント

このセクションでは、デフォルトの「Day 2」コンポーネント (59.2.1項 「コンポーネント」)に加えて`K8s upgrade`プロセスが使用するカスタムコンポーネントについて説明します。

59.2.5.1.1 rke2-upgrade

特定のノードのRKE2バージョンをアップグレードするためのコンテナイメージ。

*SUCプラン*に基づいて*SUC*によって作成されたPodを通じて提供されます。このプランは、RKE2のアップグレードが必要な各*クラスター*に配置する必要があります。

`rke2-upgrade`イメージがどのようにアップグレードを実行するかについての詳細は、アップストリームドキュメントを参照してください。

59.2.5.1.2 k3s-upgrade

特定のノードのK3sバージョンをアップグレードするためのコンテナイメージ。

*SUCプラン*に基づいて*SUC*によって作成されたPodを通じて提供されます。このプランは、K3sのアップグレードが必要な各*クラスター*に配置する必要があります。

`k3s-upgrade`イメージがどのようにアップグレードを実行するかについての詳細は、アップストリームドキュメントを参照してください。

59.2.5.2 概要

managementクラスターノードのKubernetesディストリビューションのアップグレードは、`Fleet`と`System Upgrade Controller (SUC)`を利用して行われます。

`Fleet`は、目的のクラスターに`SUC plans`をデプロイおよび管理するために使用されます。

注記
注記

`SUC plans`は、特定のタスクを一連のノードで実行するために*SUC*が従うべき手順を記述したカスタムリソースです。`SUC plan`の例については、アップストリームリポジトリを参照してください。

K8s SUC plans`は、 GitRepoまたは Bundleリソースを特定のFleet workspaceにデプロイすることで、各クラスターにデプロイされます。Fleetはデプロイされた`GitRepo/Bundle`を取得し、その内容(`K8s SUC plans)を目的のクラスター(複数可)にデプロイします。

注記
注記

`GitRepo/Bundle`リソースは常に`management cluster`にデプロイされます。`GitRepo`リソースと`Bundle`リソースのどちらを使用するかはユースケースによって異なります。詳細については59.2.2項 「ユースケースの特定」を確認してください。

`K8s SUC plans`は以下のワークフローを記述します。

  1. K8sのアップグレード前には、必ずノードをコードンしてください。

  2. 常に`control-plane`ノードを`worker`ノードより先にアップグレードしてください。

  3. 常に`control-plane`ノードは*一つ*ずつ、`worker`ノードは*二つ*ずつアップグレードしてください。

`K8s SUC plans`がデプロイされたら、ワークフローは次のようになります。

  1. SUCはデプロイされた`K8s SUC plans`を同期し、*各ノード*に`Kubernetes Job`を作成します。

  2. Kubernetesのディストリビューションに応じて、Jobはrke2-upgrade (59.2.5.1.1項 「rke2-upgrade」)またはk3s-upgrade (59.2.5.1.2項 「k3s-upgrade」)コンテナイメージのいずれかを実行するPodを作成します。

  3. 作成されたPodは、以下のワークフローに従います。

    1. ノード上の既存の`rke2/k3s`バイナリを、`rke2-upgrade/k3s-upgrade`イメージから取得したものに置き換えます。

    2. 実行中の`rke2/k3s`プロセスを停止します。

  4. `rke2/k3s`プロセスを停止すると再起動がトリガーされ、更新されたバイナリを実行する新しいプロセスが起動し、その結果、Kubernetesディストリビューションはアップグレードされたバージョンになります。

上記の説明の図を以下に示します。

fleet day2 management k8s upgrade

59.2.5.3 要件

  1. Kubernetesディストリビューションをバックアップしてください:

    1. *RKE2クラスター*については、RKE2 バックアップおよびリストアのドキュメントを参照してください。

    2. *K3sクラスター*については、K3s バックアップおよびリストアのドキュメントを参照してください。

  2. SUCプランのトレラレーションがノードのトレラレーションと一致していることを確認しましょう - Kubernetesクラスターのノードにカスタム*テイント*がある場合は、*SUCプラン*でそれらのテイントに対するトレラレーションを必ず追加してください。デフォルトでは、*SUC Plans*には*control-plane*ノードに対するトレラレーションのみが含まれています。デフォルトのトレラレーションには以下が含まれます:

    • CriticalAddonsOnly=true:NoExecute

    • node-role.kubernetes.io/control-plane:NoSchedule

    • node-role.kubernetes.io/etcd:NoExecute

      注記
      注記

      追加のトレラレーションは、各プランの`.spec.tolerations`セクションの下に追加する必要があります。Kubernetesバージョンアップグレードに関連する*SUC Plans*は、suse-edge/fleet-examplesリポジトリの以下にあります。

      • *RKE2*の場合 - fleets/day2/system-upgrade-controller-plans/rke2-upgrade

      • *K3s*の場合 - fleets/day2/system-upgrade-controller-plans/k3s-upgrade

      有効なリポジトリreleaseタグのプランを使用していることを確認してください。

      RKE2 control-plane SUCプランのカスタムトレラレーションを定義する例は、次のようになります。

      apiVersion: upgrade.cattle.io/v1
      kind: Plan
      metadata:
        name: rke2-upgrade-control-plane
      spec:
        ...
        tolerations:
        # default tolerations
        - key: "CriticalAddonsOnly"
          operator: "Equal"
          value: "true"
          effect: "NoExecute"
        - key: "node-role.kubernetes.io/control-plane"
          operator: "Equal"
          effect: "NoSchedule"
        - key: "node-role.kubernetes.io/etcd"
          operator: "Equal"
          effect: "NoExecute"
        # custom toleration
        - key: "foo"
          operator: "Equal"
          value: "bar"
          effect: "NoSchedule"
      ...

59.2.5.4 K8sアップグレード - SUCプランのデプロイメント

重要
重要

この手順を使用して以前にアップグレードされた環境の場合、ユーザーは以下の*いずれかの*手順が完了していることを確認する必要があります。

  • Remove any previously deployed SUC Plans related to older Edge release versions from the management cluster - 既存の GitRepo/Bundle ターゲット設定 から目的のクラスターを削除するか、GitRepo/Bundle リソースを完全に削除することで実行できます。

  • Reuse the existing GitRepo/Bundle resource - リソースのリビジョンを、目的の suse-edge/fleet-examples リリース に適したフリートを保持する新しいタグに向けることで実行できます。

これは、古い Edge リリースバージョンの SUC Plans との競合を避けるために行われます。

ユーザーがアップグレードを試みた際に、managementクラスター上に既存の`SUC Plans`が存在する場合、以下のフリートエラーが表示されます。

Not installed: Unable to continue with install: Plan <plan_name> in namespace <plan_namespace> exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error..

59.2.5.2項 「概要」で述べたように、Kubernetesのアップグレードは、以下のいずれかの方法で目的のクラスターに`SUC plans`を配布することによって行われます。

どのリソースを使用すべきかを判断するには、59.2.2項 「ユースケースの特定」を参照してください。

サードパーティのGitOpsツールから`K8s SUC plans`をデプロイしたいユースケースについては、59.2.5.4.3項 「SUCプランのデプロイ - サードパーティのGitOpsワークフロー」を参照してください。

59.2.5.4.1 SUC プランのデプロイメント - GitRepo リソース

必要な`K8s SUC plans`を配布する*GitRepo*リソースは、以下のいずれかの方法でデプロイできます。

  1. Rancher UI - 59.2.5.4.1.1項 「GitRepoの作成 - Rancher UI」 を通じて(`Rancher`が利用可能な場合)。

  2. management cluster にリソースを 手動でデプロイ (59.2.5.4.1.2項 「GitRepoの作成 - 手動」) することによって。

デプロイ後、ターゲットクラスターのノードのKubernetesアップグレードプロセスを監視するには、20.3項 「System Upgrade Controllerプランの監視」 を参照してください。

59.2.5.4.1.1 GitRepoの作成 - Rancher UI

Rancher UIを通じて GitRepo リソースを作成するには、公式の ドキュメント に従ってください。

Edgeチームは、RKE2 および K3s のKubernetesディストリビューション向けに、すぐに使用できるフリート(Fleet)を維持しています。環境に応じて、このフリートを直接使用することも、テンプレートとして使用することもできます。

重要
重要

これらのフリートは、必ず有効なEdge リリース タグから使用してください。

これらのフリートに同梱されている SUC plans にカスタム変更を含める必要がないユースケースでは、ユーザーは suse-edge/fleet-examples リポジトリから直接フリートを参照できます。

カスタム変更が必要な場合(カスタムTolerationを追加する場合など)、ユーザーは別のリポジトリからフリートを参照する必要があります。これにより、必要に応じてSUCプランに変更を加えることができます。

suse-edge/fleet-examples リポジトリのフリートを使用した GitRepo リソースの設定例:

59.2.5.4.1.2 GitRepoの作成 - 手動
  1. GitRepo リソースをプルします:

    • RKE2 クラスターの場合:

      curl -o rke2-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.7.0/gitrepos/day2/rke2-upgrade-gitrepo.yaml
    • K3s クラスターの場合:

      curl -o k3s-upgrade-gitrepo.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.7.0/gitrepos/day2/k3s-upgrade-gitrepo.yaml
  2. GitRepo 設定を編集します:

    • `spec.targets`セクションを削除します。これはダウンストリームクラスターにのみ必要です。

      • RKE2の場合:

        # Example using sed
        sed -i.bak '/^  targets:/,$d' rke2-upgrade-gitrepo.yaml && rm -f rke2-upgrade-gitrepo.yaml.bak
        
        # Example using yq (v4+)
        yq eval 'del(.spec.targets)' -i rke2-upgrade-gitrepo.yaml
      • K3sの場合:

        # Example using sed
        sed -i.bak '/^  targets:/,$d' k3s-upgrade-gitrepo.yaml && rm -f k3s-upgrade-gitrepo.yaml.bak
        
        # Example using yq (v4+)
        yq eval 'del(.spec.targets)' -i k3s-upgrade-gitrepo.yaml
    • GitRepo`の名前空間をfleet-local`名前空間に向けます。これは、管理クラスター上にリソースをデプロイするために行われます。

      • RKE2の場合:

        # Example using sed
        sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' rke2-upgrade-gitrepo.yaml && rm -f rke2-upgrade-gitrepo.yaml.bak
        
        # Example using yq (v4+)
        yq eval '.metadata.namespace = "fleet-local"' -i rke2-upgrade-gitrepo.yaml
      • K3sの場合:

        # Example using sed
        sed -i.bak 's/namespace: fleet-default/namespace: fleet-local/' k3s-upgrade-gitrepo.yaml && rm -f k3s-upgrade-gitrepo.yaml.bak
        
        # Example using yq (v4+)
        yq eval '.metadata.namespace = "fleet-local"' -i k3s-upgrade-gitrepo.yaml
  3. *GitRepo*リソースを`management cluster`に適用します。

    # RKE2
    kubectl apply -f rke2-upgrade-gitrepo.yaml
    
    # K3s
    kubectl apply -f k3s-upgrade-gitrepo.yaml
  4. 作成された*GitRepo*リソースを`fleet-local`名前空間の下で表示します。

    # RKE2
    kubectl get gitrepo rke2-upgrade -n fleet-local
    
    # K3s
    kubectl get gitrepo k3s-upgrade -n fleet-local
    
    # Example output
    NAME           REPO                                              COMMIT          BUNDLEDEPLOYMENTS-READY   STATUS
    k3s-upgrade    https://github.com/suse-edge/fleet-examples.git   fleet-local   0/0
    rke2-upgrade   https://github.com/suse-edge/fleet-examples.git   fleet-local   0/0
59.2.5.4.2 SUCプランのデプロイメント - Bundleリソース

必要な`Kubernetes upgrade SUC Plans`を出荷する*Bundle*リソースは、以下のいずれかの方法でデプロイできます。

  1. Rancher UI - 59.2.5.4.2.1項 「バンドルの作成 - Rancher UI」 を通じて(`Rancher`が利用可能な場合)。

  2. management cluster にリソースを 手動でデプロイ (59.2.5.4.2.2項 「バンドルの作成 - 手動」) することによって。

デプロイ後、ターゲットクラスターのノードのKubernetesアップグレードプロセスを監視するには、20.3項 「System Upgrade Controllerプランの監視」 を参照してください。

59.2.5.4.2.1 バンドルの作成 - Rancher UI

Edgeチームは、rke2およびk3sの両方のKubernetesディストリビューションですぐに使用できるバンドルを維持管理しています。環境に応じて、これらのバンドルを直接使用することも、テンプレートとして使用することもできます。

重要
重要

必ず有効なEdge releaseタグからこのバンドルを使用してください。

RancherのUIからBundleを作成するには:

  1. 左上隅で、*☰ → Continuous Delivery*をクリックします。

  2. Advanced > *Bundles*に移動します。

  3. *Create from YAML*を選択します。

  4. ここから、以下のいずれかの方法でBundleを作成できます。

    注記
    注記

    Bundleが配布する`SUC plans`にカスタム変更を含める必要があるユースケースがあるかもしれません(例:カスタムのtolerationを追加する場合など)。以下の手順で生成されるバンドルに、これらの変更が含まれていることを確認してください。

    1. `suse-edge/fleet-examples`からRKE2またはK3sのバンドルコンテンツを、*Create from YAML*ページに手動でコピーします。

    2. 目的のreleaseタグからsuse-edge/fleet-examplesリポジトリをクローンし、*Create from YAML*ページで*Read from File*オプションを選択します。そこから、必要なバンドル(RKE2の場合は`bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml`、K3sの場合は`bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml`)に移動します。これにより、*Create from YAML*ページにバンドルコンテンツが自動入力されます。

  5. Rancher UIでバンドルを編集します。

    • Bundle`の*ネームスペース*を変更して、fleet-local`ネームスペースを指すようにします。

      # Example
      kind: Bundle
      apiVersion: fleet.cattle.io/v1alpha1
      metadata:
        name: rke2-upgrade
        namespace: fleet-local
      ...
    • Bundle`の*ターゲット*クラスターを変更して、`local(管理)クラスターを指すようにします。

      spec:
        targets:
        - clusterName: local
      注記
      注記

      `local`クラスターの名前が異なる場合があるユースケースがいくつかあります。

      `local`クラスター名を取得するには、以下のコマンドを実行します。

      kubectl get clusters.fleet.cattle.io -n fleet-local
  6. [作成]を選択します。

59.2.5.4.2.2 バンドルの作成 - 手動
  1. *Bundle*リソースをプルします。

    • RKE2 クラスターの場合:

      curl -o rke2-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.7.0/bundles/day2/system-upgrade-controller-plans/rke2-upgrade/plan-bundle.yaml
    • K3s クラスターの場合:

      curl -o k3s-plan-bundle.yaml https://raw.githubusercontent.com/suse-edge/fleet-examples/refs/tags/release-3.7.0/bundles/day2/system-upgrade-controller-plans/k3s-upgrade/plan-bundle.yaml
  2. `Bundle`設定を編集します。

    • Bundle`の*ターゲット*クラスターを変更して、`local(管理)クラスターを指すようにします。

      spec:
        targets:
        - clusterName: local
      注記
      注記

      `local`クラスターの名前が異なる場合があるユースケースがいくつかあります。

      `local`クラスター名を取得するには、以下のコマンドを実行します。

      kubectl get clusters.fleet.cattle.io -n fleet-local
    • Bundle`の*ネームスペース*を変更して、fleet-local`ネームスペースを指すようにします。

      # Example
      kind: Bundle
      apiVersion: fleet.cattle.io/v1alpha1
      metadata:
        name: rke2-upgrade
        namespace: fleet-local
      ...
  3. `management cluster`に*Bundle*リソースを適用します。

    # For RKE2
    kubectl apply -f rke2-plan-bundle.yaml
    
    # For K3s
    kubectl apply -f k3s-plan-bundle.yaml
  4. fleet-local 名前空間の下で作成された Bundle リソースを表示します。

    # For RKE2
    kubectl get bundles rke2-upgrade -n fleet-local
    
    # For K3s
    kubectl get bundles k3s-upgrade -n fleet-local
    
    # Example output
    NAME           BUNDLEDEPLOYMENTS-READY   STATUS
    k3s-upgrade    0/0
    rke2-upgrade   0/0
59.2.5.4.3 SUCプランのデプロイ - サードパーティのGitOpsワークフロー

ユーザーが Kubernetes upgrade SUC plans を独自のサードパーティ GitOps ワークフロー (例: Flux) に組み込みたいというユースケースがあるかもしれません。

必要な K8s アップグレードリソースを取得するには、まず使用する suse-edge/fleet-examples リポジトリの Edge release タグを特定します。

その後、リソースは以下から入手できます。

  • RKE2 クラスターのアップグレードの場合:

    • control-plane ノード用 - fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-control-plane.yaml

    • worker ノード用 - fleets/day2/system-upgrade-controller-plans/rke2-upgrade/plan-worker.yaml

  • K3s クラスターのアップグレードの場合:

    • control-plane ノード用 - fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-control-plane.yaml

    • worker ノード用 - fleets/day2/system-upgrade-controller-plans/k3s-upgrade/plan-worker.yaml

重要
重要

これらの Plan リソースは System Upgrade Controller によって解釈され、アップグレードする各ダウンストリームクラスターに展開する必要があります。SUC 展開に関する情報については、20.2項 「System Upgrade Controllerのインストール」を参照してください。

Kubernetes バージョンアップグレードのために SUC Plans をデプロイする GitOps ワークフローをより深く理解するには、Fleet を用いた更新手順の overview (59.2.5.2項 「概要」) を確認することが有益です。

59.2.6 Helmチャートのアップグレード

このセクションでは、次の部分について説明します。

  1. 59.2.6.1項 「エアギャップ(された)環境の準備」 - Edge関連のOCIチャートおよびイメージをプライベートレジストリに配布する方法に関する情報が記載されています。

  2. 59.2.6.2項 「アップグレード手順」 - さまざまなHelmチャートアップグレードのユースケースと、そのアップグレード手順に関する情報が記載されています。

59.2.6.1 エアギャップ(された)環境の準備

59.2.6.1.1 HelmチャートFleetにアクセスできることを確認してください。

環境のサポート状況に応じて、次のいずれかのオプションを選択できます。

  1. `management cluster`からアクセス可能なローカルGitサーバーで、チャートのFleetリソースをホストします。

  2. FleetのCLIを使用して、HelmチャートをBundleに変換します。これにより、直接使用できるようになり、どこかでホストする必要がなくなります。FleetのCLIは、リリースページから取得できます。Macユーザーの場合は、fleet-cli Homebrew Formulaeが用意されています。

59.2.6.1.2 Edgeリリースバージョンに必要なアセットを見つける
  1. 「Day 2」のリリースページに移動し、チャートのアップグレード先となるEdgeリリースを見つけて、*Assets*をクリックします。

  2. *「Assets」*セクションから、次のファイルをダウンロードします。

    リリースファイル

    説明

    edge-save-images.sh

    `edge-release-images.txt`ファイルで指定されたイメージをプルし、'.tar.gz’アーカイブ内にパッケージ化します。

    edge-save-oci-artefacts.sh

    特定のEdgeリリースに関連するOCIチャートイメージをプルし、'.tar.gz’アーカイブ内にパッケージ化します。

    edge-load-images.sh

    '.tar.gz’アーカイブからイメージをロードし、リタグしてプライベートレジストリにプッシュします。

    edge-load-oci-artefacts.sh

    Edge OCI '.tgz’チャートパッケージを含むディレクトリを取得し、それらをプライベートレジストリにロードします。

    edge-release-helm-oci-artefacts.txt

    特定のEdgeリリースに関連するOCIチャートイメージのリストが含まれています。

    edge-release-images.txt

    特定のEdgeリリースに関連するイメージのリストが含まれています。

59.2.6.1.3 Edgeリリースイメージのアーカイブを作成します

インターネットに接続されたマシンで:

  1. `edge-save-images.sh`を実行可能にします:

    chmod +x edge-save-images.sh
  2. イメージアーカイブを生成します:

    ./edge-save-images.sh --source-registry registry.suse.com
  3. これにより、`edge-images.tar.gz`という名前のロード可能なアーカイブが作成されます。

    注記
    注記

    `-i|--images`オプションが指定されている場合、アーカイブの名前が異なることがあります。

  4. このアーカイブを*エアギャップ(された)*マシンにコピーします:

    scp edge-images.tar.gz <user>@<machine_ip>:/path
59.2.6.1.4 Edge OCIチャートイメージのアーカイブを作成します

インターネットに接続されたマシンで:

  1. `edge-save-oci-artefacts.sh`を実行可能にします:

    chmod +x edge-save-oci-artefacts.sh
  2. OCIチャートイメージのアーカイブを生成します:

    ./edge-save-oci-artefacts.sh --source-registry registry.suse.com
  3. これにより、`oci-artefacts.tar.gz`という名前のアーカイブが作成されます。

    注記
    注記

    `-a|--archive`オプションが指定されている場合、アーカイブの名前が異なることがあります。

  4. このアーカイブを*エアギャップ(された)*マシンにコピーします:

    scp oci-artefacts.tar.gz <user>@<machine_ip>:/path
59.2.6.1.5 Edgeリリースイメージをエアギャップ(された)マシンにロードします

エアギャップ(された)マシンで:

  1. プライベートレジストリにログインします(必要な場合):

    podman login <REGISTRY.YOURDOMAIN.COM:PORT>
  2. `edge-load-images.sh`を実行可能にします:

    chmod +x edge-load-images.sh
  3. スクリプトを実行し、以前に*コピーした*`edge-images.tar.gz`アーカイブを渡します:

    ./edge-load-images.sh --source-registry registry.suse.com --registry <REGISTRY.YOURDOMAIN.COM:PORT> --images edge-images.tar.gz
    注記
    注記

    これにより、edge-images.tar.gz`からすべてのイメージがロードされ、タグが付け直されて、--registry`オプションで指定されたレジストリにプッシュされます。

59.2.6.1.6 Edge OCIチャートイメージをエアギャップ(された)マシンにロードします

エアギャップ(された)マシンで:

  1. プライベートレジストリにログインします(必要な場合):

    podman login <REGISTRY.YOURDOMAIN.COM:PORT>
  2. `edge-load-oci-artefacts.sh`を実行可能にします:

    chmod +x edge-load-oci-artefacts.sh
  3. コピーした`oci-artefacts.tar.gz`アーカイブをuntar(する):

    tar -xvf oci-artefacts.tar.gz
  4. これにより、`edge-release-oci-tgz-<date>`という命名テンプレートを持つディレクトリが作成されます

  5. このディレクトリを`edge-load-oci-artefacts.sh`スクリプトに渡して、Edge OCIチャートイメージをプライベートレジストリにロードします:

    注記
    注記

    このスクリプトは、helm CLIが環境にプレインストールされていることを前提としています。Helmのインストール手順については、Installing Helmを参照してください。

    ./edge-load-oci-artefacts.sh --archive-directory edge-release-oci-tgz-<date> --registry <REGISTRY.YOURDOMAIN.COM:PORT> --source-registry registry.suse.com
59.2.6.1.7 Kubernetesディストリビューションでプライベートレジストリを設定します。

RKE2については、Private Registry Configurationを参照してください。

K3sについては、Private Registry Configurationを参照してください。

59.2.6.2 アップグレード手順

このセクションでは、次のHelmアップグレード手順のユースケースについて説明します。

重要
重要

手動でデプロイされたHelmチャートは、確実にアップグレードすることはできません。59.2.6.2.1項 「新しいクラスターがあり、Edge Helmチャートをデプロイおよび管理したい場合」メソッドを使用してHelmチャートを再デプロイすることをお勧めします。

59.2.6.2.1 新しいクラスターがあり、Edge Helmチャートをデプロイおよび管理したい場合

このセクションでは、次の方法について説明します。

59.2.6.2.1.1 チャートのFleetリソースを準備する
  1. 使用するEdge releaseタグから、チャートのFleetリソースを取得します。

  2. HelmチャートのFleet(fleets/day2/chart-templates/<chart>)に移動します。

  3. GitOpsワークフローを使用する予定がある場合は、チャートのFleetディレクトリを、GitOpsを実行するGitリポジトリにコピーします。

  4. 必要に応じて、Helmチャートで*values*の設定が必要な場合は、コピーしたディレクトリ内の`.helm.values`ファイルにある`fleet.yaml`設定を編集してください。

  5. 必要に応じて、環境に合わせてチャートのFleetにリソースを追加する必要があるユースケースも考えられます。Fleetディレクトリを拡張する方法については、Git Repository Contentsを参照してください。

注記
注記

場合によっては、FleetがHelm操作に使用するデフォルトのタイムアウトでは不十分であり、次のようなエラーが発生することがあります。

failed pre-install: context deadline exceeded

そのような場合は、`fleet.yaml`ファイルの`helm`設定の下にtimeoutSecondsプロパティを追加してください。

*例*として、`longhorn`ヘルムチャートの場合は次のようになります:

  • ユーザーGitリポジトリの構造:

    <user_repository_root>
    ├── longhorn
    │   └── fleet.yaml
    └── longhorn-crd
        └── fleet.yaml
  • `fleet.yaml`ユーザー`Longhorn`データが含まれるコンテンツ:

    defaultNamespace: longhorn-system
    
    helm:
      # timeoutSeconds: 10
      releaseName: "longhorn"
      chart: "longhorn"
      repo: "https://charts.rancher.io/"
      version: "1.12.1"
      takeOwnership: true
      # custom chart value overrides
      values:
        # Example for user provided custom values content
        defaultSettings:
          deletingConfirmationFlag: true
    
    # https://fleet.rancher.io/bundle-diffs
    diff:
      comparePatches:
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: engineimages.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: nodes.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
      - apiVersion: apiextensions.k8s.io/v1
        kind: CustomResourceDefinition
        name: volumes.longhorn.io
        operations:
        - {"op":"remove", "path":"/status/conditions"}
        - {"op":"remove", "path":"/status/storedVersions"}
        - {"op":"remove", "path":"/status/acceptedNames"}
    注記
    注記

    これらは、`longhorn`チャートに対するカスタム設定を説明するために使用される単なる例の値です。これらは`longhorn`チャートのデプロイメントガイドラインとして扱うべきでは*ありません*。

59.2.6.2.1.2 チャートのFleetをデプロイする

GitRepo (59.2.6.2.1.2.1項 「GitRepo」)またはBundle (59.2.6.2.1.2.2項 「バンドル」)のいずれかを使用して、チャートのFleetをデプロイできます。

注記
注記

Fleetのデプロイ中に`Modified`メッセージが表示された場合は、対応する`comparePatches`エントリをFleetの`diff`セクションに必ず追加してください。詳細については、変更されたGitRepoを無視するためのDiffの生成を参照してください。

59.2.6.2.1.2.1 GitRepo

FleetのGitRepoリソースには、チャートのFleetリソースにアクセスする方法と、それらのリソースを適用する必要があるクラスターに関する情報が保持されています。

`GitRepo`リソースは、Rancher UIを通じてデプロイするか、または手動で`management cluster`にデプロイすることもできます。

手動*デプロイ用の*Longhorn`GitRepo`リソースの例:

apiVersion: fleet.cattle.io/v1alpha1
kind: GitRepo
metadata:
  name: longhorn-git-repo
  namespace: fleet-local
spec:
  # If using a tag
  # revision: user_repository_tag
  #
  # If using a branch
  # branch: user_repository_branch
  paths:
  # As seen in the 'Prepare your Fleet resources' example
  - longhorn
  - longhorn-crd
  repo: user_repository_url
59.2.6.2.1.2.2 バンドル

Bundleリソースには、Fleetによってデプロイされる必要がある生のKubernetesリソースが保持されています。通常は`GitRepo`アプローチの使用が推奨されますが、環境がエアギャップ(された)状態でローカルGitサーバーをサポートできないユースケースでは、`Bundles`がHelmチャートFleetをターゲットクラスターにデプロイするのに役立ちます。

Bundle`は、Rancher UI(`Continuous Delivery → Advanced → Bundles → Create from YAML)を通じて、または正しいFleetネームスペースに`Bundle`リソースを手動でデプロイすることでデプロイできます。Fleetネームスペースの詳細については、アップストリームのドキュメントを参照してください。

Edge Helmチャート用の`Bundles`は、FleetのHelmチャートをバンドルに変換するアプローチを利用して作成できます。

以下に、longhornおよびlonghorn-crd HelmチャートFleetテンプレートから`Bundle`リソースを作成し、このバンドルを`management cluster`に手動でデプロイする方法の例を示します。

注記
注記

ワークフローを説明するために、以下の例ではsuse-edge/fleet-examples ディレクトリ構造を使用しています。

  1. longhornチャートFleetテンプレートに移動します:

    cd fleets/day2/chart-templates/longhorn/longhorn
  2. FleetがHelmチャートをデプロイすべきクラスターを指示する`targets.yaml`ファイルを作成します。

    cat > targets.yaml <<EOF
    targets:
    # Match your local (management) cluster
    - clusterName: local
    EOF
    注記
    注記

    ローカルクラスタの名前が異なる場合があるユースケースがいくつか存在します。

    ローカルクラスタ名を取得するには、以下のコマンドを実行します。

    kubectl get clusters.fleet.cattle.io -n fleet-local
  3. fleet-cliを使用して、Longhorn HelmチャートFleetをBundleリソースに変換します。

    注記
    注記

    FleetのCLIは、リリース・*アセット*ページ(fleet-linux-amd64)から取得できます。

    Macユーザー向けには、fleet-cliのHomebrew Formulaeが用意されています。

    fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - longhorn-bundle > longhorn-bundle.yaml
  4. longhorn-crdチャートのFleetテンプレートに移動します。

    cd fleets/day2/chart-templates/longhorn/longhorn-crd
  5. FleetがHelmチャートをデプロイすべきクラスターを指示する`targets.yaml`ファイルを作成します。

    cat > targets.yaml <<EOF
    targets:
    # Match your local (management) cluster
    - clusterName: local
    EOF
  6. fleet-cliを使用して、Longhorn CRD HelmチャートFleetをBundleリソースに変換します。

    fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - longhorn-crd-bundle > longhorn-crd-bundle.yaml
  7. `longhorn-bundle.yaml`および`longhorn-crd-bundle.yaml`ファイルを`management cluster`にデプロイします。

    kubectl apply -f longhorn-crd-bundle.yaml
    kubectl apply -f longhorn-bundle.yaml

これらの手順に従うことで、指定されたすべてのmanagementクラスターに`SUSE Storage`が確実にデプロイされます。

59.2.6.2.1.3 デプロイされたHelmチャートを管理する

Fleetでデプロイした後、Helmチャートのアップグレードについては59.2.6.2.2項 「Fleetで管理されているHelmチャートをアップグレードしたい」を参照してください。

59.2.6.2.2 Fleetで管理されているHelmチャートをアップグレードしたい
  1. 目的のEdgeリリースと互換性を持たせるために、チャートをアップグレードする必要があるバージョンを決定します。EdgeリリースごとのHelmチャートバージョンは、リリースノート (第78章 「リリースノート」)から確認できます。

  2. Fleetで監視されているGitリポジトリで、Helmチャートの`fleet.yaml`ファイルを編集し、リリースノート (第78章 「リリースノート」)から正しいチャートの*バージョン*と*リポジトリ*を指定します。

  3. 変更をコミットしてリポジトリにプッシュすると、目的のHelmチャートのアップグレードがトリガーされます。

59.2.6.2.3 EIB経由でデプロイされたHelmチャートをアップグレードしたい

第12章 「Edge Image Builder」は、`HelmChart`リソースを作成し、RKE2/K3s Helm統合機能によって導入された`helm-controller`を利用することで、Helmチャートをデプロイします。

`EIB`経由でデプロイされたHelmチャートが確実にアップグレードされるように、ユーザーはそれぞれの`HelmChart`リソースに対してアップグレードを行う必要があります。

以下の情報をご覧ください。

59.2.6.2.3.1 概要

`EIB`経由でデプロイされたHelmチャートは、eib-charts-upgraderと呼ばれる`fleet`を通じてアップグレードされます。

この`fleet`は、*ユーザー提供*のデータを処理して、特定のHelmChartリソースのセットを*更新*します。

これらのリソースを更新するとhelm-controllerがトリガーされ、変更された`HelmChart`リソースに関連付けられたHelmチャートが*アップグレード*されます。

ユーザーが行う必要があるのは、以下の操作のみです。

  1. アップグレードが必要な各Helmチャートのアーカイブをローカルでプルします。

  2. これらのアーカイブをgenerate-chart-upgrade-data.sh`generate-chart-upgrade-data.sh`スクリプトに渡します。このスクリプトは、これらのアーカイブのデータを`eib-charts-upgrader`Fleetに含めます。

  3. `eib-charts-upgrader`Fleetを`management cluster`にデプロイします。これは、`GitRepo`または`Bundle`リソースのいずれかを通じて行われます。

デプロイされると、`eib-charts-upgrader`はFleetの助けを借りて、そのリソースを目的のmanagementクラスターに配布します。

これらのリソースには以下が含まれます。

  1. *ユーザー提供*のHelmチャートデータを保持する`Secrets`のセット。

  2. 前述の`Secrets`をマウントし、それに基づいて対応するHelmChartリソースをパッチする`Pod`をデプロイする`Kubernetes Job`。

前述の通り、これにより`helm-controller`がトリガーされ、実際のHelmチャートのアップグレードが実行されます。

上記の説明の図を以下に示します。

fleet day2 management helm eib upgrade
59.2.6.2.3.2 アップグレード手順
  1. 正しいリリースタグから`suse-edge/fleet-examples`リポジトリをクローンします。

  2. プルしたHelmチャートアーカイブを保存するディレクトリを作成します。

    mkdir archives
  3. 新しく作成したアーカイブディレクトリ内で、アップグレードするHelmチャートのアーカイブをpullします:

    cd archives
    helm pull [chart URL | repo/chartname]
    
    # Alternatively if you want to pull a specific version:
    # helm pull [chart URL | repo/chartname] --version 0.0.0
  4. 目的のリリースタグの*アセット*から、`generate-chart-upgrade-data.sh`スクリプトをダウンロードします。

  5. `generate-chart-upgrade-data.sh`スクリプトを実行します:

    chmod +x ./generate-chart-upgrade-data.sh
    
    ./generate-chart-upgrade-data.sh --archive-dir /foo/bar/archives/ --fleet-path /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader

    --archive-dir`ディレクトリ内の各チャートアーカイブに対して、スクリプトはチャートのアップグレードデータを含む`Kubernetes Secret YAML`ファイルを生成し、--fleet-path`で指定されたFleetの`base/secrets`ディレクトリに保存します。

    `generate-chart-upgrade-data.sh`スクリプトは、生成された`Kubernetes Secret YAML`ファイルがFleetによってデプロイされたワークロードで正しく使用されるように、Fleetに追加の変更を適用します。

    重要
    重要

    ユーザーは、`generate-chart-upgrade-data.sh`スクリプトが生成するものに対して変更を加えるべきではありません。

以下の手順は、実行している環境によって異なります:

  1. GitOpsをサポートしている環境(例:エアギャップ環境ではない、またはエアギャップ環境だがローカルGitサーバーのサポートが許可されている場合)の場合:

    1. GitOpsに使用するリポジトリに`fleets/day2/eib-charts-upgrader` Fleetをコピーします。

      注記
      注記

      `generate-chart-upgrade-data.sh`スクリプトによって行われた変更がFleetに含まれていることを確認してください。

    2. eib-charts-upgrader Fleetのすべてのリソースを配送するために使用される`GitRepo`リソースを設定します。

      1. Rancher UIを通じた`GitRepo`の設定とデプロイについては、Rancher UIでのFleetへのアクセスを参照してください。

      2. `GitRepo`の手動設定とデプロイについては、デプロイの作成を参照してください。

  2. GitOpsをサポートしていない環境(例:エアギャップで、ローカルGitサーバーの使用が許可されていない場合)の場合:

    1. `fleet-cli``rancher/fleet`のリリースページから、バイナリをダウンロードします(Linuxの場合は`fleet-linux-amd64`から)。Macユーザー向けには、使用可能なHomebrew Formulaeがあります - fleet-cli。

    2. eib-charts-upgrader Fleetに移動します:

      cd /foo/bar/fleet-examples/fleets/day2/eib-charts-upgrader
    3. どこにデプロイするかをFleetに指示する`targets.yaml`ファイルを作成します:

      cat > targets.yaml <<EOF
      targets:
      # To map the local(management) cluster
      - clusterName: local
      EOF
      注記
      注記

      local クラスターの名前が異なる場合がある使用事例がいくつかあります。

      local クラスター名を取得するには、以下のコマンドを実行します。

      kubectl get clusters.fleet.cattle.io -n fleet-local
    4. fleet-cli を使用して、Fleet を Bundle リソースに変換します。

      fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - eib-charts-upgrade > bundle.yaml

      これにより、eib-charts-upgrader Fleet からのすべてのテンプレート化されたリソースを保持する Bundle (bundle.yaml) が作成されます。

      fleet apply コマンドの詳細については、「fleet apply」を参照してください。

      Fleet を Bundle に変換する方法の詳細については、「Convert a Helm Chart into a Bundle」を参照してください。

    5. Bundle をデプロイする。これには、次の2つの方法があります。

      1. Rancher の UI を使用する場合 - 継続的デリバリ → Advanced → Bundles → Create from YAML に移動し、bundle.yaml の内容を貼り付けるか、Read from File オプションをクリックしてファイル自体を渡します。

      2. 手動 - bundle.yaml ファイルを`management cluster`内にデプロイします。

これらの手順を実行すると、GitRepo/Bundle リソースが正常にデプロイされます。このリソースは Fleet によって取得され、その内容はユーザーが前の手順で指定したターゲットクラスターにデプロイされる。この処理の概要については、「59.2.6.2.3.1項 「概要」」を参照してください。

アップグレードの処理を追跡する方法については、59.2.6.2.3.3項 「例」 を参照してください。

重要
重要

チャートのアップグレードが正常に確認できたら、Bundle/GitRepo リソースを削除する。

これにより、不要になったアップグレードリソースを management クラスターから削除することで、将来的なバージョン競合の発生を防ぐことができます。

59.2.6.2.3.3 例
注記
注記

以下の例は、EIB を介してデプロイされた Helm チャートを management クラスター上で別のバージョンにアップグレードする方法を示しています。この例で使用されているバージョンは*推奨されているものではありません*のでご注意ください。Edge リリース固有の推奨バージョンについては、「リリースノート (第78章 「リリースノート」)」を参照してください。

使用事例:

  • `management`クラスターで、Longhornの古いバージョンが実行されています。

  • クラスターはEIBを通じてデプロイされており、次のイメージ定義_snippet_を使用しています。

    kubernetes:
      helm:
        charts:
        - name: longhorn-crd
          repositoryName: rancher-charts
          targetNamespace: longhorn-system
          createNamespace: true
          version: 104.2.0+up1.7.1
          installationNamespace: kube-system
        - name: longhorn
          repositoryName: rancher-charts
          targetNamespace: longhorn-system
          createNamespace: true
          version: 104.2.0+up1.7.1
          installationNamespace: kube-system
        repositories:
        - name: rancher-charts
          url: https://charts.rancher.io/
    ...
  • SUSE Storage`は、Edge 3.7リリースと互換性のあるバージョンにアップグレードする必要があります。つまり、1.12.1`にアップグレードする必要があります。

  • `management cluster`は*エアギャップ(された)*であり、ローカルGitサーバーのサポートがなく、Rancherが正常にセットアップされていると想定されます。

アップグレード手順 (59.2.6.2.3.2項 「アップグレード手順」)に従ってください。

  1. `release-3.7.0`タグから`suse-edge/fleet-example`リポジトリをクローンします。

    git clone -b release-3.7.0 https://github.com/suse-edge/fleet-examples.git
  2. `Longhorn`アップグレードアーカイブを保存するディレクトリを作成します。

    mkdir archives
  3. 目的の`Longhorn`チャートアーカイブバージョンをプルします。

    # First add the Rancher Helm chart repository
    helm repo add rancher-charts https://charts.rancher.io/
    
    # Pull the Longhorn 1.12.1 chart archive
    helm pull oci://dp.apps.rancher.io/charts/suse-storage --version 1.12.1
  4. `archives`ディレクトリの外で、`suse-edge/fleet-examples`リリースtagから`generate-chart-upgrade-data.sh`スクリプトをダウンロードします。

  5. ディレクトリのセットアップは次のようになります。

    .
    ├── archives
    │   └── longhorn-1.12.1.tgz
    ├── fleet-examples
    ...
    │   ├── fleets
    │   │   ├── day2
    |   |   |   ├── ...
    │   │   │   ├── eib-charts-upgrader
    │   │   │   │   ├── base
    │   │   │   │   │   ├── job.yaml
    │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   ├── patches
    │   │   │   │   │   │   └── job-patch.yaml
    │   │   │   │   │   ├── rbac
    │   │   │   │   │   │   ├── cluster-role-binding.yaml
    │   │   │   │   │   │   ├── cluster-role.yaml
    │   │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   │   └── sa.yaml
    │   │   │   │   │   └── secrets
    │   │   │   │   │       ├── eib-charts-upgrader-script.yaml
    │   │   │   │   │       └── kustomization.yaml
    │   │   │   │   ├── fleet.yaml
    │   │   │   │   └── kustomization.yaml
    │   │   │   └── ...
    │   └── ...
    └── generate-chart-upgrade-data.sh
  6. `generate-chart-upgrade-data.sh`スクリプトを実行します:

    # First make the script executable
    chmod +x ./generate-chart-upgrade-data.sh
    
    # Then execute the script
    ./generate-chart-upgrade-data.sh --archive-dir ./archives --fleet-path ./fleet-examples/fleets/day2/eib-charts-upgrader

    スクリプト実行後のディレクトリ構造は次のようになります。

    .
    ├── archives
    │   └── longhorn-1.12.1.tgz
    ├── fleet-examples
    ...
    │   ├── fleets
    │   │   ├── day2
    │   │   │   ├── ...
    │   │   │   ├── eib-charts-upgrader
    │   │   │   │   ├── base
    │   │   │   │   │   ├── job.yaml
    │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   ├── patches
    │   │   │   │   │   │   └── job-patch.yaml
    │   │   │   │   │   ├── rbac
    │   │   │   │   │   │   ├── cluster-role-binding.yaml
    │   │   │   │   │   │   ├── cluster-role.yaml
    │   │   │   │   │   │   ├── kustomization.yaml
    │   │   │   │   │   │   └── sa.yaml
    │   │   │   │   │   └── secrets
    │   │   │   │   │       ├── eib-charts-upgrader-script.yaml
    │   │   │   │   │       ├── kustomization.yaml
    │   │   │   │   │       ├── longhorn-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script
    │   │   │   │   │       └── longhorn-crd-VERSION.yaml - secret created by the generate-chart-upgrade-data.sh script
    │   │   │   │   ├── fleet.yaml
    │   │   │   │   └── kustomization.yaml
    │   │   │   └── ...
    │   └── ...
    └── generate-chart-upgrade-data.sh

    gitで変更されたファイルは次のようになります。

    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
        modified:   fleets/day2/eib-charts-upgrader/base/patches/job-patch.yaml
        modified:   fleets/day2/eib-charts-upgrader/base/secrets/kustomization.yaml
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
        fleets/day2/eib-charts-upgrader/base/secrets/longhorn-VERSION.yaml
        fleets/day2/eib-charts-upgrader/base/secrets/longhorn-crd-VERSION.yaml
  7. Bundle Fleet用の`eib-charts-upgrader`を作成します。

    1. まず、Fleet自体に移動します。

      cd ./fleet-examples/fleets/day2/eib-charts-upgrader
    2. 次に、`targets.yaml`ファイルを作成します。

      cat > targets.yaml <<EOF
      targets:
      - clusterName: local
      EOF
    3. 次に、`fleet-cli`バイナリを使用してFleetをBundleに変換します。

      fleet apply --compress --targets-file=targets.yaml -n fleet-local -o - eib-charts-upgrade > bundle.yaml
  8. Rancher UIからBundleをデプロイします:

    day2 helm chart upgrade example 1
    図 59.1: Rancher UIからBundleをデプロイする

    ここから、*Read from File*を選択し、システム上の`bundle.yaml`ファイルを見つけます。

    これにより、RancherのUI内で`Bundle`が自動的に入力されます。

    [Create]を選択します。

  9. デプロイが成功すると、Bundleは次のようになります:

    day2 helm chart upgrade example 2
    図 59.2: Bundleのデプロイに成功しました

`Bundle`のデプロイが成功した後、アップグレードの処理を監視するには:

  1. `Upgrade Pod`のログを確認します:

    day2 helm chart upgrade example 3 management
  2. 次に、helm-controllerによってアップグレード用に作成されたPodのログを確認します:

    1. Pod名は次のテンプレートになります - helm-install-longhorn-<random-suffix>

    2. Podは、`HelmChart`リソースがデプロイされたネームスペースに配置されます。今回の場合は`kube-system`です。

      day2 helm chart upgrade example 4 management
      図 59.3: 正常にアップグレードされたLonghornチャートのログ
  3. Rancherの`HelmCharts`セクション(More Resources → HelmCharts)に移動して、`HelmChart`のバージョンが更新されていることを確認します。チャートがデプロイされたネームスペースを選択します。この例では`kube-system`になります。

  4. 最後に、Longhorn Podが実行されていることを確認します。

上記の検証を行った後、Longhorn Helmチャートが`1.12.1`バージョンにアップグレードされたと判断して問題ありません。

59.2.6.2.3.4 サードパーティのGitOpsツールを使用したHelmチャートのアップグレード

Fleet以外のGitOpsワークフロー(例:Flux)でこのアップグレード手順を使用したいというユースケースがあるかもしれません。

アップグレード手順に必要なリソースを作成するには、generate-chart-upgrade-data.sh スクリプトを使用して、ユーザーが提供したデータで eib-charts-upgrader Fleet を設定できます。この方法の詳細については、59.2.6.2.3.2項 「アップグレード手順」を参照してください。

セットアップが完了したら、Kustomize を使用して、クラスターにデプロイ可能な完全に機能するソリューションを生成できます。

cd /foo/bar/fleets/day2/eib-charts-upgrader

kustomize build .

GitOps ワークフローにソリューションを含める場合は、fleet.yaml ファイルを削除し、残りの部分を有効な Kustomize セットアップとして使用できます。最初に generate-chart-upgrade-data.sh スクリプトを実行して、アップグレード先の Helm チャートのデータで Kustomize セットアップを設定できるようにすることを忘れないでください。

このワークフローの使用方法を理解するには、59.2.6.2.3.1項 「概要」 と 59.2.6.2.3.2項 「アップグレード手順」 を参照すると役立ちます。

60 ライフサイクルアクション

このセクションでは、SUSE Telco Cloud経由でデプロイされたクラスターのライフサイクル管理について説明します。

60.1 ロードバランサーの除外

ノードのドレインを必要とするライフサイクルアクションは多数あります。ドレインプロセス中、すべてのポッドはクラスター内の他のノードに移動されます。ドレインプロセスが完了すると、ノードはサービスをホストしなくなるため、トラフィックをルーティングすべきではありません。MetalLBなどのロードバランサーは、ノードにラベルを適用することで、この状態を認識させることができます。

node.kubernetes.io/exclude-from-external-load-balancers: "true"

詳細については、 Kubernetesドキュメントを参照してください。

クラスター内のすべてのノードのラベルを確認するには、次のコマンドを実行します。

kubectl get nodes -o json | jq -r '.items[].metadata | .name, .labels'

ダウンストリームのクラスターのアップグレードの場合、管理クラスター上のRKE2ControlPlaneにアノテーションを付けることで、これを自動化できます。

rke2.controlplane.cluster.x-k8s.io/load-balancer-exclusion="true"

これにより、そのRKE2ControlPlaneの管理クラスター上のすべてのマシンオブジェクトにアノテーションが即座に作成されます。

pre-drain.delete.hook.machine.cluster.x-k8s.io/rke2-lb-exclusion: ""

マシンオブジェクトにこのアノテーションが付与されると、ダウンストリームのクラスターでドレインがスケジュールされているノードには、ドレインプロセスの開始前に上記のノードラベルが付けられます。ノードが再び利用可能になり準備が整うと、ラベルはノードから削除されます。

60.2 管理クラスターのアップグレード

管理クラスターのアップグレードについては、Day 2 管理クラスター (第59章 「管理クラスタ」)のドキュメントで説明されています。

60.3 ダウンストリームクラスターのアップグレード

ダウンストリームのクラスターのアップグレードには、いくつかのコンポーネントの更新が含まれます。以下のセクションでは、各コンポーネントのアップグレードプロセスについて説明します。

オペレーティングシステムのアップグレード

このプロセスについては、新しいオペレーティングシステムバージョンで新しいイメージをビルドするために、以下のリファレンス (第50章 「接続されたシナリオ向けのダウンストリームクラスターイメージの準備」)を確認してください。 `EIB`によって生成されたこの新しいイメージを使用すると、次のプロビジョニングフェーズで提供された新しいオペレーティングバージョンが使用されます。 次のステップでは、新しいイメージを使用してノードをアップグレードします。

RKE2クラスターのアップグレード

自動ワークフローを使用して`RKE2`クラスターをアップグレードするために必要な変更は以下の通りです。

  • 以下のセクション (第52章 「ダイレクトネットワークプロビジョニング(シングルノード)によるダウンストリームクラスターのプロビジョニング」)に示す`RKE2ControlPlane`のブロック`capi-provisioning-example.yaml`を変更します。

    • 目的の`rolloutStrategy`を指定してください。

      • 少なくとも3つのコントロールプレーンノードを持つマルチノード`RKE2`クラスターにおいて、`RKE2ControlPlane.spec.rolloutStrategy.type`フィールドを`"RollingUpdate"`に、`rolloutStrategy.rollingUpdate.maxSurge`を`0`に設定することで、関連する`Metal3MachineTemplate.spec.nodeReuse`も`True`に設定されている場合、アップグレードする際に余分なノードが作成されたり、追加が必要になったりすることがない点にご注意ください。

    • RKE2`クラスターのバージョンを、${RKE2_NEW_VERSION}`を置き換える新しいバージョンに変更します。

apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: RKE2ControlPlane
metadata:
  name: multinode-cluster
  namespace: default
spec:
  infrastructureRef:
    apiGroup: infrastructure.cluster.x-k8s.io
    kind: Metal3MachineTemplate
    name: multinode-cluster-controlplane
  version: ${RKE2_NEW_VERSION}
  replicas: 3
  rolloutStrategy:
    type: "RollingUpdate"
    rollingUpdate:
      maxSurge: 0
  serverConfig:
    cni: cilium
    tlsSan:
      - ${EDGE_VIP_ADDRESS_IPV4}
      - ${EDGE_VIP_ADDRESS_IPV6}
      - https://${EDGE_VIP_ADDRESS_IPV4}.sslip.io
      - https://${EDGE_VIP_ADDRESS_IPV6}.sslip.io
  rolloutStrategy:
    rollingUpdate:
      maxSurge: 0
  registrationMethod: "control-plane-endpoint"
  registrationAddress: ${EDGE_VIP_ADDRESS}
  agentConfig:
    format: ignition
    additionalUserData:
      config: |
        variant: fcos
        version: 1.4.0
        systemd:
          units:
          - name: rke2-preinstall.service
            enabled: true
            contents: |
              [Unit]
              Description=rke2-preinstall
              Wants=network-online.target
              Before=rke2-install.service
              ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
              [Service]
              Type=oneshot
              User=root
              ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
              # Note we use _ as a delimiter for sed here because the providerid includes / characters
              ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
              ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
              ExecStartPost=/bin/sh -c "umount /mnt"
              [Install]
              WantedBy=multi-user.target
        storage:
          directories:
          - path: /var/lib/rancher/rke2/server/manifests
            overwrite: true
          files:
            - path: /var/lib/rancher/rke2/server/manifests/endpoint-copier-operator.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: endpoint-copier-operator
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/endpoint-copier-operator
                    targetNamespace: endpoint-copier-operator
                    version: {version-endpoint-copier-operator-chart}
                    createNamespace: true
            - path: /var/lib/rancher/rke2/server/manifests/metallb.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChart
                  metadata:
                    name: metallb
                    namespace: kube-system
                  spec:
                    chart: oci://registry.suse.com/edge/charts/metallb
                    targetNamespace: metallb-system
                    version: {version-metallb-chart}
                    createNamespace: true
            - path: /var/lib/rancher/rke2/server/manifests/metallb-cr.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: metallb.io/v1beta1
                  kind: IPAddressPool
                  metadata:
                    name: kubernetes-vip-ip-pool
                    namespace: metallb-system
                  spec:
                    addresses:
                      - ${EDGE_VIP_ADDRESS_IPV4}/32
                      - ${EDGE_VIP_ADDRESS_IPV6}/128
                    serviceAllocation:
                      priority: 100
                      namespaces:
                        - default
                      serviceSelectors:
                        - matchExpressions:
                          - {key: "serviceType", operator: In, values: [kubernetes-vip]}
                  ---
                  apiVersion: metallb.io/v1beta1
                  kind: L2Advertisement
                  metadata:
                    name: ip-pool-l2-adv
                    namespace: metallb-system
                  spec:
                    ipAddressPools:
                      - kubernetes-vip-ip-pool
            - path: /var/lib/rancher/rke2/server/manifests/endpoint-svc.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: v1
                  kind: Service
                  metadata:
                    name: kubernetes-vip
                    namespace: default
                    labels:
                      serviceType: kubernetes-vip
                  spec:
                    ipFamilyPolicy: PreferDualStack
                    ports:
                    - name: rke2-api
                      port: 9345
                      protocol: TCP
                      targetPort: 9345
                    - name: k8s-api
                      port: 6443
                      protocol: TCP
                      targetPort: 6443
                    type: LoadBalancer
            ###############################################################################
            # In case of deploying the RKE2 ingress controller, the following 2 files must
            # be added.
            # NOTE: The .providers stanza can be removed from the Helm parameters settings
            #       here below in case of not deploying/not planning to deploy Ingress
            #       objects including ingress-nginx annotations in its `.metadata` stanza.
            ###############################################################################
            - path: /var/lib/rancher/rke2/server/manifests/rke2-traefik-config.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: helm.cattle.io/v1
                  kind: HelmChartConfig
                  metadata:
                    name: rke2-traefik
                    namespace: kube-system
                  spec:
                    valuesContent: |-
                      ingressClass:
                        isDefaultClass: false
                      ports:
                        web:
                          hostPort: null    # disallow hostPort
                          exposedPort: 80
                        websecure:
                          hostPort: null    # disallow hostPort
                          exposedPort: 443
                      service:
                        enabled: true
                        spec:
                          type: LoadBalancer
                          ipFamilyPolicy: PreferDualStack
                          externalTrafficPolicy: Local
                          allocateLoadBalancerNodePorts: false
                      providers:
                        kubernetesIngressNGINX:  # this provider allows Traefik to "understand" most of the Ingress-NGINX annotations
                          enabled: true
                          ingressClass: "rke2-ingress-nginx-migration"
                          controllerClass: "rke2.​cattle.​io/ingress-nginx-migration"
              mode: 0644
              user:
                name: root
              group:
                name: root
            - path: /var/lib/rancher/rke2/server/manifests/metallb-traefik-cr.yaml
              overwrite: true
              contents:
                inline: |
                  apiVersion: metallb.io/v1beta1
                  kind: IPAddressPool
                  metadata:
                    name: ingress-ippool
                    namespace: metallb-system
                  spec:
                    addresses:
                      - ${INGRESS_IPV4}/32
                      - ${INGRESS_IPV6}/128
                    serviceAllocation:
                      priority: 100
                      serviceSelectors:
                      - matchExpressions:
                        - {key: app.kubernetes.io/name, operator: In, values: [rke2-traefik]} # assign to rke2-traefik LB svc
                  ---
                  apiVersion: metallb.io/v1beta1
                  kind: L2Advertisement
                  metadata:
                    name: ingress-l2-adv
                    namespace: metallb-system
                  spec:
                    ipAddressPools:
                      - ingress-ippool
              mode: 0644
              user:
                name: root
              group:
                name: root
    kubelet:
      extraArgs:
      - provider-id=metal3://PROVIDERID
    nodeName: "localhost.localdomain"
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3MachineTemplate
metadata:
  name: multinode-cluster-controlplane
  namespace: default
spec:
  nodeReuse: True
  template:
    spec:
      automatedCleaningMode: metadata
      dataTemplate:
        name: multinode-cluster-controlplane-template
      hostSelector:
        matchLabels:
          cluster-role: control-plane
      image:
        checksum: http://imagecache.local:8080/${NEW_IMAGE_GENERATED}.sha256
        checksumType: sha256
        diskFormat: raw
        url: http://imagecache.local:8080/${NEW_IMAGE_GENERATED}.raw

capi-provisioning-example.yaml ファイルを適用する前に、外部ロードバランサー(MetalLBなど)にノードがドレイン中であることを通知し、その状態のノードにトラフィックがルーティングされないようにすることをお勧めします。前述の 60.1項 「ロードバランサーの除外」 セクションで述べたように、管理クラスター上の RKE2ControlPlane にアノテーションを付けることで、これを自動化できます。この例では、multinode-cluster という名前の RKE2ControlPlane オブジェクトにアノテーションが付けられています。

kubectl annotate  RKE2ControlPlane/multinode-cluster  rke2.controlplane.cluster.x-k8s.io/load-balancer-exclusion="true"

マシンオブジェクトにアノテーションが付けられていることを確認します。

pre-drain.delete.hook.machine.cluster.x-k8s.io/rke2-lb-exclusion: ""

すべてのマシンオブジェクトのアノテーションを取得します。

kubectl get machines -o json | jq -r '.items[].metadata | .name, .annotations'
注記
注記

これらのアノテーションがないと、ロードバランサーがドレインされたノードを認識できないため、サービスの応答時間が長くなる可能性があります。

これらの変更を行った後、次のコマンドを使用して capi-provisioning-example.yaml ファイルをクラスターに適用できます。

kubectl apply -f capi-provisioning-example.yaml

60.4 Longhorn Engineイメージのクリーンアップ

本セクションでは、クラスターをアップグレードする際に蓄積される不要なLonghorn Engineイメージの自動クリーンアップを実装する方法について説明します。

60.4.1 問題の定義

Longhornは、アップグレード後に古いエンジンイメージを自動的に削除しません。これは、偶発的なデータ損失を防ぐための意図的な設計上の決定です。Longhornは、ロールバックが必要になった場合に備えて、安全対策として以前のエンジンイメージバージョンを保持します。

しかし、頻繁にアップグレードが行われる本番環境では、これらの未使用のエンジンイメージが時間の経過とともに蓄積され、以下の問題が発生します。

  • ストレージ消費:各エンジンイメージがクラスターノード上のディスク容量を消費する

  • リソースオーバーヘッド:Kubernetesが不要なイメージリソースを管理してしまう

  • 運用上の複雑さ:不要になったイメージの手動特定とクリーンアップが必要になる

60.4.2 クリーンアップを実施すべきタイミング

エンジンイメージのクリーンアップは、以下のシナリオで推奨されます。

  • 定期的なクラスターアップグレード:Longhornのバージョンアップグレードを頻繁に行う環境

  • ストレージ容量が限られた環境:ノードのストレージ容量が限られているクラスター

  • 運用上の衛生管理:日常的なDay 2メンテナンス手順の一環として

注記
注記

このクリーンアップ手順は、アクティブな参照がゼロのエンジンイメージのみを削除するため、低リスクに分類されます (refCount == 0)。現在ボリュームで使用されているイメージは保護されており、削除されません。

60.4.3 ソリューションアーキテクチャ

クリーンアップソリューションは、定期的なメンテナンス作業を実行するKubernetes CronJobを使用します:

  1. 検出:クラスターにデプロイされている最新のLonghorn Engineイメージバージョンを特定します

  2. 候補の選択:アクティブなボリューム参照がない古いエンジンイメージバージョンをすべて特定します

  3. クリーンアップの実行:安全基準を満たす不要なエンジンイメージを削除します

  4. 監査ログ:運用の可視化のためにクリーンアップ操作を記録します

実装には以下が必要です:

  • ServiceAccount:Kubernetes APIへの認証用

  • RBAC権限:`engineimages.longhorn.io`リソースへの読み取りおよび削除アクセス権

  • CronJob:クリーンアップロジックを含むスケジュール実行コンテナ

60.4.4 実装

完全なクリーンアップソリューションは、`longhorn-system`ネームスペースにデプロイされる4つのKubernetesマニフェストで構成されています。

  1. ServiceAccountを作成

    クリーンアップCronJob専用のServiceAccountを作成します。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: longhorn-engineimage-cleanup
      namespace: longhorn-system
      labels:
        app: longhorn-engineimage-cleanup
  2. RBAC権限を構成

    1. 最小限の必要な権限を持つRoleを定義します。

      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: longhorn-engineimage-cleanup
        namespace: longhorn-system
        labels:
          app: longhorn-engineimage-cleanup
      rules:
      - apiGroups: [longhorn.io]
        resources: [engineimages]
        verbs: [get, list, delete]
    2. RoleをServiceAccountにバインドします。

      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: longhorn-engineimage-cleanup
        namespace: longhorn-system
        labels:
          app: longhorn-engineimage-cleanup
      subjects:
      - kind: ServiceAccount
        name: longhorn-engineimage-cleanup
        namespace: longhorn-system
      roleRef:
        kind: Role
        name: longhorn-engineimage-cleanup
        apiGroup: rbac.authorization.k8s.io
  3. クリーンアップCronJobをデプロイ

    自動クリーンアップCronJobをデプロイします。

    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: longhorn-engineimage-cleanup
      namespace: longhorn-system
      labels:
        app: longhorn-engineimage-cleanup
      annotations:
        description: "Cleanup old Longhorn engine images left over after upgrades"
        source: "SUSE Edge Telco Cloud - Day 2 Operations"
    spec:
      # Execute weekly on Sunday at 2:00 AM UTC
      schedule: "0 2 * * 0"
      successfulJobsHistoryLimit: 3
      failedJobsHistoryLimit: 3
      concurrencyPolicy: Forbid
      jobTemplate:
        spec:
          backoffLimit: 2
          activeDeadlineSeconds: 600
          template:
            metadata:
              labels:
                app: longhorn-engineimage-cleanup
            spec:
              serviceAccountName: longhorn-engineimage-cleanup
              restartPolicy: Never
              automountServiceAccountToken: true
              containers:
              - name: cleanup
                image: registry.suse.com/bci/bci-base:15.6
                command:
                - sh
                - -c
                - |
                  set -e
    
                  # Install required tools
                  zypper --non-interactive install curl jq
    
                  # Install kubectl from official Kubernetes
                  curl -LO "https://dl.k8s.io/release/v1.36.3/bin/linux/amd64/kubectl"
                  chmod +x kubectl
                  mv kubectl /usr/local/bin/
    
                  echo "=== Longhorn Engine Image Cleanup ==="
                  echo "Automated maintenance - Day 2 Operations"
                  echo ""
    
                  echo "Step 1: Discovering latest engine image version..."
    
                  ENGINE_IMAGES=$(kubectl get engineimages.longhorn.io -n longhorn-system -o json)
    
                  LATEST_VERSION=$(echo "$ENGINE_IMAGES" | jq -r '
                    .items[]
                    | select(.status.version != null)
                    | .status.version' |
                    sed 's/^v//' |
                    sort -V |
                    tail -1)
    
                  if [ -z "$LATEST_VERSION" ]; then
                    echo "No engine images found. Nothing to cleanup."
                    exit 0
                  fi
    
                  echo "Latest version detected: v${LATEST_VERSION}"
                  echo ""
    
                  echo "Step 2: Identifying obsolete engine images..."
    
                  TO_DELETE=$(echo "$ENGINE_IMAGES" | jq -r --arg latest "v${LATEST_VERSION}" '
                    .items[]
                    | select(.status.version != $latest)
                    | select(.status.refCount == 0)
                    | .metadata.name')
    
                  if [ -z "$TO_DELETE" ]; then
                    echo "No obsolete engine images found"
                    echo "All engine images are either:"
                    echo "  - Latest version (v${LATEST_VERSION})"
                    echo "  - Still in use (refCount > 0)"
                    exit 0
                  fi
    
                  DELETE_COUNT=$(echo "$TO_DELETE" | wc -l | tr -d ' ')
                  echo "Found $DELETE_COUNT obsolete engine image(s) for deletion:"
                  echo "$TO_DELETE"
                  echo ""
    
                  COUNT=0
                  FAILED=0
                  for IMAGE_NAME in $TO_DELETE; do
                    VERSION=$(echo "$ENGINE_IMAGES" | jq -r --arg name "$IMAGE_NAME" \
                      '.items[] | select(.metadata.name == $name) | .status.version')
                    REFCOUNT=$(echo "$ENGINE_IMAGES" | jq -r --arg name "$IMAGE_NAME" \
                      '.items[] | select(.metadata.name == $name) | .status.refCount')
    
                    echo "Deleting: $IMAGE_NAME (version: $VERSION, refCount: $REFCOUNT)"
    
                    if kubectl delete engineimages.longhorn.io "$IMAGE_NAME" -n longhorn-system; then
                      COUNT=$((COUNT + 1))
                      echo "  ✓ Deleted successfully"
                    else
                      FAILED=$((FAILED + 1))
                      echo "  ✗ Failed to delete"
                    fi
                  done
    
                  echo ""
                  echo "=== Cleanup Summary ==="
                  echo "Latest version: v${LATEST_VERSION}"
                  echo "Successfully deleted: $COUNT obsolete engine images"
                  echo "Failed deletions: $FAILED engine images"
    
                  if [ $FAILED -gt 0 ]; then
                    exit 1
                  fi
    
                  echo ""
                  echo "Cleanup completed successfully"
  4. 設定を適用

    1. 4つのマニフェストすべてを1つのファイル(例: longhorn-engine-cleanup.yaml)に保存し、クラスターにデプロイします。

      kubectl apply -f longhorn-engine-cleanup.yaml
    2. CronJobが作成されたことを確認します。

      kubectl get cronjob -n longhorn-system longhorn-engineimage-cleanup

      予想される出力:

      NAME                            SCHEDULE     SUSPEND   ACTIVE   LAST SCHEDULE   AGE
      longhorn-engineimage-cleanup    0 2 * * 0    False     0        <none>          5s

60.4.5 運用手順

このセクションでは、手動実行、スケジュールのカスタマイズ、監視、検証など、LonghornエンジンイメージクリーンアップCronJobを管理するための日常的な運用タスクについて説明します。

60.4.5.1 手動実行

スケジュールされた時間を待たずにすぐにクリーンアップを実行するには、次のコマンドを実行します。

kubectl create job --from=cronjob/longhorn-engineimage-cleanup \
  longhorn-engineimage-cleanup-manual-$(date +%Y%m%d-%H%M%S) \
  -n longhorn-system

手動実行の監視:

  1. ジョブステータスの監視:

    kubectl get jobs -n longhorn-system -w
  2. ジョブログの表示:

    kubectl logs -n longhorn-system -l app=longhorn-engineimage-cleanup --tail=100

60.4.5.2 スケジュール設定

デフォルトのスケジュールでは、毎週日曜日の午前2:00(UTC)にクリーンアップが実行されます。

schedule: "0 2 * * 0"

一般的なスケジュールの代替案:

  • 毎日午前3:00: "0 3 * * *"

  • 毎月1日の午前4:00: "0 4 1 * *"

  • 6時間ごと: "0 */6 * * *"

スケジュールを変更します:

kubectl patch cronjob longhorn-engineimage-cleanup \
  -n longhorn-system \
  --type='merge' \
  -p '{"spec":{"schedule":"0 3 * * *"}}'

60.4.5.3 監視とログ

クリーンアップ履歴を表示します:

  • 完了したジョブを一覧表示します:

    kubectl get jobs -n longhorn-system -l app=longhorn-engineimage-cleanup
  • 前回の正常実行のログを表示します:

    kubectl logs -n longhorn-system \
      -l app=longhorn-engineimage-cleanup \
      --tail=200 \
      | grep -A 50 "Cleanup Summary"

特定のジョブ実行を検査します:

# Get job name
JOB_NAME=$(kubectl get jobs -n longhorn-system \
  -l app=longhorn-engineimage-cleanup \
  --sort-by=.metadata.creationTimestamp \
  -o jsonpath='{.items[-1].metadata.name}')

# View job details
kubectl describe job $JOB_NAME -n longhorn-system

# View job logs
kubectl logs job/$JOB_NAME -n longhorn-system

60.4.5.4 検証

クリーンアップ実行後、現在のエンジンイメージのみが残っていることを確認します:

  1. すべてのエンジンイメージを一覧表示します:

    kubectl get engineimages.longhorn.io -n longhorn-system
  2. 参照カウントを確認します:

    kubectl get engineimages.longhorn.io -n longhorn-system \
      -o custom-columns=NAME:.metadata.name,VERSION:.status.version,REFCOUNT:.status.refCount

アクティブな参照を持つ最新バージョンのみが表示される予期される出力です:

NAME                                VERSION     REFCOUNT
ei-acba2c08                         v1.12.1     3

パート IX ハウツーガイド

ハウツーガイドとベストプラクティス

  • 61 K3s上のMetalLB(レイヤー2モードを使用)
  • MetalLBは、標準的なルーティングプロトコルを使用する、ベアメタルKubernetesクラスター向けのロードバランサー実装です。

  • 62 K3s上のMetalLB(レイヤー3モードを使用)
  • MetalLBは、標準的なルーティングプロトコルを使用する、ベアメタルKubernetesクラスター向けの負荷分散実装です。

  • 63 Kubernetes APIサーバーの前にあるMetalLB
  • このガイドでは、MetalLBサービスを使用して、3つのコントロールプレーンノードを持つHAクラスター上でRKE2/K3s APIを外部に公開する方法を説明します。 これを実現するために、タイプ`LoadBalancer`のKubernetesサービスを手動で作成します。次に、クラスター内のすべてのコントロールプレーンノードのIPを保持する`EndpointSlices`オブジェクトが自動的に作成されます。 EndpointSlicesをクラスター内で発生するイベント(ノードの追加/削除、またはノードのオフライン化)と継続的に同期させるために、Endpoint Copier Operator …

  • 64 Edge Image Builder を使用したエアギャップ(された)デプロイメント
  • このガイドでは、Edge Image Builder(EIB) (第12章 「Edge Image Builder」) を利用して、SUSE Linux Micro 6.2 上で SUSE Telco Cloud コンポーネントの一部を完全にエアギャップ(された)環境でデプロイする方法を説明します。これにより、EIB によって作成されたカスタマイズ済みで起動可能な (CRB) イメージで起動し、インターネット接続や手動の手順なしで、指定されたコンポーネントを RKE2 または K3s クラスターにデプロイできるようになります。この構成は、デプロイに必要なすべてのアーティファクトを OS イメー…

  • 65 Kiwiを使用して更新されたSUSE Linux Microイメージを構築する
  • このセクションでは、Edge Image Builder、Cluster API (CAPI) + Metal3で使用する、またはディスクイメージをブロックデバイスに直接書き込むための、更新されたSUSE Linux Microイメージの生成方法について説明します。このプロセスは、初期システムブートイメージに最新のパッチを含める必要がある場合(インストール後のパッチ転送を最小限に抑えるため)、またはCAPIを使用するシナリオで、ホストをその場でアップグレードするよりも新しいイメージでオペレーティングシステムを再インストールすることが望ましい場合に役立ちます。

  • 66 SUSE Storage V2データエンジン
  • SUSE Storage 1.12.1には、一般提供機能としてLonghorn V2データエンジンが含まれています。 SUSE Telco Cloud 3.7以降、クラスターがV2の前提条件を満たしている場合、新規にプロビジョニングされるボリュームにはV2データエンジンが推奨されます。

  • 67 ClusterClassを使用してダウンストリームクラスターをデプロイする
  • Kubernetesクラスターのプロビジョニングは、クラスターコンポーネントの構成に関する深い専門知識を必要とする複雑なタスクです。構成が複雑になるにつれて、あるいは異なるプロバイダーの要求によってプロバイダー固有のリソース定義が多数導入されるにつれて、クラスターの作成は困難に感じられることがあります。 幸いなことに、Kubernetes Cluster API (CAPI) は、ClusterClassによってさらに強化された、よりエレガントで宣言的なアプローチを提供します。 この機能はテンプレート駆動型のモデルを導入しており、複雑さをカプセル化し一貫性を促進する再利用可能なクラスタークラス…

  • 68 Longhorn Volume 暗号化
  • Longhornは、レプリケーションと高可用性機能を備えた永続ストレージを提供する、Kubernetes向けの分散ブロックストレージシステムです。本ガイドでは、保存データの保護を確実にするために、LUKS/AES-256暗号化を使用してLonghornを構成する方法を説明します。

61 K3s上のMetalLB(レイヤー2モードを使用)

MetalLBは、標準的なルーティングプロトコルを使用する、ベアメタルKubernetesクラスター向けのロードバランサー実装です。

このガイドでは、MetalLBをレイヤー2(L2)モードでデプロイする方法を説明します。

61.1 MetalLBを使用する理由

MetalLBがベアメタルKubernetesクラスターでのロードバランシングにおいて魅力的な選択肢である理由はいくつかあります。

  1. Kubernetesとのネイティブな統合:MetalLBはKubernetesとシームレスに統合されるため、使い慣れたKubernetesツールや手法を使用して簡単にデプロイおよび管理できます。

  2. ベアメタルとの互換性:クラウドベースのロードバランサーとは異なり、MetalLBは、従来のロードバランサーが利用できない、または実現不可能なオンプレミス環境向けに特別に設計されています。

  3. 複数のプロトコルをサポート:MetalLBはレイヤー2モードとBGP(Border Gateway Protocol)モードの両方をサポートしており、さまざまなネットワークアーキテクチャや要件に対応できる柔軟性を備えています。

  4. 高可用性:MetalLBは、ロードバランシングの役割を複数のノードに分散させることで、サービスの可用性と信頼性を確保します。

  5. スケーラビリティ:MetalLBは大規模なデプロイメントに対応でき、Kubernetesクラスターとともにスケーリングして、増大する需要を満たすことができます。

レイヤー2モードでは、1つのノードがローカルネットワークに対してサービスをアドバタイズする役割を担います。ネットワークの観点からは、そのマシンに複数のIPアドレスがネットワークインタフェースに割り当てられているように見えるだけです。

レイヤー2モードの最大の利点はその汎用性です。特別なハードウェアや高度なルーターを必要とせず、あらゆるイーサネットネットワークで動作します。

61.2 K3s上のMetalLB(L2を使用)

このクイックスタートでは、L2モードを使用します。 これは、特別なネットワーク機器は必要なく、ネットワーク範囲内で3つの空きIPアドレスが必要であることを意味します。

61.3 前提条件

  • MetalLBをデプロイするK3sクラスター。

警告
警告

K3sには、Klipperという独自のサービスロードバランサーが付属しています。MetalLBを実行するには、 それを無効にする必要があります。Klipperを無効にするには、`--disable=servicelb`フラグを使用してK3sをインストールする必要があります。

  • Helm

  • ネットワーク範囲内の3つの未割り当てIPアドレス。この例では`192.168.122.10-192.168.122.12`

重要
重要

これらのIPアドレスが割り当てられていないことを確認する必要があります。 DHCP環境では、二重割り当てを避けるため、これらのアドレスをDHCPプールに含めないようにする必要があります。

61.4 展開

SUSE Telco Cloudソリューションの一部として公開されているMetalLB Helmチャートを使用します。

helm install \
  metallb oci://registry.suse.com/edge/charts/metallb \
  --namespace metallb-system \
  --create-namespace

while ! kubectl wait --for condition=ready -n metallb-system $(kubectl get\
 pods -n metallb-system -l app.kubernetes.io/component=controller -o name)\
 --timeout=10s; do
 sleep 2
done

61.5 設定

この時点で、インストール作業は完了です。それでは、例の値を使用して 設定を行います。

cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: ip-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.122.10/32
  - 192.168.122.11/32
  - 192.168.122.12/32
EOF
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: ip-pool-l2-adv
  namespace: metallb-system
spec:
  ipAddressPools:
  - ip-pool
EOF

これで、使用する準備が整いました。L2モードでは、以下のような多くの項目をカスタマイズできます。

その他、 BGPに関する多くの設定が可能です。

61.5.1 TraefikとMetalLB

TraefikはK3sでデフォルトでデプロイされ( https://docs.k3s.io/networking#traefik-ingress-controller`--disable=traefik`で無効化可能)、デフォルトで`LoadBalancer`として公開されます(Klipperで使用するため)。しかし、Klipperを無効にする必要があるため、イングレス用のTraefikサービスは依然として`LoadBalancer`タイプです。そのため、MetalLBをデプロイする時点で、最初のIPが自動的にTraefik Ingressに割り当てられます。

# Before deploying MetalLB
kubectl get svc -n kube-system traefik
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
traefik   LoadBalancer   10.43.44.113   <pending>     80:31093/TCP,443:32095/TCP   28s
# After deploying MetalLB
kubectl get svc -n kube-system traefik
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)                      AGE
traefik   LoadBalancer   10.43.44.113   192.168.122.10   80:31093/TCP,443:32095/TCP   3m10s

これはプロセスの後ほど (61.6.1項 「MetalLBを使用したイングレス」)適用されます。

61.6 使用方法

デプロイメントの例を作成してみましょう。

cat <<- EOF | kubectl apply -f -
---
apiVersion: v1
kind: Namespace
metadata:
  name: hello-kubernetes
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: hello-kubernetes
  namespace: hello-kubernetes
  labels:
    app.kubernetes.io/name: hello-kubernetes
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes
  namespace: hello-kubernetes
  labels:
    app.kubernetes.io/name: hello-kubernetes
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: hello-kubernetes
  template:
    metadata:
      labels:
        app.kubernetes.io/name: hello-kubernetes
    spec:
      serviceAccountName: hello-kubernetes
      containers:
        - name: hello-kubernetes
          image: "paulbouwer/hello-kubernetes:1.10"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          env:
          - name: HANDLER_PATH_PREFIX
            value: ""
          - name: RENDER_PATH_PREFIX
            value: ""
          - name: KUBERNETES_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: KUBERNETES_POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: KUBERNETES_NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: CONTAINER_IMAGE
            value: "paulbouwer/hello-kubernetes:1.10"
EOF

そして最後に、サービスです。

cat <<- EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes
  namespace: hello-kubernetes
  labels:
    app.kubernetes.io/name: hello-kubernetes
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: hello-kubernetes
EOF

実際に動作している様子を見てみましょう。

kubectl get svc -n hello-kubernetes
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
hello-kubernetes   LoadBalancer   10.43.127.75   192.168.122.11   80:31461/TCP   8s

curl http://192.168.122.11
<!DOCTYPE html>
<html>
<head>
    <title>Hello Kubernetes!</title>
    <link rel="stylesheet" type="text/css" href="/css/main.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300" >
</head>
<body>

  <div class="main">
    <img src="/images/kubernetes.png"/>
    <div class="content">
      <div id="message">
  Hello world!
</div>
<div id="info">
  <table>
    <tr>
      <th>namespace:</th>
      <td>hello-kubernetes</td>
    </tr>
    <tr>
      <th>pod:</th>
      <td>hello-kubernetes-7c8575c848-2c6ps</td>
    </tr>
    <tr>
      <th>node:</th>
      <td>allinone (Linux 5.14.21-150400.24.46-default)</td>
    </tr>
  </table>
</div>
<div id="footer">
  paulbouwer/hello-kubernetes:1.10 (linux/amd64)
</div>
    </div>
  </div>

</body>
</html>

61.6.1 MetalLBを使用したイングレス

Traefikはすでにイングレスコントローラーとして機能しているため、次のような`Ingress`オブジェクトを使用してHTTP/HTTPSトラフィックを公開できます。

IP=$(kubectl get svc -n kube-system traefik -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
cat <<- EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  namespace: hello-kubernetes
spec:
  rules:
  - host: hellok3s.${IP}.sslip.io
    http:
      paths:
        - path: "/"
          pathType: Prefix
          backend:
            service:
              name: hello-kubernetes
              port:
                name: http
EOF

続いて:

curl http://hellok3s.${IP}.sslip.io
<!DOCTYPE html>
<html>
<head>
    <title>Hello Kubernetes!</title>
    <link rel="stylesheet" type="text/css" href="/css/main.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300" >
</head>
<body>

  <div class="main">
    <img src="/images/kubernetes.png"/>
    <div class="content">
      <div id="message">
  Hello world!
</div>
<div id="info">
  <table>
    <tr>
      <th>namespace:</th>
      <td>hello-kubernetes</td>
    </tr>
    <tr>
      <th>pod:</th>
      <td>hello-kubernetes-7c8575c848-fvqm2</td>
    </tr>
    <tr>
      <th>node:</th>
      <td>allinone (Linux 5.14.21-150400.24.46-default)</td>
    </tr>
  </table>
</div>
<div id="footer">
  paulbouwer/hello-kubernetes:1.10 (linux/amd64)
</div>
    </div>
  </div>

</body>
</html>

MetalLBが正しく動作していることを確認します。

% arping hellok3s.${IP}.sslip.io

ARPING 192.168.64.210
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=0 time=1.169 msec
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=1 time=2.992 msec
60 bytes from 92:12:36:00:d3:58 (192.168.64.210): index=2 time=2.884 msec

上記の例では、トラフィックは次のように流れます。

  1. `hellok3s.${IP}.sslip.io`は実際のIPアドレスに解決されます。

  2. 次に、トラフィックは`metallb-speaker`ポッドによって処理されます。

  3. `metallb-speaker`はトラフィックを`traefik`コントローラーにリダイレクトします。

  4. 最後に、Traefikはリクエストを`hello-kubernetes`サービスに転送します。

62 K3s上のMetalLB(レイヤー3モードを使用)

MetalLBは、標準的なルーティングプロトコルを使用する、ベアメタルKubernetesクラスター向けの負荷分散実装です。

このガイドでは、MetalLBをレイヤー3(L3)BGPモードでデプロイする方法を説明します。

62.1 MetalLBを使用する理由

MetalLBがベアメタルKubernetesクラスターでのロードバランシングにおいて魅力的な選択肢である理由はいくつかあります。

  1. Kubernetesとのネイティブな統合:MetalLBはKubernetesとシームレスに統合されるため、使い慣れたKubernetesツールや手法を使用して簡単にデプロイおよび管理できます。

  2. ベアメタルとの互換性:クラウドベースのロードバランサーとは異なり、MetalLBは、従来のロードバランサーが利用できない、または実現不可能なオンプレミス環境向けに特別に設計されています。

  3. 複数のプロトコルをサポート:MetalLBはレイヤー2およびレイヤー3 BGP(Border Gateway Protocol)モードの両方をサポートしており、さまざまなネットワークアーキテクチャや要件に対して柔軟性を提供します。

  4. 高可用性:MetalLBは、ロードバランシングの役割を複数のノードに分散させることで、サービスの可用性と信頼性を確保します。

  5. スケーラビリティ:MetalLBは大規模なデプロイメントに対応でき、Kubernetesクラスターとともにスケーリングして、増大する需要を満たすことができます。

レイヤー2モードでは、1つのノードがローカルネットワークに対してサービスをアドバタイズする役割を担います。ネットワークの観点からは、そのマシンに複数のIPアドレスがネットワークインタフェースに割り当てられているように見えるだけです。

レイヤー2モードの大きな利点はその汎用性です。特別なハードウェアや高度なルーターを必要とせず、あらゆるイーサネットネットワークで動作します。

62.2 K3s上のMetalLB(レイヤー3モードを使用)

このクイックスタートでは、L3モードを使用します。 これは、ネットワーク範囲内にBGP機能を持つ隣接ルーターが必要であることを意味します。

注記
注記

バージョン0.16.0より、`frr-k8s`がBGPのデフォルトのバックエンドとなります。FRRモードは将来的に廃止され、最終的には削除される予定です。

62.3 前提条件

  • MetalLBがデプロイされているK3sクラスター。

  • BGPプロトコルをサポートするネットワーク上のルーター。

  • サービス用のネットワーク範囲内にある空きIPアドレス。この例では、`192.168.10.100`です。

重要
重要

このIPアドレスが割り当てられていないことを確認する必要があります。 DHCP環境では、二重割り当てを避けるため、このアドレスはDHCPプールの一部であってはなりません。

62.4 サービスIPアドレスをアドバタイズするための設定

デフォルトでは、BGPは構成されているすべてのピアに対してサービスIPアドレスをアドバタイズします。通常ルーターであるこれらのピアは、32ビットのネットワークマスクを持つ各サービスIPアドレスのルートを受信します。この例では、FRRベースのルーターを使用します。これはクラスターと同じネットワーク上にあります。次に、MetalLBのBGP機能を使用して、そのFRRベースのルーターにサービスをアドバタイズします。

62.5 展開

MetalLBはL2 VIP機能のためにデフォルトでデプロイされるため、別途インストールする必要はありません。

`metallb-system`ネームスペースに4つのポッドがあり、すべて問題なく実行されていることを確認してください。

k get pods -n metallb-system
NAME                                                      READY   STATUS    RESTARTS     AGE
metallb-controller-7fbfd8977d-m2q9t                       1/1     Running   0            46s
metallb-metallb-frr-k8s-9w7wl                             6/6     Running   0            46s
metallb-metallb-frr-k8s-webhook-server-5d9d67ffd6-8jqnc   1/1     Running   1 (6s ago)   46s
metallb-speaker-qx8bl                                     1/1     Running   0            46s

62.6 設定

  1. `IPAddressPool`を作成します。

cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: bgp-pool
  namespace: metallb-system
  labels:
    app: httpd
spec:
  addresses:
  - 192.168.10.100/32
  autoAssign: true
  avoidBuggyIPs: false
  serviceAllocation:
    namespaces:
    - metallb-system
    priority: 100
    serviceSelectors:
    - matchExpressions:
      - key: serviceType
        operator: In
        values:
        - httpd
EOF
  1. `BGPPeer`を構成します。

注記
注記

FRRルーターのASNは1000で、私たちの`BGPPeer`は1001になります。また、FRRルーターのIPアドレスが192.168.3.140であることも確認できます。

cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
  namespace: metallb-system
  name: mypeertest
spec:
  peerAddress: 192.168.3.140
  peerASN: 1000
  myASN: 1001
  routerID: 4.4.4.4
EOF
  1. BGPAdvertisement (L3) を作成します。

cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
  name: bgpadvertisement-test
  namespace: metallb-system
spec:
  ipAddressPools:
  - bgp-pool
EOF

62.7 使用方法

  1. サービスを含むサンプルアプリケーションを作成します。この場合、`IPAddressPool`からのIPアドレスは、そのサービスに対して`192.168.10.100`となります。

cat <<- EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-deployment
  namespace: metallb-system
  labels:
    app: httpd
spec:
  replicas: 3
  selector:
    matchLabels:
      pod-label: httpd
  template:
    metadata:
      labels:
        pod-label: httpd
    spec:
      containers:
      - name: httpdcontainer
        image: image: docker.io/library/httpd:2.4
        ports:
          - containerPort: 80
            protocol: TCP
      restartPolicy: Always

---
apiVersion: v1
kind: Service
metadata:
  name: http-service
  namespace: metallb-system
  labels:
    serviceType: httpd
spec:
  selector:
    pod-label: httpd
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 8080
    name: 8080-tcp
    targetPort: 80
EOF
  1. 確認するには、FRRルーターにログインして、BGPアドバタイズによって作成されたルートを確認してください。

42178089cba5# show ip bgp all

For address family: IPv4 Unicast
BGP table version is 3, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 1000
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

   Network          Next Hop            Metric LocPrf Weight Path
* i172.16.0.0/24    1.1.1.1                  0    100      0 i
*>                  0.0.0.0                  0         32768 i
* i172.17.0.0/24    3.3.3.3                  0    100      0 i
*>                  0.0.0.0                  0         32768 i
*= 192.168.10.100/32
                    192.168.3.162                          0 1001 i
*=                  192.168.3.163                          0 1001 i
*>                  192.168.3.161                          0 1001 i

Displayed  3 routes and 7 total paths
kubectl get svc -n hello-kubernetes
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
hello-kubernetes   LoadBalancer   10.43.127.75   192.168.122.11   80:31461/TCP   8s
  1. このルーターがネットワークのデフォルトゲートウェイである場合は、そのネットワーク上のボックスから curl コマンドを実行して、httpdサンプルアプリに到達できることを確認できます。

# curl http://192.168.10.100:8080
<html><body><h1>It works!</h1></body></html>
#

63 Kubernetes APIサーバーの前にあるMetalLB

このガイドでは、MetalLBサービスを使用して、3つのコントロールプレーンノードを持つHAクラスター上でRKE2/K3s APIを外部に公開する方法を説明します。 これを実現するために、タイプ`LoadBalancer`のKubernetesサービスを手動で作成します。次に、クラスター内のすべてのコントロールプレーンノードのIPを保持する`EndpointSlices`オブジェクトが自動的に作成されます。 EndpointSlicesをクラスター内で発生するイベント(ノードの追加/削除、またはノードのオフライン化)と継続的に同期させるために、Endpoint Copier Operator (第18章 「Endpoint Copier Operator」)をデプロイします。このオペレーターは、デフォルトの`kubernetes` EndpointSlicesで発生するイベントを監視し、管理対象のEndpointSlicesを自動的に更新して同期を維持します。 管理対象サービスはタイプ`LoadBalancer`であるため、MetalLBはそれに静的な`ExternalIP`を割り当てます。この`ExternalIP`は、APIサーバーとの通信に使用されます。

63.1 前提条件

  • RKE2/K3sをデプロイするための3つのホスト。

    • ホスト名がそれぞれ異なることを確認してください。

    • テスト目的であれば、これらは仮想マシンでも構いません。

  • ネットワーク内に少なくとも2つの利用可能なIPアドレス(Traefik Ingressコントローラーの公開サービス用に1つ、管理対象サービス用に1つ)。

  • Helm

63.2 RKE2/K3sのインストール

注記
注記

新規クラスターではなく既存のクラスターを使用する場合は、このステップをスキップして次のステップに進んでください。

まず、後で管理対象サービスの`ExternalIP`に使用するネットワーク内の空きIPアドレスを確保する必要があります。

最初のホストにSSHで接続し、目的のディストリビューションをクラスターモードでインストールします。

RKE2の場合:

# As a root user, create the /etc/rancher/rke2/config.yaml config file with the following content:

mkdir -p /etc/rancher/rke2/
cat <<EOF > /etc/rancher/rke2/config.yaml
# An example of the config.yaml file for a server node:
write-kubeconfig-mode: "0644"
tls-san:
  - "${VIP_SERVICE_IP}"
  - "https://${VIP_SERVICE_IP}.sslip.io"
EOF

# Install RKE2
curl -sfL https://get.rke2.io | INSTALL_RKE2_EXEC="server" sh -

# Enable and start the RKE2 service with the configuration specified in the config.yaml file
systemctl enable rke2-server.service
systemctl start rke2-server.service

# Fetch the cluster token to be used later:
RKE2_TOKEN=$(tr -d '\n' < /var/lib/rancher/rke2/server/node-token)

K3sの場合:

# Export the free IP mentioned above
export VIP_SERVICE_IP=<ip>
export INSTALL_K3S_SKIP_START=false

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --cluster-init \
 --disable=servicelb --write-kubeconfig-mode=644 --tls-san=${VIP_SERVICE_IP} \
 --tls-san=https://${VIP_SERVICE_IP}.sslip.io" K3S_TOKEN=foobar sh -
注記
注記

k3s server`コマンドで--disable=servicelb`フラグが指定されていることを確認してください。

重要
重要

これ以降、コマンドはローカルマシンで実行してください。

外部からAPIサーバーにアクセスするには、RKE2/K3s VMのIPが使用されます。

# Replace <node-ip> with the actual IP of the machine
export NODE_IP=<node-ip>
export KUBE_DISTRIBUTION=<k3s/rke2>

scp ${NODE_IP}:/etc/rancher/${KUBE_DISTRIBUTION}/${KUBE_DISTRIBUTION}.yaml ~/.kube/config && sed \
 -i '' "s/127.0.0.1/${NODE_IP}/g" ~/.kube/config && chmod 600 ~/.kube/config

63.3 既存のクラスターの設定

注記
注記

この手順は、既存のRKE2/K3sクラスターを使用する場合にのみ有効です。

既存のクラスターを使用するには、tls-san`フラグを変更する必要があります。さらに、K3sの場合は`servicelb LBを無効にする必要があります。

RKE2またはK3sサーバーのフラグを変更するには、ディストリビューションに応じて、クラスター内のすべてのVM上の`/etc/systemd/system/rke2.service`または`/etc/systemd/system/k3s.service`ファイルのいずれかを変更する必要があります。

フラグは`ExecStart`に挿入する必要があります。次に例を示します。

RKE2の場合:

# Replace the <vip-service-ip> with the actual ip
ExecStart=/usr/local/bin/rke2 \
    server \
        '--write-kubeconfig-mode=644' \
        '--tls-san=<vip-service-ip>' \
        '--tls-san=https://<vip-service-ip>.sslip.io' \

K3sの場合:

# Replace the <vip-service-ip> with the actual ip
ExecStart=/usr/local/bin/k3s \
    server \
        '--cluster-init' \
        '--write-kubeconfig-mode=644' \
        '--disable=servicelb' \
        '--tls-san=<vip-service-ip>' \
        '--tls-san=https://<vip-service-ip>.sslip.io' \

次に、新しい設定を読み込むために以下のコマンドを実行する必要があります。

systemctl daemon-reload
systemctl restart ${KUBE_DISTRIBUTION}

63.4 MetalLBのインストール

`MetalLB`をデプロイするには、MetalLB on K3s (第61章 「K3s上のMetalLB(レイヤー2モードを使用)」)ガイドを使用できます。

NOTE:`VIP_SERVICE_IP`のIPアドレスが、クラスター内の既存の`IPAddressPools`と重複しないようにしてください。

管理対象サービス専用の`IpAddressPool`と`L2Advertisement`を作成します。

*NOTE:*以下のIPAddressPoolは、`default`ネームスペース内のタイプ`LoadBalancer`のサービスに割り当てられます。そこに複数の`LoadBalancer`サービスが存在する場合は、このVIPサービスを明示的に一致させるために、追加の ServiceSelectorsを設定できます。

# Export the VIP_SERVICE_IP on the local machine
# Replace with the actual IP
export VIP_SERVICE_IP=<ip>

cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: kubernetes-vip-ip-pool
  namespace: metallb-system
spec:
  addresses:
  - ${VIP_SERVICE_IP}/32
  serviceAllocation:
    priority: 100
    namespaces:
      - default
EOF
cat <<-EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: kubernetes-vip-l2-adv
  namespace: metallb-system
spec:
  ipAddressPools:
  - kubernetes-vip-ip-pool
EOF

63.5 Endpoint Copier Operatorのインストール

helm install \
endpoint-copier-operator oci://registry.suse.com/edge/charts/endpoint-copier-operator \
--namespace endpoint-copier-operator \
--create-namespace

上記のコマンドにより、2つのレプリカを持つ`endpoint-copier-operator`オペレーターのデプロイメントがデプロイされます。一方がリーダーとなり、もう一方が必要に応じてリーダーの役割を引き継ぎます。

次に`kubernetes-vip`サービスをデプロイする必要があります。これにより、オペレーターによって調整が行われ、設定されたポートとIPを持つEndpointSlicesが作成されます。

RKE2の場合:

cat <<-EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-vip
  namespace: default
spec:
  ports:
  - name: rke2-api
    port: 9345
    protocol: TCP
    targetPort: 9345
  - name: k8s-api
    port: 6443
    protocol: TCP
    targetPort: 6443
  type: LoadBalancer
EOF

K3sの場合:

cat <<-EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-vip
  namespace: default
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: https
    port: 6443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: LoadBalancer
EOF

`kubernetes-vip`サービスが正しいIPアドレスを持っていることを確認します。

kubectl get service kubernetes-vip -n default \
 -o=jsonpath='{.status.loadBalancer.ingress[0].ip}'

`default`ネームスペース内の`kubernetes-vip-*`および`kubernetes`EndpointSlicesリソースが同じIPを指していることを確認してください。

kubectl get endpointslices | grep kubernetes

すべてが正しい場合、最後にすべきことは、`Kubeconfig`内で`VIP_SERVICE_IP`を使用することです。

sed -i '' "s/${NODE_IP}/${VIP_SERVICE_IP}/g" ~/.kube/config

これ以降、すべての kubectl は kubernetes-vip サービスを経由します。

63.6 コントロールプレーンノードの追加

プロセス全体を監視するために、ターミナルタブをあと2つ開くことができます。

1つ目のターミナル:

watch kubectl get nodes

2つ目のターミナル:

watch kubectl get endpointslices

次に、2番目と3番目のノードで以下のコマンドを実行します。

RKE2の場合:

# As a root user, create the /etc/rancher/rke2/config.yaml config file with the following content:

mkdir -p /etc/rancher/rke2/
cat <<EOF > /etc/rancher/rke2/config.yaml
# An example of the config.yaml file for an additional server node:
server: https://${VIP_SERVICE_IP}:9345
write-kubeconfig-mode: "0644"
tls-san:
  - "${VIP_SERVICE_IP}"
  - "https://${VIP_SERVICE_IP}.sslip.io"
# The one from above
token: ${RKE2_TOKEN}
EOF

# Install RKE2
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="server" sh -

# Enable the RKE2 service with the configuration specified in the config.yaml file

systemctl enable --now rke2-server.service

# Fetch the cluster token to be used later:
RKE2_TOKEN=$(tr -d '\n' < /var/lib/rancher/rke2/server/node-token)

K3sの場合:

# Export the VIP_SERVICE_IP in the VM
# Replace with the actual IP
export VIP_SERVICE_IP=<ip>
export INSTALL_K3S_SKIP_START=false

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \
 --server https://${VIP_SERVICE_IP}:6443 --disable=servicelb \
 --write-kubeconfig-mode=644" K3S_TOKEN=foobar sh -

64 Edge Image Builder を使用したエアギャップ(された)デプロイメント

64.1 紹介

このガイドでは、Edge Image Builder(EIB) (第12章 「Edge Image Builder」) を利用して、SUSE Linux Micro 6.2 上で SUSE Telco Cloud コンポーネントの一部を完全にエアギャップ(された)環境でデプロイする方法を説明します。これにより、EIB によって作成されたカスタマイズ済みで起動可能な (CRB) イメージで起動し、インターネット接続や手動の手順なしで、指定されたコンポーネントを RKE2 または K3s クラスターにデプロイできるようになります。この構成は、デプロイに必要なすべてのアーティファクトを OS イメージに事前に組み込み、起動時にすぐに利用できるようにしたいお客様にとって非常に望ましいものです。

ここでは、以下のエアギャップ(された)インストールについて説明します。

警告
警告

EIB は、提供された Helm チャートおよび Kubernetes マニフェストで参照されているすべてのイメージを解析し、事前にダウンロードします。ただし、その一部は実行時にコンテナイメージをプルし、それに基づいて Kubernetes リソースを作成しようとする場合があります。このような場合は、完全にエアギャップ(された)環境を構築するために、定義ファイルに必要なイメージを手動で指定する必要があります。

注記
注記

本ガイドの各コンポーネント(Rancher、SUSE Security、SUSE Storage、KubeVirt、およびSUSE Private Registry)で提供されているイメージリストは、ここで示されているシナリオの検証済みベースラインであり、網羅的なカタログではありません。このベースライン上でデプロイされる追加のワークロードや動的にプロビジョニングされるワークロード(例:追加のRancherカタログアプリケーションや、SR-IOVデバイスプラグインなどのハードウェア固有のコンポーネント)は、実行時に独自のコンテナイメージをプルします。完全にエアギャップ(された)環境にデプロイする前に、それらのイメージを特定し、個別に定義ファイルに追加してください。

64.2 前提条件

このガイドに従う場合は、すでに EIB (第12章 「Edge Image Builder」) に精通していることを前提としています。そうでない場合は、クイックスタートガイド (第5章 「Edge Image Builderを使用したスタンドアロンクラスター」) に従って、以下で実践する概念をより深く理解してください。

64.3 Libvirt ネットワーク設定

注記
注記

エアギャップ(された)環境へのデプロイをデモするために、このガイドではシミュレートされたエアギャップ(された) libvirt ネットワークを使用し、以下の設定をそれに合わせて調整します。独自のデプロイメントでは、次のステップで紹介する host1.local.yaml 設定を変更する必要がある場合があります。

同じ libvirt ネットワーク設定を使用したい場合は、手順に従ってください。NICI 2.6.4が不要な場合は、64.4項 「ベースディレクトリの構成」に進みます。

DHCP 用の IP アドレス範囲 192.168.100.2/24 を持つ分離されたネットワーク設定を作成しましょう。

cat << EOF > isolatednetwork.xml
<network>
  <name>isolatednetwork</name>
  <bridge name='virbr1' stp='on' delay='0'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254'/>
    </dhcp>
  </ip>
</network>
EOF

あとは、ネットワークを作成して開始するだけです。

virsh net-define isolatednetwork.xml
virsh net-start isolatednetwork

64.4 ベースディレクトリの構成

ベースディレクトリの構成はすべてのコンポーネントで共通であるため、ここで設定します。

まず、必要なサブディレクトリを作成します。

export CONFIG_DIR=$HOME/config
mkdir -p $CONFIG_DIR/base-images
mkdir -p $CONFIG_DIR/network
mkdir -p $CONFIG_DIR/kubernetes/helm/values

使用する予定のベースイメージを必ず base-images ディレクトリに追加してください。このガイドでは、 こちら にあるセルフインストール ISO に焦点を当てます。

ダウンロードしたイメージをコピーしましょう。

cp SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso $CONFIG_DIR/base-images/slemicro.iso
注記
注記

EIB がベースイメージ入力を変更することはありません。

目的のネットワーク設定を含むファイルを作成しましょう。

cat << EOF > $CONFIG_DIR/network/host1.local.yaml
routes:
  config:
  - destination: 0.0.0.0/0
    metric: 100
    next-hop-address: 192.168.100.1
    next-hop-interface: eth0
    table-id: 254
  - destination: 192.168.100.0/24
    metric: 100
    next-hop-address: 192.168.122.1
    next-hop-interface: eth0
    table-id: 254
dns-resolver:
  config:
    server:
    - 192.168.100.1
    - 8.8.8.8
interfaces:
- name: eth0
  type: ethernet
  state: up
  mac-address: 34:8A:B1:4B:16:E7
  ipv4:
    address:
    - ip: 192.168.100.50
      prefix-length: 24
    dhcp: false
    enabled: true
  ipv6:
    enabled: false
EOF

この構成により、プロビジョニングされたシステム(指定された MAC アドレスを使用)に以下が存在することが保証されます。

  • 静的 IP アドレスを持つイーサネットインターフェイス

  • ルーティング。

  • DNS

  • ホスト名 (host1.local)

結果として得られるファイル構造は、次のようになります。

├── kubernetes/
│   └── helm/
│       └── values/
├── base-images/
│   └── slemicro.iso
└── network/
    └── host1.local.yaml

64.5 ベース定義ファイル

Edge Image Builder は、定義ファイル を使用して SUSE Linux Micro イメージを変更します。これらのファイルには、構成可能なオプションの大部分が含まれています。 これらのオプションの多くはさまざまなコンポーネントセクションで繰り返されるため、ここではそれらをリストして説明します。

ヒント
ヒント

定義ファイル内のカスタマイズオプションの完全なリストは、 アップストリームドキュメント にあります。

すべての定義ファイルに存在する以下のフィールドを見ていきます。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.36.3+rke2r1
embeddedArtifactRegistry:
  images:
    - ...

image セクションは必須であり、入力イメージ、そのアーキテクチャとタイプ、および出力イメージの名前を指定します。

operatingSystem セクションはオプションであり、root/eib ユーザー名/パスワードを使用してプロビジョニングされたシステムへのログインを有効にするための設定が含まれています。

kubernetes セクションはオプションであり、Kubernetes のタイプとバージョンを定義します。RKE2 ディストリビューションを使用します。K3s を希望する場合は、kubernetes.version: v1.36.3+k3s1 を使用してください。`kubernetes.nodes`フィールドで明示的に設定しない限り、このガイドでブートストラップするすべてのクラスターはシングルノードクラスターとなります。

`embeddedArtifactRegistry`セクションには、特定のコンポーネントに対して実行時にのみ参照およびプルされるすべてのイメージが含まれます。

64.6 Rancherインストール

注記
注記

デモンストレーションされるRancher (第6章 「Rancher」)デプロイメントは、デモンストレーションの目的のために大幅に簡素化されています。実際のデプロイメントでは、構成に応じて追加のアーティファクトが必要になる場合があります。

Rancher 2.15.1リリースアセットには、エアギャップインストールに必要なすべてのイメージがリストされた`rancher-images.txt`ファイルが含まれています。

合計で600以上のコンテナイメージがあるため、結果として生成されるCRBイメージは約30GBになります。Rancherのインストールでは、そのリストを最小限の動作構成まで削減します。そこから、デプロイメントに必要なイメージを追加できます。

定義ファイルを作成し、削減したイメージリストを含めます。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.36.3+rke2r1
  manifests:
    urls:
    - https://github.com/cert-manager/cert-manager/releases/download/v1.20.1/cert-manager.crds.yaml
  helm:
    charts:
      - name: rancher
        version: 2.15.1
        repositoryName: rancher-prime
        valuesFile: rancher-values.yaml
        targetNamespace: cattle-system
        createNamespace: true
        installationNamespace: kube-system
      - name: cert-manager
        installationNamespace: kube-system
        createNamespace: true
        repositoryName: jetstack
        targetNamespace: cert-manager
        version: 1.20.1
    repositories:
      - name: jetstack
        url: https://charts.jetstack.io
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
embeddedArtifactRegistry:
  images:
    - name: registry.rancher.com/rancher/backup-restore-operator:v10.0.2
    - name: registry.rancher.com/rancher/compliance-operator:v1.4.1
    - name: registry.rancher.com/rancher/fleet-agent:v0.16.1
    - name: registry.rancher.com/rancher/fleet:v0.16.1
    - name: registry.rancher.com/rancher/hardened-addon-resizer:1.8.23-build20260717
    - name: registry.rancher.com/rancher/hardened-calico:v3.32.1-build20260722
    - name: registry.rancher.com/rancher/hardened-cluster-autoscaler:v1.10.3-build20260717
    - name: registry.rancher.com/rancher/hardened-cni-plugins:v1.9.1-build20260717
    - name: registry.rancher.com/rancher/hardened-coredns:v1.14.6-build20260722
    - name: registry.rancher.com/rancher/hardened-dns-node-cache:1.26.8-build20260722
    - name: registry.rancher.com/rancher/hardened-etcd:v3.6.14-k3s1-build20260723
    - name: registry.rancher.com/rancher/hardened-flannel:v0.28.8-build20260722
    - name: registry.rancher.com/rancher/hardened-k8s-metrics-server:v0.9.0-build20260722
    - name: registry.rancher.com/rancher/hardened-kubernetes:v1.36.3-rke2r1-build20260723
    - name: registry.rancher.com/rancher/hardened-multus-cni:v4.3.0-build20260722
    - name: registry.rancher.com/rancher/hardened-multus-dynamic-networks-controller:v0.3.8-build20260722
    - name: registry.rancher.com/rancher/hardened-multus-thick:v4.3.0-build20260722
    - name: registry.rancher.com/rancher/hardened-traefik:v3.7.8-build20260717
    - name: registry.rancher.com/rancher/hardened-whereabouts:v0.9.4-build20260721
    - name: registry.rancher.com/rancher/k3s-upgrade:v1.36.3-k3s1
    - name: registry.rancher.com/rancher/klipper-helm:v0.13.3-build20260727
    - name: registry.rancher.com/rancher/klipper-lb:v0.4.17
    - name: registry.rancher.com/rancher/kubectl:v1.35.2
    - name: registry.rancher.com/rancher/kuberlr-kubectl:v7.1.1
    - name: registry.rancher.com/rancher/local-path-provisioner:v0.0.36
    - name: registry.rancher.com/rancher/machine:v0.15.0-rancher142
    - name: registry.rancher.com/rancher/nginx-ingress-controller:v1.14.5-hardened2
    - name: registry.rancher.com/rancher/prom-prometheus:v3.8.1
    - name: registry.rancher.com/rancher/prometheus-federator:v6.0.0
    - name: registry.rancher.com/rancher/pushprox:v0.1.10
    - name: registry.rancher.com/rancher/rancher-agent:v2.15.1
    - name: registry.rancher.com/rancher/rancher-csp-adapter:v10.0.0
    - name: registry.rancher.com/rancher/rancher-webhook:v0.11.1
    - name: registry.rancher.com/rancher/rancher:v2.15.1
    - name: registry.rancher.com/rancher/remotedialer-proxy:v0.7.2
    - name: registry.rancher.com/rancher/rke2-cloud-provider:v1.36.2-0.20260610225606-10b320a3ba51-build20260709
    - name: registry.rancher.com/rancher/rke2-runtime:v1.36.3-rke2r1
    - name: registry.rancher.com/rancher/rke2-upgrade:v1.36.3-rke2r1
    - name: registry.rancher.com/rancher/scc-operator:v0.5.1
    - name: registry.rancher.com/rancher/security-scan:v0.9.1
    - name: registry.rancher.com/rancher/shell:v0.8.1
    - name: registry.rancher.com/rancher/supportability-review-app-frontend:v0.19.0
    - name: registry.rancher.com/rancher/supportability-review-internal:latest
    - name: registry.rancher.com/rancher/supportability-review-operator:v0.19.0
    - name: registry.rancher.com/rancher/supportability-review:latest
    - name: registry.rancher.com/rancher/system-agent-installer-k3s:v1.36.3-k3s1
    - name: registry.rancher.com/rancher/system-agent-installer-rke2:v1.36.3-rke2r1
    - name: registry.rancher.com/rancher/system-agent:v0.3.16-suc
    - name: registry.rancher.com/rancher/system-upgrade-controller:v0.20.1
    - name: registry.rancher.com/rancher/turtles:v0.27.1
    - name: registry.rancher.com/rancher/ui-plugin-catalog:4.15.0
    - name: registry.rancher.com/rancher/mirrored-ingress-nginx-kube-webhook-certgen:v1.6.7

600以上のコンテナイメージの完全なリストと比較して、この削減版には約60個しか含まれていないため、新しいCRBイメージは約7GBになります。

Rancher用のHelm値ファイルも作成する必要があります。

cat << EOF > $CONFIG_DIR/kubernetes/helm/values/rancher-values.yaml
hostname: 192.168.100.50.sslip.io
replicas: 1
bootstrapPassword: "adminadminadmin"
systemDefaultRegistry: registry.rancher.com
useBundledSystemChart: true
EOF
警告
警告

`systemDefaultRegistry`を`registry.rancher.com`に設定すると、Rancherは起動時にCRBイメージ内で開始される組み込みアーティファクトレジストリ内のイメージを自動的に検索できるようになります。このフィールドを省略すると、ノード上でコンテナイメージが見つからない可能性があります。

イメージをビルドしましょう。

podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
build --definition-file eib-iso-definition.yaml

出力は以下のようになるはずです。

Downloading file: dl-manifest-1.yaml 100% |██████████████████████████████████████████████████████████████████████████████| (583/583 kB, 12 MB/s)
Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |███████████████████████████████████████████████████████████████████████████| (56/56, 8 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Downloading file: rke2-images-core.linux-amd64.tar.zst 100% |███████████████████████████████████████████████████████████| (644/644 MB, 29 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% |█████████████████████████████████████████████████████████| (400/400 MB, 29 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% |███████████████████████████████████████████████████████████████████████████| (36/36 MB, 30 MB/s)
Downloading file: sha256sum-amd64.txt 100% |█████████████████████████████████████████████████████████████████████████████| (4.3/4.3 kB, 29 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

ビルドされたイメージを使用するノードがプロビジョニングされたら、Rancherのインストールを確認できます。

/var/lib/rancher/rke2/bin/kubectl get all -n cattle-system --kubeconfig /etc/rancher/rke2/rke2.yaml

出力は以下のようになり、すべてが正常にデプロイされたことが示されます。

NAME                                            READY   STATUS      RESTARTS   AGE
pod/helm-operation-6l6ld                        0/2     Completed   0          107s
pod/helm-operation-8tk2v                        0/2     Completed   0          2m2s
pod/helm-operation-blnrr                        0/2     Completed   0          2m49s
pod/helm-operation-hdcmt                        0/2     Completed   0          3m19s
pod/helm-operation-m74c7                        0/2     Completed   0          97s
pod/helm-operation-qzzr4                        0/2     Completed   0          2m30s
pod/helm-operation-s9jh5                        0/2     Completed   0          3m
pod/helm-operation-tq7ts                        0/2     Completed   0          2m41s
pod/rancher-99d599967-ftjkk                     1/1     Running     0          4m15s
pod/rancher-webhook-79798674c5-6w28t            1/1     Running     0          2m27s
pod/system-upgrade-controller-56696956b-trq5c   1/1     Running     0          104s

NAME                      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/rancher           ClusterIP   10.43.255.80   <none>        80/TCP,443/TCP   4m15s
service/rancher-webhook   ClusterIP   10.43.7.238    <none>        443/TCP          2m27s

NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/rancher                     1/1     1            1           4m15s
deployment.apps/rancher-webhook             1/1     1            1           2m27s
deployment.apps/system-upgrade-controller   1/1     1            1           104s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/rancher-99d599967                     1         1         1       4m15s
replicaset.apps/rancher-webhook-79798674c5            1         1         1       2m27s
replicaset.apps/system-upgrade-controller-56696956b   1         1         1       104s

`\https://192.168.100.50.sslip.io`にアクセスし、先ほど設定した`adminadminadmin`パスワードでログインすると、Rancherダッシュボードが表示されます。

air gapped rancher

64.7 SUSE Securityインストール

Rancherのインストールとは異なり、SUSE SecurityのインストールではEIBでの特別な処理は必要ありません。EIBは、その基盤となるコンポーネントであるNeuVectorが必要とするすべてのイメージを自動的にエアギャップ化します。

定義ファイルを作成します。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.36.3+rke2r1
  helm:
    charts:
      - name: neuvector-crd
        version: 110.0.1+up2.11.1
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector-values.yaml
      - name: neuvector
        version: 110.0.1+up2.11.1
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector-values.yaml
    repositories:
      - name: rancher-charts
        url: https://charts.rancher.io/

また、NeuVector用のHelm値ファイルも作成します。

cat << EOF > $CONFIG_DIR/kubernetes/helm/values/neuvector-values.yaml
controller:
  replicas: 1
manager:
  enabled: false
cve:
  scanner:
    enabled: false
    replicas: 1
k3s:
  enabled: true
crdwebhook:
  enabled: false
EOF

イメージをビルドしましょう。

podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
build --definition-file eib-iso-definition.yaml

出力は以下のようになるはずです。

Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████| (2/2, 4 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |██████████████████████████████████████████████████████████████████████████████| (5/5, 13 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

ビルドされたイメージを使用するノードがプロビジョニングされたら、SUSE Securityのインストールを確認できます。

/var/lib/rancher/rke2/bin/kubectl get all -n neuvector --kubeconfig /etc/rancher/rke2/rke2.yaml

出力は以下のようになり、すべてが正常にデプロイされたことが示されます。

NAME                                            READY   STATUS      RESTARTS   AGE
pod/neuvector-cert-upgrader-job-bxbnz           0/1     Completed   0          3m39s
pod/neuvector-controller-pod-7d854bfdc7-nhxjf   1/1     Running     0          3m44s
pod/neuvector-enforcer-pod-ct8jm                1/1     Running     0          3m44s

NAME                                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                         AGE
service/neuvector-svc-admission-webhook   ClusterIP   10.43.234.241   <none>        443/TCP                         3m44s
service/neuvector-svc-controller          ClusterIP   None            <none>        18300/TCP,18301/TCP,18301/UDP   3m44s
service/neuvector-svc-crd-webhook         ClusterIP   10.43.50.190    <none>        443/TCP                         3m44s

NAME                                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/neuvector-enforcer-pod   1         1         1       1            1           <none>          3m44s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/neuvector-controller-pod   1/1     1            1           3m44s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/neuvector-controller-pod-7d854bfdc7   1         1         1       3m44s

NAME                                        SCHEDULE    TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/neuvector-cert-upgrader-pod   0 0 1 1 *   <none>     True      0        <none>          3m44s
cronjob.batch/neuvector-updater-pod         0 0 * * *   <none>     False     0        <none>          3m44s

NAME                                    STATUS     COMPLETIONS   DURATION   AGE
job.batch/neuvector-cert-upgrader-job   Complete   1/1           7s         3m39s

64.8 SUSE Storageのインストール

Longhornの 公式ドキュメントには、エアギャップインストールに必要なすべてのイメージがリストされた`longhorn-images.txt`ファイルが含まれています。 Rancherコンテナレジストリからのミラー化された対応イメージを定義ファイルに含めます。 作成しましょう。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
  packages:
    sccRegistrationCode: [reg-code]
    packageList:
      - open-iscsi
kubernetes:
  version: v1.36.3+rke2r1
  helm:
    charts:
      - name: suse-storage
        releaseName: longhorn
        repositoryName: rancher-application-collection
        targetNamespace: longhorn-system
        createNamespace: true
        version: 1.12.1
    repositories:
      - name: rancher-application-collection
        url: oci://dp.apps.rancher.io/charts
        authentication:
          username: $APPS.RANCHER.IO_USERNAME
          password: $APPS.RANCHER.IO_ACCESS_TOKEN
embeddedArtifactRegistry:
  registries:
    - uri: dp.apps.rancher.io
      authentication:
        username: $APPS.RANCHER.IO_USERNAME
        password: $APPS.RANCHER.IO_ACCESS_TOKEN
  images:
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-attacher:4.12.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-provisioner:5.3.0-17.8
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-resizer:2.2.1-10.8
    - name: dp.apps.rancher.io/containers/kubernetes-csi-external-snapshotter:8.6.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-livenessprobe:2.19.0-17.6
    - name: dp.apps.rancher.io/containers/kubernetes-csi-node-driver-registrar:2.17.0-17.6
    - name: dp.apps.rancher.io/containers/longhorn-backing-image-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-engine:1.12.1-1.6
    - name: dp.apps.rancher.io/containers/longhorn-instance-manager:1.12.1-1.7
    - name: dp.apps.rancher.io/containers/longhorn-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-share-manager:1.12.1-1.5
    - name: dp.apps.rancher.io/containers/longhorn-ui:1.12.1-1.3
    - name: dp.apps.rancher.io/containers/rancher-support-bundle-kit:0.0.92-13.12
注記
注記

定義ファイルに`open-iscsi`パッケージがリストされていることにお気づきでしょう。これは、LonghornがKubernetesに永続ボリュームを提供するために、異なるノードで実行されている`iscsiadm`デーモンに依存しているため必要です。

イメージをビルドしましょう。

podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
build --definition-file eib-iso-definition.yaml

出力は以下のようになるはずです。

Setting up Podman API listener...
Pulling selected Helm charts... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Resolving package dependencies...
Rpm .......................... [SUCCESS]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████| (15/15, 20956 it/s)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Downloading file: rke2-images-core.linux-amd64.tar.zst 100% (782/782 MB, 108 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% (367/367 MB, 104 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% (34/34 MB, 108 MB/s)
Downloading file: sha256sum-amd64.txt 100% (3.9/3.9 kB, 7.5 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

ビルドされたイメージを使用するノードがプロビジョニングされたら、Longhornのインストールを確認できます。

/var/lib/rancher/rke2/bin/kubectl get all -n longhorn-system --kubeconfig /etc/rancher/rke2/rke2.yaml

出力は以下のようになり、すべてが正常にデプロイされたことが示されます。

NAME                                                    READY   STATUS    RESTARTS   AGE
pod/csi-attacher-787fd9c6c8-sf42d                       1/1     Running   0          2m28s
pod/csi-attacher-787fd9c6c8-tb82p                       1/1     Running   0          2m28s
pod/csi-attacher-787fd9c6c8-zhc6s                       1/1     Running   0          2m28s
pod/csi-provisioner-74486b95c6-b2v9s                    1/1     Running   0          2m28s
pod/csi-provisioner-74486b95c6-hwllt                    1/1     Running   0          2m28s
pod/csi-provisioner-74486b95c6-mlrpk                    1/1     Running   0          2m28s
pod/csi-resizer-859d4557fd-t54zk                        1/1     Running   0          2m28s
pod/csi-resizer-859d4557fd-vdt5d                        1/1     Running   0          2m28s
pod/csi-resizer-859d4557fd-x9kh4                        1/1     Running   0          2m28s
pod/csi-snapshotter-6f69c6c8cc-r62gr                    1/1     Running   0          2m28s
pod/csi-snapshotter-6f69c6c8cc-vrwjn                    1/1     Running   0          2m28s
pod/csi-snapshotter-6f69c6c8cc-z65nb                    1/1     Running   0          2m28s
pod/engine-image-ei-4623b511-9vhkb                      1/1     Running   0          3m13s
pod/instance-manager-6f95fd57d4a4cd0459e469d75a300552   1/1     Running   0          2m43s
pod/longhorn-csi-plugin-gx98x                           3/3     Running   0          2m28s
pod/longhorn-driver-deployer-55f9c88499-fbm6q           1/1     Running   0          3m28s
pod/longhorn-manager-dpdp7                              2/2     Running   0          3m28s
pod/longhorn-ui-59c85fcf94-gg5hq                        1/1     Running   0          3m28s
pod/longhorn-ui-59c85fcf94-s49jc                        1/1     Running   0          3m28s

NAME                                  TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/longhorn-admission-webhook    ClusterIP   10.43.77.89    <none>        9502/TCP   3m28s
service/longhorn-backend              ClusterIP   10.43.56.17    <none>        9500/TCP   3m28s
service/longhorn-conversion-webhook   ClusterIP   10.43.54.73    <none>        9501/TCP   3m28s
service/longhorn-frontend             ClusterIP   10.43.22.82    <none>        80/TCP     3m28s
service/longhorn-recovery-backend     ClusterIP   10.43.45.143   <none>        9503/TCP   3m28s

NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/engine-image-ei-4623b511   1         1         1       1            1           <none>          3m13s
daemonset.apps/longhorn-csi-plugin        1         1         1       1            1           <none>          2m28s
daemonset.apps/longhorn-manager           1         1         1       1            1           <none>          3m28s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/csi-attacher               3/3     3            3           2m28s
deployment.apps/csi-provisioner            3/3     3            3           2m28s
deployment.apps/csi-resizer                3/3     3            3           2m28s
deployment.apps/csi-snapshotter            3/3     3            3           2m28s
deployment.apps/longhorn-driver-deployer   1/1     1            1           3m28s
deployment.apps/longhorn-ui                2/2     2            2           3m28s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/csi-attacher-787fd9c6c8               3         3         3       2m28s
replicaset.apps/csi-provisioner-74486b95c6            3         3         3       2m28s
replicaset.apps/csi-resizer-859d4557fd                3         3         3       2m28s
replicaset.apps/csi-snapshotter-6f69c6c8cc            3         3         3       2m28s
replicaset.apps/longhorn-driver-deployer-55f9c88499   1         1         1       3m28s
replicaset.apps/longhorn-ui-59c85fcf94                2         2         2       3m28s

64.9 KubeVirtおよびCDIのインストール

KubeVirtとCDIの両方のHelmチャートは、それぞれのオペレーターのみをインストールします。 システムの残りの部分をデプロイするのはオペレーターの役割であるため、必要なコンテナイメージをすべて定義ファイルに含める必要があります。作成しましょう。

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.36.3+rke2r1
  helm:
    charts:
      - name: kubevirt
        repositoryName: suse-edge
        version: 307.0.3+up0.8.0
        targetNamespace: kubevirt-system
        createNamespace: true
        installationNamespace: kube-system
      - name: cdi
        repositoryName: suse-edge
        version: 307.0.3+up0.8.0
        targetNamespace: cdi-system
        createNamespace: true
        installationNamespace: kube-system
    repositories:
      - name: suse-edge
        url: oci://registry.suse.com/edge/charts
embeddedArtifactRegistry:
  images:
    - name: registry.suse.com/suse/sles/16.0/cdi-apiserver:1.65.0
    - name: registry.suse.com/suse/sles/16.0/cdi-cloner:1.65.0
    - name: registry.suse.com/suse/sles/16.0/cdi-controller:1.65.0
    - name: registry.suse.com/suse/sles/16.0/cdi-importer:1.65.0
    - name: registry.suse.com/suse/sles/16.0/cdi-operator:1.65.0
    - name: registry.suse.com/suse/sles/16.0/cdi-uploadproxy:1.65.0
    - name: registry.suse.com/suse/sles/16.0/cdi-uploadserver:1.65.0
    - name: registry.suse.com/suse/sles/16.0/virt-api:1.8.3
    - name: registry.suse.com/suse/sles/16.0/virt-controller:1.8.3
    - name: registry.suse.com/suse/sles/16.0/virt-exportproxy:1.8.3
    - name: registry.suse.com/suse/sles/16.0/virt-exportserver:1.8.3
    - name: registry.suse.com/suse/sles/16.0/virt-handler:1.8.3
    - name: registry.suse.com/suse/sles/16.0/virt-launcher:1.8.3
    - name: registry.suse.com/suse/sles/16.0/virt-operator:1.8.3

イメージをビルドしましょう。

podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.7/edge-image-builder:1.3.4 \
build --definition-file eib-iso-definition.yaml

出力は以下のようになるはずです。

Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 48 it/min)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████| (15/15, 4 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.iso

ビルドされたイメージを使用するノードがプロビジョニングされたら、KubeVirtとCDIの両方のインストールを確認できます。

KubeVirtの確認:

/var/lib/rancher/rke2/bin/kubectl get all -n kubevirt-system --kubeconfig /etc/rancher/rke2/rke2.yaml

出力は以下のようになり、すべてが正常にデプロイされたことが示されます。

NAME                                  READY   STATUS    RESTARTS   AGE
pod/virt-api-59cb997648-mmt67         1/1     Running   0          2m34s
pod/virt-controller-69786b785-7cc96   1/1     Running   0          2m8s
pod/virt-controller-69786b785-wq2dz   1/1     Running   0          2m8s
pod/virt-handler-2l4dm                1/1     Running   0          2m8s
pod/virt-operator-7c444cff46-nps4l    1/1     Running   0          3m1s
pod/virt-operator-7c444cff46-r25xq    1/1     Running   0          3m1s

NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubevirt-operator-webhook     ClusterIP   10.43.167.109   <none>        443/TCP   2m36s
service/kubevirt-prometheus-metrics   ClusterIP   None            <none>        443/TCP   2m36s
service/virt-api                      ClusterIP   10.43.18.202    <none>        443/TCP   2m36s
service/virt-exportproxy              ClusterIP   10.43.142.188   <none>        443/TCP   2m36s

NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/virt-handler   1         1         1       1            1           kubernetes.io/os=linux   2m8s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/virt-api          1/1     1            1           2m34s
deployment.apps/virt-controller   2/2     2            2           2m8s
deployment.apps/virt-operator     2/2     2            2           3m1s

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/virt-api-59cb997648         1         1         1       2m34s
replicaset.apps/virt-controller-69786b785   2         2         2       2m8s
replicaset.apps/virt-operator-7c444cff46    2         2         2       3m1s

NAME                            AGE    PHASE
kubevirt.kubevirt.io/kubevirt   3m1s   Deployed

CDIの確認:

/var/lib/rancher/rke2/bin/kubectl get all -n cdi-system --kubeconfig /etc/rancher/rke2/rke2.yaml

出力は以下のようになり、すべてが正常にデプロイされたことが示されます。

NAME                                   READY   STATUS    RESTARTS   AGE
pod/cdi-apiserver-5598c9bf47-pqfxw     1/1     Running   0          3m44s
pod/cdi-deployment-7cbc5db7f8-g46z7    1/1     Running   0          3m44s
pod/cdi-operator-777c865745-2qcnj      1/1     Running   0          3m48s
pod/cdi-uploadproxy-646f4cd7f7-fzkv7   1/1     Running   0          3m44s

NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/cdi-api                  ClusterIP   10.43.2.224    <none>        443/TCP    3m44s
service/cdi-prometheus-metrics   ClusterIP   10.43.237.13   <none>        8080/TCP   3m44s
service/cdi-uploadproxy          ClusterIP   10.43.114.91   <none>        443/TCP    3m44s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cdi-apiserver     1/1     1            1           3m44s
deployment.apps/cdi-deployment    1/1     1            1           3m44s
deployment.apps/cdi-operator      1/1     1            1           3m48s
deployment.apps/cdi-uploadproxy   1/1     1            1           3m44s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/cdi-apiserver-5598c9bf47     1         1         1       3m44s
replicaset.apps/cdi-deployment-7cbc5db7f8    1         1         1       3m44s
replicaset.apps/cdi-operator-777c865745      1         1         1       3m48s
replicaset.apps/cdi-uploadproxy-646f4cd7f7   1         1         1       3m44s

64.10 SUSE Private Registryのインストール

SUSE Private Registryをエアギャップ(された)デプロイメントに含めるには、必要なHelmチャートと新しいイメージ用の埋め込みアーティファクトを含めるように定義ファイルを更新する必要があります。

定義ファイルを更新しましょう:

apiVersion: 1.3
image:
  imageType: iso
  arch: x86_64
  baseImage: slemicro.iso
  outputImageName: eib-image.iso
operatingSystem:
  users:
    - username: root
      encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
  version: v1.36.3+rke2r1
  helm:
    charts:
      - name: metallb
        version: 307.0.3+up0.16.1
        targetNamespace: metallb-system
        createNamespace: true
        repositoryName: suse-edge-charts
        installationNamespace: kube-system
      - name: suse-storage
        releaseName: longhorn
        repositoryName: rancher-application-collection
        targetNamespace: longhorn-system
        createNamespace: true
        version: 1.12.1
      - name: private-registry-helm
        createNamespace: true
        installationNamespace: kube-system
        repositoryName: privateregistry
        targetNamespace: suse-private-registry
        valuesFile: privateregistry.yaml
        version: 1.1.1
    repositories:
      - name: privateregistry
        authentication:
          username: ${PRIVATE_REGISTRY_USERNAME}
          password: ${PRIVATE_REGISTRY_PASSWORD}
        plainHTTP: false
        skipTLSVerify: false
        url: oci://registry.suse.com/private-registry
      - name: rancher-application-collection
        url: oci://dp.apps.rancher.io/charts
        authentication:
          username: $APPS.RANCHER.IO_USERNAME
          password: $APPS.RANCHER.IO_ACCESS_TOKEN
embeddedArtifactRegistry:
  registries:
    - uri: registry.suse.com
      authentication:
        username: ${PRIVATE_REGISTRY_USERNAME}
        password: ${PRIVATE_REGISTRY_PASSWORD}
    - uri: dp.apps.rancher.io
        authentication:
          username: $APPS.RANCHER.IO_USERNAME
          password: $APPS.RANCHER.IO_ACCESS_TOKEN
  images:
    - name: registry.suse.com/private-registry/harbor-core:1.1.1-1.19
    - name: registry.suse.com/private-registry/harbor-jobservice:1.1.1-1.19
    - name: registry.suse.com/private-registry/harbor-portal:1.1.1-1.20
    - name: registry.suse.com/private-registry/harbor-registry:1.1.1-1.19
    - name: registry.suse.com/private-registry/harbor-registryctl:1.1.1-1.19
    - name: registry.suse.com/private-registry/harbor-trivy-adapter:1.1.1-1.24
注記
注記

特定の認証情報が必要になります。これは、公式の SUSE Private Registry documentationに従うことで取得できます。 また、${PRIVATE_REGISTRY_USERNAME}`変数と${PRIVATE_REGISTRY_PASSWORD}`変数を変更する必要があります。必要なコンポーネントバージョンを含むイメージを必ずリストしてください。

次に、SUSE Private Registryを適切に設定するために必要なKubernetesマニフェストを追加する必要があります。

以下のファイルで、SUSE Private Registry用に予約された静的IPを使用して`${MGMT_CLUSTER_REGISTRY_IP}`を変更する必要があります:

  1. kubernetes/manifests/metallb-registry.yaml

    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: private-registry
      namespace: metallb-system
    spec:
      ipAddressPools:
      - private-registry-pool
    ---
    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
      name: private-registry-pool
      namespace: metallb-system
    spec:
      addresses:
      - ${MGMT_CLUSTER_REGISTRY_IP}/32
      serviceAllocation:
        namespaces:
        - suse-private-registry
  2. kubernetes/helm/values/privateregistry.yaml

    core:
      secretName: suse-registry-tls
    expose:
      tls:
        certSource: secret
        enabled: true
        secret:
          secretName: suse-registry-tls
      type: loadBalancer
    externalURL: https://${MGMT_CLUSTER_REGISTRY_IP}
    persistence:
      persistentVolumeClaim:
        registry:
          size: 20Gi

最後に、以下の内容で`kubernetes/manifests/suse-private-registry-creds.yaml`を作成する必要があります:

apiVersion: v1
kind: Secret
metadata:
  name: suse-registry
  namespace: suse-private-registry
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ${DOCKER_CONFIG_JSON_BASE64}
---
apiVersion: v1
kind: Secret
metadata:
    name: suse-registry-tls
    namespace: suse-private-registry
type: kubernetes.io/tls
data:
    tls.crt: ${TLS_CRT_BASE64}
    tls.key: ${TLS_KEY_BASE64}

`${DOCKER_CONFIG_JSON_BASE64}`用のdocker config json(base64)を正しく設定するには、以下を実行します:

# ${DOCKER_CONFIG_JSON_BASE64} CONTENT
echo -n '{"auths": {"<MGMT_CLUSTER_REGISTRY_IP>": {"username": "<USERNAME>", "password": "<PASSWORD>", "auth": "<AUTH>"}}}' | base64

ここで、IPは以前に設定した`${MGMT_CLUSTER_REGISTRY_IP}`と同じであり、username、password、および`auth`は SUSE Private Registry official documentationから取得できます。

${TLS_CRT_BASE64}`および${TLS_KEY_BASE64}`用のbase64エンコードされたTLS証明書とキー(tls.crt`および`tls.key)を生成するには、以下を実行して独自のものを作成できます:

# Generate a self-signed certificate and key
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes

# Convert them to base64 for the suse-private-registry-creds.yaml file
cat cert.pem | base64 -w 0
cat key.pem | base64 -w 0

SUSE Private Registryを検証します:

/var/lib/rancher/rke2/bin/kubectl get pods -n suse-private-registry --kubeconfig /etc/rancher/rke2/rke2.yaml

出力は以下のようになり、すべてが正常にデプロイされたことが示されます。

NAME                                                      READY   STATUS    RESTARTS   AGE
pod/private-registry-harbor-core-588fd4876f-8tqnv         1/1     Running   0          4m30s
pod/private-registry-harbor-database-0                    1/1     Running   0          4m30s
pod/private-registry-harbor-jobservice-7658f97fbc-4vq6n   1/1     Running   0          4m30s
pod/private-registry-harbor-portal-5455ccc4bc-jpmt5       1/1     Running   0          4m30s
pod/private-registry-harbor-redis-0                       1/1     Running   0          4m30s
pod/private-registry-harbor-registry-5648b9d89-wdswz      2/2     Running   0          4m30s
pod/private-registry-harbor-trivy-0                       1/1     Running   0          4m30s

64.11 Metal3 インストール

EIBとHaulerを使用してエアギャップ(された)環境にMetal3をデプロイする場合、Ironic Python Agent(IPA)イメージに対して特別な設定が必要です。IPAイメージは、ベアメタルホストのインスペクションおよびプロビジョニングのためにMetal3によって使用されます。

注記
注記

MetalLBのセットアップを含む、Metal3のインストールと設定の詳細については、第4章 「Metal3によるBMC自動デプロイメント」を参照してください。

エアギャップ(された)デプロイメントにMetal3を含めるには、以下の手順が必要です:

  1. 定義ファイルにMetal3 Helmチャートを追加する

  2. 埋め込みアーティファクトレジストリにIPAイメージを追加する

  3. `useHauler: true`を使用してHelm値ファイルを作成する

定義ファイルの`kubernetes.helm.charts`セクションに以下を追加します:

  helm:
    charts:
      - name: metal3
        version: 307.0.31+up0.16.0
        targetNamespace: metal3-system
        createNamespace: true
        repositoryName: suse-edge-charts
        installationNamespace: kube-system
        valuesFile: metal3-values.yaml

`embeddedArtifactRegistry.images`セクションにIPAイメージを追加します:

embeddedArtifactRegistry:
  images:
    - name: registry.suse.com/edge/3.7/ironic-python-agent:3.0.10

Metal3用のHelm値ファイルを作成します:

cat << EOF > $CONFIG_DIR/kubernetes/helm/values/metal3-values.yaml
global:
  ironicIP: <STATIC_IRONIC_IP>
metal3-ironic:
  ipa:
    useHauler: true
EOF
重要
重要

EIB/Haulerを使用してエアギャップ(された)環境にデプロイする場合、metal3-ironic.ipa.useHauler`の値は必ず`true(ブール値)に設定する必要があります。これは、インターネットからのダウンロードを試みる代わりに、埋め込みアーティファクトレジストリからIPAイメージを取得するようにMetal3に指示するものです。

64.12 トラブルシューティング

イメージのビルド中に問題が発生した場合や、処理のさらなるテストやデバッグをご希望の場合は、 アップストリームドキュメントを参照してください。

65 Kiwiを使用して更新されたSUSE Linux Microイメージを構築する

このセクションでは、Edge Image Builder、Cluster API (CAPI) + Metal3で使用する、またはディスクイメージをブロックデバイスに直接書き込むための、更新されたSUSE Linux Microイメージの生成方法について説明します。このプロセスは、初期システムブートイメージに最新のパッチを含める必要がある場合(インストール後のパッチ転送を最小限に抑えるため)、またはCAPIを使用するシナリオで、ホストをその場でアップグレードするよりも新しいイメージでオペレーティングシステムを再インストールすることが望ましい場合に役立ちます。

このプロセスでは、 Kiwiを使用してイメージビルドを実行します。SUSE Telco Cloudには、ヘルパーユーティリティが組み込まれており、全体的なプロセスを簡素化するコンテナ化されたバージョンが付属しているため、必要なターゲット*プロファイル*を指定できます。プロファイルは、必要な出力イメージのタイプを定義します。一般的なものを以下に示します。

  • \"Base\" - パッケージセットが削減されたSUSE Linux Microディスクイメージ(podmanが含まれています)。

  • \"Base-SelfInstall\" - 上記の「Base」に基づくSelfInstallイメージ。

  • \"Base-RT\" - 上記の「Base」と同じですが、代わりにリアルタイム(rt)カーネルを使用します。

  • \"Base-RT-SelfInstall\" - 上記の「Base-RT」に基づくSelfInstallイメージ

  • \"Default\" - 上記の「Base」に基づくSUSE Linux Microディスクイメージですが、仮想化スタック、Cockpit、salt-minionなど、いくつかのツールが追加されています。

  • \"Default-SelfInstall\" - 上記の「Default」に基づくSelfInstallイメージ

詳細については、 SUSE Linux Micro 6.2のドキュメントを参照してください。

注記
注記

このプロセスはAMD64/Intel 64アーキテクチャとAArch64アーキテクチャの両方で機能しますが、構築するイメージと同じアーキテクチャのビルドホストを使用する必要があります。言い換えると、AArch64イメージを構築するにはAArch64ビルドホストを使用する必要があり、AMD64/Intel 64の場合も同様です。現時点ではクロスビルドはサポートされていません。

65.1 前提条件

Kiwiイメージビルダーには以下が必要です。

  • 構築するイメージと同じアーキテクチャのSUSE Linux Micro 6.2ホスト(「ビルドシステム」)が必要です。

  • ビルドシステムは、`SUSEConnect`を介してすでに登録されている必要があります(登録は、SUSEリポジトリから最新のパッケージを取得するために使用されます)。

  • 必要なパッケージを取得するために使用できるインターネット接続。プロキシ経由で接続する場合、ビルドホストを事前に設定しておく必要があります。

  • ビルドホスト上でSELinuxを無効にする必要があります(SELinuxのラベリングはコンテナ内で行われ、ホストのポリシーと競合する可能性があるためです)。

  • コンテナイメージ、ビルドルート、および生成される出力イメージを格納するために、少なくとも10GBの空きディスク容量が必要です。

65.2 はじめに

特定の制限により、現在はSELinuxを無効にする必要があります。SUSE Linux Micro 6.2 イメージビルドホストに接続し、SELinuxが無効になっていることを確認してください。

# setenforce 0

生成されたイメージを保存するために、Kiwiビルドコンテナと共有する出力ディレクトリを作成します。

# mkdir ~/output

SUSEレジストリから最新のKiwiビルダーイメージをプルします。

# podman pull registry.suse.com/edge/3.7/kiwi-builder:10.2.29.1
(...)

65.3 デフォルトイメージのビルド

これは、コンテナイメージの実行時に引数が指定されなかった場合のKiwiイメージコンテナのデフォルトの動作です。次のコマンドは、2つのディレクトリをコンテナにマッピングして podman を実行します。

  • 基盤となるホスト上の /etc/zypp/repos.d SUSE Linux Microパッケージリポジトリディレクトリが必要です。

  • 上記で作成した出力 ~/output ディレクトリが必要です。

Kiwiイメージコンテナでは、build-image ヘルパースクリプトを次のように実行する必要があります。

# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
    -it registry.suse.com/edge/3.7/kiwi-builder:10.2.29.1 build-image
(...)
注記
注記

このスクリプトを初めて実行する場合、開始直後に「ERROR:」というエラーで *失敗 することが予想されます。「Early loop device test failed, please retry the container run.*」というエラーは、基盤となるホストシステム上で作成されたループデバイスが、コンテナイメージ内で即座に認識されないことに起因する現象です。コマンドをもう一度実行するだけで、問題なく処理が進むはずです。

数分後、イメージはローカルの出力ディレクトリで見つかります。

(...)
INFO: Image build successful, generated images are available in the 'output' directory.

# ls -1 output/
SLE-Micro.x86_64-6.2.changes
SLE-Micro.x86_64-6.2.packages
SLE-Micro.x86_64-6.2.raw
SLE-Micro.x86_64-6.2.verified
build
kiwi.result
kiwi.result.json

65.4 他のプロファイルでのイメージビルド

異なるイメージプロファイルをビルドするには、Kiwiコンテナイメージヘルパースクリプトの「-p」コマンドオプションを使用します。例えば、「Default-SelfInstall」ISOイメージをビルドするには次のようにします。

# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
    -it registry.suse.com/edge/3.7/kiwi-builder:10.2.29.1 build-image -p Default-SelfInstall
(...)
注記
注記

データ損失を防ぐため、`output`ディレクトリ内にイメージが存在する場合、Kiwiは実行を拒否します。`rm -f output/*`に進む前に、出力ディレクトリの内容を削除する必要があります。

あるいは、リアルタイムカーネル ("kernel-rt") を使用してSelfInstall ISOイメージをビルドするには、次のようにします。

# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
    -it registry.suse.com/edge/3.7/kiwi-builder:10.2.29.1 build-image -p Base-RT-SelfInstall
(...)

65.5 大きなセクタサイズでのイメージのビルド

一部のハードウェアでは、標準の512バイトではなく、大きなセクタサイズ(例: 4096 bytes)のイメージが必要です。コンテナ化されたKiwiビルダーは、「-b」パラメータを指定することで、大きなブロックサイズのイメージを生成する機能をサポートしています。例えば、大きなセクタサイズで「Default-SelfInstall」イメージをビルドするには、次のようにします。

# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output \
    -it registry.suse.com/edge/3.7/kiwi-builder:10.2.29.1 build-image -p Default-SelfInstall -b
(...)

65.6 カスタムKiwiイメージ定義ファイルの使用

高度なユースケースでは、カスタムKiwiイメージ定義ファイル (SL-Micro.kiwi) を、必要なビルド後スクリプトと共に使用できます。これには、SUSE Telco Cloudチームによって事前にパッケージ化されたデフォルトの定義を上書きする必要があります。

新しいディレクトリを作成し、ヘルパースクリプトが参照しているコンテナイメージ内の場所にマッピングします (/micro-sdk/defs)。

# mkdir ~/mydefs/
# cp /path/to/SL-Micro.kiwi ~/mydefs/
# cp /path/to/config.sh ~/mydefs/
# podman run --privileged -v /etc/zypp/repos.d:/micro-sdk/repos/ -v ~/output:/tmp/output -v ~/mydefs/:/micro-sdk/defs/ \
    -it registry.suse.com/edge/3.7/kiwi-builder:10.2.29.1 build-image
(...)
警告
警告

これは高度なユースケースでのみ必要であり、サポート上の問題を引き起こす可能性があります。詳細なアドバイスやガイダンスについては、SUSEの担当者にお問い合わせください。

コンテナに含まれるデフォルトのKiwiイメージ定義ファイルを取得するには、以下のコマンドを使用できます。

$ podman create --name kiwi-builder registry.suse.com/edge/3.7/kiwi-builder:10.2.29.1
$ podman cp kiwi-builder:/micro-sdk/defs/SL-Micro.kiwi .
$ podman cp kiwi-builder:/micro-sdk/defs/SL-Micro.kiwi.4096 .
$ podman rm kiwi-builder
$ ls ./SL-Micro.*
(...)

66 SUSE Storage V2データエンジン

SUSE Storage 1.12.1には、一般提供機能としてLonghorn V2データエンジンが含まれています。 SUSE Telco Cloud 3.7以降、クラスターがV2の前提条件を満たしている場合、新規にプロビジョニングされるボリュームにはV2データエンジンが推奨されます。

重要
重要

SUSE Storage Helmチャートは、既存のV1ボリュームをV2に変換しません。 データエンジンは変更不可能なボリュームプロパティです。 既存のV1ボリュームは、データが新規プロビジョニングされたV2ボリュームに移行されるまで、引き続きV1を使用します。

66.1 前提条件

V2データエンジンを有効にする前に、https://longhorn.io/docs/1.12.1/deploy/install/#v2-data-engine-requirements[アップストリームのV2要件]を確認してください。 特に、V2レプリカをホストできるすべてのノードには以下が必要です。

  • 専用のフォーマットされていないブロックデバイス。本番環境のワークロードにはNVMeデバイスが推奨されます。

  • nvme-tcp、vfio_pci、および`uio_pci_generic`カーネルモジュール。

  • V2インスタンスマネージャーに十分なCPUとメモリ。デフォルト設定では、インスタンスマネージャーごとに2 GiBのヒュージページを使用します。

  • サポートされているCPUとカーネル。AMD64 CPUにはSSE4.2が必要であり、カーネル6.7以降が推奨されます。

Longhornでは、移行完了後にデータエンジンを1つだけ使用することを推奨しています。 両方のエンジンを実行すると個別のインスタンスマネージャーが作成されるため、追加のCPUとメモリが消費されます。

66.2 新規ボリューム用にV2を設定する

アプリケーションボリュームをプロビジョニングする前に、必要なブロックデバイスを準備してください。 SUSE Storage UIを使用するか、対応する`block`リソースを更新して、各デバイスをLonghornノード上の`nodes.longhorn.io`ディスクとして登録してください。

V1ボリュームが存在しない新しいクラスターの場合は、以下のHelm値を使用してください。

defaultSettings:
  v1DataEngine: false
  v2DataEngine: true
persistence:
  dataEngine: v2

V1ボリュームを持つ既存のクラスターの場合は、移行中に両方のエンジンを有効のままにしてください。

defaultSettings:
  v1DataEngine: true
  v2DataEngine: true
persistence:
  dataEngine: v2

通常のHelmデプロイメントまたはアップグレードワークフローで値を適用してください。 次に例を示します。

helm upgrade --install longhorn oci://dp.apps.rancher.io/charts/suse-storage \
  --version 1.12.1 \
  --namespace longhorn-system \
  --create-namespace \
  --reuse-values \
  --values suse-storage-v2-values.yaml

既存のインストール環境で、実行中のLonghorn設定が有効になっていることを確認してください。 Helmアップグレード後も無効のままの場合は、明示的に有効にしてください。

kubectl -n longhorn-system patch settings.longhorn.io v2-data-engine \
  --type merge --patch '{"value":"true"}'
注意
注意

クラスター内にV1ボリュームが残っている間は、V1データエンジンを無効にしないでください。 既存のリリースをアップグレードする際は、--reuse-values`が`persistence.dataEngine`の古い値(`v1)を保持していないことも確認してください。

既存のStorageClassをその場で変更するのではなく、専用のV2 StorageClassを作成してください。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-v2
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
  dataEngine: "v2"
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880"
  fsType: "ext4"

`storageClassName`を指定しないPVCに対してV2をデフォルトにするには、デフォルトのアノテーションを新しいStorageClassに移動してください。

kubectl annotate storageclass longhorn \
  storageclass.kubernetes.io/is-default-class="false" --overwrite

kubectl annotate storageclass longhorn-v2 \
  storageclass.kubernetes.io/is-default-class="true" --overwrite

この変更は、新しくプロビジョニングされたボリュームにのみ影響します。 既存のボリュームのデータエンジンは変更されません。

設定、StorageClass、ディスク、およびボリュームを確認してください。

kubectl -n longhorn-system get settings.longhorn.io \
  v1-data-engine v2-data-engine

kubectl get storageclass longhorn-v2 \
  -o jsonpath='dataEngine={.parameters.dataEngine}{"\n"}'

kubectl -n longhorn-system get nodes.longhorn.io

kubectl -n longhorn-system get volumes.longhorn.io \
  -o custom-columns='NAME:.metadata.name,ENGINE:.spec.dataEngine,STATE:.status.state,ROBUSTNESS:.status.robustness'

66.3 V1ボリュームをV2に移行する

SUSE Storage 1.12.1は、既存のボリュームをV1からV2へその場で変換することをサポートしていません。 メンテナンスウィンドウを計画し、各ワークロードを新しいV2ボリュームに移行してください。

  1. アプリケーションとそのV1ボリュームをバックアップしてください。

  2. ソースPVCに書き込むすべてのワークロードを停止またはスケールダウンしてください。

  3. longhorn-v2 StorageClassを使用し、ソースPVCと同等以上の容量を持つ宛先PVCを同じネームスペースに作成してください。

  4. アプリケーションでサポートされている方法を使用してデータをコピーしてください。

  5. ワークロードが宛先PVCを使用するように変更する前に、コピーされたデータを検証してください。

  6. ワークロードがV2 PVCを参照するように、更新または再作成してください。

  7. アプリケーションがV2で検証されるまでV1ボリュームを保持し、その後、保持ポリシーに従って削除してください。

データベースや、整合性を意識した移行を必要とする他のアプリケーションによって管理されていないファイルシステムボリュームの場合、単一のメンテナンスポッドでV1ソースを読み取り専用、V2宛先を読み取り/書き込みでマウントできます:

apiVersion: batch/v1
kind: Job
metadata:
  name: copy-v1-to-v2
  namespace: <application-namespace>
spec:
  backoffLimit: 3
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: copy
          image: registry.suse.com/bci/bci-micro:latest
          command:
            - /bin/bash
            - -c
            - |
              set -euo pipefail
              cp -a /source/. /destination/
              sync
          volumeMounts:
            - name: source
              mountPath: /source
              readOnly: true
            - name: destination
              mountPath: /destination
      volumes:
        - name: source
          persistentVolumeClaim:
            claimName: <v1-pvc-name>
        - name: destination
          persistentVolumeClaim:
            claimName: <v2-pvc-name>
警告
警告

コピー・ジョブは、一般的なファイルシステムの例にすぎません。 データベース、RAWブロックボリューム、および独自の整合性要件を持つアプリケーションには、アプリケーションネイティブのバックアップと復元、またはレプリケーションを使用してください。 ソースPVCを削除する前に、所有権、権限、拡張属性、およびアプリケーションデータを確認してください。

すべてのワークロードが移行された後、V1ボリュームが残っていないことを確認してください。

kubectl -n longhorn-system get volumes.longhorn.io \
  -o custom-columns='NAME:.metadata.name,ENGINE:.spec.dataEngine,STATE:.status.state'

その後、Helm値でV1 Data Engineを無効にし、リリースをアップグレードできます:

defaultSettings:
  v1DataEngine: false
  v2DataEngine: true
persistence:
  dataEngine: v2

Helmアップグレード後も実行設定が有効なままの場合は、明示的に無効にしてください。

kubectl -n longhorn-system patch settings.longhorn.io v1-data-engine \
  --type merge --patch '{"value":"false"}'

V1固有のノードストレージを削除する前に、ボリュームインベントリコマンドを再度実行し、V1ボリュームが見落とされていないことを確認してください。

66.4 使用上の制限

ワークロードをV2に移行する前に、https://longhorn.io/docs/1.12.1/v1-v2-volume-behavior-and-feature-parity/[V1とV2の機能比較]を確認してください。 以下の制限は、SUSE Storage 1.12.1に特に関連しています:

  • V1ボリュームをその場でV2に変換することはできません。

  • V2バッキングイメージはサポートされていません。KubeVirtイメージのインポートワークフローにはCDIを使用してください。

  • Strict-localボリューム、オフラインの高速レプリカ再構築、リビジョンカウンター、および孤立したインスタンスの管理は、V2データエンジンではサポートされていません。

  • V2エンジンのライブアップグレードはサポートされていないため、SUSE Storage 1.12のパッチ間でアップグレードを行う前に、V2ボリュームをデタッチする必要があります。

  • シャーディングされたV2データエンジンは実験的なものであり、レプリケートされたV2ボリュームと機能の同等性はありません。バックアップ、ディザスタリカバリ、クローン作成、ライブマイグレーションなど、サポートされていない機能を必要とする本番ワークロードには使用しないでください。

  • ARM64では、NVMeブロックデバイスをバックエンドとするV2ボリュームにはアップストリームの制限があります。デプロイメントの前に、https://longhorn.io/docs/1.12.1/important-notes/[Longhornの重要な注意事項]を確認してください。

67 ClusterClassを使用してダウンストリームクラスターをデプロイする

67.1 概要

Kubernetesクラスターのプロビジョニングは、クラスターコンポーネントの構成に関する深い専門知識を必要とする複雑なタスクです。構成が複雑になるにつれて、あるいは異なるプロバイダーの要求によってプロバイダー固有のリソース定義が多数導入されるにつれて、クラスターの作成は困難に感じられることがあります。 幸いなことに、Kubernetes Cluster API (CAPI) は、ClusterClassによってさらに強化された、よりエレガントで宣言的なアプローチを提供します。 この機能はテンプレート駆動型のモデルを導入しており、複雑さをカプセル化し一貫性を促進する再利用可能なクラスタークラスを定義できます。

67.2 ClusterClassとは何ですか?

CAPIプロジェクトは、クラスターインスタンス化のためのテンプレートベースの手法を採用することで、Kubernetesクラスターライフサイクル管理におけるパラダイムシフトとしてClusterClass機能を導入しました。ユーザーはクラスターごとにリソースを個別に定義する代わりに、包括的で再利用可能なブループリントとして機能するClusterClassを定義します。この抽象的な表現はKubernetesクラスターの目的の状態と構成をカプセル化し、定義された仕様に準拠する複数のクラスターを迅速かつ一貫して作成できるようにします。 この抽象化により構成の負担が軽減され、より管理しやすいデプロイメントマニフェストが実現します。 これは、ワークロードクラスターのコアコンポーネントがクラスレベルで定義されることを意味し、ユーザーはこれらのテンプレートを、クラスタープロビジョニングのために1回または複数回再利用できるKubernetesクラスターのフレーバーとして使用できます。 ClusterClassの実装は、大規模な従来のCAPI管理に固有の課題に対処するいくつかの重要な利点をもたらします。

  • 複雑さとYAMLの冗長性の大幅な削減

  • 最適化されたメンテナンスおよび更新プロセス

  • デプロイメント全体における一貫性と標準化の強化

  • スケーラビリティと自動化機能の向上

  • 宣言的な管理と堅牢なバージョン管理

clusterclass v1beta2

67.3 現在のCAPIプロビジョニングファイルの例

CAPRKE2(コントロールプレーンおよび起動)およびCAPM3(インフラストラクチャ)プロバイダーを活用してCluster API(CAPI)でKubernetesクラスターをデプロイするには、いくつかのカスタムリソースを定義する必要があります。 これらのリソースは、クラスターとその基盤となるインフラストラクチャの目的の状態を定義し、CAPIがプロビジョニングと管理のライフサイクルをオーケストレーションできるようにします。 以下のコードスニペットは、コントロールプレーンノードのみでKubernetesクラスターをインスタンス化するために設定する必要があるリソースタイプを示しています。

  • クラスター:このリソースは、ノード間の通信とサービス検出を制御するネットワークトポロジを含む、高レベルの構成をカプセル化します。さらに、コントロールプレーンの仕様と指定されたインフラストラクチャプロバイダーリソースへの重要なリンクを確立し、それによって希望するクラスタアーキテクチャと、それがプロビジョニングされる基盤となるインフラストラクチャについてCAPIに通知します。

  • Metal3Cluster:このリソースは、Metal3固有のインフラストラクチャレベルの属性を定義します。例えば、Kubernetes APIサーバーにアクセスするための外部エンドポイントなどがこれに該当します。

  • RKE2ControlPlane:RKE2ControlPlaneリソースは、クラスタのコントロールプレーンノードの特性と動作を定義します。この仕様内では、コントロールプレーンのレプリカの希望数(高可用性と耐障害性を確保するために重要)、特定のKubernetesディストリビューションバージョン(選択したRKE2リリースに準拠)、およびコントロールプレーンコンポーネントへの更新をロールアウトするための戦略といったパラメータが設定されます。さらに、このリソースはクラスター内で使用されるコンテナネットワークインタフェース(CNI)を指定し、エージェント固有の設定の注入を容易にします。多くの場合、コントロールプレーンノード上のRKE2エージェントのシームレスかつ自動化されたプロビジョニングのためにIgnitionが活用されます。

  • Metal3MachineTemplate:このリソースは、クラスターのコントロールプレーンノードを構成する個々のコンピューティングインスタンスを作成するためのブループリントとして機能します。

  • Metal3DataTemplate:Metal3MachineTemplateを補完するMetal3DataTemplateリソースを使用すると、新しくプロビジョニングされたマシンインスタンスに対して追加のメタデータを指定できます。

    apiVersion: cluster.x-k8s.io/v1beta2
    kind: Cluster
    metadata:
      name: emea-spa-cluster-3
      namespace: emea-spa
      labels:
        cluster-api.cattle.io/rancher-auto-import: "true"
    spec:
      clusterNetwork:
        pods:
          cidrBlocks:
            - 192.168.0.0/18
        services:
          cidrBlocks:
            - 10.96.0.0/12
      controlPlaneRef:
        apiGroup: controlplane.cluster.x-k8s.io
        kind: RKE2ControlPlane
        name: emea-spa-cluster-3
      infrastructureRef:
        apiGroup: infrastructure.cluster.x-k8s.io
        kind: Metal3Cluster
        name: emea-spa-cluster-3
    ---
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
    kind: Metal3Cluster
    metadata:
      name: emea-spa-cluster-3
      namespace: emea-spa
    spec:
      controlPlaneEndpoint:
        host: 192.168.122.203
        port: 6443
      cloudProviderEnabled: false
    ---
    apiVersion: controlplane.cluster.x-k8s.io/v1beta2
    kind: RKE2ControlPlane
    metadata:
      name: emea-spa-cluster-3
      namespace: emea-spa
    spec:
      machineTemplate:
        spec:
          infrastructureRef:
            apiGroup: infrastructure.cluster.x-k8s.io
            kind: Metal3MachineTemplate
            name: emea-spa-cluster-3
      replicas: 1
      version: v1.36.3+rke2r1
      rolloutStrategy:
        type: "RollingUpdate"
        rollingUpdate:
          maxSurge: 1
      registrationMethod: "control-plane-endpoint"
      registrationAddress: 192.168.122.203
      serverConfig:
        cni: cilium
        cniMultusEnable: true
        tlsSan:
          - 192.168.122.203
          - https://192.168.122.203.sslip.io
      agentConfig:
        format: ignition
        additionalUserData:
          config: |
            variant: fcos
            version: 1.4.0
            storage:
              files:
                - path: /var/lib/rancher/rke2/server/manifests/endpoint-copier-operator.yaml
                  overwrite: true
                  contents:
                    inline: |
                      apiVersion: helm.cattle.io/v1
                      kind: HelmChart
                      metadata:
                        name: endpoint-copier-operator
                        namespace: kube-system
                      spec:
                        chart: oci://registry.suse.com/edge/charts/endpoint-copier-operator
                        targetNamespace: endpoint-copier-operator
                        version: 307.0.1+up0.3.0
                        createNamespace: true
                - path: /var/lib/rancher/rke2/server/manifests/metallb.yaml
                  overwrite: true
                  contents:
                    inline: |
                      apiVersion: helm.cattle.io/v1
                      kind: HelmChart
                      metadata:
                        name: metallb
                        namespace: kube-system
                      spec:
                        chart: oci://registry.suse.com/edge/charts/metallb
                        targetNamespace: metallb-system
                        version: 307.0.3+up0.16.1
                        createNamespace: true
                - path: /var/lib/rancher/rke2/server/manifests/metallb-cr.yaml
                  overwrite: true
                  contents:
                    inline: |
                      apiVersion: metallb.io/v1beta1
                      kind: IPAddressPool
                      metadata:
                        name: kubernetes-vip-ip-pool
                        namespace: metallb-system
                      spec:
                        addresses:
                          - 192.168.122.203/32
                        serviceAllocation:
                          priority: 100
                          namespaces:
                            - default
                          serviceSelectors:
                            - matchExpressions:
                              - {key: "serviceType", operator: In, values: [kubernetes-vip]}
                      ---
                      apiVersion: metallb.io/v1beta1
                      kind: L2Advertisement
                      metadata:
                        name: ip-pool-l2-adv
                        namespace: metallb-system
                      spec:
                        ipAddressPools:
                          - kubernetes-vip-ip-pool
                - path: /var/lib/rancher/rke2/server/manifests/endpoint-svc.yaml
                  overwrite: true
                  contents:
                    inline: |
                      apiVersion: v1
                      kind: Service
                      metadata:
                        name: kubernetes-vip
                        namespace: default
                        labels:
                          serviceType: kubernetes-vip
                      spec:
                        ports:
                        - name: rke2-api
                          port: 9345
                          protocol: TCP
                          targetPort: 9345
                        - name: k8s-api
                          port: 6443
                          protocol: TCP
                          targetPort: 6443
                        type: LoadBalancer
            systemd:
              units:
                - name: rke2-preinstall.service
                  enabled: true
                  contents: |
                    [Unit]
                    Description=rke2-preinstall
                    Wants=network-online.target
                    Before=rke2-install.service
                    ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                    [Service]
                    Type=oneshot
                    User=root
                    ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                    # Note we use _ as a delimiter for sed here because the providerid includes / characters
                    ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
                    ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                    ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
                    ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                    ExecStartPost=/bin/sh -c "umount /mnt"
                    [Install]
                    WantedBy=multi-user.target
        kubelet:
          extraArgs:
          - provider-id=metal3://PROVIDERID
        nodeName: "localhost.localdomain"
    ---
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
    kind: Metal3MachineTemplate
    metadata:
      name: emea-spa-cluster-3
      namespace: emea-spa
    spec:
      nodeReuse: True
      template:
        spec:
          automatedCleaningMode: metadata
          dataTemplate:
            name: emea-spa-cluster-3
          hostSelector:
            matchLabels:
              cluster-role: control-plane
              deploy-region: emea-spa
              cluster-type: group-3
          image:
            checksum: http://fileserver.local:8080/eibimage-downstream-cluster.raw.sha256
            checksumType: sha256
            diskFormat: raw
            url: http://fileserver.local:8080/eibimage-downstream-cluster.raw
    ---
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
    kind: Metal3DataTemplate
    metadata:
      name: emea-spa-cluster-3
      namespace: emea-spa
    spec:
      clusterName: emea-spa-cluster-3
      metaData:
        objectNames:
        - key: name
          object: machine
        - key: local-hostname
          object: machine
        - key: local_hostname
          object: machine
注記
注記

cluster.x-k8s.io APIグループの`Cluster` APIオブジェクトにラベル`cluster-api.cattle.io/rancher-auto-import: "true"`を追加すると、Rancherにクラスタがインポートされます(management.cattle.io APIグループに対応するRancher Cluster APIオブジェクトが作成されます)。 詳細については、 Cluster APIドキュメントを参照してください。

67.4 CAPIプロビジョニングファイルをClusterClassに変換する

67.4.1 ClusterClass定義

以下のコードは、特定の種類のKubernetesクラスターを一貫してデプロイするための宣言型テンプレートである、ClusterClassリソースを定義しています。この仕様には、一般的なインフラストラクチャとコントロールプレーンの構成が含まれており、クラスター群全体で効率的なプロビジョニングと統一されたライフサイクル管理を実現します。 以下のClusterClassの例ではいくつかの変数が定義されており、これらはクラスターのインスタンス化プロセス中に、各クラスターインスタンスに要求された実際の値を使用して置き換えられます。 例では以下の変数が使用されています。

  • metallbHelmChartVersion:このオプション変数は、クラスターにデプロイする`MetalLB` Helmチャートのバージョンを指定するために使用します。指定がない場合、MetalLB Helmチャートはデプロイされません。

  • endpointCopierOperatorHelmChartVersion:このオプション変数は、クラスターにデプロイする`Endpoint Copier Operator` Helmチャートのバージョンを指定するために使用します(MetalLB Helmチャートのバージョンも指定されている場合)。指定がない場合、Endpoint Copier Operator Helmチャートはデプロイされません。

  • controlPlaneMachineTemplateImageURL:この必須変数は、コントロールプレーンマシンをプロビジョニングするために使用するイメージのURLを指定するために使用します。

  • controlPlaneMachineTemplateHostSelectorDeployRegion:この必須変数は、コントロールプレーンマシン用の`deploy-region`ホストセレクター値を指定するために使用します。

  • controlPlaneMachineTemplateHostSelectorClusterType:この必須変数は、コントロールプレーンマシン用の`cluster-type`ホストセレクター値を指定するために使用します。

  • controlPlaneMachineTemplateDataTemplateName:この必須変数は、コントロールプレーンマシンに使用する`Metal3DataTemplate` APIオブジェクトの名前を指定するために使用します。

  • controlPlaneEndpointHost:この必須変数は、コントロールプレーンエンドポイントのホスト名またはIPアドレスを指定するために使用します。

  • tlsSan:この必須変数は、コントロールプレーンエンドポイントのTLSサブジェクト代替名(SAN)のリストを指定するために使用します。

ClusterClass定義ファイルは、以下の4つのリソースで構成されています。

  • ClusterClass:このリソースは、コントロールプレーンテンプレートやインフラストラクチャテンプレートを含む、クラスタークラス定義全体をカプセル化します。さらに、インスタンス化プロセス中に置き換えられる変数のリストが含まれており、それらを使用するパッチも定義されています。

  • RKE2ControlPlaneTemplate:このリソースはコントロールプレーンテンプレートを定義し、コントロールプレーンノードの目的の設定を指定します。また、インスタンス化プロセス中に、一部のパラメーターが適切な値に置き換えられます。

  • Metal3ClusterTemplate:このリソースはインフラストラクチャテンプレートを定義し、基盤となるインフラストラクチャの目的の設定を指定します。これには、コントロールプレーンエンドポイントやcloudProviderEnabled(true|false)フラグなどのパラメータが含まれます。また、インスタンス化プロセス中に、一部のパラメーターが適切な値に置き換えられます。

  • Metal3MachineTemplate:このリソースは、コントロールプレーンノードのマシンテンプレートブループリントを定義し、インスタンス化プロセス中に適切な値に置き換えられるそれらのパラメータのプレースホルダーを提供します。

    apiVersion: controlplane.cluster.x-k8s.io/v1beta2
    kind: RKE2ControlPlaneTemplate
    metadata:
      name: example-controlplane
      namespace: emea-spa
    spec:
      template:
        spec:
          rolloutStrategy:
            type: "RollingUpdate"
            rollingUpdate:
              maxSurge: 1
          registrationMethod: "control-plane-endpoint"
          registrationAddress: TO-BE-PATCHED-AUTOMATICALLY  # This will be replaced by the involved patch when applying the cluster instance
          serverConfig:
            cni: cilium
            cniMultusEnable: true
            tlsSan:
            - TO-BE-PATCHED-AUTOMATICALLY    # This will be replaced by the involved patch when applying the cluster instance
          agentConfig:
            format: ignition
            additionalUserData:
              config: |          # This will be replaced by the involved patch when applying the cluster instance
                TO-BE-PATCHED-AUTOMATICALLY
            kubelet:
              extraArgs:
              - provider-id=metal3://PROVIDERID
            nodeName: "localhost.localdomain"
    ---
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
    kind: Metal3ClusterTemplate
    metadata:
      name: example-cluster-template
      namespace: emea-spa
    spec:
      template:
        spec:
          controlPlaneEndpoint:
            host: TO-BE-PATCHED-AUTOMATICALLY  # This will be replaced by the involved patch when applying the cluster instance
            port: 6443
          cloudProviderEnabled: false
    ---
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
    kind: Metal3MachineTemplate
    metadata:
      name: example-controlplane-machineinfrastructure
      namespace: emea-spa
    spec:
      nodeReuse: true
      template:
        spec:
          automatedCleaningMode: metadata
          dataTemplate:
            name: to-be-patched-automatically  # This will be replaced by the involved patch when applying the cluster instance
          hostSelector:
            matchLabels:  # The labels used to identify the BMHs to select.
              cluster-role: control-plane
              deploy-region: TO-BE-PATCHED-AUTOMATICALLY # This will be replaced by the involved patch when applying the cluster instance
              cluster-type: TO-BE-PATCHED-AUTOMATICALLY  # This will be replaced by the involved patch when applying the cluster instance
          image:
            checksum: http://TO-BE-PATCHED-AUTOMATICALLY # This will be replaced by the involved patch when applying the cluster instance
            checksumType: sha256
            diskFormat: raw
            url: http://TO-BE-PATCHED-AUTOMATICALLY      # This will be replaced by the involved patch when applying the cluster instance
    ---
    apiVersion: cluster.x-k8s.io/v1beta2
    kind: ClusterClass
    metadata:
      name: example-clusterclass
      namespace: emea-spa
    spec:
      infrastructure:
        templateRef:
          kind: Metal3ClusterTemplate
          apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
          name: example-cluster-template
      controlPlane:
        templateRef:
          kind: RKE2ControlPlaneTemplate
          apiVersion: controlplane.cluster.x-k8s.io/v1beta2
          name: example-controlplane
        machineInfrastructure:
          templateRef:
            kind: Metal3MachineTemplate
            apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
            name: example-controlplane-machineinfrastructure
      variables:
      - name: metallbHelmChartVersion
        required: false
        schema:
          openAPIV3Schema:
            type: string
      - name: endpointCopierOperatorHelmChartVersion
        required: false
        schema:
          openAPIV3Schema:
            type: string
      - name: controlPlaneMachineTemplateImageURL
        required: true
        schema:
          openAPIV3Schema:
            type: string
      - name: controlPlaneMachineTemplateHostSelectorDeployRegion
        required: true
        schema:
          openAPIV3Schema:
            type: string
      - name: controlPlaneMachineTemplateHostSelectorClusterType
        required: true
        schema:
          openAPIV3Schema:
            type: string
      - name: controlPlaneMachineTemplateDataTemplateName
        required: true
        schema:
          openAPIV3Schema:
            type: string
      - name: controlPlaneEndpointHost
        required: true
        schema:
          openAPIV3Schema:
            type: string
      - name: tlsSan
        required: true
        schema:
          openAPIV3Schema:
            type: array
            items:
              type: string
      patches:
      - name: setControlPlaneMachineTemplateImageURL
        definitions:
        - selector:
            apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
            kind: Metal3MachineTemplate
            matchResources:
              controlPlane: true        # Added to select ControlPlane
          jsonPatches:
          - op: replace
            path: "/spec/template/spec/image/url"
            valueFrom:
              variable: controlPlaneMachineTemplateImageURL
          - op: replace
            path: "/spec/template/spec/image/checksum"
            valueFrom:
              template: "{{ .controlPlaneMachineTemplateImageURL }}.sha256"
      - name: setControlPlaneMachineTemplateHostSelectorDeployRegion
        definitions:
        - selector:
            apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
            kind: Metal3MachineTemplate
            matchResources:
              controlPlane: true
          jsonPatches:
          - op: replace
            path: "/spec/template/spec/hostSelector/matchLabels/deploy-region"
            valueFrom:
              variable: controlPlaneMachineTemplateHostSelectorDeployRegion
      - name: setControlPlaneMachineTemplateHostSelectorClusterType
        definitions:
        - selector:
            apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
            kind: Metal3MachineTemplate
            matchResources:
              controlPlane: true        # Added to select ControlPlane
          jsonPatches:
          - op: replace
            path: "/spec/template/spec/hostSelector/matchLabels/cluster-type"
            valueFrom:
              variable: controlPlaneMachineTemplateHostSelectorClusterType
      - name: setControlPlaneMachineTemplateDataTemplateName
        definitions:
        - selector:
            apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
            kind: Metal3MachineTemplate
            matchResources:
              controlPlane: true        # Added to select ControlPlane
          jsonPatches:
          - op: replace
            path: "/spec/template/spec/dataTemplate/name"
            valueFrom:
              variable: controlPlaneMachineTemplateDataTemplateName
      - name: setControlPlaneEndpoint
        definitions:
        - selector:
            apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
            kind: Metal3ClusterTemplate
            matchResources:
              infrastructureCluster: true  # Added to select InfraCluster
          jsonPatches:
          - op: replace
            path: "/spec/template/spec/controlPlaneEndpoint/host"
            valueFrom:
              variable: controlPlaneEndpointHost
      - name: setRegistrationAddress
        definitions:
        - selector:
            apiVersion: controlplane.cluster.x-k8s.io/v1beta2
            kind: RKE2ControlPlaneTemplate
            matchResources:
              controlPlane: true        # Added to select ControlPlane
          jsonPatches:
          - op: replace
            path: "/spec/template/spec/registrationAddress"
            valueFrom:
              variable: controlPlaneEndpointHost
      - name: setTlsSan
        definitions:
        - selector:
            apiVersion: controlplane.cluster.x-k8s.io/v1beta2
            kind: RKE2ControlPlaneTemplate
            matchResources:
              controlPlane: true        # Added to select ControlPlane
          jsonPatches:
          - op: replace
            path: "/spec/template/spec/serverConfig/tlsSan"
            valueFrom:
              variable: tlsSan
      - name: updateAdditionalUserData
        definitions:
        - selector:
            apiVersion: controlplane.cluster.x-k8s.io/v1beta2
            kind: RKE2ControlPlaneTemplate
            matchResources:
              controlPlane: true
          jsonPatches:
          - op: replace
            path: "/spec/template/spec/agentConfig/additionalUserData"
            valueFrom:
              template: |
                config: |
                  variant: fcos
                  version: 1.4.0
                  {{ if .metallbHelmChartVersion }}
                  storage:
                    files:
                    - path: /var/lib/rancher/rke2/server/manifests/metallb.yaml
                      overwrite: true
                      contents:
                        inline: |
                          apiVersion: helm.cattle.io/v1
                          kind: HelmChart
                          metadata:
                            name: metallb
                            namespace: kube-system
                          spec:
                            chart: oci://registry.suse.com/edge/charts/metallb
                            targetNamespace: metallb-system
                            version: {{ .metallbHelmChartVersion }}
                            createNamespace: true
                    {{ if .endpointCopierOperatorHelmChartVersion }}
                    - path: /var/lib/rancher/rke2/server/manifests/endpoint-copier-operator.yaml
                      overwrite: true
                      contents:
                        inline: |
                          apiVersion: helm.cattle.io/v1
                          kind: HelmChart
                          metadata:
                            name: endpoint-copier-operator
                            namespace: kube-system
                          spec:
                            chart: oci://registry.suse.com/edge/charts/endpoint-copier-operator
                            targetNamespace: endpoint-copier-operator
                            version: {{ .endpointCopierOperatorHelmChartVersion }}
                            createNamespace: true
                    - path: /var/lib/rancher/rke2/server/manifests/metallb-cr.yaml
                      overwrite: true
                      contents:
                        inline: |
                          apiVersion: metallb.io/v1beta1
                          kind: IPAddressPool
                          metadata:
                            name: kubernetes-vip-ip-pool
                            namespace: metallb-system
                          spec:
                            addresses:
                              - {{ .controlPlaneEndpointHost }}/32
                            serviceAllocation:
                              priority: 100
                              namespaces:
                                - default
                              serviceSelectors:
                                - matchExpressions:
                                  - {key: "serviceType", operator: In, values: [kubernetes-vip]}
                          ---
                          apiVersion: metallb.io/v1beta1
                          kind: L2Advertisement
                          metadata:
                            name: ip-pool-l2-adv
                            namespace: metallb-system
                          spec:
                            ipAddressPools:
                              - kubernetes-vip-ip-pool
                    - path: /var/lib/rancher/rke2/server/manifests/endpoint-svc.yaml
                      overwrite: true
                      contents:
                        inline: |
                          apiVersion: v1
                          kind: Service
                          metadata:
                            name: kubernetes-vip
                            namespace: default
                            labels:
                              serviceType: kubernetes-vip
                          spec:
                            ports:
                            - name: rke2-api
                              port: 9345
                              protocol: TCP
                              targetPort: 9345
                            - name: k8s-api
                              port: 6443
                              protocol: TCP
                              targetPort: 6443
                            type: LoadBalancer
                    {{ end }}
                  {{ end }}
                  systemd:
                    units:
                    - name: rke2-preinstall.service
                      enabled: true
                      contents: |
                        [Unit]
                        Description=rke2-preinstall
                        Wants=network-online.target
                        Before=rke2-install.service
                        ConditionPathExists=!/run/cluster-api/bootstrap-success.complete
                        [Service]
                        Type=oneshot
                        User=root
                        ExecStartPre=/bin/sh -c "mount -L config-2 /mnt"
                        # Note we use _ as a delimiter for sed here because the providerid includes / characters
                        ExecStart=/bin/sh -c "sed -i \"s_PROVIDERID_$(jq -r .providerid /mnt/openstack/latest/meta_data.json)_\" /etc/rancher/rke2/config.yaml"
                        ExecStart=/bin/sh -c "echo \"node-name: $(jq -r .name /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                        ExecStart=/bin/sh -c "echo \"node-label:\" >> /etc/rancher/rke2/config.yaml"
                        ExecStart=/bin/sh -c "echo \"  - metal3.io/uuid=$(jq -r .uuid /mnt/openstack/latest/meta_data.json)\" >> /etc/rancher/rke2/config.yaml"
                        ExecStartPost=/bin/sh -c "umount /mnt"
                        [Install]
                        WantedBy=multi-user.target

67.4.2 クラスターインスタンスの定義

ClusterClassのコンテキストにおいて、クラスターインスタンスとは、定義されたClusterClassに基づいて作成された、特定の実行中のクラスターのインスタンス化を指します。 これは、ClusterClassで指定されたブループリントから直接派生した、独自の設定、リソース、および運用状態を持つ具体的なデプロイメントを表します。 これには、アクティブに実行されている特定のマシンセット、ネットワーク設定、および関連するKubernetesコンポーネントが含まれます。 クラスターインスタンスを理解することは、ClusterClassフレームワークを使用してプロビジョニングされた特定のデプロイ済みクラスターのライフサイクル管理、アップグレードの実行、スケーリング操作の実行、および監視を行うために不可欠です。

クラスターインスタンスを定義するには、以下の2つのリソースを定義する必要があります。

  • クラスター:このリソースは実際のクラスターインスタンスを表し、その`topology`(つまり`ClusterClass`オブジェクト)への参照、必要なKubernetesバージョン、インスタンス化するコントロールプレーンノードの数、および参照される`ClusterClass`で定義された各変数に提供される値を含みます。これらはインスタンス化プロセス中に使用されます。

  • Metal3DataTemplate:このリソースは、クラスター内のマシン(この例ではコントロールプレーンマシンのみ)に関する追加のメタデータを提供し、インスタンス化されたクラスターごとに自動的に作成される`Metal3MachineTemplate`オブジェクトを補完します。共通の`Metal3DataTemplate`からインスタンス化されたすべてのクラスターに対して有効な単一の`ClusterClass`リソースを定義することはできないことに注意してください。`clusterName`仕様の`Metal3DataTemplate`フィールドは、それが「属する」特定のクラスターインスタンスを参照する必要があるためです。

    apiVersion: cluster.x-k8s.io/v1beta2
    kind: Cluster
    metadata:
      name: emea-spa-cluster-3
      namespace: emea-spa
      labels:
        cluster-api.cattle.io/rancher-auto-import: "true"
    spec:
      topology:
        classRef:
          name: example-clusterclass
          namespace: emea-spa
        version: v1.36.3+rke2r1
        controlPlane:
          replicas: 1
        variables:                       # Values to be replaced in the clusterclass template variables to create this specific cluster
        - name: endpointCopierOperatorHelmChartVersion
          value: 307.0.1+up0.3.0
        - name: metallbHelmChartVersion
          value: 307.0.3+up0.16.1
        - name: controlPlaneMachineTemplateImageURL
          value: http://fileserver.local:8080/eibimage-downstream-cluster.raw.sha256
        - name: controlPlaneMachineTemplateHostSelectorDeployRegion
          value: emea-spa
        - name: controlPlaneMachineTemplateHostSelectorClusterType
          value: group-3
        - name: controlPlaneMachineTemplateDataTemplateName
          value: emea-spa-cluster-3
        - name: controlPlaneEndpointHost
          value: 192.168.122.203
        - name: tlsSan
          value:
          - 192.168.122.203
          - https://192.168.122.203.sslip.io
    ---
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
    kind: Metal3DataTemplate
    metadata:
      name: emea-spa-cluster-3
      namespace: emea-spa
    spec:
      clusterName: emea-spa-cluster-3
      metaData:
        objectNames:
        - key: name
          object: machine
        - key: local-hostname
          object: machine
        - key: local_hostname
          object: machine
注記
注記

cluster.x-k8s.io APIグループの`Cluster` APIオブジェクトにラベル`cluster-api.cattle.io/rancher-auto-import: "true"`を追加すると、Rancherにクラスタがインポートされます(management.cattle.io APIグループに対応するRancher Cluster APIオブジェクトが作成されます)。 詳細については、 Cluster APIドキュメントを参照してください。

このアプローチにより処理が合理化され、ClusterClassのブループリントが定義されていれば、わずか2つのリソースを使用してクラスターをデプロイできるようになります。

68 Longhorn Volume 暗号化

Longhornは、レプリケーションと高可用性機能を備えた永続ストレージを提供する、Kubernetes向けの分散ブロックストレージシステムです。本ガイドでは、保存データの保護を確実にするために、LUKS/AES-256暗号化を使用してLonghornを構成する方法を説明します。

68.1 概要

データセキュリティは、現代のクラウドネイティブアプリケーション、特に機密情報を扱う環境において重要な要件です。ボリューム暗号化は、物理的なセキュリティが侵害されたシナリオであっても、物理メディアに保存されたデータを不正アクセスから保護する基本的なセキュリティ層を提供します。

Longhornは、業界標準の暗号化技術を使用してボリュームレベルの暗号化を実装しています。

  • LUKS (Linux Unified Key Setup):プラットフォームに依存しない標準のオンディスクフォーマットを提供する、ブロックデバイス暗号化の仕様です。

  • AES-256:256ビットキーによる高度暗号化標準(AES)であり、堅牢な暗号化保護を提供します

68.2 ボリューム暗号化を実装する理由

ボリューム暗号化は、いくつかのセキュリティおよびコンプライアンス要件に対応します。

  • 保存データの保護:物理ストレージメディア上の暗号化されたデータは、ディスクが物理的に取り外されたり盗難に遭ったりした場合でも、不正アクセスから保護されます。

  • 業界規制に対するコンプライアンス:GDPR、HIPAA、PCI-DSSなどの業界規制では機密データの暗号化が義務付けられており、コンプライアンスを実現するためにボリューム暗号化が不可欠です。

  • 多層防御:暗号化は、KubernetesのRBACやネットワークポリシーを補完する追加のセキュリティ層を提供します。

  • 安全なデータ廃棄:暗号化されたボリュームは、暗号化キーを破棄するだけで安全に廃棄でき、データに永続的にアクセスできないようにすることができます。

注記
注記

暗号化は、ボリュームレベルで透過的に適用されます。アプリケーションは、コードを変更することなく、標準のKubernetes永続ボリューム要求を通じて暗号化されたボリュームとやり取りします。

68.3 アーキテクチャの概要

Longhorn暗号化は、Kubernetes Container Storage Interface (CSI) と統合され、透過的なボリューム暗号化を提供します。暗号化プロセスはボリュームのプロビジョニング中に行われ、以下のコンポーネントを通じて管理されます。

  • Kubernetes Secrets:暗号化キーは、Kubernetes Secret リソースとして安全に保存されます。

  • StorageClass パラメーター:暗号化構成は、CSI固有のパラメーターを通じて指定されます。

  • LUKSデバイスマッパー:各暗号化ボリュームは、LUKSで暗号化されたデバイスマッパー・ターゲットを基盤として利用して構成されています。

  • CSIドライバー:Longhorn CSIドライバーは、暗号化キーの取得とボリュームのステージングを管理します。

暗号化ワークフローは次のように動作します。

  1. PersistentVolumeClaim (PVC) が暗号化された StorageClass からストレージを要求すると、Longhorn CSIドライバーは指定されたSecretから暗号化キーを取得します。

  2. 暗号化キーを使用して、LUKSで暗号化されたデバイスマッパー・ターゲットが作成されます。

  3. ボリュームに書き込まれるすべてのデータは、基盤となるストレージにコミットされる前に暗号化されます。

  4. ボリュームがマウントされると、CSIドライバーは保存されている暗号化キーを使用してLUKSデバイスをロック解除し、ボリュームをステージングします。

68.4 前提条件

Longhornボリューム暗号化を実装する前に、以下の前提条件が満たされていることを確認してください。

  • SUSE Storage 1.12.1 がインストールされた機能的なKubernetesクラスター

  • で説明されているように有効化および準備されたV2データエンジン第66章 「SUSE Storage V2データエンジン」

  • 適切なRBAC権限を持つクラスター管理アクセス権限

  • kubectl クラスターアクセス用に構成されたコマンドラインツール

  • openssl 暗号化キー生成用ユーティリティ

68.5 実装

  1. 暗号化キーを生成する

    暗号化キーの生成は、暗号学的に安全な乱数生成を使用して実行する必要があります。次のコマンドを実行して、`base64`形式でエンコードされた256ビットの暗号化キーを生成します。

    openssl rand -base64 32

    出力例:

    Kq8Xh2vN9pL3mZ1wR4tY6uI0oP5aS7dF8gH9jK1lM2n=
    警告
    警告

    キー管理の重要な要件

    • 暗号化キーをバージョン管理システムにコミットしないでください

    • 暗号化キーを紛失すると、永続的かつ不可逆的なデータ損失が発生します。

  2. 暗号化キーのシークレットを作成する

    生成された暗号化キーは、`longhorn-system`ネームスペースのKubernetesシークレットとして保存する必要があります。

    CRYPTO_KEY_VALUE="Kq8Xh2vN9pL3mZ1wR4tY6uI0oP5aS7dF8gH9jK1lM2n="
    
    kubectl create secret generic longhorn-crypto \
      --from-literal=CRYPTO_KEY_VALUE="${CRYPTO_KEY_VALUE}" \
      -n longhorn-system

    シークレットが正常に作成されたことを確認します。

    kubectl get secret longhorn-crypto -n longhorn-system
    ヒント
    ヒント

    本番環境では、機密データをクラスターのetcdに直接保存することを避けるため、External Secrets Operatorやsealed-secretsなど、Kubernetesと統合された外部シークレット管理ソリューションの使用を検討してください。

  3. 暗号化されたStorageClassを構成する

    1. Longhorn CSIドライバーの暗号化パラメーターを指定する`StorageClass`を定義します。

      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: longhorn-encrypted
      provisioner: driver.longhorn.io
      allowVolumeExpansion: true
      parameters:
        dataEngine: "v2"
        numberOfReplicas: "3"
        staleReplicaTimeout: "2880"
        fromBackup: ""
        fsType: "ext4"
        dataLocality: "disabled"
        # Encryption configuration
        encrypted: "true"
        csi.storage.k8s.io/provisioner-secret-name: "longhorn-crypto"
        csi.storage.k8s.io/provisioner-secret-namespace: "longhorn-system"
        csi.storage.k8s.io/node-publish-secret-name: "longhorn-crypto"
        csi.storage.k8s.io/node-publish-secret-namespace: "longhorn-system"
        csi.storage.k8s.io/node-stage-secret-name: "longhorn-crypto"
        csi.storage.k8s.io/node-stage-secret-namespace: "longhorn-system"

      暗号化固有のパラメーターは、CSIシークレット参照を構成します。

      • encrypted: "true" - このStorageClassからプロビジョニングされるすべてのボリュームに対してLUKS暗号化を有効にします

      • csi.storage.k8s.io/provisioner-secret-name - ボリュームのプロビジョニング中に使用される暗号化キーを含むシークレットを指定します

      • csi.storage.k8s.io/node-publish-secret-name - ポッドにボリュームをマウントする際に使用されるシークレットを識別します

      • csi.storage.k8s.io/node-stage-secret-name - ボリュームのステージング操作中に使用されるシークレットを参照します。

    2. StorageClass定義を適用します。

      kubectl apply -f longhorn-encrypted-storageclass.yaml
    3. StorageClassの作成と構成を検証します。

      kubectl get storageclass longhorn-encrypted
      kubectl get storageclass longhorn-encrypted -o yaml
  4. テストワークロードのデプロイ

    暗号化の実装を検証するために、暗号化されたボリュームにデータを書き込むテストPodをデプロイします。

    1. 次のマニフェスト(test-encryption.yaml)を作成します。

      # Test Longhorn Encryption
      # Deploys a simple pod that writes data to an encrypted volume
      
      ---
      # PVC using the encrypted StorageClass
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: test-encrypted-pvc
        namespace: default
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: longhorn-encrypted
        resources:
          requests:
            storage: 1Gi
      
      ---
      # Pod that writes sensitive data to the volume
      apiVersion: v1
      kind: Pod
      metadata:
        name: encryption-test-pod
        namespace: default
        labels:
          app: encryption-test
      spec:
        containers:
        - name: writer
          image: busybox
          command:
            - sh
            - -c
            - |
              echo "=== Writing sensitive data to encrypted volume ==="
              echo "SECRET DATA: Credit Card 4111-1111-1111-1111" > /data/secret.txt
              echo "SECRET DATA: Password MySuperSecret123!" >> /data/secret.txt
              echo "SECRET DATA: API Key sk-1234567890abcdef" >> /data/secret.txt
              date >> /data/secret.txt
              echo "=== Data written successfully ==="
              echo "Content of /data/secret.txt:"
              cat /data/secret.txt
              echo "=== Sleeping forever (use 'kubectl exec' to verify) ==="
              sleep infinity
          volumeMounts:
          - name: encrypted-storage
            mountPath: /data
        volumes:
        - name: encrypted-storage
          persistentVolumeClaim:
            claimName: test-encrypted-pvc

      このマニフェストは以下を定義します。

      • PersistentVolumeClaim`が`longhorn-encrypted StorageClassから1Giのストレージを要求する

      • 暗号化されたボリュームにテストデータを書き込み、検証のために実行状態を維持するPod

    2. テストワークロードをデプロイします。

      kubectl apply -f test-encryption.yaml
    3. Podの起動を監視します。

      kubectl get pod encryption-test-pod -w
  5. ボリューム機能の検証

    Podが`Running`状態になったら、データ操作が正常に完了することを確認します。

    1. Podのログを表示します。

      kubectl logs encryption-test-pod
    2. Pod内でシェルを実行します。

      kubectl exec -it encryption-test-pod -- sh
    3. Pod内でコンテンツを確認します。

      cat /data/secret.txt
      ls -lh /data/

      予想される出力:

      SECRET DATA: Credit Card 4111-1111-1111-1111
      SECRET DATA: Password MySuperSecret123!
      SECRET DATA: API Key sk-1234567890abcdef
      Thu Jul 03 10:30:45 UTC 2026
      注記
      注記

      データ操作が成功すれば、ボリュームのプロビジョニングとマウント機能が確認されたことになります。ただし、この検証だけでは暗号化は検証されません。次の手順で暗号化の検証を行います。

  6. 暗号化の検証

    暗号化が有効であることを確実に検証するには、基盤となるストレージデバイスを直接検査する必要があります。

    1. ボリュームの場所を特定する

      ボリュームレプリカをホストしているノードを特定します:

      # Get the PVC details
      kubectl get pvc test-encrypted-pvc
      
      # Get the associated PersistentVolume
      kubectl get pv | grep test-encrypted
      
      # View Longhorn volume details
      kubectl get volumes -n longhorn-system | grep test-encrypted
    2. ノードにアクセスしてボリュームファイルを特定する

      (前の出力から特定された)ボリュームをホストしているノードにSSHで接続します:

      # Connect to the node
      ssh root@<node-ip>
      
      # Locate the volume image file
      find /var/lib/longhorn -name "*.img*" -type f | grep -i test

      一般的なボリュームパス:

      /var/lib/longhorn/replicas/pvc-abc12345-r-6789/volume-head-001.img
    3. プレーンテキストデータの抽出を試みる

      次のコマンドを実行して、暗号化されていないデータを検索します:

      # Attempt to find plaintext strings in the volume file
      strings /var/lib/longhorn/replicas/pvc-*/volume-head-*.img | grep -i "credit card"

      検証結果:

      • 暗号化が有効:プレーンテキストの文字列は見つかりませんでした(データは暗号化されています)

      • 暗号化が無効:プレーンテキストの文字列が検出されました(データは暗号化されていません)

    4. 16進数検査

      ボリュームの生のバイトコンテンツを調べます:

      # Navigate to the replica directory
      cd /var/lib/longhorn/replicas/pvc-XXXXX-r-YYYY/
      
      # Display raw volume content
      hexdump -C volume-head-*.img | head -100

      暗号化されたボリュームの出力(ランダムなバイト):

      00000000  a3 7f 2c d9 8b 4e f1 2a  9c 5d 8e 6b 4f 1d 3c 7a  |..,..N.*.[.kO.<z|
      00000010  d2 9f 4a 8c 3b e7 6d 1e  5f 0c b8 a4 7d 2f 9e 6c  |..J.;.m._...}/.l|

      暗号化されていないボリュームの出力(読み取り可能なASCII):

      00000000  53 45 43 52 45 54 20 44  41 54 41 3a 20 43 72 65  |SECRET DATA: Cre|
      00000010  64 69 74 20 43 61 72 64  20 34 31 31 31 2d 31 31  |dit Card 4111-11|
  7. LUKSデバイスの検証

    Longhornは、LinuxのLUKSサブシステムを使用して暗号化を実装しています。LUKSデバイスマッパーのターゲットを検証します:

    # List block devices with encryption type
    lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT | grep -i crypt
    
    # List device mapper crypt targets
    dmsetup ls --target crypt

    crypto_LUKS ファイルシステムタイプまたはデバイスマッパー暗号化ターゲットの存在は、LUKS暗号化が有効であることを示しています。

  8. データ永続性の検証

    暗号化されたボリュームがポッドのライフサイクルイベント全体でデータの整合性を維持していることを確認します:

    # Delete the pod (volume persists)
    kubectl delete pod encryption-test-pod
    
    # Recreate the pod
    kubectl apply -f test-encryption.yaml
    
    # Wait for Running state
    kubectl get pod encryption-test-pod -w
    
    # Verify data persistence
    kubectl exec -it encryption-test-pod -- cat /data/secret.txt

    データはそのまま保持され、適切なボリュームの永続性が実証される必要があります。

68.6 暗号化検証の概要

次の表は、暗号化検証の指標をまとめたものです:

検証方法暗号化される暗号化しない

strings 出力

プレーンテキストは見つかりませんでした

プレーンテキスト文字列が表示されています

hexdump 出力

ランダムなバイナリデータ

読み取り可能なASCIIテキスト

lsblk 出力

crypto_LUKS タイプが存在します

crypto_LUKS タイプはありません

dmsetup ls --target crypt

暗号化デバイスを一覧表示します

暗号化デバイスは一覧表示されません

68.7 テスト環境のクリーンアップ

テストリソースを削除します:

# Delete the test pod
kubectl delete -f test-encryption.yaml

# Delete the PVC and volume
kubectl delete pvc test-encrypted-pvc

68.8 CAPI統合

Metal3 を使用してCluster API (CAPI) でクラスターをデプロイする場合、暗号化構成をクラスタープロビジョニングマニフェストに埋め込むことができ、初期クラスター起動から暗号化されたストレージを有効にできます。

完全なリファレンス実装は、 SUSE Edge telco-cloud-examples リポジトリで入手できます。

このリファレンス実装には以下が含まれます。

  • マルチノードコントロールプレーンデプロイメント用のBareMetalHost定義

  • Longhorn暗号化設定が統合されたCAPIクラスターマニフェスト

  • クラスター初期化中の自動シークレットプロビジョニング

  • デフォルトとして設定された事前構成済みの暗号化StorageClass

  • VIP管理用のMetalLB設定

  • コントロールプレーンエンドポイント同期用のEndpoint Copier Operator

CAPIベースのデプロイメントでは、暗号化キーは通常、クラスタープロビジョニング変数を通じて提供されます:

# Example variable reference from CAPI manifest
# Full manifests available in the repository
CRYPTO_KEY_VALUE: "YOUR_GENERATED_KEY_HERE"

この変数は、クラスターのプロビジョニング中に使用され、ダウンストリームクラスターの`longhorn-system`ネームスペースに`longhorn-crypto`シークレットを自動的に作成します。

注意
注意

CAPI暗号化デプロイメントに関する考慮事項:

  • クラスターのプロビジョニング前に`openssl rand -base64 32`を使用して暗号化キーを生成してください。

  • マニフェスト内のプレースホルダ値を実際の暗号化キーに置き換えてください。

  • 実際の暗号化キーを含むマニフェストは、決してバージョン管理にコミットしないでください。

  • シークレット管理ソリューションを使用してGitOpsワークフローを実装してください。

  • 災害復旧のために、暗号化キーをエンタープライズシークレット管理システムで維持してください。

  • キーが漏洩した場合の被害範囲を制限するため、クラスターごとに一意の暗号化キーを使用してください。

パート X ヒントとトラブルシューティング

Edgeコンポーネントのヒントとコツ

  • 69 Edge Image Builder
  • Linux以外の環境でこれらの手順に従ってイメージをビルドしている場合、おそらく仮想マシン経由で`Podman`を実行しています。デフォルトでは、この仮想マシンには少量のシステムリソースしか割り当てられないように構成されており、RPM解決プロセスなどのリソースを大量に消費する操作中に`Edge Image Builder`が不安定になる可能性があります。Podman Desktop(設定の歯車アイコン→、Podmanマシンの編集アイコン)を使用するか、podman-machine-set コマンドを使用して直接、podmanマシンのリソースを調整する必要があります。

  • 70 Metal3
  • Metalˆ3ˆクラスターオブジェクトとその対応する関連オブジェクトが作成されると、どの`BareMetalHost`をクラスターの一部にするかを選択するプロセスが実行されます。 このプロセスは、標準の Kubernetesラベルおよびセレクターを使用して、`BareMetalHost`と特定の`Metal3MachineTemplate`を接続します。

69 Edge Image Builder

69.1 Common(通常のネットワーキング)

  • Linux以外の環境でこれらの手順に従ってイメージをビルドしている場合、おそらく仮想マシン経由で`Podman`を実行しています。デフォルトでは、この仮想マシンには少量のシステムリソースしか割り当てられないように構成されており、RPM解決プロセスなどのリソースを大量に消費する操作中に`Edge Image Builder`が不安定になる可能性があります。Podman Desktop(設定の歯車アイコン→、Podmanマシンの編集アイコン)を使用するか、podman-machine-set コマンドを使用して直接、podmanマシンのリソースを調整する必要があります。

  • 現時点では、`Edge Image Builder`はクロスアーキテクチャ設定でイメージをビルドできません。つまり、以下で実行する必要があります。

    • SL Micro AArch64イメージをビルドするための`aarch64`システム(Apple Siliconなど)

    • SL Micro AMD64/Intel 64イメージをビルドするための`x86_64`システム。

69.2 SUSE Linux Micro

  • 起動時にカーネルモジュールをロードするには、対応する`/etc/modprobe.d/module.conf`ファイルを使用します。Edge Image Builderを使用して、対応する`os-files`フォルダーを作成します。

.
├── definition.yaml
└── os-files
    └── etc
        └── modprobe.d
            └── module.conf

詳細については、 SUSE Linux Enterprise Serverドキュメントの「カーネルモジュールの管理」セクションを参照してください。

69.3 Kubernetes

  • マルチノードのKubernetesクラスターを作成するには、定義ファイルの`kubernetes`セクションを次のように調整する必要があります。

    • `kubernetes.nodes`の下にすべてのサーバーノードとエージェントノードをリストする

    • `kubernetes.network.apiVIP`の下で、すべての非イニシャライザーノードがクラスターに参加するために使用する仮想IPアドレスを設定する

    • オプションで、`kubernetes.network.apiHost`の下でクラスターにアクセスするためのドメインアドレスを指定するAPIホストを設定する。この設定の詳細については、 Kubernetesセクションのドキュメントを参照してください。

  • Edge Image Builder`は、各ノードのホスト名を使用して、そのKubernetesタイプ(`server`または`agent)を判別します。この構成は定義ファイルで管理されますが、マシンの一般的なネットワーク設定には、第13章 「エッジネットワーキング」で説明されているDHCP構成のいずれかを利用できます。

70 Metal3

70.1 `BareMetalHost`の選択とクラスターの関連付け

Metalˆ3ˆクラスターオブジェクトとその対応する関連オブジェクトが作成されると、どの`BareMetalHost`をクラスターの一部にするかを選択するプロセスが実行されます。 このプロセスは、標準の Kubernetesラベルおよびセレクターを使用して、`BareMetalHost`と特定の`Metal3MachineTemplate`を接続します。

例として、各`BareMetalHost`には、そのプロパティと対象のクラスターを識別するためのラベルが付けられます(例:クラスターロール、クラスター名、場所など)。

apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: mynode1
  labels:
    cluster-role: control-plane
    cluster: foobar
    location: madrid
    datacenter: xyz
<snip>
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: mynode2
  labels:
    cluster-role: worker
    cluster: foobar
    location: madrid
    datacenter: xyz
<snip>
---
apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: mynode3
  labels:
    cluster-role: worker
    cluster: foobar2
    location: madrid
    datacenter: xyz
<snip>
...

次に、`Metal3MachineTemplate`オブジェクトは spec.hostSelectorフィールドを使用して、目的の`BareMetalHost`と照合します。

matchLabels(完全なキーと値の一致用)と matchExpressions(より複雑なルール用)の両方を使用できます。

apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3MachineTemplate
metadata:
  name: foobar-cluster-controlplane
  namespace: mynamespace
spec:
  template:
    spec:
      hostSelector:
        matchLabels:
          cluster-role: control-plane
          cluster: foobar
<snip>
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: Metal3MachineTemplate
metadata:
  name: foobar-cluster-worker
  namespace: mynamespace
spec:
  template:
    spec:
      hostSelector:
        matchExpressions:
          - { key: cluster-role, operator: In, values: [worker] }
          - { key: cluster, operator: In, values: [foobar] }
<snip>
注記
注記

Kubernetesネームスペースを使用して、さまざまなオブジェクトをより適切に整理することもできます。

70.2 古いEFIブートエントリーのクリーンアップ

UEFIブートマネージャーには、おそらくもう不要な古いオペレーティングシステムの項目が複数含まれていることがあります(特に、ホストが何度も再プロビジョニングされる場合に顕著です)。 以下のいずれかの手順に従って、それらの古い項目をクリーンアップできます。

  • BIOS/EFIセットアップインターフェース上で直接削除します(正確な手順はハードウェアによって異なります)。

  • UEFI bcfgシェルを次のように実行します。

    # List the entries
    bcfg boot dump -b
    # Delete entry number X
    bcfg boot rm X
    # X is the number associated the entry to remove. For example, if the entry is "Boot0002 foobar", then X is 2.
  • Linuxシステム上で`efibootmgr`を次のように使用します。

    # List the entries
    efibootmgr -v
    # Delete entry number X
    efibootmgr -b X -B

このプロセスにより、EFIシステムパーティション(ESP)に孤立したファイルが残る場合があります。これらは通常、ベンダー名(例: EFI/opensuse`や`EFI/Microsoft)のサブディレクトリにあります。 これらのファイルは一般的に無害ですが、過剰な容量を消費している場合は、新しいOSのインストールやブートマネージャーの更新を妨げる可能性があるため、削除する必要があります。 削除するには、ESPを明示的にマウントする必要がある場合があります。通常、Linuxシステムでは`/boot/efi/EFI`としてマウントされます。

70.3 2つのシークレットアプローチを使用したカスタムネットワーク構成

Metal3がベアメタルノードをプロビジョニングする際、それぞれ異なるネットワーク構成が必要となる可能性のある2つの明確なフェーズを経由します。

  • IPAフェーズ:ハードウェアの検査およびプロビジョニング中にIronic Python Agent(IPA)ラムディスクが実行されるフェーズ

  • ターゲットOSフェーズ。デプロイされたSLE Microシステムが初回起動後に実行されるフェーズです。

2つのシークレットを使用するアプローチは、各フェーズごとに個別のネットワーク設定用シークレットを許可することでこの問題に対処します。IPAフェーズには`preprovisioningNetworkDataName`フィールドを、ターゲットOSフェーズには`networkData`フィールドを使用します。 これは、IPAカーネルとSLE Microカーネルが同じハードウェアを異なる名前で検出するため、フェーズ間でインターフェース名が異なる場合に特に便利です。

70.3.1 VLANのインターフェース名変更の例

一般的なシナリオとしては、ハードウェアが`enp1s0np123`のような長いPCIベースのインターフェース名を取得する場合があります。 その上にVLANを追加すると、Linuxカーネルのインターフェース名に対するハード制限である*15文字*を超える可能性があります。

enp1s0np123.100   = 15 chars  (barely fits, risky)
enp1s0np123.3669  = 17 chars  (exceeds limit, fails)
eth0.3669         =  9 chars  (works)

IPAフェーズでは`enp1s0np123`(カーネルが検出した名前)を参照する必要があり、ターゲットOSでは`eth0`のような短い名前を使用して`eth0.3669`が制限内に収まるようにします。nmc(nm-configurator)は、名前ではなくMACアドレスでインターフェースを照合することで2つのフェーズを橋渡しします。つまり、ハードウェアMACアドレスと一緒に`name: eth0`を宣言し、`nmc`はカーネルが何を割り当てたかに関係なく、目的の名前でNetworkManagerプロファイルを作成します。

70.3.2 前提条件:

70.3.2.1 EIBイメージのセットアップ

4.4.5.1項 「スタティック IP アドレスを設定する」に従い、EIBイメージには、プロビジョニング中にMetal3が書き込むネットワーク設定を`config-2`パーティションから読み取る、初回起動時に実行されるスクリプトを含める必要があります。 次のスクリプトを`/opt/EIB/network/configure-network.sh`に作成してください。

#!/bin/bash
set -eux

# Source: https://documentation.suse.com/suse-telco/3.7/html/telco/quickstart-metal3.html#metal3-add-network-eib

CONFIG_DRIVE=$(blkid --label config-2 || true)
if [ -z "${CONFIG_DRIVE}" ]; then
  echo "No config-2 device found, skipping network configuration"
  exit 0
fi

mount -o ro $CONFIG_DRIVE /mnt

NETWORK_DATA_FILE="/mnt/openstack/latest/network_data.json"

if [ ! -f "${NETWORK_DATA_FILE}" ]; then
  umount /mnt
  echo "No network_data.json found, skipping network configuration"
  exit 0
fi

DESIRED_HOSTNAME=$(cat /mnt/openstack/latest/meta_data.json | tr ',\{\}' '\n' | grep '\"metal3-name\"' | sed 's/.*\"metal3-name\": \"\(.*\)\"/\1/')
echo "${DESIRED_HOSTNAME}" > /etc/hostname

mkdir -p /tmp/nmc/\{desired,generated\}
cp ${NETWORK_DATA_FILE} /tmp/nmc/desired/_all.yaml
umount /mnt

./nmc generate --config-dir /tmp/nmc/desired --output-dir /tmp/nmc/generated
./nmc apply --config-dir /tmp/nmc/generated

次に、それを実行可能にしてから、通常通りEIBイメージをビルドします。

mkdir -p /opt/EIB/network
chmod +x /opt/EIB/network/configure-network.sh
注記
注記

EIBは`network/`ディレクトリからスクリプトを自動的に取得します。Combustionは、完全なOSが起動する前のinitramfs内で初回起動時にそれらを実行します。

注記
注記

このスクリプトは、Metal3の`metal3-name`メタデータフィールドからノードのホスト名も設定します。

70.3.3 2つのシークレットの設定

以下の例では、データNIC MAC aa:bb:cc:11:22:33、ブートNIC MAC aa:bb:cc:44:55:66、ノードIP 10.0.0.10/24、ゲートウェイ 10.0.0.1、DNS 10.0.0.53、VLAN ID 100、BMCアドレス `10.1.0.10`のダミー値を使用しています。

シークレット1 — IPAフェーズ (static-networkdata-ipa.yaml):カーネルが割り当てたインターフェース名を参照します。ハードウェア検出中にシンプルに保つため、ここではDHCPを使用します。

apiVersion: v1
kind: Secret
metadata:
  name: static-networkdata-ipa
  namespace: default
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: enp1s0np123
      type: ethernet
      state: up
      mac-address: "aa:bb:cc:11:22:33"
      ipv4:
        enabled: true
        dhcp: true
    dns-resolver:
      config:
        server:
        - 10.0.0.53

シークレット2 — ターゲットOSフェーズ (static-networkdata-os.yaml):目的の短い名前を参照し、VLANを宣言します。`nmc`がインターフェースを照合できるように、同じMACアドレスが使用されます。

apiVersion: v1
kind: Secret
metadata:
  name: static-networkdata-os
  namespace: default
type: Opaque
stringData:
  networkData: |
    interfaces:
    - name: eth0
      type: ethernet
      state: up
      mac-address: "aa:bb:cc:11:22:33"
      mtu: 1500
      ipv4:
        enabled: false
        dhcp: false
    - name: eth0.100
      type: vlan
      state: up
      mtu: 1500
      vlan:
        base-iface: eth0
        id: 100
      ipv4:
        address:
        - ip: 10.0.0.10
          prefix-length: 24
        enabled: true
        dhcp: false
    dns-resolver:
      config:
        server:
        - 10.0.0.53
    routes:
      config:
      - destination: 0.0.0.0/0
        next-hop-address: 10.0.0.1
        next-hop-interface: eth0.100

`BareMetalHost`オブジェクトは両方のシークレットを参照します。

apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
  name: my-node
  namespace: default
spec:
  online: true
  bootMACAddress: "aa:bb:cc:44:55:66"
  rootDeviceHints:
    deviceName: /dev/nvme0n1
  bmc:
    address: redfish-virtualmedia://10.1.0.10/redfish/v1/Systems/1/
    disableCertificateVerification: true
    credentialsName: my-node-credentials
  preprovisioningNetworkDataName: static-networkdata-ipa
  networkData:
    name: static-networkdata-os
警告
警告

`preprovisioningNetworkDataName`はプレーンな文字列フィールドですが、`networkData`は`name:`サブキーを必要とするSecretReferenceオブジェクトです。 両者の構文は異なっており、エラーの一般的な原因となっています。

すべてのオブジェクトを適用します:

kubectl apply -f bmc-credentials.yaml
kubectl apply -f static-networkdata-ipa.yaml
kubectl apply -f static-networkdata-os.yaml
kubectl apply -f baremetalhost.yaml

プロビジョニング後、ノードにSSH接続して以下を確認してください:

# Interface names
ip link show
# Expected: eth0 and eth0.100@eth0

# IP on VLAN interface
ip addr show eth0.100

# NetworkManager profiles
nmcli connection show

# VLAN details
nmcli connection show eth0.100 | grep -E '(vlan.parent|vlan.id)'

パート XI トラブルシューティング

このセクションでは、SUSE Telco Cloudのデプロイメントと運用に関する一般的な問題を診断および解決するためのガイダンスを提供します。コンポーネント固有のトラブルシューティング手順、主要なツール、関連するログの場所など、さまざまなトピックを扱っています。

71 一般的なトラブルシューティングの原則

コンポーネント固有の問題に取り組む前に、以下の一般的な原則を考慮してください。

  • ログを確認する:ログは情報の主要なソースです。多くの場合、エラーは自己説明的であり、何が失敗したかについてのヒントが含まれています。

  • クロックを確認する:システム間でクロックに差異があると、あらゆる種類の異なるエラーにつながる可能性があります。クロックが同期されていることを確認してください。EIBは起動時にクロック同期を強制するように指示できます。OS時刻の設定 (第5章 「Edge Image Builderを使用したスタンドアロンクラスター」)を参照してください。

  • 起動の問題:システムが起動中に停止した場合は、最後に表示されたメッセージを記録してください。コンソール(物理的またはBMC経由)にアクセスして、起動メッセージを確認してください。

  • ネットワークの問題:ネットワークインタフェースの設定(ip a)、ルーティングテーブル(ip route)を確認し、他のノードや外部サービスとの接続性をテストしてください(ping、nc)。ファイアウォールのルールが必要なポートをブロックしていないことを確認してください。

  • コンポーネントの状態を確認する:Kubernetesリソースには`kubectl get`および`kubectl describe`を使用してください。特定のKubernetesネームスペースのイベントを確認するには、`kubectl get events --sort-by='.lastTimestamp' -n <namespace>`を使用してください。

  • サービスの状態を確認する:systemdサービスには`systemctl status <service>`を使用してください。

  • 構文の確認:ソフトウェアは、設定ファイルに対して特定の構造と構文を想定しています。例えばyamlファイルの場合、`yamllint`や同様のツールを使用して、適切な構文であることを確認してください。

  • 問題の切り分け:問題を特定のコンポーネントまたは階層(ネットワーク、ストレージ、OS、Kubernetes、Metal3、Ironicなど…​)に絞り込むようにしてください。

  • ドキュメント:詳細については、常に公式の SUSE Telco Cloudドキュメントおよびアップストリームドキュメントを参照してください。

  • バージョン: SUSE Telco Cloudは、さまざまなSUSEコンポーネントを対象に、独自の設計思想に基づいて徹底的にテストされたバージョンです。各SUSE Telco Cloudリリースの各コンポーネントのバージョンは、 SUSE Telco Cloudサポートマトリックスで確認できます。

  • 既知の問題:各SUSE Telco Cloudリリースには、リリースノートに「既知の問題」セクションがあり、将来のリリースで修正される予定ですが、現在のリリースに影響を与える可能性のある問題に関する情報が記載されています。

72 Kiwiのトラブルシューティング

Kiwiは、Edge Image Builderで使用する更新されたSUSE Linux Microイメージを生成するために使用されます。

よくある問題
  • SL Microのバージョン不一致:ビルドホストのオペレーティングシステムバージョンは、ビルド対象のオペレーティングシステムバージョンと一致している必要があります(SL Micro 6.0ホスト → SL Micro 6.0イメージ)。

  • SELinuxがEnforcing状態:特定の制限により、現在Kiwiでイメージをビルドするには、一時的にSELinuxを無効にする必要があります。`getenforce`でSELinuxの状態を確認し、`setenforce 0`でビルドプロセスを実行する前に無効にしてください。

  • ビルドホストが登録されていません:ビルドプロセスでは、SUSE SCCからパッケージを取得するためにビルドホストのサブスクリプションを使用します。ホストが登録されていないと失敗します。

  • ループデバイスのテスト失敗:Kiwiビルドプロセスを初めて実行すると、開始直後に「ERROR:」で失敗します。「Early loop device test failed, please retry the container run.」というエラーは、基盤となるホストシステム上で作成されたループデバイスが、コンテナイメージ内で即座に認識されないことに起因する現象です。Kiwiビルドプロセスを再度実行すれば、問題なく進行するはずです。

  • 権限の不足:ビルドプロセスは、ルートユーザ(またはsudo経由)として実行されることを想定しています。

  • 権限が正しくありません:ビルドプロセスでは、コンテナの実行時に --privileged フラグが必要です。それが存在することを再確認してください。

ログ
  • ビルドコンテナログ:ビルドコンテナのログを確認してください。ログは、アーティファクトの保存に使用されたディレクトリに生成されます。必要な情報については、docker logsまたはpodman logsも確認してください。

  • 一時ビルドディレクトリ:Kiwiはビルドプロセス中に一時ディレクトリを作成します。メインの出力で不十分な場合は、これらの中間ログやアーティファクトを確認してください。

問題の対策の手順
  1. * build-image 出力の確認*:コンソール出力のエラーメッセージは、通常、非常に重要な情報を示しています。

  2. ビルド環境の確認:Kiwi自体に必要なすべての前提条件(例:docker/podman、SELinux、十分なディスク容量)が、Kiwiを実行しているマシンで満たされていることを確認してください。

  3. ビルドコンテナのログを確認:失敗したコンテナのログを確認して、より詳細なエラーがないか調べてください(上記を参照)。

  4. 定義ファイルの検証:カスタムKiwiイメージ定義ファイルを使用している場合は、ファイルに誤字や構文エラーがないか再確認してください。

注記
注記

Kiwiトラブルシューティングガイドを確認してください。

73 Edge Image Builder (EIB) のトラブルシューティング

EIBは、カスタムSUSE Telco Cloudイメージの作成に使用されます。

よくある問題
  • SCCコードが間違っています:EIB定義ファイルで使用されているSCCコードが、SL Microのバージョンおよびアーキテクチャと一致していることを確認してください。

  • 依存関係が不足しています:ビルド環境内に不足しているパッケージやツールがないことを確認してください。

  • イメージサイズが正しくありません:rawイメージの場合、`diskSize`パラメーターが必要であり、これはイメージに含まれるイメージ、RPM、およびその他のアーティファクトに大きく依存します。

  • 権限:カスタム/ファイルディレクトリにスクリプトを保存する場合は、それらのファイルはcombustion時に利用可能になるだけでEIBによって変更は行われないため、実行権限があることを確認してください。

  • オペレーティングシステムのグループ依存関係:カスタムユーザーおよびグループでイメージを作成する場合、"`primaryGroup`"として設定されるグループは明示的に作成する必要があります。

  • オペレーティングシステムのユーザーのSSHキーにはホームフォルダーが必要です:SSHキーを持つユーザーでイメージを作成する場合、`createHomeDir=true`を使用してホームフォルダーも作成する必要があります。

  • Combustionの問題:EIBは、OSのカスタマイズおよびその他すべてのSUSE Telco Cloudコンポーネントのデプロイメントをcombustionに依存しています。これには、custom/scriptsフォルダーに配置されるカスタムスクリプトも含まれます。combustion処理は`initrd`時に実行されるため、スクリプトが実行される時点ではシステムは完全に起動していないことに注意してください。

  • Podmanマシンのサイズ:EIBのヒントとコツのセクション (パートX「ヒントとトラブルシューティング」)で説明されているように、Linux以外のオペレーティングシステムでEIBコンテナを実行するために、podmanマシンに十分なCPU/メモリがあることを確認してください。

  • 不適切なイメージ:使用しているベースイメージが、 `checksum`を検証することで適切にダウンロードされていることを確認してください。kiwi-builder (第65章 「Kiwiを使用して更新されたSUSE Linux Microイメージを構築する」)を使用してイメージをビルドしている場合は、プロセスによって生成されたsumファイルも確認してください。

ログ
  • EIB出力:`eib build`コマンドのコンソール出力は非常に重要です。

  • ビルドコンテナログ:ビルドコンテナのログを確認してください。ログは、アーティファクトの保存に使用されたディレクトリに生成されます。必要な情報については、`docker logs`または`podman logs`も確認してください。

    注記
    注記

    詳細については、 デバッグを参照してください。

  • 一時ビルドディレクトリ:EIBは、ビルドプロセス中に一時ディレクトリを作成します。メインの出力で不十分な場合は、これらの中間ログやアーティファクトを確認してください。

  • Combustionログ:EIBでビルドされたイメージが何らかの理由で起動しない場合は、ルートシェルが利用可能です。ホストコンソール(物理的、BMC経由など)に接続し、`journalctl -u combustion`でCombustionログを確認してください。また、エラーの根本原因を特定するために、`journalctl`を使用してオペレーティングシステムのログ全般を確認してください。

問題の対策の手順
  1. 出力`eib-build`の確認:コンソール出力のエラーメッセージは、通常、非常に重要な情報を示しています。

  2. ビルド環境の確認:EIB自体に必要なすべての前提条件(例:docker/podman、十分なディスク容量など)が、EIBを実行しているマシンで満たされていることを確認してください。

  3. ビルドコンテナのログを調査する:失敗したコンテナのログを確認し、より詳細なエラーがないか調べてください(上記を参照)。

  4. の設定`eib`を検証する:`eib`の設定ファイルに誤字がないか、またはソースファイルやビルドスクリプトへのパスが正しく指定されているかを再確認してください。

    • コンポーネントを個別にテストする:EIBビルドにカスタムスクリプトやステージが含まれている場合は、それらを個別に実行してエラー箇所を特定してください。

注記
注記

Edge Image Builderのデバッグを確認してください。

74 エッジネットワークのトラブルシューティング (NMC)

NMCはSL Micro EIBイメージに注入され、combustionを介して起動時にエッジホストのネットワークを設定します。また、検査プロセスの一環としてMetal3ワークフローでも実行されます。ホストの初回起動時やMetal3検査プロセスで問題が発生することがあります。

よくある問題
  • 初回起動時にホストが正常に起動できない:ネットワーク定義ファイルが不正な場合、combustionフェーズが失敗し、ホストがルートシェルをドロップすることがあります。

  • ファイルが正しく生成されない:ネットワークファイルが NMState形式と一致していることを確認してください。

  • ネットワークインタフェースが正しく設定されていない:ホストで使用されているネットワークインタフェースとMACアドレスが一致していることを確認してください。

  • ネットワークインタフェース名の不一致:SL Microはデフォルトで ネットワークインターフェースの予測可能な命名スキームを有効にしているため、`eth0`は存在せず、代わりに`enp2s0`のような他の命名スキームが使用されます。

ログ
  • Combustionログ:nmcはCombustion時に使用されるため、プロビジョニング中のホストで`journalctl -u combustion`を使用してCombustionログを確認してください。

  • NetworkManagerログ:Metal3デプロイメントワークフローでは、nmcはIPA実行の一部であり、systemdのExecStartPre機能を使用してNetworkManagerサービスの依存関係として実行されます。`journalctl -u NetworkManager`としてIPAホスト上のNetworkManagerログを確認してください(IPAで起動したホストへのアクセス方法については、ダイレクトネットワークプロビジョニングのトラブルシューティング (第75章 「ダイレクトネットワークプロビジョニングのトラブルシューティング」)セクションを参照してください)。

問題の対策の手順
  1. yaml構文の検証: nmc設定ファイルはyamlファイルです。`yamllint`や同様のツールを使用して適切な構文であることを確認してください。

  2. nmcの手動実行:nmcはEIBコンテナの一部であるため、問題をデバッグするにはローカルのpodmanコマンドを使用できます。

    1. nmcファイルを保存するための一時フォルダーを作成してください。

      mkdir -p ${HOME}/tmp/foo
    2. その場所にnmcファイルを保存してください。

      ❯ tree --noreport ${HOME}/tmp/foo
      /Users/johndoe/tmp/foo
      ├── host1.example.com.yaml
      └── host2.example.com.yaml
    3. nmcをエントリーポイントとし、generateコマンドを指定してEIBコンテナを実行し、コンバッション時にnmcが行うのと同じタスクを実行してください:

      podman run -it --rm -v ${HOME}/tmp/foo:/tmp/foo:Z --entrypoint=/usr/bin/nmc registry.suse.com/edge/3.7/edge-image-builder:1.3.4 generate --config-dir /tmp/foo --output-dir /tmp/foo/
      
      [2025-06-04T11:58:37Z INFO  nmc::generate_conf] Generating config from "/tmp/foo/host2.example.com.yaml"...
      [2025-06-04T11:58:37Z INFO  nmc::generate_conf] Generating config from "/tmp/foo/host1.example.com.yaml"...
      [2025-06-04T11:58:37Z INFO  nmc] Successfully generated and stored network config
    4. ログと、一時フォルダーに生成されるファイルを確認してください。

75 ダイレクトネットワークプロビジョニングのトラブルシューティング

ダイレクトネットワークプロビジョニングのシナリオでは、Metal3およびCAPI要素を使用してダウンストリームクラスターをプロビジョニングします。また、OSイメージを作成するためのEIBも含まれています。ホストの初回起動時、またはインスペクションやプロビジョニングのプロセス中に問題が発生することがあります。

よくある問題
  • 古いファームウェア:使用している物理ホストのすべてのファームウェアが最新であることを確認してください。これにはBMCファームウェアも含まれます。場合によっては、Metal3 が特定のものまたは更新されたもののファームウェアを必要とすることがあります。

  • SSLエラーでプロビジョニングに失敗した:イメージを提供するWebサーバーがhttpsを使用している場合、IPAイメージ上で証明書を注入して信頼するようにMetal3を構成する必要があります。Metal3チャートに`ca-additional.crt`ファイルを含める方法については、Kubernetesフォルダー (29.4項 「Kubernetes フォルダ」)を参照してください。

  • IPAでホストを起動する際の証明書の問題:一部のサーバーベンダーは、仮想メディアISOイメージをBMCに接続する際にSSL接続を検証します。Metal3デプロイメント用に生成された証明書は自己署名されているため、これが問題を引き起こす可能性があります。ホストが起動しても、UEFIシェルにドロップされることがあります。これを修正する方法については、仮想メディアISO接続のTLS無効化 (4.7.2項 「virtualmedia ISOアタッチメントのTLS無効化」)を参照してください。

  • 名前またはラベルの参照が誤っている:クラスターが誤った名前またはラベルでノードを参照している場合、クラスターはデプロイ済みとなりますが、BMHは「Available(利用可能)」のままになります。BMHに関連するオブジェクトの参照を再確認してください。

  • BMC通信の問題:管理クラスター上で実行されているMetal3ポッドが、プロビジョニング対象のホストのBMCに到達できることを確認してください(通常、BMCネットワークは非常に制限されています)。

  • ベアメタルホストの状態が正しくない:BMHオブジェクトは、そのライフサイクル中にさまざまな状態(検査中、準備中、プロビジョニング済みなど)に移行します ステートマシンのライフタイム。誤った状態が検出された場合は、BMHオブジェクトの status フィールドを確認してください。これには kubectl get bmh <name> -o jsonpath=’{.status}’| jq として詳細な情報が含まれています。

  • ホストがデプロビジョニングされない:ホストのデプロビジョニングが意図した通りに失敗した場合は、BMHオブジェクトに「detached」アノテーションを追加した後に、次のように削除を試みることができます: kubectl annotate bmh/<BMH> baremetalhost.metal3.io/detached=””。

  • イメージエラー:EIBを使用してダウンストリームクラスター用にビルドされたイメージが利用可能であり、適切なチェックサムを持ち、解凍するには大きすぎず、ディスクに対して大きすぎないことを確認してください。

  • ディスクサイズの不一致:デフォルトでは、ディスクは全容量に拡張されません。Growfsスクリプト (4.4.4.1.2項 「Growfs スクリプト」)セクションで説明されているように、ダウンストリームクラスターのホスト用にEIBでビルドされるイメージには、Growfsスクリプトを含める必要があります。

  • クリーンアッププロセスがスタックする:クリーンアッププロセスは数回再試行されます。ホストのクリーンアップに関する問題により実行できなくなった場合は、BMHオブジェクトの automatedCleanMode フィールドを disabled に設定して、まずクリーンアップを無効にしてください。

    警告
    警告

    クリーンアッププロセスに時間がかかりすぎている場合や失敗している場合に、手動でファイナライザーを削除することは推奨されません。そうすると、Kubernetesからホストレコードは削除されますが、Ironicには残ってしまいます。現在実行中のアクションはバックグラウンドで継続され、競合が発生してホストを再度追加しようとしても失敗する可能性があります。

  • Metal3/Rancher Turtles/CAPIポッドの問題:必要なすべてのコンポーネントのデプロイフローは以下の通りです。

    • Rancher TurtlesコントローラーがCAPIオペレーターコントローラーをデプロイします。

    • 次に、CAPIオペレーターコントローラーがプロバイダーコントローラー(CAPIコア、CAPM3、およびRKE2コントロールプレーン/ブートストラップ)をデプロイします。

すべてのポッドが正常に実行されていることを確認し、そうでない場合はログを確認してください。

ログ
  • Metal3 ログ:さまざまなポッドのログをチェックします。

    kubectl logs -n metal3-system -l app.kubernetes.io/component=baremetal-operator
    kubectl logs -n metal3-system -l app.kubernetes.io/component=ironic
    注記
    注記

    metal3-ironicポッドには、同じポッド上に少なくとも4つの異なるコンテナ(ironic-httpd、` ironic-log-watch`、ironic、ironic-ipa-downloader(init))が含まれています。各コンテナのログを検証するには、kubectl logs`を使用する際に-c`フラグを使用します。

    注記
    注記

    `ironic-log-watch`コンテナは、ネットワーク接続によってこれらのログを管理クラスターに送信できる場合に限り、検査/プロビジョニング後のホストからのコンソールログを公開します。これは、プロビジョニングエラーが発生しているものの、BMCコンソールログに直接アクセスできない場合に役立ちます。

  • Rancher Turtlesログ:さまざまなポッドのログをチェックします。

    kubectl logs -n cattle-turtles-system -l control-plane=controller-manager
    kubectl logs -n cattle-turtles-system -l app.kubernetes.io/name=cluster-api-operator
    kubectl logs -n rke2-bootstrap-system -l cluster.x-k8s.io/provider=bootstrap-rke2
    kubectl logs -n rke2-control-plane-system -l cluster.x-k8s.io/provider=control-plane-rke2
    kubectl logs -n cattle-capi-system -l cluster.x-k8s.io/provider=cluster-api
    kubectl logs -n capm3-system -l cluster.x-k8s.io/provider=infrastructure-metal3
  • BMCログ:通常、BMCにはほとんどの操作を実行できるUIがあります。通常、「ログ」セクションがあり、潜在的な問題(イメージに到達できない、ハードウェアエラーなど)を確認できます。

  • コンソールログ:BMCコンソール(BMC Web UI、シリアルなど経由)に接続し、書き込まれているログにエラーがないかチェックします。

問題の対策の手順
  1. `BareMetalHost`ステータスのチェック:

    • kubectl get bmh -A`は現在の状態を示します。`provisioning、ready、error、`registering`を探します。

    • `kubectl describe bmh -n <namespace> <bmh_name>`は、BMHがスタックしている理由を説明する詳細なイベントと条件を提供します。

  2. RedFish接続のテスト:

    • `curl`Metal3コントロールプレーンからを使用して、Redfish経由でBMCへの接続をテストします。

    • `BareMetalHost-Secret`定義で正しいBMC認証情報が提供されていることを確認します。

  3. turtles/CAPI/metal3ポッドステータスの確認:管理クラスター上のコンテナが稼働していることを確認します: kubectl get pods -n metal3-system および kubectl get pods -n cattle-turtles-system (cattle-capi-system、capm3-system、rke2-bootstrap-system、および rke2-control-plane-system も参照してください)。

  4. プロビジョニング対象のホストからIronicエンドポイントに到達可能であることを確認します:プロビジョニング対象のホストは、Metal3 に報告するためにIronicエンドポイントに到達できる必要があります。kubectl get svc -n metal3-system metal3-metal3-ironic でIPを確認し、curl/nc を介して到達できるか試してください。

  5. BMCからIPAイメージに到達可能であることを確認します:IPAはIronicエンドポイントによって提供されており、仮想CDとして使用されるため、BMCから到達可能である必要があります。

  6. プロビジョニング対象のホストからOSイメージに到達可能であることを確認します:ホストのプロビジョニングに使用されるイメージは、(IPA実行時に) ホスト自体から到達可能である必要があります。これは、一時的にダウンロードされてディスクに書き込まれるためです。

  7. Metal3 コンポーネントのログを確認します:詳細については上記の説明を参照してください。

  8. BMHインスペクションの再トリガー: インスペクションが失敗した場合や、利用可能なホストのハードウェアが変更された場合は、BMHオブジェクトに inspect.metal3.io: "" をアノテーションすることで、新しいインスペクションプロセスをトリガーできます。詳細については、 Metal3 インスペクションの制御 ガイドを参照してください。

  9. ベアメタルIPAコンソール:IPAの問題をトラブルシュートするには、いくつかの代替策があります:

    • 「autologin」を有効にします。これにより、IPAコンソールに接続する際にルートユーザが自動的にログインできるようになります。

      警告
      警告

      これはホストへのフルアクセスを許可するため、デバッグ目的のみに限定されます。

      autologinを有効にするには、Metal3 helm global.ironicKernelParams 値を次のように設定する必要があります: console=ttyS0 suse.autologin=ttyS0 (ttyS0 はコンソールに応じて変更可能です)。その後、Metal3 チャートの再デプロイを実行する必要があります。(注: ttyS0 は例であり、実際の端末と一致させる必要があります。例えば、ベアメタルでは多くの場合 tty1 になる可能性があります。これは、起動時にIPAラムディスクからのコンソール出力を確認することで検証できます。そこでは /etc/issue がコンソール名を出力します)。

      別の方法として、metal3-system ネームスペースの ironic configmap で IRONIC_KERNEL_PARAMS パラメーターを変更する方法があります。これは kubectl 編集で行えるため簡単ですが、チャートを更新すると上書きされます。次に、Metal3 ポッドを kubectl delete pod -n metal3-system -l app.kubernetes.io/component=ironic で再起動する必要があります。

    • IPA のルートユーザに対してSSHキーを挿入します。

      警告
      警告

      これはホストへのフルアクセスを許可するため、デバッグ目的のみに限定されます。

      ルートユーザのSSHキーを挿入するには、Metal3 helm の debug.ironicRamdiskSshKey 値を使用する必要があります。次に、Metal3 チャートの再デプロイを実行する必要があります。

      別の方法として、metal3-system ネームスペースの ironic configmap で IRONIC_RAMDISK_SSH_KEY パラメーターを変更する方法があります。これは kubectl 編集で行えるため簡単ですが、チャートを更新すると上書きされます。次に、Metal3 ポッドを kubectl delete pod -n metal3-system -l app.kubernetes.io/component=ironic で再起動する必要があります。

注記
注記

CAPI トラブルシューティング ガイドと Metal3 トラブルシューティング ガイドを確認してください。

76 その他のコンポーネントのトラブルシューティング

その他の SUSE Telco Cloud コンポーネントのトラブルシューティングガイドについては、各公式ドキュメントを参照してください。

SUSE ナレッジベースも参照できます。

77 サポートのための診断情報の収集

SUSEサポートに問い合わせる際は、包括的な診断情報を提供することが不可欠です。

収集すべき重要な情報
  • 詳細な問題の説明:何が起きたのか、いつ起きたのか、何をしていたのか、期待される動作は何か、そして実際の動作は何か?

  • 再現手順:その問題を確実に再現できますか?再現できる場合は、正確な手順をリストアップしてください。

  • コンポーネントバージョン: SUSE Telco Cloud バージョン、コンポーネントバージョン(RKE2/K3、EIB、Metal3、Elementalなど)。

  • 関連ログ:

    • journalctl 出力(可能であればサービスでフィルタリングしたもの、または完全なブートログ)。

    • Kubernetesポッドログ(kubectl logs)。

    • Metal³/Elementalコンポーネントログ。

    • EIBビルドログおよびその他のログ

  • システム情報:

    • uname -a

    • df -h

    • ip a

    • /etc/os-release

  • 設定ファイル:Elemental、Metal3、EIBに関連する設定ファイル(helmチャートの値、configmapなど)。

  • Kubernetes情報:ノード、サービス、デプロイメントなど。

  • 影響を受けるKubernetesオブジェクト:BMH、MachineRegistrationなど。

収集方法
  • ログの場合:コマンドの出力をファイルにリダイレクトします(例: journalctl -u k3s > k3s_logs.txt)。

  • Kubernetesリソースの場合:詳細なYAML定義を取得するには、`kubectl get <resource> -o yaml > <resource_name>.yaml`を使用します。

  • システム情報の場合:上記にリストされているコマンドの出力を収集します。

  • SL Microの場合:`supportconfig`のサポートのためのシステム情報収集方法については、 SUSE Linux Micro Troubleshooting Guideのドキュメントを確認してください。

  • RKE2/Rancherの場合:https://www.suse.com/support/kb/doc/?id=000020191[The Rancher v2.x Linux log collector script]の記事を確認して、Rancher v2.x Linuxログ収集スクリプトを実行してください。

  • Edge (Nessie) の場合:Nessie 1.1.0は、SUSE Telco Cloud環境からログと設定データを収集するように設計された強力な診断ツールです。ホストシステムとKubernetesクラスターの両方から包括的な情報を収集するため、トラブルシューティングやサポートに非常に役立ちます。

    • Nessieには、Kubernetesモードとシステムモードという2つの「モード」があります。

      • SUSE Telco Cloudクラスターからログを収集するには、(ローカルでkubeconfigファイルにアクセスできることを前提として)以下を実行します。

        podman run --rm --privileged \
          -v /etc/rancher/k3s/k3s.yaml:/etc/rancher/k3s/k3s.yaml:ro \
          -v /var/log/journal:/var/log/journal:ro \
          -v /run/systemd:/run/systemd:ro \
          -v /etc/machine-id:/etc/machine-id:ro \
          -v /tmp:/tmp \
          -e NESSIE_LOG_DIR="/tmp" \
          -e NESSIE_ZIP_DIR="/tmp" \
          registry.suse.com/edge/3.7/nessie:1.1.0
        注記
        注記

        必要に応じて`k3s.yaml/rke2.yaml`ファイルのパスを調整してください。詳細については、 Nessieを参照してください。 適切な権限がある場合は、非特権モードでこのコンテナを実行できるはずです(通常、k3s.yaml / `rke2-server.yaml`ファイルはルートが所有しています)。

      • 実際のオペレーティングシステムからシステムモードでログを収集するには、次を実行してください:

        podman run --rm --privileged \
          -v /var/log/journal:/var/log/journal:ro \
          -v /run/systemd:/run/systemd:ro \
          -v /etc/machine-id:/etc/machine-id:ro \
          -v /tmp:/tmp \
          -e NESSIE_LOG_DIR="/tmp" \
          -e NESSIE_ZIP_DIR="/tmp" \
          -e NESSIE_VERBOSE="1" \
          -e NESSIE_SKIP_POD_LOGS="true" \
          -e NESSIE_SKIP_K8S_CONFIGS="true" \
          -e NESSIE_SKIP_METRICS="true" \
          registry.suse.com/edge/3.7/nessie:1.1.0
        注記
        注記

        環境でNessieを実行する方法の詳細や情報については、必ず Nessieを確認してください。 同様に、適切な権限があれば、非特権モードでこのコンテナを実行できるはずです。

[技術サポートの連絡先]. SUSEサポートへの連絡方法の詳細については、 ハウツー: SUSE Technical Supportとの効果的な連携方法で入手可能な記事と、 SUSE Technical Support Handbookにあるサポートハンドブックを確認してください。

パート XII 付録

  • 78 リリースノート
  • SUSE Telco Cloud 3.7は、エッジにおけるインフラストラクチャおよびクラウドネイティブアプリケーションのデプロイメントという独自の課題に対処するための、緊密に統合され、包括的に検証されたエンドツーエンドソリューションです。その主な目的は、初期デプロイメントのイメージ構築、ノードのプロビジョニングとオンボーディング、アプリケーションのデプロイ、監視、ライフサイクル管理にわたって、独自の設計思想を持ちながらも非常に柔軟で、拡張性が高く、安全なプラットフォームを提供することです。

78 リリースノート

78.1 抽象データ型

SUSE Telco Cloud 3.7は、エッジにおけるインフラストラクチャおよびクラウドネイティブアプリケーションのデプロイメントという独自の課題に対処するための、緊密に統合され、包括的に検証されたエンドツーエンドソリューションです。その主な目的は、初期デプロイメントのイメージ構築、ノードのプロビジョニングとオンボーディング、アプリケーションのデプロイ、監視、ライフサイクル管理にわたって、独自の設計思想を持ちながらも非常に柔軟で、拡張性が高く、安全なプラットフォームを提供することです。

このソリューションは、お客様の要件や期待が大きく異なるため、「万能な」エッジプラットフォームは存在しないという考えに基づいて設計されています。エッジデプロイメントは、大規模なスケーラビリティ、制限されたネットワーク可用性、物理的なスペースの制約、新しいセキュリティの脅威と攻撃ベクトル、ハードウェアアーキテクチャとシステムリソースの多様性、レガシーインフラストラクチャおよびアプリケーションとのデプロイとインターフェースの要件、そして寿命が長い顧客ソリューションなど、最も困難な問題のいくつかを解決し、継続的に進化させることを私たちに求めています。

SUSE Telco Cloudは、安全で安定した認定済みのSUSE Linuxプラットフォームを提供してきた30年の歴史と、Rancherポートフォリオによる拡張性が高く機能豊富なKubernetes管理を提供してきた経験の両方と一貫して、ゼロから最高クラスのオープンソースソフトウェアに基づいて構築されています。SUSE Telco Cloudは、これらの機能を基盤として、小売、医療、輸送、物流、電気通信、スマートマニュファクチャリング、産業用IoTなど、幅広い市場セグメントの要件に対処できる機能を提供します。

SUSE Telco Cloudの製品サポートライフサイクルの更新に関する詳細については、Product Support Lifecycleを参照してください。

注記
注記

SUSE Telco CloudはSUSE Edgeの派生製品であり、電気通信のユースケースで見られる要件にプラットフォームが対応できるようにするための追加の最適化とコンポーネントを備えています。

78.2 バージョン情報

これらのリリースノートは、明示的に指定および説明されている場合を除き、すべてのアーキテクチャで同一であり、最新バージョンは、他のすべてのSUSE製品のリリースノートとともに、オンラインの https://www.suse.com/releasenotesで常に入手可能です。

項目は一度だけリストされますが、重要であり、複数のセクションに該当する場合は、複数の場所で参照されることがあります。リリースノートには通常、2つの連続するリリースの間に行われた変更のみが記載されます。以前の製品バージョンのリリースノートからの重要な項目が繰り返される場合があります。これらの項目を識別しやすくするために、その旨を記載した注記が含まれています。

ただし、繰り返される項目は便宜上提供されているに過ぎません。したがって、1つ以上のリリースをスキップする場合は、スキップしたリリースのリリースノートも確認してください。現在のリリースのリリースノートのみを読んでいると、システム動作に影響を与える可能性のある重要な変更を見逃す可能性があります。SUSE Telco Cloudのバージョンはx.y.zとして定義されます。ここで「x」はメジャーバージョン、「y」はマイナーバージョン、「z」はパッチバージョン(「zストリーム」とも呼ばれます)を示します。SUSE Telco Cloudの製品ライフサイクルは、特定のマイナーリリースに基づいて定義されます(例:)。「3.7」ですが、そのライフサイクルを通じて後続のパッチアップデートとともにリリースされます(例:「3.7.1」)。"3.7.1".

注記
注記

SUSE Telco Cloudのzストリームリリースは、バージョン管理されたスタックとして緊密に統合され、徹底的にテストされています。上記以外のバージョンへの個々のコンポーネントのアップグレードは、システムダウンタイムを引き起こす可能性があります。テストされていない構成でEdgeクラスターを実行することは可能ですが、推奨はされず、サポートチャネルを通じた解決に時間がかかる場合があります。

78.3 リリース 3.7.0。

提供開始日:2026年9月23日。

フルサポート終了日:2027年3月22日。

メンテナンスサポート終了日:2028年3月22日。

EOL:2028年3月23日。

まとめ:SUSE Telco Cloud 3.7.0は、SUSE Telco Cloud 3.7リリースストリームにおける最初のリリースです。

78.3.1 新機能

78.3.2 バグおよびセキュリティ更新

78.3.3 既知の問題

警告
警告

新しいクラスターをデプロイする場合は、第65章 「Kiwiを使用して更新されたSUSE Linux Microイメージを構築する」 に従って最初に新しいイメージをビルドしてください。 これは、イメージに最新のセキュリティ修正とバグ修正が含まれていることを確認するために、管理クラスターおよびダウンストリームクラスターに対して推奨されます。

リリース固有の既知の問題は、リリース検証が完了次第追加されます。

78.3.3.1 SUSE Storage V2データエンジンの制限

SUSE Storage 1.12.1では、既存のV1ボリュームをその場でV2に変換することはできません。 既存のボリュームはアップグレード後もV1のままとなるため、新しくプロビジョニングされたV2ボリュームに移行する必要があります。 すべてのV1ワークロードが移行および検証されるまで、両方のデータエンジンを有効にしておいてください。

V2エンジンのライブアップグレードはサポートされていないため、SUSE Storage 1.12のパッチリリース間でアップグレードを行う前に、V2ボリュームをデタッチする必要があります。 V2バッキングイメージもサポートされていません。KubeVirtデプロイメントでは、イメージインポートワークフローにCDIを使用する必要があります。 その他の機能の違いと顧客向けの移行手順については、第66章 「SUSE Storage V2データエンジン」に記載されています。

78.3.4 コンポーネントのバージョン

次の表は、3.7.0リリースを構成する個々のコンポーネントについて、バージョン、Helmチャートのバージョン(該当する場合)、およびバイナリ形式でリリースされたアーティファクトの取得元を説明しています。使用方法やデプロイの例については、関連するドキュメントに従ってください。

名前

バージョン

Helmチャートのバージョン

アーティファクトの場所 (URL/イメージ)

SUSE Linux Micro

6.2 (latest)

N/A

SUSE Linux Micro ダウンロードページ

SUSE Linux Micro

6.2 (latest)

N/A

チェックサムと署名は、 SUSE Linux Micro ダウンロードページからダウンロードできます。
SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso
SL-Micro.x86_64-6.2-Base-RT-SelfInstall-GM.install.iso
SL-Micro.x86_64-6.2-Base-GM.raw.xz
SL-Micro.x86_64-6.2-Base-RT-GM.raw.xz

SUSE Multi-Linux Manager

5.2

N/A

SUSE Multi-Linux Manager ダウンロードページ

K3s

1.36.3

N/A

アップストリーム K3s リリース

RKE2

1.36.3

N/A

Upstream RKE2 Release

SUSE Rancher Prime

2.15.1

2.15.1

Rancher Prime Helm リポジトリ
https://prime.ribs.rancher.io/rancher/v2.15.1/rancher-images.txt[Rancher 2.15.1 Container Images]

SUSE Storage (Longhorn)

1.12.1

1.12.1

SUSE Storage Helm リポジトリ
https://apps.rancher.io/applications/suse-storage/components[SUSE Storage Container Images]

SUSE Security (NeuVector)

5.6.1

110.0.1+up2.11.1

Rancher Charts Helm リポジトリ
registry.rancher.com/rancher/neuvector-controller:5.6.1
registry.rancher.com/rancher/neuvector-enforcer:5.6.1
registry.rancher.com/rancher/neuvector-compliance-config:1.0.16
registry.rancher.com/rancher/neuvector-updater:0.0.14

Rancher Turtles プロバイダー (CAPI)

0.27.0

307.0.8+up0.27.0

registry.suse.com/edge/3.7/rancher-turtles-providers-chart:307.0.8+up0.27.0
registry.rancher.com/rancher/cluster-api-controller:v1.13.3
registry.rancher.com/rancher/turtles:v0.27.1
registry.suse.com/rancher/cluster-api-provider-rke2-bootstrap:v0.25.0
registry.suse.com/rancher/cluster-api-provider-rke2-controlplane:v0.25.0

Metal3

0.16.0

307.0.31+up0.16.0

registry.suse.com/edge/3.7/metal3-chart:307.0.31+up0.16.0
registry.suse.com/edge/3.7/baremetal-operator:0.13.3.0
registry.suse.com/edge/3.7/ironic:38.0.0.0
registry.suse.com/edge/3.7/ironic-ipa-downloader:3.1.2
registry.suse.com/edge/3.7/ironic-python-agent:3.0.10

MetalLB

0.16.1

307.0.3+up0.16.1

registry.suse.com/edge/3.7/metallb-chart:307.0.3+up0.16.1
registry.suse.com/edge/3.7/metallb-controller:v0.16.1
registry.suse.com/edge/3.7/metallb-speaker:v0.16.1
registry.suse.com/edge/3.7/frr:10.2.1
registry.suse.com/edge/3.7/frr-k8s:v0.0.25

Elemental

1.9.2

1.9.2

registry.suse.com/rancher/elemental-operator-chart:1.9.2
registry.suse.com/rancher/elemental-operator-crds-chart:1.9.2
registry.suse.com/rancher/elemental-operator:1.9.2

Elemental ダッシュボード拡張機能

3.0.1

3.0.1

Elemental 拡張機能 Helm チャート

Edge Image Builder

1.3.4

N/A

registry.suse.com/edge/3.7/edge-image-builder:1.3.4

KubeVirt

1.8.3

307.0.3+up0.8.0

registry.suse.com/edge/3.7/kubevirt-chart:307.0.3+up0.8.0
registry.suse.com/suse/sles/16.0/virt-operator:1.8.3
registry.suse.com/suse/sles/16.0/virt-api:1.8.3
registry.suse.com/suse/sles/16.0/virt-controller:1.8.3
registry.suse.com/suse/sles/16.0/virt-handler:1.8.3
registry.suse.com/suse/sles/16.0/virt-launcher:1.8.3
registry.suse.com/suse/sles/16.0/virt-exportproxy:1.8.3
registry.suse.com/suse/sles/16.0/virt-exportserver:1.8.3

KubeVirt ダッシュボード拡張機能

1.4.2

307.0.5+up1.4.2

registry.suse.com/edge/3.7/kubevirt-dashboard-extension-chart:307.0.5+up1.4.2

Containerized Data Importer (CDI)

1.65.0

307.0.3+up0.8.0

registry.suse.com/edge/3.7/cdi-chart:307.0.3+up0.8.0
registry.suse.com/suse/sles/16.0/cdi-operator:1.65.0
registry.suse.com/suse/sles/16.0/cdi-controller:1.65.0
registry.suse.com/suse/sles/16.0/cdi-apiserver:1.65.0
registry.suse.com/suse/sles/16.0/cdi-uploadproxy:1.65.0
registry.suse.com/suse/sles/16.0/cdi-cloner:1.65.0
registry.suse.com/suse/sles/16.0/cdi-importer:1.65.0
registry.suse.com/suse/sles/16.0/cdi-uploadserver:1.65.0

Endpoint Copier Operator

0.3.0

307.0.1+up0.3.0

registry.suse.com/edge/3.7/endpoint-copier-operator-chart:307.0.1+up0.3.0
registry.suse.com/edge/3.7/endpoint-copier-operator:0.3.0

SR-IOV Network Operator

1.6.0

307.1.0+up1.6.0

registry.suse.com/edge/3.7/sriov-network-operator-chart:307.1.0+up1.6.0
registry.suse.com/edge/3.7/sriov-crd-chart:307.1.0+up1.6.0
registry.suse.com/edge/3.7/sriov-network-metrics-exporter:v1.2.0
registry.suse.com/edge/3.7/kube-rbac-proxy:0.22.1

System Upgrade Controller

0.20.1

110.0.0

Rancher Charts Helm リポジトリ
registry.rancher.com/rancher/system-upgrade-controller:v0.20.1

Upgrade Controller

0.1.3

307.0.4+up0.1.3

registry.suse.com/edge/3.7/upgrade-controller-chart:307.0.4+up0.1.3
registry.suse.com/edge/3.7/upgrade-controller:0.1.3
registry.rancher.com/rancher/kubectl:v1.35.2
registry.suse.com/edge/3.7/release-manifest:3.7.0

SUSE Private Registry

1.1.1

1.1.1

oci://registry.suse.com/private-registry/private-registry-helm[SUSE Private Registry Helm リポジトリ]
registry.suse.com/private-registry/harbor-core:1.1.1-1.19
registry.suse.com/private-registry/harbor-jobservice:1.1.1-1.19
registry.suse.com/private-registry/harbor-portal:1.1.1-1.20
registry.suse.com/private-registry/harbor-registry:1.1.1-1.19
registry.suse.com/private-registry/harbor-registryctl:1.1.1-1.19
registry.suse.com/private-registry/harbor-trivy-adapter:1.1.1-1.24

Kiwi Builder

10.2.29.1

N/A

registry.suse.com/edge/3.7/kiwi-builder:10.2.29.1

Cert-Manager

1.20.1

1.20.1

Jetstack Helm リポジトリ
quay.io/jetstack/cert-manager-controller:v1.20.1
quay.io/jetstack/cert-manager-webhook:v1.20.1
quay.io/jetstack/cert-manager-cainjector:v1.20.1

78.4 削除された機能

特に記載がない限り、これらは3.7.0リリースおよびそれ以降のすべてのzストリームバージョンに適用されます。

  • Akriは以前のEdgeリリースにおいてテクノロジープレビューとして提供されていましたが、3.4.0以降は廃止されました。現在は製品から完全に削除されています。

78.5 技術プレビュー

特に記載がない限り、これらは3.7.0リリースおよびそれ以降のすべてのzストリーム版に適用されます。

  • シングルスタックIPv6管理クラスターのデプロイはテクノロジープレビューとして提供されており、標準的なサポート範囲の対象外です。

78.6 コンポーネントの検証

上記のコンポーネントは、ソフトウェア部品表(SBOM)データを使用して検証できます。例えば、以下のように`cosign`を使用します。

SUSE署名キーソースからSUSE Telco Cloudコンテナの公開鍵をダウンロードします。

> cat key.pem
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7N0S2d8LFKW4WU43bq7Z
IZT537xlKe17OQEpYjNrdtqnSwA0/jLtK83m7bTzfYRK4wty/so0g3BGo+x6yDFt
SVXTPBqnYvabU/j7UKaybJtX3jc4SjaezeBqdi96h6yEslvg4VTZDpy6TFP5ZHxZ
A0fX6m5kU2/RYhGXItoeUmL5hZ+APYgYG4/455NBaZT2yOywJ6+1zRgpR0cRAekI
OZXl51k0ebsGV6ui/NGECO6MB5e3arAhszf8eHDE02FeNJw5cimXkgDh/1Lg3KpO
dvUNm0EPWvnkNYeMCKR+687QG0bXqSVyCbY6+HG/HLkeBWkv6Hn41oeTSLrjYVGa
T3zxPVQM726sami6pgZ5vULyOleQuKBZrlFhFLbFyXqv1/DokUqEppm2Y3xZQv77
fMNogapp0qYz+nE3wSK4UHPd9z+2bq5WEkQSalYxadyuqOzxqZgSoCNoX5iIuWte
Zf1RmHjiEndg/2UgxKUysVnyCpiWoGbalM4dnWE24102050Gj6M4B5fe73hbaRlf
NBqP+97uznnRlSl8FizhXzdzJiVPcRav1tDdRUyDE2XkNRXmGfD3aCmILhB27SOA
Lppkouw849PWBt9kDMvzelUYLpINYpHRi2+/eyhHNlufeyJ7e7d6N9VcvjR/6qWG
64iSkcF2DTW61CN5TrCe0k0CAwEAAQ==
-----END PUBLIC KEY-----

例えば`crane`を使用して、コンテナイメージのハッシュを検証します。

> crane digest registry.suse.com/edge/3.7/baremetal-operator:0.13.3.0 --platform linux/amd64
sha256:247e687143b2d21d9cebcef0bbac8ca3d14b4d1b6e0ba04812dd61d44b32b776
注記
注記

マルチアーキテクチャイメージの場合は、ダイジェストを取得する際にプラットフォームを指定する必要もあります。例: --platform linux/amd64 または --platform linux/arm64。これを行わないと、次のステップ (Error: no matching attestations) でエラーが発生します。

次のコマンドで確認します: cosign

> cosign verify-attestation --type spdxjson --key key.pem registry.suse.com/edge/3.7/baremetal-operator@sha256:247e687143b2d21d9cebcef0bbac8ca3d14b4d1b6e0ba04812dd61d44b32b776 > /dev/null
#
Verification for registry.suse.com/edge/3.7/baremetal-operator@sha256:example-digest-placeholder --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The signatures were verified against the specified public key

SUSE SBOMドキュメントに記載されている手順に従って、SBOMデータを抽出します。

> cosign verify-attestation --type spdxjson --key key.pem registry.suse.com/edge/3.7/baremetal-operator@sha256:247e687143b2d21d9cebcef0bbac8ca3d14b4d1b6e0ba04812dd61d44b32b776 | jq '.payload | @base64d | fromjson | .predicate'

78.7 アップグレード手順

新しいリリースへのアップグレード方法の詳細については、パートVIII「Day 2運用」を参照してください。

78.8 製品サポートライフサイクル

SUSE Telco Cloudは、実績あるテクノロジーリーダーであるSUSEが提供する、受賞歴のあるサポートに支えられています。詳細については、 https://www.suse.com/lifecycleおよび https://www.suse.com/support/policy.htmlのサポートポリシーページを参照してください。サポートケースの起票方法、SUSEによる重大度レベルの分類方法、またはサポート範囲についてご質問がある場合は、 https://www.suse.com/support/handbook/のテクニカルサポートハンドブックを参照してください。

SUSE Telco Cloud "3.7" は18か月間のプロダクションサポートが提供され、最初の6か月間は「フルサポート」、その後の12か月間は「メンテナンスサポート」となります。 これらのサポートフェーズが終了すると、製品は「サービス終了」(EOL) となり、サポートは提供されなくなります。ライフサイクルフェーズの詳細については、以下の表を参照してください。

フルサポート (6か月)

フルサポート期間中は、緊急および選択された優先度の高いバグ修正がリリースされます。その他のすべてのパッチ (緊急ではないもの、機能強化、新機能) は、通常のリリーススケジュールに従ってリリースされます。

メンテナンスサポート (12か月)

この期間中は、重大な修正のみがパッチを通じてリリースされます。その他のバグ修正はSUSEの判断でリリースされる場合がありますが、期待はしないでください。

サービス終了 (EOL)

製品リリースがサービス終了日を迎えると、お客様は製品ライセンス契約の条件の範囲内で製品を引き続き使用できます。 SUSEのサポートプランは、サービス終了日(EOL)を過ぎた製品リリースには適用されません。

明記されていない限り、リストされているすべてのコンポーネントは一般提供(GA)されており、SUSEの標準的なサポート範囲に含まれます。一部のコンポーネントは「Technology Preview」としてリストされている場合があります。これは、SUSEがお客様に評価目的でGA前の機能へのアクセスを提供するものであり、標準的なサポートポリシーの対象外であり、本番環境での使用は推奨されません。SUSEは、Technology Previewコンポーネントに対する改善に関するフィードバックや提案を大いに歓迎しますが、お客様のニーズを満たさない場合や、当社が要求する成熟度に達しない場合、一般提供(GA)される前にTechnology Preview機能を廃止する権利を留保します。

SUSEは、時折、機能を廃止したり、API仕様を変更したりする場合があることにご留意ください。機能の廃止やAPI変更の理由には、機能が更新または新しい実装に置き換えられること、新しい機能セット、アップストリームテクノロジーが利用できなくなること、またはアップストリームコミュニティが互換性のない変更を導入したことなどが含まれます。これは特定のマイナーリリース(x.z)内では発生しないことを意図しており、すべてのz ストリームリリースはAPIの互換性と機能性を維持します。SUSEは、サービスの中断を最小限に抑えるため、リリースノート内で十分な通知期間をもって廃止の警告を提供し、回避策、提案、および緩和策を提供するよう努めます。

SUSE Telco Cloudチームはコミュニティからのフィードバックも歓迎しており、問題は https://www.github.com/suse-edge内のそれぞれのリポジトリで提起できます。

78.9 ソースコードの入手

本SUSE製品には、GNU一般公衆利用許諾契約書(GPL)およびその他のさまざまなオープンソースに基づいてSUSEにライセンス供与された素材が含まれています。GPLでは、SUSEはGPLライセンス対象の素材に対応するソースコードを提供することが義務付けられており、SUSEはその他すべてのオープンソースの要件を遵守しています。そのため、SUSEはすべてのソースコードを利用可能にしており、一般的にSUSE Telco Cloud GitHubリポジトリ( https://www.github.com/suse-edge)、依存コンポーネントについてはSUSE Rancher GitHubリポジトリ( https://www.github.com/rancher)、特にSUSE Linux Microについては、ソースコードは https://www.suse.com/download/sle-microの「Medium 2」からダウンロードできます。

78.10 保証と著作権

SUSEは、本書の内容または使用に関していかなる表明も保証も行わず、特に、商業性および特定目的への適合性について、明示的か黙示的かを問わず、いかなる保証も否認します。さらに、SUSEは、本書をいつでも改訂またはその内容を変更する権利を留保し、何人に対しても当該の改訂または変更について通知する義務を負わないものとします。

さらに、SUSEは、すべてのソフトウェアについて、いかなる表明または保証も行わず、特に、ソフトウェアの商業性および特定目的への適合性について、明示的か黙示的かを問わず、いかなる保証も否認します。さらに、SUSEは、SUSE製ソフトウェアの一部または全部をいつでも変更する権利を留保し、何人に対しても当該の変更について通知する義務を負わないものとします。

本契約の下で提供される製品または技術情報はすべて、米国の輸出管理規定およびその他の国の輸出関連法規の制限を受けます。お客様は、すべての輸出管理規制を遵守し、成果物の輸出、再輸出、または輸入に必要なすべての許可または等級を取得することに同意するものとします。お客様は、現在の米国の輸出除外リストに掲載されている企業、および米国の輸出管理規定で指定された輸出禁止国またはテロリスト国に本製品を輸出または再輸出しないことに同意するものとします。お客様は、成果物を、禁止されている核兵器、ミサイル、または化学兵器・生物兵器の最終用途に使用しないことに同意するものとします。SUSEソフトウェアの輸出に関する詳細は、 https://www.suse.com/company/legal/を参照してください。SUSEは、必要な輸出許可の取得をお客様が怠った場合の責任は問われないものとします。

Copyright © 2024 SUSE LLC.

このリリースノートドキュメントは、Creative Commons Attribution-NoDerivatives 4.0 International License (CC-BY-ND-4.0) の下でライセンスされています。このドキュメントとともにライセンスのコピーを受け取っているはずです。そうでない場合は、 https://creativecommons.org/licenses/by-nd/4.0/を参照してください。

SUSEは、本書に記載されている製品に組み込まれている技術に関連する知的財産権を有しています。特に、これらの知的財産権には、 https://www.suse.com/company/legal/に記載されている1つまたは複数の米国特許、および米国ならびに他の国における1つまたは複数のその他の特許や出願中の特許(これらに限定されません)が含まれている場合があります。

SUSEの商標については、SUSEの商標およびサービスマークリスト (https://www.suse.com/company/legal/) を参照してください。サードパーティ各社とその製品の商標は、所有者であるそれぞれの会社に所属します。SUSEのブランド情報および使用要件については、 https://brand.suse.com/で公開されているガイドラインを参照してください。