Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。 この連載はvSphere環境上にOpenShift Container Platform(以下、OpenShift)およびOpenShift Virtualizationの環境を構築する方法を解説するシリーズです。
第3回は共有ストレージの作成について解説します。今後の連載予定は下記の通りです。
- 第1回:OpenShiftのインストール
- 第2回:OpenShiftインストール後の作業
- 第3回:共有ストレージの作成(NFS CSIドライバーの構築)(←本記事)
- 第4回:OpenShift Virtualizationのインストールと実行
- 第5回:vSphere仮想マシンの移行
- 【番外編】:共有ストレージの作成(NFSプロビジョナーの構築)
(2024/7/17追記:2つ目のディスクを/mnt/nfsにマウントする手順を追加しました)
(2024/7/23追記:NFS CSIドライバーを使用する内容に変更しました。以前の内容は番外編として別記事にしました。)
(2024/9/29追記:NFS CSIドライバーのアップデート方法を追加しました)
(2024/10/2追記:踏み台サーバーに2つ目のディスクを追加するコマンドを修正しました)
-目次-
- 共有ストレージの作成概要
- 前提条件
- 1. OpenShift Virtualizationに必要なストレージ
- 2. 踏み台サーバー上のNFSサーバー設定
- 3. NFS CSIドライバーの設定
- 4. イメージレジストリの設定
- まとめ
共有ストレージの作成概要
本記事ではOpenShift Virtualizationに必要な共有ストレージの作成を目的として、下記の内容を紹介します。
- OpenShift Virtualizationに必要なストレージ
- 踏み台サーバー上のNFSサーバー設定
- NFS CSIドライバーの設定
- イメージレジストリの設定
OpenShiftの標準サブスクリプションであるOpenShift Container Platform(OCP)やその下位エディションのOpenShift Kubernetes Engine(OKE)*1は複数ノードから書き込み可能な共有ストレージの機能は標準搭載していません。 通常はOpenShiftクラスター外部のストレージ製品を利用する形態でこれを構成します。 対して、OCPの上位エディションのOpenShift Platform Plus(OPP)*2にはOpenShift Data Foundation(ODF)*3が含まれます。このODFを使用することでOpenShiftをHCIで構成し共有ストレージを提供できるようになります(vSphereで言うところのvSANと同様のことができるとイメージください)。 ODFはOpenShiftに統合されたストレージであるため、実稼働環境における推奨されたストレージの選択です。
しかしながら、ODFはその構成上非常に多くのリソースを使用します。潤沢なリソースがない環境での利用は難しいため、今回の検証環境でODFは利用しません。 今回は1台のRHEL(または他のLinux等でも可)で構成できるNFSを利用したシンプルな共有ストレージを作成することとします。 なお、このストレージはあくまで検証用途であり、実稼働環境での利用はできませんのでご注意ください。*4
前提条件
- 連載第1回および第2回の作業を完了していることとします
- 全体の構成や各パラメーターなどは連載第1回を参照してください
- 作業用端末のプロンプトは
%
とします - 踏み台サーバーのプロンプトは
$
とします - 踏み台サーバーの作業は明示的に記載がある場合を除いて、作業ディレクトリ
${HOME}/work
で作業することとします
1. OpenShift Virtualizationに必要なストレージ
1-1 ストレージのアクセスモードについて
OpenShift Virtualizationに必要なストレージの要件についてはOpenShiftのインストールドキュメントに記載があります。 その一節にライブマイグレーションについての要件の記載があります。
ライブマイグレーションには共有ストレージが必要です。OpenShift Virtualizationのストレージは、ReadWriteMany(RWX)アクセスモードをサポートし、使用する必要があります。
ReadWriteMany(RWX)モードとは、複数のノードからの読み書き(ReadWrite)に対応したアクセスモードのことです。 対してReadWriteOnce (RWO)とは、1つのノードから読み書きに対応したアクセスモードです。
アクセスモードは他にもReadOnlyMany(ROX)やReadWriteOncePod(RWOP)がありますが本記事では詳細な解説は省略します。 OpenShiftが対応しているアクセスモードの詳細については下記ドキュメントの「表3.1 アクセスモード」を参照ください。
OpenShiftではブロック、ファイル、オブジェクトの3種類のストレージタイプに対応しており、RWXモードで利用可能なのはファイルかオブジェクトのタイプです。
OpenShiftで推奨されるストレージのタイプ
今回は構築が簡単なNFSを使ったファイルストレージを共有ストレージとして使用します。
1-2 永続ストレージ
OpenShiftがサポートするストレージのタイプは大別して2つのカテゴリーに大別されます。
- 一時ストレージ:Podとコンテナーが短期間のローカルストレージの操作に使用し、再起動や障害でデータが失われることを想定したストレージ
- 永続ストレージ:Podとコンテナーがデータの永続性を保証し、再起動や障害後もデータが保持されるストレージ
OpenShift Virtualizationでは仮想マシンのディスクが永続化されている必要があるため、使用するストレージのタイプは永続ストレージになります。 本記事では一時ストレージについては触れませんので、詳細は下記ドキュメントを参照ください。
1-3 永続ボリュームの動的プロビジョニング
OpenShiftでPodやコンテナで永続ストレージを利用する場合は永続ボリューム(PV)を利用します。 PVはOpenShiftクラスタ内で永続的なストレージリソースを提供するためのオブジェクトです。 また、PVはクラスタ全体で利用可能なストレージを抽象化し、コンテナのライフサイクルとは独立してデータを保存できます。
PVの動的プロビジョニングとは、必要なときに必要な量のストレージを自動的に割り当てる機能です。これにより、管理者は事前に大量のストレージを確保する必要がなくなり、効率的なリソース利用が可能となります。
[PVの動的プロビジョニングメリット]
- 自動化: 手動でのストレージ割り当ての手間が省ける。
- 効率化: 必要な分だけストレージを割り当てるため、無駄が少ない。
- スケーラビリティ: 必要に応じてストレージを増減できるため、システムのスケールアップ・ダウンが容易。
手動プロビジョニングと動的プロビジョニングのPV作成のフローを図で表したものが下記になります。
1-4 Container Storage Interface (CSI)
Container Storage Interface (CSI)は、異なるコンテナーオーケストレーションシステム間でコンテナーストレージを管理するためのAPI仕様です*5。 ストレージベンダーはCSIに準拠したプラグイン(ドライバー)を開発することで、他のコンテナーオーケストレーションシステムでもプラグインに対応したストレージが機能するようにします。 CSIはストレージを共通化した仕様で抽象化することにより、接続に必要な手順を一律化し、コンテナーオーケストレーションシステムが多様なストレージに対応が可能となります。
OpenShiftはKubernetesを拡張したものであり、純粋なアップストリーム版のKubernetes(いわゆるVanilla Kubernetes)と同様にCSIドライバーを利用できます。 このCSIドライバーを利用することでPVの動的プロビジョニングを行うことができます。
2. 踏み台サーバー上のNFSサーバー設定
今回の検証環境の構成では永続ストレージの元となるNFSサーバーは踏み台サーバー上で実行します。 そのために、まずはLinuxでNFSサーバーを実行する基本機能として、NFSのエクスポートを行います。
2-1 NFSサーバーの設定
NFSをエクスポートする基点となるディレクトリを作成します。
このディレクトリはOSの起動ディスクとは別のディスク上に作成することとします。
第1回で踏み台サーバーの仮想マシンに2つ目のディスクを追加していない場合は追加してください。
govc
コマンドで実行する場合は下記のコマンドを使用します。
踏み台サーバーに2つ目のディスクを追加します。
$ node=bastion $ govc vm.disk.create \ -vm ${node} \ -name "${node}/${node}_1.vmdk" \ -size 500G \ -thick=false \ -ds=NVMe
ディスクデバイスを確認します。 下記のように2つ目のディスクが追加されました。
$ govc device.ls -vm ${node} | grep disk disk-1000-0 VirtualDisk 104,857,600 KB disk-1000-1 VirtualDisk 524,288,000 KB
2つ目のディスクをOS上で使用できるようにし、/mnt/nfs
にマウントします。
下記のコマンドを実行します。(2つ目のディスクが/dev/sdbにあることとします)
$ sudo parted /dev/sdb --script mklabel gpt $ sudo parted /dev/sdb --script mkpart primary ext4 0% 100% $ sudo mkfs.ext4 /dev/sdb1 $ sudo mkdir -p /mnt/nfs $ echo '/dev/sdb1 /mnt/nfs ext4 defaults 0 0' | sudo tee -a /etc/fstab $ sudo systemctl daemon-reload $ sudo mount -a
正常にマウントされているか確認します。
$ df -h /mnt/nfs ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/sdb1 492G 28K 467G 1% /mnt/nfs
次に/etc/exports
ファイルにNFSエクスポート用の設定を追記します。
$ sudo vi /etc/exports /mnt/nfs 192.168.1.0/24(rw,async,no_subtree_check,no_root_squash)
exportfs -r
コマンドを使用して設定の検証を行います。設定に問題がなければ何も出力はされません。
$ sudo exportfs -r $
たとえば、エクスポートするディレクトリが見つからない場合は下記のエラーが出ます。
$ sudo exportfs -r exportfs: Failed to stat /mnt/nfs: No such file or directory
NFSエクスポートの設定に問題がなければファイアーウォールの設定を行います。 NFSで使用するポートをファイアーウォール設定に追記します。
$ sudo firewall-cmd --add-service nfs --permanent $ sudo firewall-cmd --reload
NFSサービスを自動起動サービスに登録し、同時に起動します。
$ sudo systemctl enable --now nfs-server
これでNFSサーバーの設定が完了しました。
3. NFS CSIドライバーの設定
踏み台サーバー上に構築したNFSサーバーを利用してPVの動的プロビジョニングを行うため、OpenShiftにNFS CSI driver for Kubernetes(以下、NFS CSIドライバー)をインストールします。
3-1 NFS CSIドライバーについて
OpenShiftでPVの動的プロビジョニングを行うためにはストレージとそれに対応したCSIドライバーが必要です。 今回構築したストレージはRHELで立てた汎用的なNFSサーバーなので専用のCSIドライバーがありません。 そこで今回は、汎用的なNFSサーバーをバックエンドに使用しPVの動的プロビジョニングを行うことができるNFS CSIドライバーを利用します。
このNFS CSIドライバーはKubernetes CSIでホストされているリポジトリの1つです。OSSで開発されておりApache-2.0 licenseに従い無償で利用できます。
kubernetes-csi/csi-driver-nfs: This driver allows Kubernetes to access NFS server on Linux node.
NFS CSIドライバーはfsGroupPolicy、Volume Snapshot、Volume Cloningに対応しています。
実稼働環境ではストレージベンダーなどの製品をご利用ください。
3-2 NFS CSIドライバーの動作
NFS CSIドライバーの動作の流れは下記の通りです
3-3 NFS CSIドライバーのインストール
NFS CSIドライバーをインストールする流れは下記のとおりです。
- Helmのインストール
- NFS CSIドライバーのインストール
現時点ではコマンドの詳細を深く理解する必要はありません。まずはおまじない的にコマンドをコピペして実行してください。
(1)Helmのインストール
NFS CSIドライバーのインストールでHelm*6を使用します。 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
(2)NFS CSIドライバーのインストール
NFS CSIドライバーはOpenShiftにインストールします。初めにチャートリポジトリを追加し、その後にインストールを行います。
helm repo add
コマンドでNFS CSIドライバーのチャートリポジトリを追加します。
実行コマンド
$ helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
実行コマンドと結果
$ helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts "csi-driver-nfs" has been added to your repositories
~/.config/helm
ディレクトリが作成され、参照するリポジトリの情報が保存されます
helm install
コマンドでNFS CSIドライバーをインストールします。
--version
オプションを使ってバージョンを指定します。(記事執筆時点での最新版はv4.8.0)
実行コマンド
$ helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace kube-system --version v4.8.0
--namespace kube-system
:インストール先のネームスペースにkube-system
を指定--version v4.8.0
:インストールするバージョンを指定。指定するバージョンはNFS CSIドライバーのリリースページ*7を参照のこと
helm install
コマンドを実行すると下記のような応答が出力されます
実行コマンドと結果
$ helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace kube-system --version v4.8.0 NAME: csi-driver-nfs LAST DEPLOYED: Fri Jul 19 10:40:55 2024 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: The CSI NFS Driver is getting deployed to your cluster. To check CSI NFS Driver pods status, please run: kubectl --namespace=kube-system get pods --selector="app.kubernetes.io/instance=csi-driver-nfs" --watch
NFS CSIドライバーが正常にインストールできたかどうかは次の手順で確認します。
(追記)NFS CSIドライバーのアップデート
NFS CSIドライバーのリリースページ*8で新しいバージョンがリリースされた場合は、helm repo update
を行うことで新しいバージョンのインストールを行うことができます。
下記はチャートリポジトリのアップデートを行い、v4.9.0
をインストールする手順です。
実行コマンド
$ helm repo update $ helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace kube-system --version v4.9.0
実行コマンドと結果
$ helm repo update Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "csi-driver-nfs" chart repository Update Complete. ⎈Happy Helming!⎈ $ helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace kube-system --version v4.9.0 NAME: csi-driver-nfs LAST DEPLOYED: Thu Sep 26 23:18:01 2024 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: The CSI NFS Driver is getting deployed to your cluster. To check CSI NFS Driver pods status, please run: kubectl --namespace=kube-system get pods --selector="app.kubernetes.io/instance=csi-driver-nfs" --watch
(3)NFS CSIドライバーのインストールの確認
OpenShiftのWebコンソールから「管理者向け表示」のプルダウンを選択し「開発者」を選択します。 これにより開発者向け表示(Developerパースペクティブ)に切り替えることができます。
左のメニューから「トポロジー」を選択します。プロジェクトのプルダウンメニューから「すべてのプロジェクト」を選択します。 「デフォルトプロジェクトの表示」スイッチをオンにします。
「デフォルトプロジェクトの表示」をオンにすることでOpenShift上の管理用のプロジェクトの選択が可能になります。
入力欄にkube-system
と入力して表示のフィルタリングを行い、プロジェクト欄に表示されたkube-system
を選択します。
画面内に「D」のアイコンがついたcsi-nfs-controller
というオブジェクト(Deployment)と、「DS」のアイコンがついたcsi-nfs-node
というオブジェクト(DaemonSet)が表示されます。
csi-nfs-controller
がNFS CSIドライバーの管理コンテナ、csi-nfs-node
が各ノード上で稼働する実行コンテナになります。
csi-nfs-controller
とcsi-nfs-node
の2つを合わせたものがcsi-driver-nfs
という名前のHelmチャートとしてデプロイされています。
左のメニューからHelmを選択すると、現在選択しているプロジェクトに登録済みのHelmリリース*9の情報が表示されます。
「HR」アイコンが付いたHelmリリース名(ここではcsi-driver-nfs
)のリンクを選択します。
リソースタブを選択すると、Helmでインストールされたリソースの名前やタイプが一覧で表示されます。
3-4 ストレージクラスとボリュームスナップショットクラスの作成
インストールしたNFS CSIドライバーを使ってPVの動的プロビジョニングを行うためにストレージクラス(StorageClass)を作成します。 ストレージクラスとはPVの動的プロビジョニングを定義するために使用されます。ユーザーは必要なストレージクラスを指定して永続ボリューム要求(PVC)を作成します。 ストレージクラスの詳細については下記のドキュメントを参照してください。
また、合わせてOpenShift Virtualizationで仮想マシンのスナップショットを取得するためのボリュームスナップショットクラス(VolumeSnapshotClass)も作成します。 ボリュームスナップショットについては下記のドキュメントを参照してください。
(1)ストレージクラスの作成
下記のコマンドでストレージクラスのカスタムリソースをstorageclass-nfs.yaml
という名前で作成します。
$ cat > storageclass-nfs.yaml <<EOF apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-csi provisioner: nfs.csi.k8s.io parameters: server: 192.168.1.206 share: /mnt/nfs reclaimPolicy: Delete volumeBindingMode: Immediate EOF
server: 192.168.1.206
:NFSサーバーのIPアドレス(またはホスト名)を指定しますshare: /mnt/nfs
:NFSサーバー上でエクスポートしているパス名を指定しますreclaimPolicy: Delete
:PVを削除した時にNFSサーバー上のデータを保持するかどうかを指定します。Delete
はPVCの削除と同時にPVも削除され、NFSサーバー上の実データも削除されます。- PVCの削除後もPVとして残す場合は
Retain
、PVは削除しつつもNFSサーバー上の実データを残す場合はArchive
を指定します。
- PVCの削除後もPVとして残す場合は
下記のコマンドでストレージクラスを作成します。
$ oc create -f storageclass-nfs.yaml
(2)ボリュームスナップショットクラスの作成
下記のコマンドでボリュームスナップショットクラスのカスタムリソースをsnapshotclass-nfs.yaml
という名前で作成します。
$ cat > snapshotclass-nfs.yaml <<EOF apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: csi-nfs-snapclass driver: nfs.csi.k8s.io deletionPolicy: Delete EOF
下記のコマンドでボリュームスナップショットクラスを作成します。
$ oc create -f snapshotclass-nfs.yaml
3-5 デフォルトストレージクラスの設定
デフォルトストレージクラスとは2つ以上のストレージクラスが存在する場合に標準的に使用されるストレージクラスのことです。 今回の構成ではストレージクラスは1つしか作成されていませんが、明示的に設定をしておくことで他のストレージクラスよりも優先的に利用するようにしておきます。
デフォルトストレージクラスを設定するには下記のコマンドを実行します。
今回はストレージクラス名:nfs-csi
に対して通常のコンテナアプリケーションと仮想マシンの両方にデフォルト設定を行います。
$ oc patch storageclass nfs-csi -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' $ oc patch storageclass nfs-csi -p '{"metadata": {"annotations":{"storageclass.kubevirt.io/is-default-virt-class":"true"}}}'
同様にデフォルトボリュームスナップショットクラスを設定するコマンドを実行します。
ボリュームスナップショットクラス名はcsi-nfs-snapclass
を指定します。
$ oc patch volumesnapshotclass csi-nfs-snapclass --type merge -p '{"metadata": {"annotations":{"snapshot.storage.kubernetes.io/is-default-class":"true"}}}' $ oc patch volumesnapshotclass csi-nfs-snapclass --type merge -p '{"metadata": {"annotations":{"snapshot.storage.kubevirt.io/is-default-virt-class":"true"}}}'
設定が反映されているか下記のコマンドを実行して確認を行います。
oc get
コマンドで引数にstorageclass
とnfs-csi
を指定し、さらに-o yaml
オプションを追加して、ストレージクラスの設定内容をYAML形式で出力を行います。
$ oc get storageclass nfs-csi -o yaml
出力結果内のannotations:
に先ほど設定した値が反映されているか確認できます。下記の出力結果を展開して内容を確認ください。
出力結果を開く
$ oc get storageclass nfs-csi -o yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: annotations: storageclass.kubernetes.io/is-default-class: "true" storageclass.kubevirt.io/is-default-virt-class: "true" creationTimestamp: "2024-07-23T05:35:49Z" name: nfs-csi resourceVersion: "596631" uid: 86a54044-89fa-4f49-8c35-6c5bc6cff696 parameters: server: 192.168.1.206 share: /mnt/nfs provisioner: nfs.csi.k8s.io reclaimPolicy: Delete volumeBindingMode: Immediate
同様にボリュームスナップショットクラスの設定内容を確認します。
oc get
コマンドの引数はvolumesnapshotclass
をcsi-nfs-snapclass
指定します。
$ oc get volumesnapshotclass csi-nfs-snapclass -o yaml
出力結果を開く
$ oc get volumesnapshotclass csi-nfs-snapclass -o yaml apiVersion: snapshot.storage.k8s.io/v1 deletionPolicy: Delete driver: nfs.csi.k8s.io kind: VolumeSnapshotClass metadata: annotations: snapshot.storage.kubernetes.io/is-default-class: "true" snapshot.storage.kubevirt.io/is-default-virt-class: "true" creationTimestamp: "2024-07-23T05:37:13Z" generation: 1 name: csi-nfs-snapclass resourceVersion: "597248" uid: 774868f9-23f8-46c7-b02e-bf832d6c31ec
3-6 動的プロビジョニングの動作テスト
NFS CSIドライバーの設定ができたので実際にサンプルのDeploymentを実行して動的プロビジョニングの動作テストを行います。
(1)サンプルファイルのダウンロード
NFSプロビジョナーのリポジトリで公開されているサンプルのファイルをダウンロードします。 PVCとPodの実行が定義されたDeploymentのYAMLファイルをダウンロードします。
$ wget https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/deploy/example/deployment.yaml $ ls -d deployment.yaml deployment.yaml
(2)PVCとPodの作成
oc create
コマンドでYAMLファイルからリソースを作成します。-f
オプションで読み込むYAMLファイルを指定します。
最初にテスト実行用のプロジェクトを作成し、そのプロジェクト内にリソースを作成します。
下記のコマンドでプロジェクトを新規作成します。名前はtest
とします。
実行コマンド
$ oc new-project test
実行コマンドと結果
$ oc new-project test Now using project "test" on server "https://api.ocp.home.lab:6443". You can add applications to this project with the 'new-app' command. For example, try: oc new-app rails-postgresql-example to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application: kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.43 -- /agnhost serve-hostname
続けてDeploymentリソースを作成します。
実行コマンド
$ oc create -f deployment.yaml
実行コマンドと結果
$ oc create -f deployment.yaml persistentvolumeclaim/pvc-deployment-nfs created deployment.apps/deployment-nfs created
PVCとPodの実行を定義したDeploymentが作成されました。
(3)確認
Webコンソールの管理者向け表示のメニューから「ストレージ>PersistentVolumeClaims」を選択すると、作成されたPVCとバインドされたPVが一覧で表示されます。
「プロジェクト」選択プルダウンからtest
を選ぶと、先ほど作成したtest
プロジェクト上に作成されたPVCが表示されます。
このサンプルでは下記の情報が確認できます。
- PVC:pvc-deployment-nfs
- PV:pvc-43c68d68-95f2-4b2a-99cf-4eef0debba39
- PVの容量:10 GiB
- 使用したストレージクラス:nfs-csi
踏み台サーバー上のNFSエクスポートディレクトリを確認すると、PV用のディレクトリが自動で作成されていることが分かります。
$ tree /mnt/nfs/ /mnt/nfs/ └── pvc-43c68d68-95f2-4b2a-99cf-4eef0debba39 └── outfile 1 directory, 1 file
NFSサーバー上に作成されるディレクトリの命名規則は
PV名
と同じものになります。
Webコンソールの管理者向け表示のメニューから「Workloads>Pods」を選択すると、実行中のPodが一覧で表示されます。
サンプルのPod(deployment-nfs-7579c47f6-r6zbq
)のステータスがRunning
になっており、このPodが正常に実行していることが分かります。
Pod名のdeployment-nfs-7579c47f6-r6zbq
のリンクを選択するとPodの詳細画面が表示されます。
このコンテナがmcr.microsoft.com/oss/nginx/nginx
コンテナイメージから作成されていて状態がRunning
になっており、コンテナの実行が継続していることが確認できます。
また、このコンテナではPVはnfs
という名前でボリュームとして扱われており、コンテナ内の/mnt/nfs
ディレクトリに読み書き可能でマウントされています。
このサンプルではコンテナの実行コマンドとしてホスト名と日時を1秒ごとにループで書き込み続けるようにプログラムされています*10。
そのため、サンプルのPod起動後にNFSサーバー上のディレクトリを確認すると、コンテナの中で作成されたoutfile
ファイルに継続的にデータが書き込み続けていることが分かります。
$ tail -f /mnt/nfs/pvc-43c68d68-95f2-4b2a-99cf-4eef0debba39/outfile deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:02 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:03 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:04 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:05 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:06 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:07 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:08 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:09 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:10 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:11 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:12 UTC 2024 deployment-nfs-7579c47f6-r6zbq Tue Jul 23 08:04:13 UTC 2024 ...
(4)サンプルのPodとPVの削除
作成したサンプルのPodとPVを削除する場合は下記のコマンドを実行します。
oc delete project
コマンドでプロジェクトごとOpenShift上のリソースを削除します。
実行コマンド
$ oc delete project test
実行コマンドと結果
$ oc delete project test project.project.openshift.io "test" deleted
実行中のコンテナが強制的に停止し、すべてのリソースが削除するまで数十秒程度かかります。
PV削除後のNFSサーバー上の実体ディレクトリは下記のようになります。
$ tree /mnt/nfs/ /mnt/nfs/ 0 directories, 0 files
PV削除と同時に実体のディレクトリも削除されます
(5)NFS CSIドライバーの削除
NFS CSIドライバーの削除を行う場合はhelm delete
コマンドを実行します。
helm delete
コマンドに引数としてcsi-driver-nfs
とネームスペースにkube-system
を指定して実行します。
$ helm uninstall csi-driver-nfs -n kube-system
4. イメージレジストリの設定
NFS CSIドライバーを設定したことで永続ボリュームを利用できるようになりました。 次は、OpenShiftのインストール後の作業の1つであるイメージレジストリの設定を行います。
この作業はストレージの設定が事前に必要なため、第2回のインストール後の作業では対象外としました
4-1 イメージレジストリーの構成
イメージレジストリはOpenShiftの内部で実行されるコンテナレジストリーです。 イメージレジストリーはパブリックなコンテナレジストリーと同様に、OpenShift上でビルドしたコンテナイメージを登録したり、登録したコンテナイメージからコンテナを実行できます。 また、OpenShiftの外部との接続口(ルート)を作成することでイメージレジストリーを外部へ公開できます。
イメージレジストリーの設定方法はOpenShiftのインストールドキュメントに記載があります。下記のドキュメントを参照してください。
実稼働環境におけるレジストリーの推奨ストレージはオブジェクトストレージです(次点はブロックストレージ)。 本記事で紹介するファイルストレージを使った構成はあくまで検証用途での利用を前提としています。
ファイルストレージは、実稼働ワークロードを使用した OpenShift イメージレジストリークラスターのデプロイメントには推奨されません。
4-2 イメージレジストリーの設定
まず、現在のイメージレジストリーの設定を確認します。
下記のコマンドでconfigs.imageregistry.operator.openshift.io
のリソースからstorage
とmanagementState
の値を取得します。
実行コマンド
$ oc get configs.imageregistry.operator.openshift.io -o json | jq '.items[] | {storage: .spec.storage, managementState: .spec.managementState}'
実行コマンドと結果
$ oc get configs.imageregistry.operator.openshift.io -o json | jq '.items[] | {storage: .spec.storage, managementState: .spec.managementState}' { "storage": {}, "managementState": "Removed" }
storage
は空の値、managementState
はRemoved
がセットされています。
次に、下記のコマンドを実行してレジストリーPodが存在しないことを確認します。
oc get pod
コマンドで-l
オプションを使用し、ラベルがdocker-registry=default
であるポッドをフィルタリングします。
実行コマンド
$ oc get pod -n openshift-image-registry -l docker-registry=default
実行コマンドと結果
$ oc get pod -n openshift-image-registry -l docker-registry=default No resources found in openshift-image-registry namespace.
イメージレジストリーがまだ設定されていないことが確認できました。下記のコマンドを実行し、イメージレジストリーを有効化します。
実行コマンド
$ oc patch config.imageregistry.operator.openshift.io/cluster --type merge -p '{"spec":{"storage":{"pvc":{"claim":""}}}}' $ oc patch config.imageregistry.operator.openshift.io/cluster --type merge -p '{"spec":{"managementState":"Managed"}}'
実行コマンドと結果
$ oc patch config.imageregistry.operator.openshift.io/cluster --type merge -p '{"spec":{"storage":{"pvc":{"claim":""}}}}' config.imageregistry.operator.openshift.io/cluster patched $ oc patch config.imageregistry.operator.openshift.io/cluster --type merge -p '{"spec":{"managementState":"Managed"}}' config.imageregistry.operator.openshift.io/cluster patched
コマンドの実行後、先ほどの設定を再度確認します。
claim
にimage-registry-storage
の値が自動で追加されています。
実行コマンド
$ oc get configs.imageregistry.operator.openshift.io -o json | jq '.items[] | {storage: .spec.storage, managementState: .spec.managementState}'
実行コマンドと結果
$ oc get configs.imageregistry.operator.openshift.io -o json | jq '.items[] | {storage: .spec.storage, managementState: .spec.managementState}' { "storage": { "managementState": "Managed", "pvc": { "claim": "image-registry-storage" } }, "managementState": "Managed" }
しばらくしてからレジストリーPodを確認すると、下記のように先ほどは無かったレジストリーPodが起動していることが分かります。
$ oc get pod -n openshift-image-registry -l docker-registry=default NAME READY STATUS RESTARTS AGE image-registry-5cd6bf8ddf-mgkpm 1/1 Running 0 53s
デフォルトではレジストリーPodのレプリカ数は1で実行されます。 PVのアクセスモードがRWXをサポートしている場合はレジストリーPodのレプリカ数を2にして高可用性構成が可能です。
下記のコマンドを実行して自動で作成されたPVCとPVの設定を確認します。 イメージレジストリーのPVはデフォルトで100GiBの容量を使用します。
$ oc get pvc -n openshift-image-registry NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE image-registry-storage Bound pvc-b3c88568-404c-40c1-a4c8-d252b804a9fc 100Gi RWX nfs-csi <unset> 2m4s $ oc get pv -n openshift-image-registry NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-b3c88568-404c-40c1-a4c8-d252b804a9fc 100Gi RWX Delete Bound openshift-image-registry/image-registry-storage nfs-csi <unset> 2m11s
4-3 レジストリーの公開
OpenShift上で起動したイメージレジストリーを外部から利用できるように公開設定を行います。 イメージレジストリーの公開方法のドキュメントは下記です。
下記のコマンドを実行してイメージレジストリーを公開します。
実行コマンド
$ oc patch configs.imageregistry.operator.openshift.io/cluster --type=merge -p '{"spec":{"defaultRoute":true}}'
実行コマンドと結果
$ oc patch configs.imageregistry.operator.openshift.io/cluster --type=merge -p '{"spec":{"defaultRoute":true}}' config.imageregistry.operator.openshift.io/cluster patched
イメージレジストリーの公開後、下記のコマンドで接続するためのURL(HOST/PORT
)を確認できます。
$ oc get route default-route -n openshift-image-registry NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD default-route default-route-openshift-image-registry.apps.ocp.home.lab image-registry <all> reencrypt None
4-4 レジストリーの操作
(1)ログイン
外部のコンテナツール(今回はPodmanを使用します)から公開したイメージレジストリーを利用するためにはコンテナレジストリーへのログインが必要です。 下記のコマンドを実行してコンテナレジストリーへのログインを行います。
イメージレジストリーのURLを取得しHOST
環境変数へセットします。
$ HOST=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}') $ echo ${HOST} default-route-openshift-image-registry.apps.ocp.home.lab
Ingress Operatorの証明書を取得してシステムの信頼された証明書ストアに追加することで、イメージレジストリーへのHTTPSでのアクセスを行えるようにします。
oc get secret
で証明書を取得し、踏み台サーバー上の証明書ストアに保存します。
$ oc get secret -n openshift-ingress router-certs-default -o go-template='{{index .data "tls.crt"}}' | base64 -d | sudo tee /etc/pki/ca-trust/source/anchors/${HOST}.crt > /dev/null
信頼されたルート証明書の一覧を更新します。
$ sudo update-ca-trust enable
podman login
コマンドを実行しイメージレジストリーへログインを行います。
ログインに使用するユーザーはocpadmin
を使用します。
ocpadmin
でログインしていない場合は事前にoc login
を実行します(連載第2回を参照)。
$ unset KUBECONFIG $ oc login -u ocpadmin https://api.ocp.home.lab:6443 $ podman login -u ocpadmin -p $(oc whoami -t) ${HOST}
Login Succeeded!
が表示されたらログイン成功です。
(2)イメージのプッシュ
Podmanでサンプルのコンテナイメージを作成し、イメージレジストリーへプッシュします。
下記のコマンドを実行し、ベースイメージにUBI9を使用したContainerfileを作成します。
$ cat > Containerfile <<EOF FROM ubi9 RUN echo "hello" | tee hello.txt EOF
podman build
コマンドでコンテナイメージをビルドします。
$ podman build -t ${HOST}/openshift/push-test .
出力結果を開く
$ podman build -t ${HOST}/openshift/push-test . STEP 1/2: FROM ubi9 Resolved "ubi9" as an alias (/etc/containers/registries.conf.d/001-rhel-shortnames.conf) Trying to pull registry.access.redhat.com/ubi9:latest... Getting image source signatures Checking if image destination supports signatures Copying blob f50ab65647ec done | Copying config e9beb314b7 done | Writing manifest to image destination Storing signatures STEP 2/2: RUN echo "hello" | tee hello.txt hello COMMIT default-route-openshift-image-registry.apps.ocp.home.lab/openshift/push-test --> 4d7c9eb63a75 Successfully tagged default-route-openshift-image-registry.apps.ocp.home.lab/openshift/push-test:latest 4d7c9eb63a75563e6c4deee82d472ddf5fd0770ca4850b0e2e379ee03fe280fc
podman push
コマンドでコンテナイメージをプッシュします。
$ podman push ${HOST}/openshift/push-test
出力結果を開く
$ podman push ${HOST}/openshift/push-test Getting image source signatures Copying blob 09a48287d5f7 done | Copying blob f36b8ecab85c done | Copying config 4d7c9eb63a done | Writing manifest to image destination
(3)プッシュしたイメージの確認
Skopeoを使ってプッシュしたコンテナイメージがイメージレジストリーに登録されているか確認します。
下記のコマンドを実行します。
すでにpodamn login
を実行しているためskopeo login
の実行は不要です(SkopeoはPodmanのログイン情報を利用できます)。
$ skopeo inspect docker://${HOST}/openshift/push-test
下記を展開して出力結果を確認ください。
出力結果を開く
$ skopeo inspect docker://${HOST}/openshift/push-test { "Name": "default-route-openshift-image-registry.apps.ocp.home.lab/openshift/push-test", "Digest": "sha256:4c537beccd99c1853f7e242dcfab054cbaf0bf5535233bcb2ac24335f2f8492f", "RepoTags": [ "latest" ], "Created": "2024-07-09T21:16:33.272504929Z", "DockerVersion": "", "Labels": { "architecture": "x86_64", "build-date": "2024-06-28T07:36:05", "com.redhat.component": "ubi9-container", "com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI", "description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.", "distribution-scope": "public", "io.buildah.version": "1.33.7", "io.k8s.description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.", "io.k8s.display-name": "Red Hat Universal Base Image 9", "io.openshift.expose-services": "", "io.openshift.tags": "base rhel9", "maintainer": "Red Hat, Inc.", "name": "ubi9", "release": "1123.1719560047", "summary": "Provides the latest release of Red Hat Universal Base Image 9.", "url": "https://access.redhat.com/containers/#/registry.access.redhat.com/ubi9/images/9.4-1123.1719560047", "vcs-ref": "92a4a475241865d0d11bd861fb2b29fbd9b17df0", "vcs-type": "git", "vendor": "Red Hat, Inc.", "version": "9.4" }, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:f50ab65647ec96ba313779f24c41e04bc6fde3e3ee79ee377ea8fd1901b896d5", "sha256:68513cceebd5b717b7e307a2c2ff646147e5a84b16657755c25da1be2732bf15" ], "LayersData": [ { "MIMEType": "application/vnd.oci.image.layer.v1.tar+gzip", "Digest": "sha256:f50ab65647ec96ba313779f24c41e04bc6fde3e3ee79ee377ea8fd1901b896d5", "Size": 79313334, "Annotations": null }, { "MIMEType": "application/vnd.oci.image.layer.v1.tar+gzip", "Digest": "sha256:68513cceebd5b717b7e307a2c2ff646147e5a84b16657755c25da1be2732bf15", "Size": 270, "Annotations": null } ], "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "container=oci" ] }
Webコンソール上で確認する場合は、メニューの「Builds>ImageStreams」を選択します。
イメージレジストリーに登録されているイメージの一覧が表示されます。
名前で検索できますのでプッシュしたイメージ名:push-test
を入力します。
push-test
のリンクを選択するとイメージの詳細画面が表示されます。
パブリックイメージリポジトリーに表示されているURLが、OpenShiftの外部からこのイメージをプルする時のURLになります。
(4)OpenShift上のイメージをプルする
OpenShift上のイメージをローカルにプルするテストを行います。
ローカルにあるコンテナイメージを削除します。
$ podman images $ podman rmi push-test:latest
出力結果を開く
$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE default-route-openshift-image-registry.apps.ocp.home.lab/openshift/push-test latest 4d7c9eb63a75 19 minutes ago 220 MB registry.access.redhat.com/ubi9 latest e9beb314b7a2 11 days ago 220 MB $ podman rmi push-test:latest Untagged: default-route-openshift-image-registry.apps.ocp.home.lab/openshift/push-test:latest Deleted: 4d7c9eb63a75563e6c4deee82d472ddf5fd0770ca4850b0e2e379ee03fe280fc
podman pull
コマンドでイメージをプルします。
$ podman pull ${HOST}/openshift/push-test $ podman images
出力結果を開く
$ podman pull ${HOST}/openshift/push-test Trying to pull default-route-openshift-image-registry.apps.ocp.home.lab/openshift/push-test:latest... Getting image source signatures Copying blob f50ab65647ec skipped: already exists Copying blob 68513cceebd5 done | Copying config 4d7c9eb63a done | Writing manifest to image destination 4d7c9eb63a75563e6c4deee82d472ddf5fd0770ca4850b0e2e379ee03fe280fc $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE default-route-openshift-image-registry.apps.ocp.home.lab/openshift/push-test latest 4d7c9eb63a75 21 minutes ago 220 MB registry.access.redhat.com/ubi9 latest e9beb314b7a2 11 days ago 220 MB
イメージレジストリー上のイメージをプルすることができました。
まとめ
OpenShift Virtualizationで使用するための共有ストレージの作成を行いました。 汎用的なNFSサーバーをバックエンドに使用し、NFS CSIドライバーを使用することでPVの動的なプロビジョニングが行えます。 このストレージはOpenShift Virtualization以外でも使用できるため、イメージレジストリーのイメージ保存用のストレージの設定を行いました。 また、イメージレジストリーを公開設定を行うことにより、OpenShiftの外部からイメージをプッシュ、プルできるようになります。 第1回からここまでの作業でようやくOpenShift Virtualizationのインストールを行う準備が整いました。 次はいよいよOpenShift Virtualizationの設定になります。
(次回予告) 次回はOpenShift Virtualizationのインストールと仮想マシンの実行方法について解説します。
*1:Red Hat OpenShift Kubernetes Engine | Red Hat
*2:Red Hat OpenShift Platform Plus とは?をわかりやすく解説
*3:Red Hat OpenShift Data Foundation | Red Hat
*4:7.1.2.1. 特定アプリケーションのストレージの推奨事項を参照 第7章 スケーラビリティとパフォーマンスの最適化 | Red Hat Product Documentation
*5:container-storage-interface/spec: Container Storage Interface (CSI) Specification.
*7:Releases · kubernetes-csi/csi-driver-nfs
*8:Releases · kubernetes-csi/csi-driver-nfs
*9:OpenShift上にHelmでデプロイされたアプリケーションやサービスのインスタンスのこと
*10:詳細を知りたい方はdeployment.yamlファイルの中身を参照ください