はじめに
前回の記事では、Single Node構成での永続データを利用できるStorage基盤の作成について記載しました。
本記事では追加の内容として、OpenShiftクラスターとStorage間でNFS通信を行うためのNetworkを個別に設定してTraidentを利用する内容になります。
アプリケーション用PODに複数のNetworkを持たせるという内容では無いです。
何をしたい?できる?
- NMState Operator設定とStorage通信用のNIC設定
- TridentBackendでは管理とデータのネットワークを分ける
- PODを作成してPVを使用している事の確認
NMState Operator(Kubernetes NMState Operator)とは
NMState Operator(Kubernetes NMState Operator)は、Kubernetes環境やOpenShiftクラスターにおいて、各Node(ホスト)のNetwork設定を「宣言的(マニフェスト記述)」に自動化・一元管理されます。
また、NMState Operator構築後にNodeNetworkConfigurationPolicy (NNCP) の設定を実施しますが、NMCPとはクラスターを構成する各NodeのNetwork設定を定義するカスタムリソースで、ブリッジ接続やVLAN設定、NICのチーミング、Nodeへ固定IPの付与などを行う際に使用されるものとなります。
記事における環境情報
本記事では、以下の環境で実施した内容となります。
OSやモジュールは以下の構成としています。
- ONTAP 9.17.1
- NetApp Trident 26.02.1
- Windows Server 2025 Hyper-V環境
- Red Hat Enterprise Linux 9.8
- OpenShift 4.21.16
踏み台サーバはStorage用の通信と疎通できるようにNIC及びIPは設定済となってます。
設定手順
設定の流れとしては以下のような形になります。
1. 前回の記事の管理とデータが同一Network環境時におけるTridentの設定の削除
2. OpenShift用の Single NodeにNIC追加とNMState Operatorの導入+設定
3. PV作成用のNFS Storageの設定を修正
4. Tridentの設定+POD作成
1. 前回の記事の設定を削除
本記事では、前回のTrident Backendの設定が残っている環境を利用するので、踏み台サーバから設定の削除を実施します。
PersistentVolumeClaimの削除を実施します。
# 状態の確認
> oc get pvc -n testspace01
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-nas Bound pvc-fcf6f7b4-cc50-430d-9013-13bbbcd596e6 2Gi RWX ontap-nas-class <unset> 2d4h
# 削除の実施
> oc delete pvc pvc-nas -n testspace01
persistentvolumeclaim "pvc-nas" deleted from testspace01 namespace
storageclassの削除を実施します。
# 状態の確認
> oc get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ontap-nas-class csi.trident.netapp.io Delete Immediate true 2d4h
# 削除の実施
> oc delete storageclass ontap-nas-class
storageclass.storage.k8s.io "ontap-nas-class" deleted
Trident Backendの削除を実施します。
# 状態の確認
> oc get tbc -n trident
NAME BACKEND NAME BACKEND UUID PHASE STATUS
ontap-nfs-backend-tbc ontap-nas-backend 9fb91550-de6a-4ccd-aa8f-cf2d90eff3aa Bound Success
# 削除の実施
> oc delete tbc ontap-nfs-backend-tbc -n trident
tridentbackendconfig.trident.netapp.io "ontap-nfs-backend-tbc" deleted from trident namespace
2. 追加のNetwork設定
2-1. Single Nodeの仮想マシンへNIC追加
OpenShiftのSingle Nodeで構築した仮想マシンの設定でVLAN 21のNetworkに繋がるNetworkアダプターを追加します。
「仮想LANを有効にする」のチェックボックスをオンにしてVLAN IDを設定すると、仮想マシンが送出するイーサネットフレームに指定したVLAN IDを記述したVLANタグが付与されます。
つまり、仮想マシンのLinux OS上ではvlan設定が不要という事です。
OpenShiftのGUI画面にアクセスし、左側の[コンピュート]から[Nodes]をクリックします。
表示された画面でNodeを選択し、[ターミナル]タブでNICを認識している事を確認します。
踏み台からocコマンドで確認する際には、以下のように確認できます。
# 接続先Nodeの確認
> oc get node
NAME STATUS ROLES AGE VERSION
master01.ocp100.example.org Ready control-plane,master,worker 2d14h v1.34.7
# debug nodeで接続
> oc debug node/master01.ocp100.example.org
Starting pod/master01ocp100exampleorg-debug-njblh ...
(中略)
If you don't see a command prompt, try pressing enter.
sh-5.1# <==プロンプトが変更している事の確認
sh-5.1# chroot /host
sh-5.1# ip a s eth1
226: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:d7:09:30 brd ff:ff:ff:ff:ff:ff
inet6 fe80::cd0:fe5e:7d31:a853/64 scope link noprefixroute
valid_lft forever preferred_lft forever
勿論、SSH接続を利用して確認する事もできます。
(本記事ではuser01で操作しており、OpenShift Install時にuser01の公開鍵を登録してます)
# SSHで公開鍵を使って接続
> ssh -i /home/user01/.ssh/id_rsa core@master01.ocp100.example.org
Red Hat Enterprise Linux CoreOS 9.6.20260510-0
Part of OpenShift 4.21, RHCOS is a Kubernetes-native operating system
managed by the Machine Config Operator (`clusteroperator/machine-config`).
(中略)
# 追加NICの確認
> ip a s eth1
226: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:d7:09:30 brd ff:ff:ff:ff:ff:ff
2-2. NMState Operatorインストール及びNMStateの作成
OpenShiftクラスター上で ノードのNetwork設定を管理するためのオペレーターであるNMStateの導入を実施します。
OpenShiftのGUI画面にアクセスし、左側の[エコシステム]から[ソフトウェアカタログ]をクリックします。
表示された画面でNMStateと入力し、表示される[Kubernetes NMState Operator]をクリックします。
表示された画面で値を変更することなく[インストール]をクリックします。

