【Harvester 1.8】 外部ストレージ(NFS・CSI)を使う 3Tier 構成と冗長化の確認手順

Harvester は既定で HCI ストレージ(Longhorn)を使いますが、v1.5 から外部ストレージの CSI ドライバーで仮想マシンのディスク(ブート ディスクを含む)を作れます。ここでは NFS サーバーと csi-driver-nfs を使った 3Tier 構成を作り、ライブ マイグレーション、NIC 障害、ノードの電源断(HA)を確認しました。

目次

この記事の前提

構成と冗長化の考え方

項目内容
ストレージNFS サーバー(192.168.1.182、Rocky Linux 9)の /exports/harv
CSI ドライバーcsi-driver-nfs v4.11.0(プロビジョナー nfs.csi.k8s.io)
経路各ノードの管理ボンド mgmt-bo(ens18・ens19、active-backup)を通る
アクセス モードReadWriteMany(ライブ マイグレーションに必要)

NFS は 1 本のセッションで使うため、経路の冗長化はノード側のボンドで行いました。iSCSI や FC のストレージでマルチパスを使うときは、ストレージ ベンダーの CSI ドライバーが対応しているかを確認してください。なお、この検証の Harvester 1.8.2 のノードには multipathd のサービスがありませんでした(systemctl is-enabled multipathd が「No such device or address」)。

NFS サーバー自体の冗長化(コントローラー 2 台の NAS など)は、ストレージ側で行います。この検証の NFS サーバーは 1 台です。

NFS の公開

実行する場所:NFS サーバー(root)

# mkdir -p /exports/harv && chmod 777 /exports/harv
# echo "/exports/harv 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)" >> /etc/exports
# exportfs -ra
# exportfs -v | grep harv

期待する出力:

/exports/harv 	192.168.1.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)

CSI ドライバーの導入

Harvester(RKE2)に組み込まれている Helm コントローラーで csi-driver-nfs を入れます。スナップショットのコントローラーは Harvester に入っているため、チャートの externalSnapshotter は無効にします。

実行する場所:いずれかのノード(rancher ユーザー。kubectl は sudo /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml)

$ cat > csi-nfs-helmchart.yaml <<'EOF'
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: csi-driver-nfs
  namespace: kube-system
spec:
  repo: https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
  chart: csi-driver-nfs
  version: v4.11.0
  targetNamespace: kube-system
  valuesContent: |-
    externalSnapshotter:
      enabled: false
    controller:
      replicas: 1
EOF
$ kubectl apply -f csi-nfs-helmchart.yaml
$ kubectl get csidriver

期待する出力(1〜2 分後):

NAME                 ATTACHREQUIRED   PODINFOONMOUNT   ...
driver.longhorn.io   true             true             ...
nfs.csi.k8s.io       false            false            ...

続けて、NFS 用の VolumeSnapshotClass を作ります。Harvester はイメージから仮想マシンのディスクを作るときなどにスナップショットを使います。

$ cat > vsc-nfs.yaml <<'EOF'
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: csi-nfs-snapclass
driver: nfs.csi.k8s.io
deletionPolicy: Delete
EOF
$ kubectl apply -f vsc-nfs.yaml

期待する出力:

volumesnapshotclass.snapshot.storage.k8s.io/csi-nfs-snapclass created

CSI ドライバーの登録(csi-driver-config)

(1) [Advanced] → [Settings] で csi-driver-config を編集し、[Add] をクリックして Provisioner に nfs.csi.k8s.io、Volume Snapshot Class Name に csi-nfs-snapclass を選んで [Save] をクリックします。ここに登録したドライバーが、ストレージ クラスの作成画面で選べるようになります。

csi-driver-config

ストレージ クラスの作成

(1) [Advanced] → [Storage Classes] で [Create] をクリックし、名前を入力して Provisioner に nfs.csi.k8s.io を入力・選択します。パラメーターはフォームに Longhorn 用の項目が残るため、[Edit as YAML] で全体を書き換えて [Create] をクリックしました。

ストレージ クラス
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-csi
  annotations:
    field.cattle.io/description: 3Tier-NFS-doc-nfs
    cdi.harvesterhci.io/storageProfileVolumeSnapshotClass: csi-nfs-snapclass
    cdi.harvesterhci.io/storageProfileVolumeModeAccessModes: '{"Filesystem":["ReadWriteMany"]}'
