目次にジャンプページナビゲーションにジャンプ: 前のページ[アクセスキーp]/次のページ[アクセスキーn]
documentation.suse.com / SUSE Edgeドキュメント / 製品マニュアル / 管理クラスタの設定

29 管理クラスタの設定

29.1 はじめに

管理クラスタは、ATIP内でランタイムスタックのプロビジョニングとライフサイクルを管理するために使用されます。技術的観点からは、管理クラスタには次のコンポーネントが含まれています。

  • SUSE Linux Enterprise Micro (OS)。ユースケースに応じて、ネットワーキング、ストレージ、ユーザ、カーネル引数などの一部の設定をカスタマイズできます。

  • RKE2 (Kubernetesクラスタ)。ユースケースに応じて、MultusCiliumなどの特定のCNIプラグインを使用するように設定できます。

  • Rancher (管理プラットフォーム)。クラスタのライフサイクルを管理します。

  • Metal3 (コンポーネント)。ベアメタルノードのライフサイクルを管理します。

  • CAPI (コンポーネント)。Kubernetesクラスタ (ダウンストリームクラスタ)のライフサイクルを管理します。ATIPでは、RKE2クラスタ(ダウンストリームクラスタ)のライフサイクルを管理するためにRKE2 CAPI Providerも使用します。

上記のコンポーネントをすべて使用すると、管理クラスタは、宣言型アプローチを使用してインフラストラクチャやアプリケーションを管理し、ダウンストリームクラスタのライフサイクルを管理できます。

注記
注記

SUSE Linux Enterprise Microの詳細については、「SLE Micro」(第7章 「SLE Micro)を参照してください。

RKE2の詳細については、「RKE2」(第14章 「RKE2)を参照してください。

Rancherの詳細については、「Rancher」(第4章 「Rancher)を参照してください。

Metal3の詳細については、「Metal3」(第8章 「Metal3)を参照してください。

29.2 管理クラスタの設定手順

管理クラスタを設定するには、次の手順が必要です(シングルノードを使用)。

製品atip管理クラスタ1

宣言型アプローチを使用して管理クラスタを設定するには、主に3つの手順があります。

  1. 接続環境のイメージの準備(29.3項 「接続環境用のイメージの準備」): 最初の手順では、接続環境で使用する必要がある設定をすべて含むマニフェストとファイルを準備します。

    • 接続環境のディレクトリ構造(29.3.1項 「ディレクトリ構造」): この手順では、Edge Image Builderで使用するディレクトリ構造を作成し、設定ファイルとイメージそのものを保存します。

    • 管理クラスタ定義ファイル(29.3.2項 「管理クラスタ定義ファイル」): mgmt-cluster.yamlファイルが管理クラスタのメイン定義ファイルです。このファイルには、作成するイメージに関する次の情報が含まれています。

      • イメージ情報: ゴールデンイメージを使用して作成するイメージに関する情報。

      • オペレーティングシステム: イメージで使用するオペレーティングシステムの設定。

      • Kubernetes: Helmチャートとリポジトリ、Kubernetesのバージョン、ネットワーク設定、およびクラスタで使用するノード。

    • Customフォルダ(29.3.3項 「Customフォルダ」): customフォルダには設定ファイルとスクリプトが含まれ、Edge Image Builderはこれらを使用して完全に機能する管理クラスタをデプロイします。

      • ファイル: 管理クラスタが使用する設定ファイルが含まれています。

      • スクリプト: 管理クラスタが使用するスクリプトが含まれています。

    • Kubernetesフォルダ(29.3.4項 「Kubernetesフォルダ」): kubernetesフォルダには、管理クラスタが使用する設定ファイルが含まれています。

      • Manifests: 管理クラスタが使用するマニフェストが含まれています。

      • Helm: 管理クラスタが使用するHelmチャートが含まれています。

      • Config: 管理クラスタが使用する設定ファイルが含まれています。

    • Networkフォルダ(29.3.5項 「ネットワーキングフォルダ」): networkフォルダには、管理クラスタノードが使用するネットワーク設定ファイルが含まれています。

  2. エアギャップ環境でのイメージの準備(29.4項 「エアギャップ環境のイメージの準備」): この手順では、エアギャップシナリオで使用するマニフェストとファイルを準備する際の相違点を示します。

    • エアギャップ環境のディレクトリ構造(29.4.1項 「エアギャップ環境のディレクトリ構造」): ディレクトリ構造を変更して、管理クラスタをエアギャップ環境で実行するために必要なリソースを含める必要があります。

    • 定義ファイルの変更(29.4.2項 「定義ファイルの変更」): mgmt-cluster.yamlファイルを変更してembeddedArtifactRegistryセクションを含め、imagesフィールドに、EIBの出力イメージに組み込むすべてのコンテナイメージを設定する必要があります。

    • customeフォルダの変更(29.4.3項 「カスタムフォルダの変更」): customフォルダを変更し、管理クラスタをエアギャップ環境で実行するために必要なリソースを含める必要があります。

      • 登録スクリプト: エアギャップ環境を使用する場合、custom/scripts/99-register.shスクリプトを削除する必要があります。

      • エアギャップリソース: custom/files/airgap-resources.tar.gzファイルを、管理クラスタをエアギャップ環境で運用するために必要なすべてのリソースとともにcustom/filesフォルダに含める必要があります。

      • スクリプト: custom/scripts/99-mgmt-setup.shスクリプトを変更し、airgap-resources.tar.gzファイルを抽出して最終的な場所にコピーするようにする必要があります。また、custom/files/metal3.shスクリプトを変更し、インターネットからリソースをダウンロードするのではなく、airgap-resources.tar.gzファイルに含まれるローカルリソースを使用するようにする必要があります。

  3. イメージの作成(29.5項 「イメージの作成」): この手順では、Edge Image Builderツールを使用してイメージを作成します(接続環境とエアギャップ環境の両方が対象です)。ご使用のシステムでEdge Image Builderツールを実行するための前提条件(第9章 「Edge Image Builder)を確認してください。

  4. 管理クラスタのプロビジョニング(29.6項 「管理クラスタのプロビジョニング」): この手順では、前の手順で作成したイメージを使用して管理クラスタをプロビジョニングする方法について説明します(接続シナリオとエアギャップシナリオの両方が対象です)。この手順は、ラップトップ、サーバ、VM、またはUSBポートを搭載した他の任意のx86_64システムを使用して実行できます。