peratorインストールが完了後、[Operatorの表示]をクリックします。

[NMState]タブをクリックし、表示された画面で[NMStateの作成]をクリックします。
NMState の作成では、値を変更せずに、画面下方の[作成]をクリックします。

管理画面にログインし直すと、画面左側の[ネットワーク]の項目が増えている点が確認できます。

2-3. NodeNetworkConfigurationPolicy (NNCP) の適用
NMCPとはクラスターを構成する各NodeのNetwork設定を定義するカスタムリソースで、ブリッジ接続やVLAN設定、NICのチーミング、Nodeへ固定IPの付与などを行う際に使用します。
本記事の環境では、yamlファイルを作成し、踏み台サーバから設定を実施します。
# 追加NICにIPを付与しているNodeNetworkConfigurationPolicyを作成
> cat nncp-storage.yaml
apiVersion: nmstate.io/v1
kind: NodeNetworkConfigurationPolicy
metadata:
name: storage-net
spec:
nodeSelector:
kubernetes.io/hostname: master01.ocp100.example.org
desiredState:
interfaces:
- name: eth1
type: ethernet
state: up
ipv4:
enabled: true
address:
- ip: 172.16.21.45
prefix-length: 24
作成したPolicyを適用し、nncpがocコマンドで表示される事を確認します。
# 適用前は何も表示されない事の確認
> oc get nncp
No resources found
> oc get nnce
No resources found
# Policyを適用
> oc apply -f nncp-storage.yaml
nodenetworkconfigurationpolicy.nmstate.io/storage-net created
# リソースが表示される事の確認
> oc get nncp
NAME STATUS REASON
storage-net Available SuccessfullyConfigured
> oc get nnce
NAME STATUS STATUS AGE REASON
master01.ocp100.example.org.storage-net Available 59s SuccessfullyConfigured
# OpenShiftのSingle Nodeへpingを飛ばして疎通確認
> ping -c 2 172.16.21.45
PING 172.16.21.45 (172.16.21.45) 56(84) bytes of data.
64 バイト応答 送信元 172.16.21.45: icmp_seq=1 ttl=64 時間=0.365ミリ秒
64 バイト応答 送信元 172.16.21.45: icmp_seq=2 ttl=64 時間=0.378ミリ秒
--- 172.16.21.45 ping 統計 ---
送信パケット数 2, 受信パケット数 2, 0% packet loss, time 1029ms
rtt min/avg/max/mdev = 0.365/0.371/0.378/0.006 ms
3. PV作成用のNFS Storageの設定修正
本記事では既にNFS用SVMは作成されてますが、Storage通信用の172.16.21.0/24を使ってデータ通信を行うようになってないので、LIFの修正を実施します。
前回の記事でTrident Operator作成時にhostNetworkの有効化設定を記載していないので、本記事ではデータ通信用のLIFのみが172.16.21.0/24を使用して通信する事ができます。(管理LIFで171.16.21.0/24を使用してもAPI通信には失敗します)
3-1. NFS用のSVMへLIFの修正
データ通信用のLIFのIPや通信に利用するPortの修正を実施します。
# 設定情報の確認
> network interface show -vserver nfs100
Logical Status Network Current Current Is
Vserver Interface Admin/Oper Address/Mask Node Port Home
----------- ---------- ---------- ------------------ ------------- ------- ----
nfs100
data up/up 10.11.100.48/24 PS-A400-01 a0a true
manage up/up 10.11.100.47/24 PS-A400-01 a0a true
2 entries were displayed.
# LIFの修正
> net int modify -vserver nfs100 -lif data -service-policy default-data-files -address 172.16.21.47 -netmask 255.255.255.0 -home-node PS-A400-01 -home-port a0a-21
(network interface modify)
Warning: Changing the home port to a new broadcast domain may result in a momentary loss of connectivity while the LIF
is moved to the new port.
Do you want to continue? {y|n}: y
# 設定情報の確認
> network interface show -vserver nfs100
Logical Status Network Current Current Is
Vserver Interface Admin/Oper Address/Mask Node Port Home
----------- ---------- ---------- ------------------ ------------- ------- ----
nfs100
data up/up 172.16.21.47/24 PS-A400-01 a0a-21 true
manage up/up 10.11.100.47/24 PS-A400-01 a0a true
2 entries were displayed.
4. NetApp Tridentの設定
4-1. Trident Backendの設定
dataLIFの部分は、今回追加している172.16.21.47を指定します。
# マニフェスト
> cat trident-tbc-nfs.yaml
apiVersion: trident.netapp.io/v1
kind: TridentBackendConfig
metadata:
name: ontap-nfs-backend-tbc
namespace: trident
spec:
version: 1
backendName: ontap-nas-backend
storageDriverName: ontap-nas
managementLIF: 10.11.100.47
dataLIF: 172.16.21.47
svm: nfs100
credentials:
name: ontap-svm-admin
defaults:
spaceReserve: none
exportPolicy: default
# 作成したファイルの適用
> oc apply -f trident-tbc-nfs.yaml -n trident
tridentbackendconfig.trident.netapp.io/ontap-nfs-backend-tbc created
# 作成後の確認
> oc get tridentbackend -n trident
NAME BACKEND NAME BACKEND UUID PHASE STATUS
ontap-nfs-backend-tbc ontap-nas-backend c2a6447a-0e99-468b-b175-1318357243f1 Bound Success
4-2. StorageClassの設定
StorageClassでは、特にIP指定は不要です、
# マニフェスト
> cat storageclass-nas.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ontap-nas-class
provisioner: csi.trident.netapp.io
mountOptions:
- nfsvers=3
parameters:
backendType: "ontap-nas"
allowVolumeExpansion: true
# 作成したファイルの適用
> oc apply -f storageclass-nas.yaml
storageclass.storage.k8s.io/ontap-nas-class created
# 作成後の確認
> oc get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ontap-nas-class csi.trident.netapp.io Delete Immediate true 9s
4-3. Persistent Volumeの作成
Persistent Volume用のNamespaceを作成します。
> oc create namespace testspace01
namespace/testspace01 created
# 作成後の確認
> oc get ns testspace01
NAME STATUS AGE
testspace01 Active 18s
Persistent Volumeの払い出しを実施します。
# PersistentVolumeClaim マニフェスト
> cat pvc.yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-nas
namespace: testspace01
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
storageClassName: ontap-nas-class
# マニフェストの適用
> oc apply -f pvc.yaml
persistentvolumeclaim/pvc-nas created
# 作成後の確認
> oc get pvc -n testspace01
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-nas Bound pvc-bda3b44b-4436-4db7-b46e-44c8747d9fb9 2Gi RWX ontap-nas-class <unset> 88m
> oc get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-bda3b44b-4436-4db7-b46e-44c8747d9fb9 2Gi RWX Delete Bound testspace01/pvc-nas ontap-nas-class <unset> 88m
4-4. テスト用のPodの作成
PVへの書き込みができるかを確認する為のPodを作成します。
- 軽量なコンテナ「Red Hat Universal Base Image (UBI)」を作成
- 1秒毎にdateの結果を作成したPVにlogとして出力
# マニフェスト
> cat pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-test-app
namespace: testspace01
spec:
containers:
- name: logger
image: registry.access.redhat.com/ubi9/ubi-minimal:latest
command: ["/bin/sh"]
args: ["-c", "while true; do echo $(date -u) >> /mnt/storage/access.log; sleep 1; done"]
volumeMounts:
- name: data-volume
mountPath: /mnt/storage
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: pvc-nas
# マニフェストの適用
> oc apply -f pod-test.yaml
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "logger" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "logger" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "logger" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "logger" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
pod/pod-test-app created
# 作成後の確認
> oc get pod -n testspace01
NAME READY STATUS RESTARTS AGE
pod-test-app 1/1 Running 0 40s
> oc get pods -o wide -n testspace01
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-test-app 1/1 Running 0 14s 192.168.0.234 master01.ocp100.example.org <none> <none>
作成したPodに入って、PVが接続されている事を確認します。
# Podに接続
> oc exec -n testspace01 --stdin --tty pod-test-app -- /bin/bash
# Pod内の操作(mount状態の確認)
[root@pod-test-app /]# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 200G 47G 153G 24% /
tmpfs 64M 0 64M 0% /dev
shm 64M 0 64M 0% /dev/shm
tmpfs 4.7G 126M 4.6G 3% /proc/acpi
172.16.21.47:/trident_pvc_bda3b44b_4436_4db7_b46e_44c8747d9fb9 2.0G 320K 2.0G 1% /mnt/storage
/dev/sda4 200G 47G 153G 24% /etc/hosts
tmpfs 23G 20K 23G 1% /run/secrets/kubernetes.io/serviceaccount
devtmpfs 4.0M 0 4.0M 0% /proc/keys
PODから抜けた後に、踏み台サーバからOpenShift Nodeに接続してmountコマンドを実行し、SVMのデータアクセス用のIPが表示される事を確認します。
> ssh -i /home/user01/.ssh/id_rsa core@master01.ocp100.example.org
Red Hat Enterprise Linux CoreOS 9.6.20260510-0
Part of OpenShift 4.21, RHCOS is a Kubernetes-native operating system
managed by the Machine Config Operator (`clusteroperator/machine-config`).
(中略)
[core@master01 ~]$ mount |grep "172.16.21.47"
172.16.21.47:/trident_pvc_bda3b44b_4436_4db7_b46e_44c8747d9fb9 on /var/lib/kubelet/pods/29617dfd-53dc-4272-8fca-05033adf2b3d/volumes/kubernetes.io~csi/pvc-bda3b44b-4436-4db7-b46e-44c8747d9fb9/mount type nfs (rw,relatime,vers=3,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=172.16.21.47,mountvers=3,mountport=635,mountproto=udp,local_lock=none,addr=172.16.21.47)
参考及びリンク
OpenShiftコンテナ環境でTrident + ONTAP利用①【OpenShift Single Node環境の構築】







