このブログを検索

この記事の内容は、個人の見解、検証の範囲のものであり、誤りがある可能性があります。
個人の責任において情報活用をお願いします。


2022年1月31日月曜日

俺とkubernetesと時々vSphere -動的PVCの利用について その2-

このブログは、コンテナのオーケストレーターであるkubernetesについて

自分の知識をまとめることを目的として記事を書いています。

もともとなが~くvSphereのあれやこれやに携わってきたのでvSphereとの類似点や

相違点についてもちょっと混ぜていけたりしたらいいかなぁとかも思っています。


今回はPodのストレージ周りのお話の続きとなります。

Podがデータを保存するために追加するPod用の外部ストレージ、PersistentVolumeを自動的に作ってくれる動的PVCの導入です。


今回は、nfs-clientを導入しNFSで動的PVCを使えるようにします。

そのため、ノードとなっているOSに/NFSという領域を作って、そこにCentOSで作成したNFSサーバーをくっ付けて使います。

気を付けていただきたいのは、Kubernetesクラスタはマスターとワーカーのノードがあり、Podはワーカーで動くのでワーカーとなっているサーバーにNFSをマウントしておかないとPodがNFSの領域を使えません。


うっかりマスターにだけ追加して、あれ? PV作られないじゃん??? とならないようご注意ください。(n敗

では、すべてのノードにNFSがマウントされている状態を前提として、nfs-clientの導入手順を紹介したいと思います


nfs-clientの導入方法はいくつか方法がありますが、簡単なのでhelmを使って導入したいと思います。

helmは、Kubernetes用のyamlみたいなものです。

これを使うと、Kubernetes上にアプリケーションのPodを展開してくれます。


作業自体は、マスターノードで行います。

まず、helmを使えるようにします。

  curl -O https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3

  ls

  bash ./get-helm-3


nfs-clientを導入するためhelmのレポジトリ追加

  helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/


nfs-clientインストール

  helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \

  --set nfs.server=192.168.0.5 \

  --set nfs.path=/nfs


        nfs.server → NFSサーバーのIPアドレス

        nfs.path → NFSサーバー側で共有しているディレクトリ


※なんかうまくいかなくてアンインストールする場合は以下

  helm uninstall nfs-subdir-external-provisioner


何ができたかの確認

  # kubectl get pod

  NAME                                              READY   STATUS    RESTARTS   AGE

  nfs-subdir-external-provisioner-59479459d5-qbbdv   1/1     Running   0          22h


  # kubectl get sc

  NAME         PROVISIONER                                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE

  nfs-client   cluster.local/nfs-subdir-external-provisioner   Delete          Immediate           true                   5m43s


nfs-subdir-external-provisionerのPodとStorageClassが作成されます。

このnfs-clientという名前で作られたStorageClassを指定してPVCを作成すると自動でPVを作ってくれるというわけです。


実際にやってみましょう!

こんな感じでyamlを用意します。


確認用のPVC作成例

 pvc.yaml

  ----

  apiVersion: v1

  kind: PersistentVolumeClaim

  metadata:

    name: my-provisioner

    annotations:

      # ここでStorageClass の名称を指定

      volume.beta.kubernetes.io/storage-class: nfs-client

  spec:

    accessModes:

      - ReadWriteOnce

    resources:

      requests:

        # ここでリクエストするボリュームサイズを決定

        storage: 5Gi

  ----


PVCの作成

  # kubectl apply -f pvc.yaml


作成したPVCを確認する

  # kubectl get pvc

  NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE

  my-provisioner   Bound    pvc-4b8ca59d-28cf-4f2d-a078-e8392bde5a81   5Gi        RWO            nfs-client     36s


PVCを作成すると、NFS側に以下の命名規則でディレクトリが作成される。


   ${namespace}-${pvcName}-${pvName}


   ※ここの例では以下のディレクトリがNFSサーバー側にできる


     default-my-provisioner-pvc-4b8ca59d-28cf-4f2d-a078-e8392bde5a81


当然PVも自動で作成される。

  # kubectl get pv

  NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGE

  pvc-4b8ca59d-28cf-4f2d-a078-e8392bde5a81   5Gi        RWO            Delete           Bound    default/my-provisioner   nfs-client              46s             15s



このPVCを要求するPodを作成する


確認用のPVC作成例

  test-pod.yaml

  ----

  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:

          claimName: my-provisioner # 作成した PVC 名

  ----


Podの作成

  # kubectl apply -f test-pod.yaml


作成したPodはnginxなのでアクセスして状態を確認するため、IPアドレスを確認する。

  # kubectl get pod -o wide

  NAME                                              READY   STATUS    RESTARTS   AGE     IP             NODE                      NOMINATED NODE   READINESS GATES

  my-mginx                                           1/1     Running   0          38s   10.244.2.5   snt-k8s-node2.snt.local   <none>           <none>

  nfs-subdir-external-provisioner-59479459d5-qbbdv   1/1     Running   0          13m   10.244.1.4   snt-k8s-node1.snt.local   <none>           <none>


確認できたIPアドレスにcurlでアクセスすると、以下の表示になる。


  # curl 10.244.2.5

  <html>

  <head><title>403 Forbidden</title></head>

  <body>

  <center><h1>403 Forbidden</h1></center>

  <hr><center>nginx/1.21.6</center>

  </body>

  </html>


NFSサーバー側にできたディレクトリ(PV)にインデックスファイルを置いて表示される内容が期待した通りになるか確認。


  まず、PVの領域に移動 # cd /mnt/default-my-provisioner-pvc-4b8ca59d-28cf-4f2d-a078-e8392bde5a81/


  ファイルはこのコマンドで作成 # echo "nfs-clint TEST" > index.html


  ファイルができてるか確認 # ls


再びcurlでアクセスし、nfs-clint TEST が表示されることを確認。

  # curl 10.244.2.5

  nfs-clint TEST


自動でPVCからPVが作られ、その領域にPodからちゃんとアクセスできていることが確認できた。

ということで、nfs-clientを導入し動的PVCが使えるようになりました。

これがあるとステートフルセットというPodの作り方ができるので、現在一般的なpodの作り方である

デプロイメントと合わせてそれぞれのPodの作り方と違いを解説したいと思います。