注記
注記

Edge Image Builderの詳細については、「Edge Image Builder」(第9章 「Edge Image Builder)およびEdge Image Builderのクイックスタート(第3章 「Edge Image Builderを使用したスタンドアロンクラスタ)を参照してください。

29.3 接続環境用のイメージの準備

Edge Image Builderを使用して管理クラスタのイメージを作成すると、多くの設定をカスタマイズできますが、このドキュメントでは、管理クラスタの設定に必要な最小設定について説明します。Edge Image Builderは通常、コンテナ内から実行されるため、まだコンテナを実行する手段がない場合は、まずコンテナランタイム(PodmanRancher Desktop)などのコンテナランタイムをインストールする必要があります。このガイドでは、コンテナランタイムをすでに使用できる状況であることを想定しています。

また、高可用性管理クラスタをデプロイするための前提条件として、ネットワークで次の3つのIPを予約する必要があります。- apiVIP (API VIPアドレス用(Kubernetes APIサーバへのアクセスに使用))、- ingressVIP (Ingress VIPアドレス(Rancher UIなどで使用))、- metal3VIP (Metal3 VIPアドレス用)。

29.3.1 ディレクトリ構造

EIBを実行する場合、ディレクトリはホストからマウントされます。したがって、最初に実行する手順は、EIBが設定ファイルとイメージ自体を保存するために使用するディレクトリ構造を作成することです。このディレクトリの構造は次のとおりです。

eib
├── mgmt-cluster.yaml
├── network
│ └── mgmt-cluster-node1.yaml
├── 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
├── 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
注記
注記

イメージSLE-Micro.x86_64-5.5.0-Default-SelfInstall-GM2.install.isoは、SUSE Customer CenterまたはSUSEダウンロードページからダウンロードして、base-imagesフォルダに配置する必要があります。

イメージのSHA256チェックサムを確認し、イメージが改ざんされていないことを確認する必要があります。このチェックサムは、イメージをダウンロードした場所と同じ場所にあります。

ディレクトリ構造の例は、 SUSE Edge GitHubリポジトリの「telco-examples」フォルダにあります。

29.3.2 管理クラスタ定義ファイル

mgmt-cluster.yamlファイルは管理クラスタのメイン定義ファイルで、次の情報が含まれます。

apiVersion: 1.0
image:
  imageType: iso
  arch: x86_64
  baseImage: SLE-Micro.x86_64-5.5.0-Default-SelfInstall-GM2.install.iso
  outputImageName: eib-mgmt-cluster-image.iso
operatingSystem:
  isoConfiguration:
    installDevice: /dev/sda
  users:
  - username: root
    encryptedPassword: ${ROOT_PASSWORD}
  packages:
    packageList:
    - git
    - jq
    sccRegistrationCode: ${SCC_REGISTRATION_CODE}
kubernetes:
  version: ${KUBERNETES_VERSION}
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: 1.14.2
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn-crd
        version: 103.3.0+up1.6.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn
        version: 103.3.0+up1.6.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: metal3-chart
        version: 0.7.1
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: neuvector-crd
        version: 103.0.3+up2.7.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 103.0.3+up2.7.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.8.4
        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
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
    network:
      apiHost: ${API_HOST}
      apiVIP: ${API_VIP}
    nodes:
      - hostname: mgmt-cluster-node1
        initializer: true
        type: server
#     - hostname: mgmt-cluster-node2
#       initializer: true
#       type: server
#     - hostname: mgmt-cluster-node3
#       initializer: true
#       type: server

mgmt-cluster.yaml定義ファイルのフィールドと値について説明するために、ここではこのファイルを次のセクションに分割しています。

  • イメージセクション(定義ファイル):

image:
  imageType: iso
  arch: x86_64
  baseImage: SLE-Micro.x86_64-5.5.0-Default-SelfInstall-GM2.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: ${KUBERNETES_VERSION}
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: 1.14.2
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn-crd
        version: 103.3.0+up1.6.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn
        version: 103.3.0+up1.6.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: metal3-chart
        version: 0.7.1
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: neuvector-crd
        version: 103.0.3+up2.7.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 103.0.3+up2.7.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.8.4
        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
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
    network:
      apiHost: ${API_HOST}
      apiVIP: ${API_VIP}
    nodes:
      - hostname: mgmt-cluster1
        initializer: true
        type: server
#      - hostname: mgmt-cluster2
#        type: server
#      - hostname: mgmt-cluster3
#        type: server

