Ubuntu 24.04
Sponsored Link

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

 

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

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

+----------------------+   +----------------------+
|  [ ctrl.srv.world ]  |   |   [ dlp.srv.world ]  |
|     Manager Node     |   |     Control Plane    |
+-----------+----------+   +-----------+----------+
        eth0|10.0.0.25             eth0|10.0.0.30
            |                          |
------------+--------------------------+-----------
            |                          |
        eth0|10.0.0.51             eth0|10.0.0.52
+-----------+----------+   +-----------+----------+
| [ node01.srv.world ] |   | [ node02.srv.world ] |
|     Worker Node#1    |   |     Worker Node#2    |
+----------------------+   +----------------------+

 

例として、NFS サーバー [nfs.srv.world (10.0.0.35)] のストレージ領域を利用するように、NFS プロビジョナーによる動的プロビジョニングの設定をします。

[1]

こちらを参考に NFS サーバーを設定しておきます
当例では [/home/nfsshare] ディレクトリを共有ディレクトリとして設定します。

[2]

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

[3]

こちらを参考に、Helm をインストールしておきます

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

root@ctrl:~#
helm install nfs-client -n kube-system --set nfs.server=10.0.0.35 --set nfs.path=/home/nfsshare nfs-subdir-external-provisioner/nfs-subdir-external-provisioner
NAME: nfs-client
LAST DEPLOYED: Fri Jun  7 04:45:13 2024
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None

root@ctrl:~#
kubectl get deployment -n kube-system

NAME                                         READY   UP-TO-DATE   AVAILABLE   AGE
calico-kube-controllers                      1/1     1            1           4h54m
coredns                                      2/2     2            2           4h55m
metrics-server                               1/1     1            1           16m
nfs-client-nfs-subdir-external-provisioner   1/1     1            1           19s
[4] Pod からの使用例です。
root@ctrl:~#
kubectl get pv

No resources found in default namespace.
root@ctrl:~#
kubectl get pvc

No resources found in default namespace.
root@ctrl:~#
kubectl get storageclass

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

# PVC 作成

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

root@ctrl:~#
kubectl apply -f my-pvc.yml

persistentvolumeclaim/my-provisioner created
root@ctrl:~#
kubectl get pvc

NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
my-provisioner   Bound    pvc-7b9f17ed-fc6f-4e7e-99dc-96324c1a4076   5Gi        RWO            nfs-client     <unset>                 5s

# PV は自動生成される

root@ctrl:~#
kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-7b9f17ed-fc6f-4e7e-99dc-96324c1a4076   5Gi        RWO            Delete           Bound    default/my-provisioner   nfs-client     <unset>                          35s

root@ctrl:~#
vi my-pod.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: nginx-pvc
      volumes:
        - name: nginx-pvc
          persistentVolumeClaim:
            # 作成した PVC 名
            claimName: my-provisioner

root@ctrl:~#
kubectl apply -f my-pod.yml

deployment.apps/my-nginx created
root@ctrl:~#
kubectl get pods

NAME                        READY   STATUS    RESTARTS   AGE
my-nginx-69d9cb4f47-zzjj7   1/1     Running   0          5s

root@ctrl:~#
kubectl exec my-nginx-69d9cb4f47-zzjj7 -- df /usr/share/nginx/html

Filesystem                                                                               1K-blocks  Used Available Use% Mounted on
10.0.0.35:/home/nfsshare/default-my-provisioner-pvc-7b9f17ed-fc6f-4e7e-99dc-96324c1a4076 164028416     0 155623424   0% /usr/share/nginx/html

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

root@ctrl:~#
echo "Nginx Index" > index.html

root@ctrl:~#
kubectl cp index.html my-nginx-69d9cb4f47-zzjj7:/usr/share/nginx/html/index.html

root@ctrl:~#
kubectl expose deployment my-nginx --type="NodePort" --port 80

root@ctrl:~#
kubectl port-forward service/my-nginx --address 127.0.0.1 80:80 &

root@ctrl:~#
curl localhost

Handling connection for 80
Nginx Index
# pod を削除する場合は PVC を削除すると PV も削除される

root@ctrl:~#
kubectl delete deployment my-nginx

deployment.apps "my-nginx" deleted
root@ctrl:~#
kubectl delete pvc my-provisioner

persistentvolumeclaim "my-provisioner" deleted
root@ctrl:~#
kubectl get pv

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

No resources found in default namespace.
root@ctrl:~#
kubectl get pvc

No resources found in default namespace.
root@ctrl:~#
kubectl get storageclass

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

root@ctrl:~#
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@ctrl:~#
kubectl apply -f statefulset.yml

statefulset.apps/my-mginx created
root@ctrl:~#
kubectl get statefulset

NAME       READY   AGE
my-mginx   1/1     6s

root@ctrl:~#
kubectl get pods

NAME         READY   STATUS    RESTARTS   AGE
my-mginx-0   1/1     Running   0          31s

root@ctrl:~#
kubectl get pvc

NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
data-my-mginx-0   Bound    pvc-4e2ce32d-c318-4669-b570-949043fc9d30   5Gi        RWO            nfs-client     <unset>                 48s

root@ctrl:~#
kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-4e2ce32d-c318-4669-b570-949043fc9d30   5Gi        RWO            Delete           Bound    default/data-my-mginx-0   nfs-client     <unset>                          78s
関連コンテンツ