provisioner: nfs.csi.k8s.io
parameters:
  server: 192.168.1.182
  share: /exports/harv
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
mountOptions:
  - nfsvers=4.1
  - hard
項目説明
parameters.server / shareNFS サーバーと公開しているパス
cdi.harvesterhci.io/storageProfileVolumeSnapshotClassイメージ(CDI)からディスクを作るときに使う VolumeSnapshotClass
cdi.harvesterhci.io/storageProfileVolumeModeAccessModesディスクのボリューム モードとアクセス モード。ライブ マイグレーションには ReadWriteMany が必要
mountOptionsNFS のマウント オプション。hard は NFS サーバーが応答しない間、I/O を待たせる(エラーにしない)

(2) nfs-csi が一覧に表示されます。

ストレージ クラスの完了

NFS 上のイメージと仮想マシン

(1) [Images] で [Create] をクリックし、[Basics] で URL を入力、[Storage] の Storage Class で nfs-csi を選んで [Create] をクリックします。Longhorn 以外のストレージでは、イメージは CDI(Containerized Data Importer)で取り込まれます。

NFS のイメージ

(2) Active になれば使えます(この環境では約 4 分)。

イメージの完了

(3) [Virtual Machines] で仮想マシンを作ります。手順は HCI の記事と同じで、[Volumes] の [Image] で nfs-csi のイメージを選びます。

イメージの選択

(4) Network Data では IP アドレスを 192.168.1.176 にしました。

Network Data

(5) ディスクはイメージのスナップショットから作られます。csi-driver-nfs のスナップショットは tar.gz のため、展開に時間がかかり、この環境では作成から Running まで約 4 分でした。

仮想マシンの起動

NFS サーバーには、ボリュームごとのディレクトリーができます(イメージ用と仮想マシンのディスク用。作成中だけ snapshot-… のディレクトリーもできます)。

実行する場所:NFS サーバー

# ls /exports/harv/

期待する出力(例):

pvc-6164bfa7-b145-4290-a2cc-82d48cce7f7c
pvc-6db398f6-bffe-4af5-a2cf-b4c98b2299af

ライブ マイグレーション

(1) 仮想マシンの︙から [Migrate] をクリックし、移動先のノードを選んで [Apply] をクリックします。

移動先

(2) 移動先のノードで Running になります。

移動後
項目結果(3 回)
転送(migrationState の開始〜終了)8 秒・7 秒・7 秒
ping の最長の途切れ(0.2 秒間隔)8.9 秒・0.6 秒・0.6 秒

ディスクは共有の NFS にあるため、転送するのはメモリーだけです。1 回目の 8.9 秒の途切れは HCI でも 1 回起きており、ネットワーク側の MAC アドレスの学び直しの待ちと考えられます。

NIC 障害(NFS の経路の片側断)

仮想マシンが動いている doc-harv3 の管理ボンドの稼働側(ens18)のリンクを、仮想マシンで 2 GB を書き込んでいる最中に切りました。NFS の通信は管理ボンドを通っています。

項目結果
ボンドens19 に切り替わった
書き込み止まらずに完了(97.1 MB/s)
ノードの管理 IP(.174)への ping1 回の欠落
仮想マシンへの ping1 回(0.4 秒)の欠落

HA(ノードの電源断)

仮想マシンが動いている doc-harv3 の電源を強制的に切りました。

(1) HCI のときと同じく、退避のマイグレーションのタイムアウトの後、別のノード(doc-harv2)で起動し直しました。

再起動
経過(電源断から)状態
56 秒ノードが NotReady
267 秒仮想マシンが Failed
278 秒doc-harv2 にスケジュール
284 秒doc-harv2 で Running
320 秒ゲストが起動し ping が通った(途切れは 320 秒)

NFS は複数のノードから同時にマウントできるため、ディスクの付け替え(アタッチ)の待ちはありません。時間の大半は vm-force-reset-policy の待ち(既定 15 秒+180 秒)です。

結果のまとめ

試験3Tier(NFS)HCI(Longhorn)※
ライブ マイグレーション(転送)7〜8 秒6〜8 秒
経路の NIC 障害書き込み継続、ping の欠落 1 回書き込み継続、欠落なし(ストレージ ボンド)
ノードの電源断(HA)320 秒で再起動338 秒で再起動

※ HCI の値は前の記事です。

次の手順

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次