🍆

Kubernetes に democratic-csi を入れて、TrueNAS に自動的にPVを作ってもらうようにした

2022/11/23に公開

democratic-csi とは

GitHub - democratic-csi/democratic-csi: csi storage for container orchestration systems より

democratic-csi implements the csi (container storage interface) spec providing storage for various container orchestration systems (ie: Kubernetes).
The current focus is providing storage via iscsi/nfs from zfs-based storage systems, predominantly FreeNAS / TrueNAS and ZoL on Ubuntu.
The current drivers implement the depth and breadth of the csi spec, so you have access to resizing, snapshots, clones, etc functionality.

意訳) democratic-csi とは、Kubernetes の中で PersistentVolume リソースを要求する PersistentVolumeClaim を定義されたときに、自動的に TrueNAS や FreeNAS 等の NAS 上で対応するボリュームを作成して iSCSI や NFS 経由で Export & Mount して、Pod に引き渡してくれるところまでを、CSI (Container Storage Interface) の仕様に基づいて自動的に行ってくれるドライバー(仕組み)を提供してくれるものです。

実際に利用してみる

TrueNAS 上で ZFS Dataset を切り出しておく

今回は家に転がっていた TrueNAS 13.0 (Intel NUC に NVMe M.2 SSD を挿したもの) 上の ZFS に あらかじめ Dataset を作っておきます。

TrueNAS のサービスを自動起動にしておく

SSH と実際にストレージアクセスに用いるプロトコル (iSCSI/NFS) のサービスを自動起動にしておきます。なお SSH アクセスで root ユーザーを指定した場合は Actions の設定ボタンから Permit Root Login も設定しておきます。

Helm で democratic-csi のリポジトリを追加する

Kubernetes の kubectl が動くマシン上で helm コマンドを使って democratic-csi の導入の準備をしておきます。

$ helm repo add democratic-csi https://democratic-csi.github.io/charts/
$ helm repo update
$ helm search repo democratic-csi/

設定ファイルを作成する

TrueNAS に対して、Kubernetes 上の trunas-iscsi-democratic-csi-controller が実際に指示を出すために必要となる SSH / HTTP / ZFS 等のパラメータを YAML ファイルに組み立てていきます。

truenas-iscsi.yml
csiDriver:
  name: "org.democratic-csi.iscsi"
storageClasses:
- name: truenas-iscsi-csi
  defaultClass: true
  reclaimPolicy: Delete
  volumeBindingMode: Immediate
  allowVolumeExpansion: true
  parameters:
    fsType: ext4
  mountOptions: []
  secrets:
    provisioner-secret:
    controller-publish-secret:
    node-stage-secret:
    node-publish-secret:
    controller-expand-secret:
driver:
  config:
    driver: freenas-iscsi #TrueNAS Coreを使っているときでも driver 名は freenas-* になる
    httpConnection:
      protocol: http
      host: 192.168.1.xxx
      port: 80
      username: root
      password: PASSWORD
    sshConnection:
      host: 192.168.1.xxx
      port: 22
      username: root
      password: PASSWORD
    zfs:
      datasetParentName: main/k8s-pvs # PV を生やす ZFS Dataset 名を指定する
      detachedSnapshotsDatasetParentName: main/k8s-snaps # ZFS Snapshot を生やす場所を指定する (省略不可)
    iscsi:
      targetPortal: 192.168.1.xxx:3260
      namePrefix: csi-
      targetGroups:
        - targetGroupPortalGroup: 1
          targetGroupInitiatorGroup: 1
          targetGroupAuthType: None
          targetGroupAuthGroup:
      extentInsecureTpc: true
      extentXenCompat: false
      extentDisablePhysicalBlocksize: true
      extentBlocksize: 4096
      extentRpm: "SSD"
      extentAvailThreshold: 0

TrueNAS で 設定ファイルに合わせて iSCSI Portal と Initiator Group を作る

Portal


Initiator Group


democratic-csi をデプロイする

先ほど作成した設定ファイルを引き渡して、実際に trunas-iscsi-democratic-csi-controller をデプロイしていきます。

$ helm upgrade --install --values truenas-iscsi.yml --create-namespace --namespace democratic-csi trunas-iscsi democratic-csi/democratic-csi