ここで、versionはインストールするKubernetesのバージョンです。ここでは、RKE2クラスタを使用しているため、バージョンは1.29未満のマイナーバージョンにしてRancherとの互換性を保つ必要があります(v1.28.9+rke2r1など)。

helmセクションには、インストールするHelmチャートのリスト、使用するリポジトリ、およびこれらすべてのバージョン設定が含まれます。

networkセクションには、RKE2コンポーネントが使用するapiHostapiVIPなどのネットワーク設定が含まれます。apiVIPは、ネットワーク内で使用されていないIPアドレスにし、DHCPを使用する場合はDHCPプールから除外してください。マルチノードクラスタでは、apiVIPがKubernetes APIサーバへのアクセスに使用されます。apiHostは、RKE2コンポーネントが使用するapiVIPへの名前解決として機能します。

nodesセクションには、クラスタで使用するノードのリストが含まれています。nodesセクションには、クラスタで使用するノードのリストが含まれています。この例では、シングルノードクラスタを使用していますが、リストにノードを追加する(行のコメントを解除する)ことによってマルチノードクラスタに拡張できます。

注記
注記

ノードの名前はクラスタ内で一意にし、リストの最初のノードのinitializerフィールドはtrueに設定する必要があります。ノードの名前は、networkセクションで定義したホスト名と同じにする必要があります。これはnetworkセクションのファイル名と直接照合されます。

29.3.3 Customフォルダ

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バージョンに関する設定パラメータ、およびRancherMetalLBの基本パラメータが含まれます。このファイルを変更するのは、使用するコンポーネントのバージョンまたはネームスペースを変更する場合のみにしてください。

    #!/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"
    export METAL3_CLUSTERCTLVERSION="1.6.2"
    export METAL3_CAPICOREVERSION="1.6.2"
    export METAL3_CAPIMETAL3VERSION="1.6.0"
    export METAL3_CAPIRKE2VERSION="0.2.6"
    export METAL3_CAPIPROVIDER="rke2"
    export METAL3_CAPISYSTEMNAMESPACE="capi-system"
    export METAL3_RKE2BOOTSTRAPNAMESPACE="rke2-bootstrap-system"
    export METAL3_CAPM3NAMESPACE="capm3-system"
    export METAL3_RKE2CONTROLPLANENAMESPACE="rke2-control-plane-system"
    export METAL3_CAPI_IMAGES="registry.suse.com/edge"
    # Or registry.opensuse.org/isv/suse/edge/clusterapi/containerfile/suse for the upstream ones
    
    ###########
    # 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-bmo -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
    
    # If clusterctl is not installed, install it
    if ! command -v clusterctl > /dev/null 2>&1; then
      LINUXARCH=$(uname -m)
      case $(uname -m) in
        "x86_64")
          export GOARCH="amd64" ;;
        "aarch64")
          export GOARCH="arm64" ;;
        "*")
          echo "Arch not found, asumming amd64"
          export GOARCH="amd64" ;;
      esac
    
      # Clusterctl bin
      # Maybe just use the binary from hauler if available
      curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v${METAL3_CLUSTERCTLVERSION}/clusterctl-linux-${GOARCH} -o /usr/local/bin/clusterctl
      chmod +x /usr/local/bin/clusterctl
    fi
    
    # If rancher is deployed
    if [ $(${KUBECTL} get pods -n ${RANCHER_CHART_TARGETNAMESPACE} -l app=rancher -o name | wc -l) -ge 1 ]; then
      cat <<-EOF | ${KUBECTL} apply -f -
    	apiVersion: management.cattle.io/v3
    	kind: Feature
    	metadata:
    	  name: embedded-cluster-api
    	spec:
    	  value: false
    	EOF
    
      # Disable Rancher webhooks for CAPI
      ${KUBECTL} delete mutatingwebhookconfiguration.admissionregistration.k8s.io mutating-webhook-configuration
      ${KUBECTL} delete validatingwebhookconfigurations.admissionregistration.k8s.io validating-webhook-configuration
      ${KUBECTL} wait --for=delete namespace/cattle-provisioning-capi-system --timeout=300s
    fi
    
    # Deploy CAPI
    if [ $(${KUBECTL} get pods -n ${METAL3_CAPISYSTEMNAMESPACE} -o name | wc -l) -lt 1 ]; then
    
      # https://github.com/rancher-sandbox/cluster-api-provider-rke2#setting-up-clusterctl
      mkdir -p ~/.cluster-api
      cat <<-EOF > ~/.cluster-api/clusterctl.yaml
    	images:
    	  all:
    	    repository: ${METAL3_CAPI_IMAGES}
    	EOF
    
      # Try this command 3 times just in case, stolen from https://stackoverflow.com/a/33354419
      if ! (r=3; while ! clusterctl init \
        --core "cluster-api:v${METAL3_CAPICOREVERSION}"\
        --infrastructure "metal3:v${METAL3_CAPIMETAL3VERSION}"\
        --bootstrap "${METAL3_CAPIPROVIDER}:v${METAL3_CAPIRKE2VERSION}"\
        --control-plane "${METAL3_CAPIPROVIDER}:v${METAL3_CAPIRKE2VERSION}" ; do
                ((--r))||exit
                echo "Something went wrong, let's wait 10 seconds and retry"
                sleep 10;done) ; then
          echo "clusterctl failed"
          exit 1
      fi
    
      # Wait for capi-controller-manager
      while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_CAPISYSTEMNAMESPACE} $(${KUBECTL} get pods -n ${METAL3_CAPISYSTEMNAMESPACE} -l cluster.x-k8s.io/provider=cluster-api -o name) --timeout=10s; do sleep 2 ; done
    
      # Wait for capm3-controller-manager, there are two pods, the ipam and the capm3 one, just wait for the first one
      while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_CAPM3NAMESPACE} $(${KUBECTL} get pods -n ${METAL3_CAPM3NAMESPACE} -l cluster.x-k8s.io/provider=infrastructure-metal3 -o name | head -n1 ) --timeout=10s; do sleep 2 ; done
    
      # Wait for rke2-bootstrap-controller-manager
      while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_RKE2BOOTSTRAPNAMESPACE} $(${KUBECTL} get pods -n ${METAL3_RKE2BOOTSTRAPNAMESPACE} -l cluster.x-k8s.io/provider=bootstrap-rke2 -o name) --timeout=10s; do sleep 2 ; done
    
      # Wait for rke2-control-plane-controller-manager
      while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_RKE2CONTROLPLANENAMESPACE} $(${KUBECTL} get pods -n ${METAL3_RKE2CONTROLPLANENAMESPACE} -l cluster.x-k8s.io/provider=control-plane-rke2 -o name) --timeout=10s; do sleep 2 ; done
    
    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 on
      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.3.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
