2021年3月7日日曜日

kubernetes で nfs をマウントして使う方法

kubernetes で nfs をマウントして使う方法

概要

k8s で nfs を使うにはいろいろな方法がありますが nfs-subdir-external-provisioner という helm chart が便利そうだったので使ってみました

環境

  • kubernetes v1.19.3
  • nfs-subdir-external-provisioner 4.0.2

nfs サーバの準備

こちらを参考に Ubuntu 上に構築しています
また nfs は no_root_squash を設定しましょう
export しているパスは / にしています

nfs-subdir-external-provisioner のインストール

helm を使います
リポジトリを add したら install します

  • helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
    --set nfs.server=192.168.100.10 \
    --set nfs.path=/ \
    --set storageClass.name=nfs

nfs サーバの IP と export したパスを指定しましょう
storageClass.name は好きな storageClass 名を指定しましょう
storageClass が作成され nfs 用の Pod が作成されていれば OK です

  • kubectl get storageclass
NAME  PROVISIONER                                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs   cluster.local/nfs-subdir-external-provisioner   Delete          Immediate           true                   4m30s
  • kubectl get pod
NAME  PROVISIONER                                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs   cluster.local/nfs-subdir-external-provisioner   Delete          Immediate           true                   4m30s

動作確認

nfs が使用できるか確認してみます

PersistentVolumeClaim の作成

pv は不要です
まずは pvc を作成します
必ず storageClassName: nfs を指定しましょう

  • vim pvc1.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc1
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs
  • kubectl apply -f pvc1.yml

動作確認用の redis Pod の作成

Pod で nfs をマウントしてデータを配置します
何でも OK です
今回は redis のバックアップデータでも配置してみます

  • vim redis.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      name: redis
  template:
    metadata:
      labels:
        name: redis
    spec:
      containers:
        - args:
            - redis-server
            - --appendonly
            - "yes"
          image: redis:6
          name: redis
          resources: {}
          volumeMounts:
            - mountPath: /data
              name: pvc1
      restartPolicy: Always
      volumes:
        - name: pvc1
          persistentVolumeClaim:
            claimName: pvc1
  • kubectl apply -f redis.yml

これで redis Pod ができれば OK です
Pod の中を確認するとちゃんと指定のパスにバックアップデータが作成されているのが確認できます

  • kubectl get pod
NAME                                              READY   STATUS    RESTARTS   AGE
nfs-subdir-external-provisioner-59cccbc98-h8cnl   1/1     Running   0          91m
redis-87846d68-7pl9c                              1/1     Running   0          79s
  • kubectl exec redis-87846d68-7pl9c -- ls /data

=> appendonly.aof

alpine Pod を作成してデータがあるか確認してみる

別の Pod を作成して同じ pvc をマウントしてみて先程作成された redis のバックアップデータがあるか確認してみましょう

  • vim alpine.yml
apiVersion: v1
kind: Pod
metadata:
  name: alpine-test
spec:
  containers:
    - image: alpine:latest
      name: alpine-test
      resources: {}
      volumeMounts:
        - mountPath: /data
          name: pvc1
      command: ["ls"]
      args: ["/data"]
  restartPolicy: Never
  volumes:
    - name: pvc1
      persistentVolumeClaim:
        claimName: pvc1
  • kubectl apply -f alpine.yml
  • kubectl logs alpine-test

=> appendonly.aof

ちゃんと redis のバックアップがあることが確認できました

別の pvc を作成してみる

1 つの storageClass から別の pvc を作成してみるとどうなるか確認してみました

  • vim pvc2.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc2
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs
  • kubectl apply -f pvc2.yml

これで pvc2 をマウントしてデータ領域を確認すると redis のバックアップデータがないことが確認できます
つまり同じ nfs の export パスを使っているにも関わらず別のデータ領域を使っていることがわかります

  • vim alpine2.yml
apiVersion: v1
kind: Pod
metadata:
  name: alpine-test2
spec:
  containers:
    - image: alpine:latest
      name: alpine-test2
      resources: {}
      volumeMounts:
        - mountPath: /data
          name: pvc2
      command: ["ls"]
      args: ["/data"]
  restartPolicy: Never
  volumes:
    - name: pvc2
      persistentVolumeClaim:
        claimName: pvc2
  • kubectl apply -f alpine2.yml
  • kubectl logs alpine-test

=> 表示されない

nfs 内ではどうなっているか

VM で適当に nfs をマウントして中身を見てみると pvc ごとにディレクトリが作成されているようです
これが別の pvc を作成してもデータ領域が異なっているように見えた原因になります

ls /mnt/test/
default-pvc1-pvc-8d750fd7-9e5e-4392-ab87-eb99196777e3  default-pvc2-pvc-ecfd3eca-9b43-412b-91c7-037588cd16c5

最後に

これで pvc ごとに nfs の export を作成する必要がなくなるのでかなり便利かなと思います
データ領域的には 1 つの領域を共有しているので pvc の使いすぎによる別 pvc の逼迫には注意しましょう

おまけ: デフォルトの storageClasss として使う方法

--set storageClass.defaultClass=true

参考サイト

0 件のコメント:

コメントを投稿