前置き
サイオステクノロジーの中島です。Kubernetesで動かしているコンテナのデータを保存したりする場合は永続ボリューム機能を使用する必要がありますので、完全なローカルで使用する場合について、三パターン(hostpath、NFS、iSCSI)に分けて使用する方法について説明します。
永続ボリューム機能とは
PersistentVolume(PV)とPersistentVolumeClaim(PVC)のAPIを使用して用意される機能のことで、これら2点を定義することで、Pod内で作成されたデータをコンテナの外に保存することができます。
詳細は、公式ドキュメント(https://kubernetes.io/ja/docs/concepts/storage/persistent-volumes/)を参照してください。本記事であげた、三つ以外で対応されているプラグインについて記載されています。
試験環境
以下の構成を仮想環境上に構築して作業するものとします。
各ノードの状態は以下の通りになります。
$ kubectl get node NAME STATUS ROLES AGE VERSION k8s-mm Ready master 40h v1.19.2 k8s-ns Ready nas 40h v1.19.2 k8s-wk1 Ready worker 40h v1.19.2 k8s-wk2 Ready worker 40h v1.19.2
hostpathを使用する
永続ボリュームでhostpathを指定するとそれをマウントしたpodで、それが動作しているノード本体のフォルダパスにマウントされたディスク領域にデータを記載します。この方法は各ノードで動作させるためのライブラリーを追加でインストールする必要がありません。
Kubernetes作業
フォルダ構成
Kubernetesで動作させるためのファイルのフォルダ構成を以下に示します。
./ ├── pod │ └── hostpath-test-pod.yaml └── volume └── hostpath-volume.yaml
ファイル説明
上記フォルダ構成内のファイル内のデータを以下に示します。
- hostpath-volume.yaml
apiVersion: v1 kind: PersistentVolume metadata: name: hostpath-pv spec: capacity: storage: 5Gi persistentVolumeReclaimPolicy: Retain accessModes: - ReadWriteOnce hostPath: path: "/tmp/data" --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: hostpathpvc annotations: volume.beta.kubernetes.io/persistent-volume: hostpath-pv spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi
- hostpath-test-pod.yaml
apiVersion: v1 kind: Pod metadata: labels: test: hostpath-pvc-pod name: hostpath-pv-pod1 spec: affinity: #起動制限 nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/worker operator: In values: - worker #起動ノード指定 containers: - name: hostpath-pv-busybox image: busybox command: ["/bin/sh", "-c"] args: [ "tail -f /dev/null" ] volumeMounts: - name: hostpath-vol1 mountPath: /var/lib/busybox readOnly: false volumes: - name: hostpath-vol1 persistentVolumeClaim: claimName: hostpathpvc
Kubernetes実行
以下のコマンドで、永続ボリュームの設定を行う。
$ kubectl apply -f volume
以下のコマンドでpodを起動させる
$ kubectl apply -f pod
動作確認
以下のコマンドで、起動させたpodが動作しているノードを調べる。
$ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hostpath-pv-pod1 1/1 Running 0 8s 10.244.1.9 k8s-wk1 <none> <none>
先ほど起動させたpodに入る
$ kubectl exec -it hostpath-pv-pod1 /bin/ash
podのコンテナでマウントしたフォルダに向けてファイルを作成する。
# echo hello >> /var/lib/busybox/test.txt
podが実行しているノードで、先ほどの作成したファイルが存在していることを確認する。
$ ssh k8s-wk1 ls -la /tmp/data 合計 12 drwxr-xr-x 2 root root 4096 10月 14 11:01 . drwxrwxrwt 20 root root 4096 10月 14 11:00 .. -rw-r--r-- 1 root root 6 10月 14 11:01 test.txt
ファイルの中身を確認する。
$ ssh k8s-wk1 cat /tmp/data/test.txt hello
また、podが起動していないWorkerで、フォルダができていないことを確認する。
$ ssh k8s-wk2 ls -la /tmp/data ls: '/tmp/data' にアクセスできません: そのようなファイルやディレクトリはありません
NFSを使用する
NFS(Network File System)を使用して、その共有フォルダをpodにマウントすることができます。これを使用すればNFSが動作しているサーバにデータを書き込むことができます。これをKubernetesで動作するには、NFSをマウントするために必要なライブラリをインストールします。なお、NFSは設定するのが容易ですが、速度が遅いことが欠点になります。
事前準備
k8s-nsをNFSのファイルサーバとするためk8s-nsノードで以下の作業を行いサーバを構築します。
サーバのインストールを以下のコマンドで行います。
$ sudo apt install -y nfs-kernel-server
以下のコマンドで、公開するフォルダを作成します。
$ sudo mkdir -p /nfs/data
$ sudo chown nobody.nogroup /nfs/data/
以下のデータを/etc/exportsの最終行に記載する。
/nfs/data 192.168.0.0/24(rw,sync,fsid=0,crossmnt,no_subtree_check,insecure,all_squash)
以下のコマンドで、先ほどの設定を有効にする
$ sudo exportfs -ra
すべてのノードでNFSのフォルダをマウントできるようにライブラリを追加する。
$ sudo apt install -y nfs-common
Kubernetes作業
フォルダ構成
Kubernetesで実行するためのフォルダ構成を以下に示す。
./ ├── pod │ └── nfs-test-pod.yaml └── volume └── nfs-volume.yaml
ファイル説明
上記フォルダ構成内のファイル内のデータを以下に示します。
- nfs-volume.yaml
apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv spec: capacity: storage: 5Gi persistentVolumeReclaimPolicy: Retain accessModes: - ReadWriteOnce nfs: server: 192.168.0.133 path: "/nfs/data" --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: nfs-pvc annotations: volume.beta.kubernetes.io/persistent-volume: nfs-pv spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi
- nfs-test-pod.yaml
apiVersion: v1 kind: Pod metadata: labels: test: nfs-pvc-pod name: nfs-pv-pod1 spec: affinity: #起動制限 nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/worker operator: In values: - worker #起動ノード指定 containers: - name: nfs-pv-busybox image: busybox command: ["/bin/sh", "-c"] args: [ "tail -f /dev/null" ] volumeMounts: - name: nfs-vol1 mountPath: /var/lib/busybox readOnly: false volumes: - name: nfs-vol1 persistentVolumeClaim: claimName: nfs-pvc
Kubernetes実行
以下のコマンドで、永続ボリュームの設定を行う。
$ kubectl apply -f volume
以下のコマンドでpodを起動させる
$ kubectl apply -f pod
動作確認
先ほど起動させたpodに入る
$ kubectl exec -it nfs-pv-pod1 /bin/ash
podのコンテナでマウントしたフォルダに向けてファイルを作成する。
# echo hello >> /var/lib/busybox/test.txt
podでマウントしたフォルダのポイントに、先ほど作成したファイルが存在していることを確認する。
$ ssh k8s-ns ls -la /nfs/data 合計 12 drwxr-xr-x 2 nobody nogroup 4096 10月 14 11:10 . drwxr-xr-x 3 root root 4096 10月 14 10:23 .. -rw-r--r-- 1 nobody nogroup 6 10月 14 11:10 test.txt
作成されたファイルの中身を確認する。
$ ssh k8s-ns cat /nfs/data/test.txt hello
iSCSIを使用する
iSCSI(Internet Small Computer System Interface)を使用して、共有ディスクをpod内のフォルダにマウントすることができます。これを使用するのにNFSと同じようにライブラリをすべてのノードで導入する必要があります。なお、NFSより高速のストレージを使用することができますがNFSの設定より複雑な設定になります。
事前準備
サーバとなるk8s-nsノードで以下の作業を行い、iSCSIサーバにします。
$ sudo apt -y install tgt
5Gのイメージを作成します。
$ sudo mkdir /var/lib/iscsi_disks
$ sudo dd if=/dev/zero of=/var/lib/iscsi_disks/disk01.img count=0 bs=1 seek=5G
設定ファイルを作成します。
$ sudo sh -c "cat <<EOF> /etc/tgt/conf.d/target01.conf <target iqn.2020-10.local:k8s-ns.target01> backing-store /var/lib/iscsi_disks/disk01.img initiator-name iqn.2020-10.local:k8s-mm.initiator01 # ( username, password は任意のものを設定) incominguser username password </target> EOF "
作成した設定ファイルを有効にします。
$ sudo systemctl restart tgt
全てのノードで以下のコマンドを実行してiSCSIが実行できるようにします。
$ sudo apt install -y open-iscsi xfsprogs
以下のコマンドで、設定ファイルを書き換えます。
$ sudo vi /etc/iscsi/initiatorname.iscsi
設定は以下のように書き換えます。
#InitiatorName=iqn.1993-08.org.debian:01:da97a3f725a0 InitiatorName=iqn.2020-10.local:k8s-mm.initiator01
以下のコマンドで、認証の設定ファイルを書き換えます。
$ sudo vi /etc/iscsi/iscsid.conf
以下の通り、一部のコメントアウトを解除して、usernameやpasswordを設定どおり変更する
# To enable CHAP authentication set node.session.auth.authmetho # to CHAP. The default is None. node.session.auth.authmethod = CHAP # To set a CHAP username and password for initiator # authentication by the target(s), uncomment the following lines: node.session.auth.username = username node.session.auth.password = passwordd
設定を有効にする。
$ sudo systemctl restart iscsid open-iscsi
接続先の設定を追加する。
$ sudo iscsiadm -m discovery -t sendtargets -p 192.168.0.133
xfsフォーマット
このままでは、フォーマットされていないため対象となるディスクでxfsフォーマットを行い使用できるようにします。
まず、どのノードでもいいので、iSCSIをデバイスマウントする。
$ sudo iscsiadm -m node --login
マウントしたデバイスをxfsフォーマットする
$ sudo mkfs.xfs /dev/sdb
フォーマットが終わったら、iSCSIをデバイスアンマウントします。
$ sudo iscsiadm -m node --logout
Kubernetes作業
フォルダ構成
Kubernetesで実行するためのフォルダ構成を以下に示す。
./ ├── pod │ └── iscsi-test-pod.yaml └── volume ├── iscsi-chap-secret.yaml └── iscsi-volume.yaml
ファイル説明
上記フォルダ構成内のファイル内のデータを以下に示します。
- iscsi-chap-secret.yaml
apiVersion: v1 kind: Secret metadata: name: iscsi-targetd-chap-secret type: "kubernetes.io/iscsi-chap" data: discovery.sendtargets.auth.username: dXNlcm5hbWUK discovery.sendtargets.auth.password: cGFzc3dvcmQK
上記の設定で、usernameやpasswordはbase64フォーマットしたデータが記載されています。iSCSIで設定されたusernameやpasswordを必要に応じて変更してください。
- iscsi-volume.yaml
apiVersion: v1 kind: PersistentVolume metadata: name: iscsi-pv spec: capacity: storage: 5Gi persistentVolumeReclaimPolicy: Retain accessModes: - ReadWriteOnce iscsi: targetPortal: 192.168.0.133:3260 iqn: iqn.2020-10.local:k8s-ns.target01 lun: 1 fsType: xfs chapAuthDiscovery: true chapAuthSession: true readOnly: false secretRef: name: iscsi-targetd-chap-secret --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: iscsi-pvc annotations: volume.beta.kubernetes.io/persistent-volume: iscsi-pv spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi
- iscsi-test-pod.yaml
apiVersion: v1 kind: Pod metadata: labels: test: iscsi-pvc-pod name: iscsi-pv-pod1 spec: containers: - name: iscsi-pv-busybox image: busybox command: ["/bin/sh", "-c"] args: [ "tail -f /dev/null" ] volumeMounts: - name: iscsi-vol1 mountPath: /var/lib/busybox readOnly: false volumes: - name: iscsi-vol1 persistentVolumeClaim: claimName: iscsi-pvc
Kubernetes実行
以下のコマンドで、永続ボリュームの設定を行う。
$ kubectl apply -f volume
以下のコマンドでpodを起動させる
$ kubectl apply -f pod
動作確認
先ほど起動したpodに入ります。
$ kubectl exec -it iscsi-pv-pod1 /bin/ash
pod内にマウントしたフォルダに向けてファイルを作成する。
# echo hello >> /var/lib/busybox/test.txt
先ほどpodで作成されたファイルが、iSCSIのディスクに作成されていることを確認します。
確認するため、masterノードにiSCSIのディスクをデバイスマウントする。
$ sudo iscsiadm -m node --login
/mntフォルダに先ほどデバイスマウントしたディスクをマウントする
$ sudo mount /dev/sdb /mnt
podが作成ファイルが作成されていることを確認します。
$ ls -la /mnt 合計 8 drwxrwsr-x 2 root 1001 22 10月 14 11:14 . drwxr-xr-x 20 root root 4096 10月 12 18:33 .. -rw-r--r-- 1 root 1001 6 10月 14 11:14 test.txt
ファイルの中身を確認します。
$ cat /mnt/test.txt hello