注記
注記

これは、使用するCNIプラグインなどの特定のKubernetesカスタマイズを定義する任意のファイルです。さまざまなオプションについては、公式ドキュメントで確認できます。

kubernetes/manifestsフォルダには次のファイルが含まれます。

  • rke2-ingress-config.yaml: 管理クラスタ用のIngressサービスを作成するための設定が含まれます(変更不要)。

    apiVersion: helm.cattle.io/v1
    kind: HelmChartConfig
    metadata:
      name: rke2-ingress-nginx
      namespace: kube-system
    spec:
      valuesContent: |-
        controller:
          config:
            use-forwarded-headers: "true"
            enable-real-ip: "true"
          publishService:
            enabled: true
          service:
            enabled: true
            type: LoadBalancer
            externalTrafficPolicy: Local
  • neuvector-namespace.yaml: NeuVectorネームスペースを作成するための設定が含まれます(変更不要)。

    apiVersion: v1
    kind: Namespace
    metadata:
      labels:
        pod-security.kubernetes.io/enforce: privileged
      name: neuvector
  • ingress-l2-adv.yaml: MetalLBコンポーネントのL2Advertisementを作成するための設定が含まれます(変更不要)。

    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: ingress-l2-adv
      namespace: metallb-system
    spec:
      ipAddressPools:
        - ingress-ippool
  • ingress-ippool.yaml: rke2-ingress-nginxコンポーネントのIPAddressPoolを作成するための設定が含まれます。${INGRESS_VIP}を正しく設定し、rke2-ingress-nginxコンポーネントで使用するために予約する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-ingress-nginx]}

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.psp.enabled: "false"
  • neuvector.yaml: NeuVectorコンポーネントを作成するための設定が含まれます(変更不要)。

    controller:
      replicas: 1
      ranchersso:
        enabled: true
    manager:
      enabled: false
    cve:
      scanner:
        enabled: false
        replicas: 1
    k3s:
      enabled: true
    crdwebhook:
      enabled: false
  • metal3.yaml: Metal3コンポーネントを作成するための設定が含まれます。${METAL3_VIP}を正しく設定して、Metal3コンポーネントで使用するIPアドレスを定義する必要があります。

    global:
      ironicIP: ${METAL3_VIP}
      enable_vmedia_tls: false
      additionalTrustedCAs: false
    metal3-ironic:
      global:
        predictableNicNames: "true"
      persistence:
        ironic:
          size: "5Gi"
注記
注記

メディアサーバは、Metal3に含まれるオプションの機能です(デフォルトでは無効になっています)。このMetal3の機能を使用するには、以前のマニフェストで設定する必要があります。Metal3メディアサーバを使用するには、次の変数を指定します。

  • メディアサーバ機能を有効にするために、globalセクションにenable_metal3_media_serverを追加してtrueに設定します。

  • メディアサーバ設定に次の内容を含めます。${MEDIA_VOLUME_PATH}はメディアボリュームのパスです(例: /home/metal3/bmh-image-cache)。

    metal3-media:
      mediaVolume:
        hostPath: ${MEDIA_VOLUME_PATH}

外部のメディアサーバを使用してイメージを保存できます。外部のメディアサーバをTLSで使用する場合は、次の設定を変更する必要があります。

  • 前のmetal3.yamlファイルでadditionalTrustedCAstrueに設定し、外部のメディアサーバから、信頼できる追加のCAを有効にします。

  • kubernetes/manifests/metal3-cacert-secret.yamlフォルダに次のシークレット設定を含めて、外部のメディアサーバのCA証明書を保存します。

    apiVersion: v1
    kind: Namespace
    metadata:
      name: metal3-system
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: tls-ca-additional
      namespace: metal3-system
    type: Opaque
    data:
      ca-additional.crt: {{ additional_ca_cert | b64encode }}

additional_ca_certは、外部のメディアサーバのbase64エンコードCA証明書です。次のコマンドを使用し、証明書をエンコードして手動でシークレットを生成できます。

kubectl -n meta3-system create secret generic tls-ca-additional --from-file=ca-additional.crt=./ca-additional.crt
  • certmanager.yaml: Cert-Managerコンポーネントを作成するための設定が含まれます(変更不要)。

    installCRDs: "true"

