Fedora 41
Sponsored Link

Kubernetes : 動的プロビジョニング (NFS)2024/11/06

 

外部ストレージを使用している場合、ボリュームの動的プロビジョニング機能を利用することで、クラスター管理者が事前に PV (Persistent Volume) を作成することなく、ユーザーからの PVC (Persistent Volume Claim) 作成要求時に、動的に PV を作成することができます。

当例では以下のように 3 台のノードを使用して Kubernetes クラスターを構成しています。

例として、Control Plane ノード上に NFS サーバーを起動し、NFS プロビジョナーによる動的プロビジョニングの設定をします。

-----------+---------------------------+--------------------------+------------
           |                           |                          |
       eth0|10.0.0.30              eth0|10.0.0.51             eth0|10.0.0.52
+----------+-----------+   +-----------+----------+   +-----------+----------+
|   [ dlp.srv.world ]  |   | [ node01.srv.world ] |   | [ node02.srv.world ] |
|     Control Plane    |   |      Worker Node     |   |      Worker Node     |
+----------------------+   +----------------------+   +----------------------+

[1]

こちらを参考に Control Plane ノード上に NFS サーバーを稼働させておきます
なお、当例では [/home/nfsshare] ディレクトリを共有ディレクトリとして設定します。

[2]

Worker ノードは NFS の共有ディレクトリがマウント可能であることが必要です

[3] NFS Client Provisioner をインストールします。
[root@dlp ~]#
dnf -y install helm
[root@dlp ~]#
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
# nfs.server = (NFS サーバーのホスト名 または IP アドレス)
# nfs.path = (NFS 共有のパス)

[root@dlp ~]#
helm install nfs-client -n kube-system --set nfs.server=10.0.0.30 --set nfs.path=/home/nfsshare nfs-subdir-external-provisioner/nfs-subdir-external-provisioner
NAME: nfs-client
LAST DEPLOYED: Wed Nov  6 11:33:19 2024
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None

[root@dlp ~]#
kubectl get pods -n kube-system

NAME                                                         READY   STATUS    RESTARTS       AGE
.....
.....
nfs-client-nfs-subdir-external-provisioner-779f4566db-md7t5   1/1     Running   0          21s
[4] Pod からの使用例です。
[root@dlp ~]#
kubectl get pv

No resources found in default namespace.
[root@dlp ~]#
kubectl get pvc

No resources found in default namespace.
[root@dlp ~]#
kubectl get storageclass

NAME         PROVISIONER                                                RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client   cluster.local/nfs-client-nfs-subdir-external-provisioner   Delete          Immediate           true                   63s

# PVC 作成

[root@dlp ~]#
vi my-pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-provisioner
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      # リクエストするボリュームサイズ
      storage: 5Gi
  # StorageClass の名称を指定
  storageClassName: nfs-client

[root@dlp ~]#
kubectl apply -f my-pvc.yml

persistentvolumeclaim/my-provisioner created
[root@dlp ~]#
kubectl get pvc

NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
my-provisioner   Bound    pvc-42743b06-0794-41eb-8f0e-5372385bd632   5Gi        RWO            nfs-client     <unset>                 4s

# PV は自動生成される

[root@dlp ~]#
kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-42743b06-0794-41eb-8f0e-5372385bd632   5Gi        RWO            Delete           Bound    default/my-provisioner   nfs-client     <unset>                          2m15s

[root@dlp ~]#
vi my-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: my-mginx
spec:
  containers:
    - name: my-mginx
      image: nginx
      ports:
        - containerPort: 80
          name: web
      volumeMounts:
      - mountPath: /usr/share/nginx/html
        name: nginx-pvc
  volumes:
    - name: nginx-pvc
      persistentVolumeClaim:
        # 作成した PVC 名
        claimName: my-provisioner

[root@dlp ~]#
kubectl apply -f my-pod.yml

pod/my-mginx created
[root@dlp ~]#
kubectl get pod my-mginx -o wide

NAME       READY   STATUS    RESTARTS   AGE   IP               NODE               NOMINATED NODE   READINESS GATES
my-mginx   1/1     Running   0          14s   192.168.40.198   node01.srv.world   <none>           <none>

[root@dlp ~]#
kubectl exec my-mginx -- df /usr/share/nginx/html

Filesystem                                                                               1K-blocks    Used Available Use% Mounted on
10.0.0.30:/home/nfsshare/default-my-provisioner-pvc-42743b06-0794-41eb-8f0e-5372385bd632  80674816 5331968  75342848   7% /usr/share/nginx/html

# index ファイルを作成して動作確認

[root@dlp ~]#
echo "Nginx Index" > index.html

[root@dlp ~]#
kubectl cp index.html my-mginx:/usr/share/nginx/html/index.html

[root@dlp ~]#
curl 192.168.40.198

Nginx Index
# 削除する場合は PVC を削除すると PV も削除される

[root@dlp ~]#
kubectl delete pod my-mginx

pod "my-mginx" deleted
[root@dlp ~]#
kubectl delete pvc my-provisioner

persistentvolumeclaim "my-provisioner" deleted
[root@dlp ~]#
kubectl get pv

No resources found in default namespace.
[5] StatefulSet を使用すると [volumeClaimTemplates] が指定可能なため、PVC の作成までまとめて記述できます。
[root@dlp ~]#
kubectl get pv

No resources found in default namespace.
[root@dlp ~]#
kubectl get pvc

No resources found in default namespace.
[root@dlp ~]#
kubectl get storageclass

NAME         PROVISIONER                                                RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client   cluster.local/nfs-client-nfs-subdir-external-provisioner   Delete          Immediate           true                   9m42s

[root@dlp ~]#
vi statefulset.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-mginx
spec:
  serviceName: my-mginx
  replicas: 1
  selector:
    matchLabels:
      app: my-mginx
  template:
    metadata:
      labels:
        app: my-mginx
    spec:
      containers:
      - name: my-mginx
        image: nginx
        volumeMounts:
        - name: data
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      # StorageClass の名称を指定
      storageClassName: nfs-client
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi

[root@dlp ~]#
kubectl apply -f statefulset.yml

statefulset.apps/my-mginx created
[root@dlp ~]#
kubectl get statefulset

NAME       READY   AGE
my-mginx   1/1     13s

[root@dlp ~]#
kubectl get pods -o wide

NAME         READY   STATUS    RESTARTS   AGE   IP               NODE               NOMINATED NODE   READINESS GATES
my-mginx-0   1/1     Running   0          29s   192.168.40.199   node01.srv.world   <none>           <none>

[root@dlp ~]#
kubectl get pvc

NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
data-my-mginx-0   Bound    pvc-149e89de-0bd6-4e6b-b229-50706494f426   5Gi        RWO            nfs-client     <unset>                 63s

[root@dlp ~]#
kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-149e89de-0bd6-4e6b-b229-50706494f426   5Gi        RWO            Delete           Bound    default/data-my-mginx-0   nfs-client     <unset>                          87s
関連コンテンツ