0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

オンプレ環境でのStorageClass

Last updated at Posted at 2023-11-29

環境

  • ubuntu:22.0.4.1 LTS
  • kubernetes:1.28.2
  • containerd:1.6.24

StorageClassについて

StorageClassを用いずにPersistentVolumeを使用するには、クラスターの管理者が事前にPersistentVolumeを作成して、ユーザーがPersistentVolumeClaimを作成する流れになると思います。

ですが、もう少し運用を楽にしたい。クラスターの管理者を介さずに、PersistentVolumeを作成したいといった要件があると思います。

そこで、使えるのがStorageClassです。
今回、オンプレ環境でStorageClassを利用するための外部プロビジョナー(対する「内部プロビジョナー」はデフォルトで使用できるプロビジョナーを指す)を用いて、NFS使った動的プロビジョンについて書いていきます。

NFSサーバーの準備

NFSサーバーを構築していきます。詳細は「nfs-kernel-server」で検索していただきたいですが、以下の通り、インストールします。

# sudo apt-get update
# sudo apt-get install nfs-kernel-server

インストールが完了したら公開するディレクトリの作成および権限設定をします。

今回は、/export/nfsという公開用のディレクトリを作成し、然る権限を付与します。

# sudo mkdir /export/nfs
# sudo chmod 1777 /export/nfs/.

次に、NFSの設定をします。