29.3.5 ネットワーキングフォルダ

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アドレスを取得する場合、次の設定を使用できます(${MGMT_MAC}変数を使用して、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.yamlmgmt-cluster-node3.yamlなどのように追加のファイルを作成して残りのノードを設定できます。

  • routesセクションは、管理クラスタのルーティングテーブルを定義するために使用します。

29.4 エアギャップ環境のイメージの準備

このセクションでは、エアギャップ環境を準備する方法について説明し、前の各セクションとの相違点のみを示します。エアギャップ環境のイメージを準備するには、前のセクション(接続環境のイメージの準備(29.3項 「接続環境用のイメージの準備」))を次のように変更する必要があります。

  • mgmt-cluster.yamlファイルを変更してembeddedArtifactRegistryセクションを含め、imagesフィールドに、EIB出力イメージに組み込むすべてのコンテナイメージを設定する必要があります。

  • エアギャップ環境を使用する場合、custom/scripts/99-register.shスクリプトは削除する必要があります。

  • custom/files/airgap-resources.tar.gzファイルを、管理クラスタをエアギャップ環境で実行するために必要なすべてのリソースとともにcustom/filesフォルダに含める必要があります。

  • custom/scripts/99-mgmt-setup.shスクリプトを変更し、airgap-resources.tar.gzファイルを抽出して最終的な場所にコピーするようにする必要があります。

  • custom/files/metal3.shスクリプトを変更し、インターネットからリソースをダウンロードするのではなく、airgap-resources.tar.gzファイルに含まれるローカルリソースを使用するように必要があります。

29.4.1 エアギャップ環境のディレクトリ構造

エアギャップ環境のディレクトリ構造は接続環境とほぼ同じです。相違点を次に説明します。

eib
|-- base-images
|   |-- SLE-Micro.x86_64-5.5.0-Default-SelfInstall-GM2.install.iso
|-- custom
|   |-- files
|   |   |-- airgap-resources.tar.gz
|   |   |-- basic-setup.sh
|   |   |-- metal3.sh
|   |   |-- mgmt-stack-setup.service
|   |   |-- rancher.sh
|   |-- scripts
|       |-- 99-alias.sh
|       |-- 99-mgmt-setup.sh
|-- kubernetes
|   |-- config
|   |   |-- server.yaml
|   |-- helm
|   |   |-- values
|   |       |-- certmanager.yaml
|   |       |-- metal3.yaml
|   |       |-- neuvector.yaml
|   |       |-- rancher.yaml
|   |-- manifests
|       |-- neuvector-namespace.yaml
|-- mgmt-cluster.yaml
|-- network
    |-- mgmt-cluster-network.yaml
注記
注記

イメージSLE-Micro.x86_64-5.5.0-Default-SelfInstall-GM2.install.isoSUSE Customer CenterまたはSUSEダウンロードページからダウンロードし、プロセスを開始する前にbase-imagesフォルダに配置する必要があります。

イメージのSHA256チェックサムを確認し、イメージが改ざんされていないことを確認する必要があります。このチェックサムは、イメージをダウンロードした場所と同じ場所にあります。

ディレクトリ構造の例は、 SUSE Edge GitHubリポジトリの「telco-examples」フォルダにあります。

29.4.2 定義ファイルの変更

mgmt-cluster.yamlファイルを変更してembeddedArtifactRegistryセクションを含め、imagesフィールドに、EIB出力イメージに組み込むすべてのコンテナイメージを設定する必要があります。imagesフィールドには、出力イメージに含めるすべてのコンテナイメージのリストを含める必要があります。次に、embeddedArtifactRegistryセクションが含まれるmgmt-cluster.yamlファイルの例を示します。

apiVersion: 1.0
image:
  imageType: iso
  arch: x86_64
  baseImage: SLE-Micro.x86_64-5.5.0-Default-SelfInstall-GM2.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: ${KUBERNETES_VERSION}
  helm:
    charts:
      - name: cert-manager
        repositoryName: jetstack
        version: 1.14.2
        targetNamespace: cert-manager
        valuesFile: certmanager.yaml
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn-crd
        version: 103.3.0+up1.6.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: longhorn
        version: 103.3.0+up1.6.1
        repositoryName: rancher-charts
        targetNamespace: longhorn-system
        createNamespace: true
        installationNamespace: kube-system
      - name: metal3-chart
        version: 0.7.1
        repositoryName: suse-edge-charts
        targetNamespace: metal3-system
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: metal3.yaml
      - name: neuvector-crd
        version: 103.0.3+up2.7.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: neuvector
        version: 103.0.3+up2.7.6
        repositoryName: rancher-charts
        targetNamespace: neuvector
        createNamespace: true
        installationNamespace: kube-system
        valuesFile: neuvector.yaml
      - name: rancher
        version: 2.8.4
        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
      - name: rancher-prime
        url: https://charts.rancher.com/server-charts/prime
    network:
      apiHost: ${API_HOST}
      apiVIP: ${API_VIP}
    nodes:
      - hostname: mgmt-cluster-node1
        initializer: true
        type: server
#     - hostname: mgmt-cluster-node2
#       initializer: true
#       type: server
#     - hostname: mgmt-cluster-node3
#       initializer: true
#       type: server
embeddedArtifactRegistry:
  images:
    - name: registry.rancher.com/rancher/backup-restore-operator:v4.0.2
    - name: registry.rancher.com/rancher/calico-cni:v3.27.0-rancher1
    - name: registry.rancher.com/rancher/cis-operator:v1.0.13
    - name: registry.rancher.com/rancher/coreos-kube-state-metrics:v1.9.7
    - name: registry.rancher.com/rancher/coreos-prometheus-config-reloader:v0.38.1
    - name: registry.rancher.com/rancher/coreos-prometheus-operator:v0.38.1
    - name: registry.rancher.com/rancher/flannel-cni:v0.3.0-rancher9
    - name: registry.rancher.com/rancher/fleet-agent:v0.9.4
    - name: registry.rancher.com/rancher/fleet:v0.9.4
    - name: registry.rancher.com/rancher/gitjob:v0.9.7
    - name: registry.rancher.com/rancher/grafana-grafana:7.1.5
    - name: registry.rancher.com/rancher/hardened-addon-resizer:1.8.20-build20240410
    - name: registry.rancher.com/rancher/hardened-calico:v3.27.3-build20240423
    - name: registry.rancher.com/rancher/hardened-cluster-autoscaler:v1.8.10-build20240124
    - name: registry.rancher.com/rancher/hardened-cni-plugins:v1.4.1-build20240325
    - name: registry.rancher.com/rancher/hardened-coredns:v1.11.1-build20240305
    - name: registry.rancher.com/rancher/hardened-dns-node-cache:1.22.28-build20240125
    - name: registry.rancher.com/rancher/hardened-etcd:v3.5.9-k3s1-build20240418
    - name: registry.rancher.com/rancher/hardened-flannel:v0.25.1-build20240423
    - name: registry.rancher.com/rancher/hardened-k8s-metrics-server:v0.7.1-build20240401
    - name: registry.rancher.com/rancher/hardened-kubernetes:v1.28.9-rke2r1-build20240416
    - name: registry.rancher.com/rancher/hardened-multus-cni:v4.0.2-build20240208
    - name: registry.rancher.com/rancher/hardened-node-feature-discovery:v0.14.1-build20230926
    - name: registry.rancher.com/rancher/hardened-whereabouts:v0.6.3-build20240208
    - name: registry.rancher.com/rancher/helm-project-operator:v0.2.1
    - name: registry.rancher.com/rancher/istio-kubectl:1.5.10
    - name: registry.rancher.com/rancher/jimmidyson-configmap-reload:v0.3.0
    - name: registry.rancher.com/rancher/k3s-upgrade:v1.28.9-k3s1
    - name: registry.rancher.com/rancher/klipper-helm:v0.8.3-build20240228
    - name: registry.rancher.com/rancher/klipper-lb:v0.4.7
    - name: registry.rancher.com/rancher/kube-api-auth:v0.2.1
    - name: registry.rancher.com/rancher/kubectl:v1.28.7
    - name: registry.rancher.com/rancher/library-nginx:1.19.2-alpine
    - name: registry.rancher.com/rancher/local-path-provisioner:v0.0.26
    - name: registry.rancher.com/rancher/machine:v0.15.0-rancher112
    - name: registry.rancher.com/rancher/mirrored-cluster-api-controller:v1.4.4
    - name: registry.rancher.com/rancher/nginx-ingress-controller:nginx-1.9.6-rancher1
    - name: registry.rancher.com/rancher/pause:3.6
    - name: registry.rancher.com/rancher/prom-alertmanager:v0.21.0
    - name: registry.rancher.com/rancher/prom-node-exporter:v1.0.1
    - name: registry.rancher.com/rancher/prom-prometheus:v2.18.2
    - name: registry.rancher.com/rancher/prometheus-auth:v0.2.2
    - name: registry.rancher.com/rancher/prometheus-federator:v0.3.4
    - name: registry.rancher.com/rancher/pushprox-client:v0.1.0-rancher2-client
    - name: registry.rancher.com/rancher/pushprox-proxy:v0.1.0-rancher2-proxy
    - name: registry.rancher.com/rancher/rancher-agent:v2.8.4
    - name: registry.rancher.com/rancher/rancher-csp-adapter:v3.0.1
    - name: registry.rancher.com/rancher/rancher-webhook:v0.4.5
    - name: registry.rancher.com/rancher/rancher:v2.8.4
    - name: registry.rancher.com/rancher/rke-tools:v0.1.96
    - name: registry.rancher.com/rancher/rke2-cloud-provider:v1.29.3-build20240412
    - name: registry.rancher.com/rancher/rke2-runtime:v1.28.9-rke2r1
    - name: registry.rancher.com/rancher/rke2-upgrade:v1.28.9-rke2r1
    - name: registry.rancher.com/rancher/security-scan:v0.2.15
    - name: registry.rancher.com/rancher/shell:v0.1.24
    - name: registry.rancher.com/rancher/system-agent-installer-k3s:v1.28.9-k3s1
    - name: registry.rancher.com/rancher/system-agent-installer-rke2:v1.28.9-rke2r1
    - name: registry.rancher.com/rancher/system-agent:v0.3.6-suc
    - name: registry.rancher.com/rancher/system-upgrade-controller:v0.13.1
    - name: registry.rancher.com/rancher/ui-plugin-catalog:1.3.0
    - name: registry.rancher.com/rancher/ui-plugin-operator:v0.1.1
    - name: registry.rancher.com/rancher/webhook-receiver:v0.2.5
    - name: registry.rancher.com/rancher/kubectl:v1.20.2
    - name: registry.rancher.com/rancher/mirrored-longhornio-csi-attacher:v4.4.2
    - name: registry.rancher.com/rancher/mirrored-longhornio-csi-provisioner:v3.6.2
    - name: registry.rancher.com/rancher/mirrored-longhornio-csi-resizer:v1.9.2
    - name: registry.rancher.com/rancher/mirrored-longhornio-csi-snapshotter:v6.3.2
    - name: registry.rancher.com/rancher/mirrored-longhornio-csi-node-driver-registrar:v2.9.2
    - name: registry.rancher.com/rancher/mirrored-longhornio-livenessprobe:v2.12.0
    - name: registry.rancher.com/rancher/mirrored-longhornio-backing-image-manager:v1.6.1
    - name: registry.rancher.com/rancher/mirrored-longhornio-longhorn-engine:v1.6.1
    - name: registry.rancher.com/rancher/mirrored-longhornio-longhorn-instance-manager:v1.6.1
    - name: registry.rancher.com/rancher/mirrored-longhornio-longhorn-manager:v1.6.1
    - name: registry.rancher.com/rancher/mirrored-longhornio-longhorn-share-manager:v1.6.1
    - name: registry.rancher.com/rancher/mirrored-longhornio-longhorn-ui:v1.6.1
    - name: registry.rancher.com/rancher/mirrored-longhornio-support-bundle-kit:v0.0.36
    - name: registry.suse.com/edge/cluster-api-provider-rke2-bootstrap:v0.2.6
    - name: registry.suse.com/edge/cluster-api-provider-rke2-controlplane:v0.2.6
    - name: registry.suse.com/edge/cluster-api-controller:v1.6.2
    - name: registry.suse.com/edge/cluster-api-provider-metal3:v1.6.0
    - name: registry.suse.com/edge/ip-address-manager:v1.6.0

29.4.3 カスタムフォルダの変更

  • エアギャップ環境を使用する場合、custom/scripts/99-register.shスクリプトを削除する必要があります。ディレクトリ構造からわかるように、99-register.shスクリプトはcustom/scriptsフォルダに含まれていません。

  • custom/scripts/99-mgmt-setup.shスクリプトを変更し、airgap-resources.tar.gzファイルを抽出して最終的な場所にコピーするようにする必要があります。次に、airgap-resources.tar.gzファイルを抽出してコピーするように変更した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
    
    # Extract the airgap resources
    tar zxf airgap-resources.tar.gz
    
    # Copy the clusterctl binary to the final location
    cp airgap-resources/clusterctl /opt/mgmt/bin/ && chmod +x /opt/mgmt/bin/clusterctl
    
    # Copy the clusterctl.yaml and override
    mkdir -p /root/cluster-api
    cp -r airgap-resources/clusterctl.yaml airgap-resources/overrides /root/cluster-api/
  • custom/files/metal3.shスクリプトを変更し、インターネットからリソースをダウンロードするのではなく、airgap-resources.tar.gzファイルに含まれるローカルリソースを使用するようにする必要があります。次に、ローカルリソースを使用するように変更したmetal3.shスクリプトの例を示します。

    #!/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
    
    # If rancher is deployed
    if [ $(${KUBECTL} get pods -n ${RANCHER_CHART_TARGETNAMESPACE} -l app=rancher -o name | wc -l) -ge 1 ]; then
      cat <<-EOF | ${KUBECTL} apply -f -
    	apiVersion: management.cattle.io/v3
    	kind: Feature
    	metadata:
    	  name: embedded-cluster-api
    	spec:
    	  value: false
    	EOF
    
      # Disable Rancher webhooks for CAPI
      ${KUBECTL} delete mutatingwebhookconfiguration.admissionregistration.k8s.io mutating-webhook-configuration
      ${KUBECTL} delete validatingwebhookconfigurations.admissionregistration.k8s.io validating-webhook-configuration
      ${KUBECTL} wait --for=delete namespace/cattle-provisioning-capi-system --timeout=300s
    fi
    
    # Deploy CAPI
    if [ $(${KUBECTL} get pods -n ${METAL3_CAPISYSTEMNAMESPACE} -o name | wc -l) -lt 1 ]; then
    
      # Try this command 3 times just in case, stolen from https://stackoverflow.com/a/33354419
      if ! (r=3; while ! /opt/mgmt/bin/clusterctl init \
        --core "cluster-api:v${METAL3_CAPICOREVERSION}"\
        --infrastructure "metal3:v${METAL3_CAPIMETAL3VERSION}"\
        --bootstrap "${METAL3_CAPIPROVIDER}:v${METAL3_CAPIRKE2VERSION}"\
        --control-plane "${METAL3_CAPIPROVIDER}:v${METAL3_CAPIRKE2VERSION}"\
        --config /root/cluster-api/clusterctl.yaml ; do
                ((--r))||exit
                echo "Something went wrong, let's wait 10 seconds and retry"
                sleep 10;done) ; then
          echo "clusterctl failed"
          exit 1
      fi
    
      # Wait for capi-controller-manager
      while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_CAPISYSTEMNAMESPACE} $(${KUBECTL} get pods -n ${METAL3_CAPISYSTEMNAMESPACE} -l cluster.x-k8s.io/provider=cluster-api -o name) --timeout=10s; do sleep 2 ; done
    
      # Wait for capm3-controller-manager, there are two pods, the ipam and the capm3 one, just wait for the first one
      while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_CAPM3NAMESPACE} $(${KUBECTL} get pods -n ${METAL3_CAPM3NAMESPACE} -l cluster.x-k8s.io/provider=infrastructure-metal3 -o name | head -n1 ) --timeout=10s; do sleep 2 ; done
    
      # Wait for rke2-bootstrap-controller-manager
      while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_RKE2BOOTSTRAPNAMESPACE} $(${KUBECTL} get pods -n ${METAL3_RKE2BOOTSTRAPNAMESPACE} -l cluster.x-k8s.io/provider=bootstrap-rke2 -o name) --timeout=10s; do sleep 2 ; done
    
      # Wait for rke2-control-plane-controller-manager
      while ! ${KUBECTL} wait --for condition=ready -n ${METAL3_RKE2CONTROLPLANENAMESPACE} $(${KUBECTL} get pods -n ${METAL3_RKE2CONTROLPLANENAMESPACE} -l cluster.x-k8s.io/provider=control-plane-rke2 -o name) --timeout=10s; do sleep 2 ; done
    
    fi
    
    # Clean up the lock cm
    
    ${KUBECTL} delete configmap ${METAL3LOCKCMNAME} -n ${METAL3LOCKNAMESPACE}
  • custom/files/airgap-resources.tar.gzファイルを変更し、管理クラスタをエアギャップ環境で実行するために必要なすべてのリソースとともにcustom/filesフォルダに含める必要があります。このファイルを準備するには、すべてのリソースを手動でダウンロードして1つのファイルに圧縮する必要があります。airgap-resources.tar.gzファイルには次のリソースが含まれます。

    |-- clusterctl
    |-- clusterctl.yaml
    |-- overrides
        |-- bootstrap-rke2
        |   |-- v0.2.6
        |       |-- bootstrap-components.yaml
        |       |-- metadata.yaml
        |-- cluster-api
        |   |-- v1.6.2
        |       |-- core-components.yaml
        |       |-- metadata.yaml
        |-- control-plane-rke2
        |   |-- v0.2.6
        |       |-- control-plane-components.yaml
        |       |-- metadata.yaml
        |-- infrastructure-metal3
            |-- v1.6.0
                |-- cluster-template.yaml
                |-- infrastructure-components.yaml
                |-- metadata.yaml

