Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。 この連載はvSphere環境上にOpenShift Container Platform(以下、OpenShift)およびOpenShift Virtualizationの環境を構築する方法を解説するシリーズです。
本記事は元々、連載「ゼロからはじめるOpenShift Virtualization」の第3回として投稿した内容のNFSプロビジョナーの構築部分のみをピックアップした内容です。 このNFSプロビジョナーはボリュームのスナップショットに対応しておらず、OpenShift Virtuzalizationとして利用するには機能不足な点がありました。 そのため、本連載第3回の内容はNFS CSI driver for Kubernetes(以下、NFS CSIドライバー)を使った内容に変更しております。 本記事はあくまで参考情報として残しておくことを目的とします。
本連載の一覧は下記の通りです。
- 第1回:OpenShiftのインストール
- 第2回:OpenShiftインストール後の作業
- 第3回:共有ストレージの作成(NFS CSIドライバーの構築)
- 第4回:OpenShift Virtualizationのインストールと実行
- 第5回:vSphere仮想マシンの移行
- 【番外編】:共有ストレージの作成(NFSプロビジョナーの構築)(←本記事)
-目次-
前提条件
- 連載第1回、第2回および、第3回の「2. 踏み台サーバー上のNFSサーバー設定」作業が完了していることとします
- NFSプロビジョナー構築後の「イメージレジストリの設定」は第3回を参照ください
- 全体の構成や各パラメーターなどは連載第1回を参照してください
- 作業用端末のプロンプトは
%
とします - 踏み台サーバーのプロンプトは
$
とします - 踏み台サーバーの作業は明示的に記載がある場合を除いて、作業ディレクトリ
${HOME}/work
で作業することとします
1. NFSプロビジョナーの設定
踏み台サーバー上に構築したNFSサーバーを利用してPVの動的プロビジョニングを行うため、OpenShiftにNFSプロビジョナーをインストールします。
1-1 NFSプロビジョナーについて
OpenShiftでPVの動的プロビジョニングを行うためにはストレージとそれに対応したCSIドライバーが必要です。 今回構築したストレージはRHELで立てた汎用的なNFSサーバーなので専用のCSIドライバーがありません。 そこで今回は、汎用的なNFSサーバーをバックエンドに使用しPVの動的プロビジョニングを行うことができる「NFS Subdir External Provisioner(以下、NFSプロビジョナー)」を利用します。
このNFSプロビジョナーはKuberentes SIGsでホストされているリポジトリの1つです。OSSで開発されておりApache-2.0 licenseに従い無償で利用できます。
なお、このNFSプロビジョナーは汎用的なNFSサーバーをバックエンドに利用できる反面、高度な機能には対応していません(ストレージの機能を使ったVolume CLoneなど)。
Support for "CSI Volume Cloning" · Issue #182 · kubernetes-sigs/nfs-subdir-external-provisioner
実稼働環境ではスナップショットやボリュームクローニングに対応したCSIドライバを提供しているストレージベンダーなどの製品をご利用ください。
1-2 NFSプロビジョナーの動作
NFSプロビジョナーの動作の流れは下記の通りです
1-3 NFSプロビジョナーのインストール
NFSプロビジョナーをインストールする流れは下記のとおりです。
- NFSプロビジョナー用のプロジェクトを作成
- サービスアカウントの作成
- Helmのインストール
- NFSプロビジョナーのインストール
現時点ではコマンドの詳細を深く理解する必要はありません。まずはおまじない的にコマンドをコピペして実行してください。
(1)NFSプロビジョナー用のプロジェクトを作成
oc new-project
コマンドでNFSプロビジョナー用のプロジェクトを作成します。
プロジェクト名はnfs-subdir-external-provisioner
とします。
$ oc new-project nfs-subdir-external-provisioner
(2)サービスアカウントの作成
NFSプロビジョナーのインストールの前にサービスアカウントを作成します。 サービスアカウントは、KubernetesやOpenShiftでシステムコンポーネントやアプリケーションがAPIサーバーと安全に通信するために使用される特殊なアカウントです。
手動で作成したnfs-subdir-external-provisioner
サービスアカウントに権限、ラベル、アノテーションを追加します。
$ oc create sa nfs-subdir-external-provisioner $ oc adm policy add-scc-to-user hostmount-anyuid system:serviceaccount:nfs-subdir-external-provisioner:nfs-subdir-external-provisioner $ oc label sa nfs-subdir-external-provisioner app.kubernetes.io/managed-by=Helm $ oc annotate sa nfs-subdir-external-provisioner meta.helm.sh/release-name=nfs-subdir-external-provisioner meta.helm.sh/release-namespace=nfs-subdir-external-provisioner
oc adm policy add-scc-to-user
:サービスアカウントにhostmount-anyuid
というSCCを追加しますoc label sa
:このサービスアカウントがHelmによって管理されていることを示すラベルを追加するoc annotate sa
:サービスアカウントにHelmリリースに関するメタデータをアノテーションとして追加する
これでNFSプロビジョナーをインストールする準備が整いました。
(3)Helmのインストール
NFSプロビジョナーのインストールでHelm*1を使用します。 Helmはパッケージマネージャーの1つで、アプリケーションをパッケージ(Helmではチャートという)としてKuberenetes上に簡単にデプロイできる仕組みです。 今回の構成では踏み台サーバーにHelmをインストールします。Helmのインストールドキュメントは下記です(本記事ではRed Hatが提供しているHelmのバイナリを利用します)。
x86_64の環境にHelmをインストールするコマンド例は下記のとおりです。
$ sudo curl -L https://mirror.openshift.com/pub/openshift-v4/clients/helm/latest/helm-linux-amd64 -o /usr/local/bin/helm $ sudo chmod +x /usr/local/bin/helm
Helmのインストール後、helm
コマンドを実行して動作確認を行います。
$ helm version WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/user/work/auth/kubeconfig WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/user/work/auth/kubeconfig version.BuildInfo{Version:"v3.14.4+37.el9", GitCommit:"7163c12e65c8c0a40334c0a4b514b991ea37aa21", GitTreeState:"clean", GoVersion:"go1.21.9 (Red Hat 1.21.9-2.el9_4)"}
KUBECONFIG
環境変数がセットされていて、かつkubeconfig
ファイルのパーミッションが所有者以外から読み込み可能になっているとコマンドの出力に警告が出ます。
気になる方はchmod
コマンドでパーミッションを変更してください。
$ chmod 600 auth/kubeconfig
(4)NFSプロビジョナーのインストール
NFSプロビジョナーはOpenShiftにインストールします。初めにチャートリポジトリを追加し、その後にインストールを行います。
helm repo add
コマンドでNFSプロビジョナーのチャートリポジトリを追加します。
$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
~/.config/helm
ディレクトリが作成され、参照するリポジトリの情報が保存されます
helm install
コマンドでNFSプロビジョナーをインストールします。
--set
オプションを使って固有の情報を追加で指定します。
$ helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ --set nfs.server=192.168.1.206 \ --set nfs.path=/mnt/nfs \ --set storageClass.accessMode=ReadWriteMany
nfs.server
:NFSサーバーのIPアドレス/ホスト名を指定nfs.path
:NFSエクスポートを行ったパスを指定storageClass.accessMode
:RWXを使用するためReadWriteMany
を指定
helm install
コマンドを実行すると下記のような応答が出力されます
... NAME: nfs-subdir-external-provisioner LAST DEPLOYED: Mon Jul 8 05:15:36 2024 NAMESPACE: nfs-subdir-external-provisioner STATUS: deployed REVISION: 1 TEST SUITE: None
NFSプロビジョナーが正常にインストールできたかどうかは次の手順で確認します。
(5)NFSプロビジョナーのインストールの確認
OpenShiftのWebコンソールから「管理者向け表示」のプルダウンを選択し「開発者」を選択します。 これにより開発者向け表示(Developerパースペクティブ)に切り替えることができます。
左のメニューから「トポロジー」を選択します。プロジェクトのプルダウンメニューから「nfs-subdir-external-provisioner
」を選択します。
画面内に「D」のアイコンがついたnfs-subdir-external-provisioner
というオブジェクト(Deployment)が表示されます。
このDeploymentはNFSプロビジョナーのアプリケーションPodの展開と管理を行うリソースです。
左のメニューからHelmを選択すると、現在選択しているプロジェクトに登録済みのHelmリリース*2の情報が表示されます。
「HR」アイコンが付いたHelmリリース名(ここではnfs-subdir-external-provisioner
)のリンクを選択します。
Helmでインストールされたリソースの名前やタイプが一覧で表示されます。先ほど確認したDeploymentのステータス欄にはPodが1つ起動していることが確認できます。 このPodがNFSプロビジョナーを実行する実体(のコンテナ)となります。
1-4 デフォルトストレージクラスの設定
ストレージクラスとはPVの動的プロビジョニングを定義するために使用されます。ユーザーは必要なストレージクラスを指定して永続ボリューム要求(PVC)を作成します。
ストレージクラスの詳細については下記のドキュメントを参照してください。
デフォルトストレージクラスとは2つ以上のストレージクラスが存在する場合に標準的に使用されるストレージクラスのことです。 今回の構成ではストレージクラスは1つしか作成されていませんが、明示的に設定をしておくことで他のストレージクラスよりも優先的に利用するようにしておきます。
デフォルトストレージクラスを設定するには下記のコマンドを実行します。
今回はストレージクラス名:nfs-client
に対して通常のコンテナアプリケーションと仮想マシンの両方にデフォルト設定を行います。
$ oc patch storageclass nfs-client -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' $ oc patch storageclass nfs-client -p '{"metadata": {"annotations":{"storageclass.kubevirt.io/is-default-virt-class":"true"}}}'
設定が反映されているか下記のコマンドを実行して確認を行います。
oc get
コマンドで引数にstorageclass
を指定し、さらに-o yaml
オプションを追加して、ストレージクラスの設定内容をYAML形式で出力を行います。
$ oc get storageclass -o yaml
出力結果内のannotations:
に先ほど設定した値が反映されているか確認できます。下記の出力結果を展開して内容を確認ください。
出力結果を開く
$ oc get storageclass -o yaml apiVersion: v1 items: - allowVolumeExpansion: true apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: annotations: meta.helm.sh/release-name: nfs-subdir-external-provisioner meta.helm.sh/release-namespace: nfs-subdir-external-provisioner storageclass.kubernetes.io/is-default-class: "true" storageclass.kubevirt.io/is-default-virt-class: "true" creationTimestamp: "2024-06-28T07:10:00Z" labels: app: nfs-subdir-external-provisioner app.kubernetes.io/managed-by: Helm chart: nfs-subdir-external-provisioner-4.0.18 heritage: Helm release: nfs-subdir-external-provisioner name: nfs-client resourceVersion: "128018" uid: fd859079-dcb4-4b15-b1f2-747189033af2 parameters: archiveOnDelete: "true" provisioner: cluster.local/nfs-subdir-external-provisioner reclaimPolicy: Delete volumeBindingMode: Immediate kind: List metadata: resourceVersion: ""
1-5 動的プロビジョニングの動作テスト
NFSプロビジョナーの設定ができたので実際にサンプルのPodを実行して動的プロビジョニングの動作テストを行います。
(1)サンプルファイルのダウンロード
NFSプロビジョナーのリポジトリで公開されているサンプルのファイルをダウンロードします。 PVCとPodをそれぞれ実行するYAMLファイルをダウンロードします。
$ wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-claim.yaml $ wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-pod.yaml $ ls -d test-claim.yaml test-pod.yaml test-claim.yaml test-pod.yaml
(2)PVCの作成
oc create
コマンドでYAMLファイルからリソースを作成します。-f
オプションで読み込むYAMLファイルを指定します。
今回は前の作業からの流れのままプロジェクトは変更せずに行います。
$ oc create -f test-claim.yaml persistentvolumeclaim/test-claim created
Webコンソールの管理者向け表示のメニューから「ストレージ>PersistentVolumeClaims」を選択すると、作成されたPVCとバインドされたPVが一覧で表示されます。
このサンプルでは下記の情報が確認できます。
- PVC:test-claim
- PV:pvc-51702f11-4b99-451f-b2a1-109ab9e35557
- PVの容量:1 MiB
- 使用したストレージクラス:nfs-client
踏み台サーバー上のNFSエクスポートディレクトリを確認すると、PV用のディレクトリが自動で作成されていることが分かります。
$ tree /mnt/nfs/ /mnt/nfs/ └── nfs-subdir-external-provisioner-test-claim-pvc-51702f11-4b99-451f-b2a1-109ab9e35557 1 directory, 0 files
NFSサーバー上に作成されるディレクトリの命名規則はPVCのプロジェクト名(Namespace名)
-PVC名
-PV名
になります。
(3)Podの作成
作成されたPVを使用するサンプルのPodを起動します。PVCの作成と同様にoc create
コマンドを使用します。
$ oc create -f test-pod.yaml pod/test-pod created
Webコンソールの管理者向け表示のメニューから「Workloads>Pods」を選択すると、実行中のPodが一覧で表示されます。
サンプルのPod(test-pod
)のステータスがCompleted
になっており、このPodの実行が正常に完了したことが分かります。
Pod名のtest-pod
のリンクを選択するとPodの詳細画面が表示されます。
test-pod
コンテナがbusybox:stable
コンテナイメージから作成されており、状態がTerminated
になっており、すでに実行が終了していることが確認できます。
終了コードが0
になっており、このコンテナの実行が正常に終了したことが示されています。
また、このコンテナではPVはnfs-pvc
という名前でボリュームとして扱われており、コンテナ内の/mnt
ディレクトリにマウントされています。
このサンプルではコンテナの実行コマンドとしてtouch /mnt/SUCCESS
が実行されて成功すればexit 0
で終了するようにプログラムされています*3。
そのため、サンプルのPod起動後にNFSサーバー上のディレクトリを確認すると、コンテナの中で作成されたSUCCESS
ファイルが生成されていることが確認できます。
$ tree /mnt/nfs/ /mnt/nfs/ └── nfs-subdir-external-provisioner-test-claim-pvc-51702f11-4b99-451f-b2a1-109ab9e35557 └── SUCCESS 1 directory, 1 file
(4)サンプルのPodとPVの削除
作成したサンプルのPodとPVを削除する場合は下記のコマンドを実行します。
oc delete
コマンドでOpenShift上のリソースを削除します。
-f
オプションでYAMLファイルを指定し対象のリソースのみを削除できます。-f
オプションは複数指定可能で、今回はPodとPVを同時に削除します。
$ oc delete -f test-claim.yaml -f test-pod.yaml
PV削除後のNFSサーバー上の実体ディレクトリは下記のようになります。
$ tree /mnt/nfs/ /mnt/nfs/ └── archived-nfs-subdir-external-provisioner-test-claim-pvc-51702f11-4b99-451f-b2a1-109ab9e35557 └── SUCCESS 1 directory, 1 file
NFSプロビジョナーのデフォルト動作では、PV削除時のNFSサーバー上の実体ディレクトリはarchived-
が追加された名前にリネームされて保持されます。
これはストレージクラスの設定を出力することで確認できます。
OpenShift上のリソースから特定のセクションのパラメーターを取得する場合は、oc get
コマンドの出力を-o json
オプションによりJSON形式で出力し、パイプで繋いでjq
コマンドでパースします。
下記のコマンドでストレージクラスのparameters
セクションの値のみを取り出すことができます。
$ oc get storageclasses -o json | jq '.items[].parameters' { "archiveOnDelete": "true" }
parameters
セクションにarchiveOnDelete:true
で設定されているため、PVを削除した場合でも実体ディレクトリがアーカイブされて保持されます。
この設定をarchiveOnDelete:false
に変更することで、PVの削除と同時に実体ディレクトリを削除できます。
なお、NFSプロビジョナーのインストール後にストレージクラスのパラメーターは変更できません。
次の項目を参照してNFSプロビジョナーを削除し、再度インストールする時に--set storageClass.archiveOnDelete=false
オプションを追加してコマンドを実行してください。
(5)NFSプロビジョナーの削除
NFSプロビジョナーの削除を行う場合はhelm delete
コマンドを実行します。
helm delete
コマンドに引数としてnfs-subdir-external-provisioner
を指定して実行します。
$ helm delete nfs-subdir-external-provisioner release "nfs-subdir-external-provisioner" uninstalled
合わせてOpenShiftのプロジェクトを削除する場合は下記のコマンドを実行します。
oc delete project
コマンドに引数でプロジェクト名:nfs-subdir-external-provisioner
を指定して実行します。
$ oc delete project nfs-subdir-external-provisioner project.project.openshift.io "nfs-subdir-external-provisioner" deleted
プロジェクトを削除した場合、NFSプロビジョナーを再インストールする場合はサービスアカウントの作成から行う必要があります。
まとめ
汎用的なNFSサーバーをバックエンドとして、PVの動的プロビジョニングを行う方法としてNFSプロビジョナーの構築方法をご紹介しました。 PVの動的プロビジョニングを行うだけであればNFSプロビジョナーで十分ですが、OpenShift Virtualizationで仮想マシンのスナップショット機能には対応していません。 そのため、基本的にはNFSプロビジョナーと同様に構成して、Helmでインストールを行うことができる「NFS CSIドライバー」の利用を推奨します。 詳細は第3回:共有ストレージの作成(NFS CSIドライバーの構築)を参照ください。