/etc/exports
/export/nfs/ 172.21.0.0/24(rw,sync,no_subtree_check,no_root_squash,no_all_squash

最後に設定を反映させるためにNFSサービスを再起動させます。

# sudo systemctl reload nfs-kernel-server

これで準備完了です。

image.png

NFSクライアントのインストール

ワーカーノードすべてでNFSクライアントをインストールする。

# sudo apt-get update
# sudo apt-get install nfs-common

NFSクライアントの確認

NFSクライアントが正常に動作することを確認する。

# sudo mount -t nfs 172.21.0.50:/export /mnt
# ls /mnt/nfs
<show something>
# sudo umount /mnt

プロビジョナーの導入

プロビジョナーの導入をしていきます。
以下のレポジトリのREADME通りに実施しています。HelmやKustomizeでの導入も可能ですが、今回は、マニュアルで導入していきます。

gitクローンするディレクトリを作成する。

# mkdir dynamic-provisioner-nfs && cd dynamic-provisioner-nfs
# git init --initial-branch main
# Initialized empty Git repository in /dynamic-provisioner-nfs/.git/

gitの設定

/deployディレクトリのみ必要なので、特定のディレクトリのみクローンできるように設定していきます。併せてリモートレポジトリを追加します。

# git config core.sparsecheckout true
# git config --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
+ core.sparsecheckout=true
# git remote add origin https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner.git
# echo /deploy >> .git/info/sparse-checkout

gitクローン

それでは、/deployディレクトリをクローンします。

# git pull origin master
From https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
 * branch            master     -> FETCH_HEAD

# ls
deploy

これで準備が完了しました。
次に各yamlファイルの作成・修正をしていきます。

namespaceの作成

まずは、プロビジョナー用Namespaceのマニフェストを作成します。
ここではNamespace名をdynamic-provisioner-nfsとします。

namespace-dynamic-provisioner-nfs.yaml
sioner-nfs.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: dynamic-provisioner-nfs
spec: {}
status: {}

上記で作成したマニフェストを'apply'します。

# kubectl apply -f namespace-dynamic-provisioner-nfs.yaml
namespace/dynamic-provisioner-nfs created

image.png

rbac.yaml、deployment.yamlの修正

/deployには、それぞれDeployment、ServiceAccount、StorageClass、テスト用PVC、テスト用Podのマニフェストが入っております。rbac.yamlやdeployment.yamlはデフォルトでNamespaceがdefaultになっているので、上記で作成したNamespace dynamic-provisioner-nfsに変更します。

# NAMESPACE=dynamic-provisioner-nfs
# echo $NAMESPACE
dynamic-provisioner-nfs
# sed -i "s/default/$NAMESPACE/g" ./deploy/rbac.yaml ./deploy/deployment.yaml

ServiceAccountの作成

ここで、rbac.yamlの中身をみてみます。

./deploy/rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: dynamic-provisioner-nfs
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: dynamic-provisioner-nfs
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: dynamic-provisioner-nfs
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: dynamic-provisioner-nfs
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: dynamic-provisioner-nfs
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

Node、PVC、PVを管理するための権限と、上記で作成したnameSpaceのEndpointsを管理するための権限を付与したServiceAccountを作成しています。Endpointsの権限はなぜ必要なのかわからないですが、一旦そのままにしておきます。

このServiceAccountを、後で作成するDeploymentに渡して、上記のリソースを管理するPodをデプロイします。

では、'apply'します。

# kubectl create -f deploy/rbac.yaml
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created

image.png

Deploymentの作成

では、先に修正したDeployment.yamlをさらに修正していきます。
デフォルトでNFSサーバーのアドレスと、ディレクトリがサンプルのパラメータとして記載されています。
ここでは、以下のように修正します。

deploy/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: dynamic-provisioner-nfs
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
-              value: 10.3.243.101
+              value: 172.21.0.50
            - name: NFS_PATH
-              value: /ifs/kubernetes
+              value: /export/nfs
      volumes:
        - name: nfs-client-root
          nfs:
-            server: 10.3.243.101
+            server: 172.21.0.50
-            path: /ifs/kubernetes
+            path: /export/nfs

では、'apply'します。

# kubectl apply -f deploy/deployment.yaml
deployment.apps/nfs-client-provisioner created

これで、対象のPodが立ち上がるのを待ちます。
少しだけ時間がかかった気がします。

# kubectl get pods -n dynamic-provisioner-nfs
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-85975c94c6-lpxnt   1/1     Running   0          6m46s

image.png

StrageClassの作成

最後にStorageClassの作成をしていきます。
必要に応じてマニフェストの修正が必要になりますが、用意されているclass.yamlをそのまま'apply'してみます。

# kubectl apply -f deploy/class.yaml
storageclass.storage.k8s.io/nfs-client created
# kubectl get sc
NAME         PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  2m16s

image.png

これで準備が整いました。
それでは、PersistentVolumeClaimを作成していきます。

動作確認

このGitでは親切にもテスト用のマニフェストが用意されていますので、そのまま使用してみたいと思います。用意されているPod、PVCマニフェストのNamespaceはdefaultとなっています。

# kubectl apply -f deploy/test-pod.yaml -f deploy/test-claim.yaml
pod/test-pod created
persistentvolumeclaim/test-claim created
# kubectl get pvc
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim   Bound    pvc-b1888a30-6361-4dd9-bfe4-77649c095733   1Mi        RWX            nfs-client     42s
# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
pvc-b1888a30-6361-4dd9-bfe4-77649c095733   1Mi        RWX            Delete           Bound    default/test-claim   nfs-client              71s
# kubectl get pods
NAME       READY   STATUS      RESTARTS        AGE
test-pod   0/1     Completed   0               82s

image.png

上記でtest-claimというPVCと、それに対応するpvc-b1888a30-6361-4dd9-bfe4-77649c095733というPVが作成されます。
NFSサーバーには、以下のようなディレクトリが作成されます。

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

ここでは「default-test-claim-pvc-b1888a30-6361-4dd9-bfe4-77649c095733」といったディレクトリが公開ディレクトリに作成されます。

加えて、Pod test-podで先に作成されたPVC test-claimをマウントします。

image.png

ここで、NFSサーバーにアクセスし、公開ディレクトリを確認してみます。

# ls /export/nfs/default-test-claim-pvc-b1888a30-6361-4dd9-bfe4-77649c095733/
SUCCESS

「SUCCESS」ファイルが作成されていれば完了です。
動作確認出来たら、先のPVCとPodを削除します。

# kubectl delete -f deploy/test-pod.yaml -f deploy/test-claim.yaml
pod "test-pod" deleted
persistentvolumeclaim "test-claim" deleted

これでクラスター管理者を介さずにPersistentVolumeを作成できるようになりました。

今回は以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?