clusterctl.yamlファイルには、イメージの場所、およびclusterctlツールで利用する上書き設定が含まれます。overridesフォルダには、インターネットからダウンロードする代わりに使用するyamlファイルマニフェストが含まれます。

providers:
  # override a pre-defined provider
  - name: "cluster-api"
    url: "/root/cluster-api/overrides/cluster-api/v1.6.2/core-components.yaml"
    type: "CoreProvider"
  - name: "metal3"
    url: "/root/cluster-api/overrides/infrastructure-metal3/v1.6.0/infrastructure-components.yaml"
    type: "InfrastructureProvider"
  - name: "rke2"
    url: "/root/cluster-api/overrides/bootstrap-rke2/v0.2.6/bootstrap-components.yaml"
    type: "BootstrapProvider"
  - name: "rke2"
    url: "/root/cluster-api/overrides/control-plane-rke2/v0.2.6/control-plane-components.yaml"
    type: "ControlPlaneProvider"
images:
  all:
    repository: registry.suse.com/edge

overridesフォルダに含まれるclusterctlと残りのファイル は、次のcurlsコマンドを使用してダウンロードできます。

# clusterctl binary
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/1.6.2/clusterctl-linux-${GOARCH} -o /usr/local/bin/clusterct

# boostrap-components (boostrap-rke2)
curl -L https://github.com/rancher-sandbox/cluster-api-provider-rke2/releases/download/v0.2.6/bootstrap-components.yaml
curl -L https://github.com/rancher-sandbox/cluster-api-provider-rke2/releases/download/v0.2.6/metadata.yaml

