CentOS Stream 9
Sponsored Link

Kubernetes : 動的プロビジョニング (NFS)2023/10/20

 

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

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

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

[root@mgr ~]#
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 Oct 20 15:46:59 2023
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None

[root@mgr ~]#
kubectl get deployment -n kube-system

NAME                                         READY   UP-TO-DATE   AVAILABLE   AGE
calico-kube-controllers                      1/1     1            1           27h
coredns                                      2/2     2            2           27h
metrics-server                               1/1     1            1           55m
nfs-client-nfs-subdir-external-provisioner   1/1     1            1           3m2s
[4] Pod からの使用例です。
[root@mgr ~]#
kubectl get pv

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

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

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

# PVC 作成

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

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

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

NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-provisioner   Bound    pvc-6b2fb244-4a22-4f0e-a507-50fb213e20d0   5Gi        RWO            nfs-client     2m33s

# PV は自動生成される

[root@mgr ~]#
kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGE
pvc-6b2fb244-4a22-4f0e-a507-50fb213e20d0   5Gi        RWO            Delete           Bound    default/my-provisioner   nfs-client              3m8s

[root@mgr ~]#
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@mgr ~]#
kubectl apply -f my-pod.yml

deployment.apps/my-nginx created
[root@mgr ~]#
kubectl get pods

NAME                        READY   STATUS    RESTARTS   AGE
my-nginx-66fc75ffb8-vflks   1/1     Running   0          39s

[root@mgr ~]#
kubectl exec my-nginx-66fc75ffb8-vflks -- df /usr/share/nginx/html

Filesystem                                                                               1K-blocks    Used Available Use% Mounted on
10.0.0.35:/home/nfsshare/default-my-provisioner-pvc-6b2fb244-4a22-4f0e-a507-50fb213e20d0 167689728 1202688 166487040   1% /usr/share/nginx/html

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

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

[root@mgr ~]#
kubectl cp index.html my-nginx-66fc75ffb8-vflks:/usr/share/nginx/html/index.html

[root@mgr ~]#
kubectl expose deployment my-nginx --type="NodePort" --port 80

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

[root@mgr ~]#
curl localhost

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

[root@mgr ~]#
kubectl delete deployment my-nginx

deployment.apps "my-nginx" deleted
[root@mgr ~]#
kubectl delete pvc my-provisioner

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

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

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

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

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

[root@mgr ~]#
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@mgr ~]#
kubectl apply -f statefulset.yml

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

NAME       READY   AGE
my-mginx   1/1     9s

[root@mgr ~]#
kubectl get pods

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

[root@mgr ~]#
kubectl get pvc

NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-my-mginx-0   Bound    pvc-6a9bd00f-c3f6-45b8-8b76-2cdeab655eab   5Gi        RWO            nfs-client     82s

[root@mgr ~]#
kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE
pvc-6a9bd00f-c3f6-45b8-8b76-2cdeab655eab   5Gi        RWO            Delete           Bound    default/data-my-mginx-0   nfs-client              91s
関連コンテンツ