成功すると controller と node が起動してきます。

$ kubectl get pod -n democratic-csi

democratic-csi の中でどのような処理がされているのかは、deployment のログを追いかけるとわかりやすいと思います。

$ kubectl logs -n democratic-csi deployments/trunas-iscsi-democratic-csi-controller

StatefulSet で実際に PVC/PV が作られるか見てみる

テスト用の StatefulSet 定義

とりあえずのテスト用に Ubuntu の Pod を 3個 起動して、それぞれに PersistentVolume を付けるような StatefulSet を定義してみました。

statefulset-test.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: ubuntu
  labels:
    app: ubuntu
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ubuntu
  template:
    metadata:
      labels:
        app: ubuntu
    spec:
      containers:
      - image: ubuntu:latest
        name: ubuntu
        command: [ 'sleep', 'infinity']
        volumeMounts:
        - name: test-claim-iscsi
          mountPath: /pv-test
  volumeClaimTemplates:
    - metadata:
        name: test-claim-iscsi
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 30Gi

Apply してみる

適用してみると、Pod が 3個起動して、PVCとPVもそれぞれに合わせて、自動的に作成されています。

$ kubectl apply -f statefulset-test.yml
statefulset.apps/ubuntu created

$ kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
ubuntu-0                            1/1     Running   0          34s
ubuntu-1                            1/1     Running   0          24s
ubuntu-2                            1/1     Running   0          13s

$ kubectl get pvc
NAME                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS        AGE
test-claim-iscsi-ubuntu-0   Bound    pvc-1c9d1a85-5b5a-4c1c-a806-05384226c254   30Gi       RWO            truenas-iscsi-csi   54s
test-claim-iscsi-ubuntu-1   Bound    pvc-8037a743-afec-4e3e-bc45-7b7053a78dc1   30Gi       RWO            truenas-iscsi-csi   44s
test-claim-iscsi-ubuntu-2   Bound    pvc-d206a88e-4c4f-4780-a69b-0ceb47367b46   30Gi       RWO            truenas-iscsi-csi   33s

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                               STORAGECLASS        REASON   AGE
pvc-1c9d1a85-5b5a-4c1c-a806-05384226c254   30Gi       RWO            Delete           Bound    default/test-claim-iscsi-ubuntu-0   truenas-iscsi-csi            64s
pvc-8037a743-afec-4e3e-bc45-7b7053a78dc1   30Gi       RWO            Delete           Bound    default/test-claim-iscsi-ubuntu-1   truenas-iscsi-csi            54s
pvc-d206a88e-4c4f-4780-a69b-0ceb47367b46   30Gi       RWO            Delete           Bound    default/test-claim-iscsi-ubuntu-2   truenas-iscsi-csi            43s

TrueNAS 上でも PVC の名前に合わせた ZVol が自動的に切り出されて、iSCSI ボリュームとして共有されています。


Pod の中に入って確認してみる

kubectl exec して、実際に Pod の中に入って df コマンドを実行すると、指定したとおり 30Gi のボリューム (表示上は29 Gですが) をマウントしていることが分かります。

$ kubectl exec -it ubuntu-0 -- bash
root@ubuntu-0:/#
root@ubuntu-0:/#
root@ubuntu-0:/# df -h
Filesystem                         Size  Used Avail Use% Mounted on
overlay                             29G  7.7G   20G  29% /
tmpfs                               64M     0   64M   0% /dev
/dev/sda                            30G   24K   28G   1% /pv-test
/dev/mapper/ubuntu--vg-ubuntu--lv   29G  7.7G   20G  29% /etc/hosts
shm                                 64M     0   64M   0% /dev/shm
tmpfs                               16G   12K   16G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                              7.9G     0  7.9G   0% /proc/acpi
tmpfs                              7.9G     0  7.9G   0% /proc/scsi
tmpfs                              7.9G     0  7.9G   0% /sys/firmware

この後は、通常の PersistentVolume として、ファイルの読み書きや Pod の停止→起動後もきちんとデータが永続化されて利用可能になっています。

最後に

PV を地味にポチポチ作ったり、Localに置いててあれ?どこに行ったがなくなると、気が楽になりますから、
お家に CSI 準拠のストレージがあると何かと捗りますよ (ぇ

Discussion