# control-plane-components (control-plane-rke2)
curl -L https://github.com/rancher-sandbox/cluster-api-provider-rke2/releases/download/v0.2.6/control-plane-components.yaml
curl -L https://github.com/rancher-sandbox/cluster-api-provider-rke2/releases/download/v0.2.6/metadata.yaml

# cluster-api components
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.6.2/core-components.yaml
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.6.2/metadata.yaml

# infrastructure-components (infrastructure-metal3)
curl -L https://github.com/metal3-io/cluster-api-provider-metal3/releases/download/v1.6.0/infrastructure-components.yaml
curl -L https://github.com/metal3-io/cluster-api-provider-metal3/releases/download/v1.6.0/metadata.yaml
注記
注記

異なるバージョンのコンポーネントを使用する場合、URL内のバージョンを変更すると、特定のバージョンのコンポーネントをダウンロードできます。

以前のリソースをダウンロード済みの場合、次のコマンドを使用してそれらを1つのファイルに圧縮できます。

tar -czvf airgap-resources.tar.gz clusterctl clusterctl.yaml overrides

29.5 イメージの作成

前の各セクションに従ってディレクトリ構造を準備したら(接続シナリオとエアギャップシナリオの両方が対象です)、次のコマンドを実行してイメージを構築します。

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

ISO出力イメージファイルが作成されます。ここでは、上記のイメージ定義に基づくeib-mgmt-cluster-image.isoという名前のファイルです。

29.6 管理クラスタのプロビジョニング

前のイメージには、上述のコンポーネントがすべて含まれています。このイメージを使って、仮想マシンまたはベアメタルサーバを使用して(仮想メディア機能を使用して)管理クラスタをプロビジョニングできます。