Raspberry Piクラスターに永続ボリュームを定義してみる

# はじめに

Kubernates の Podのデータは一時的なもので、Podが削除や再起動されると、Podのデータは消えます。

そのため、Kubernates には、Podが削除や再起動しても、データを永続化するための Volumeという仕組みがあります。利用している Raspberry Piクラスターでも、この Volume を使って、データを永続化の方法を確認してみます。


## 作業手順

Kubernates でデータを永続化するための手順は、以下の通りになります。

1.  永続化させるデータを保存するためのストレージを準備

この手順は、Kubernatesのノードから利用可能なストレージを準備する手順になります。
具体的にはNFS/iSCSIなどのストレージであり、Persistane Volumeのプラグインとして、
提供されてるようです。

今回は、Raspberry PIの1台にUSB接続のHDDを接続して、NFSサーバを構築してストレージを定義します。

1.  Kubernates側にストレージに対応するPersistent Volumeリソースを定義

Kubernates でストレージに対応するリソースがPersistent Volumeになります。今回は静的に
Persistent Volumeを構成していますが、StorageClass リソースを利用して、動的に、
Persistent Volumeを構成することもできるそうです。

1.  Persistent Volume を要求するためのPersistent Volume Claimリソースを定義

Kubernates では、Podから直接 Persistent Volumeリソースを利用するのではなく、
Persistent Volume Claimリソースを経由して、Persistent Volume リソースを利用します。
Persistent Volume Claimを経由する理由は、Pod と Persistent Volume リソースが直接依存
関係をもたないようにするためです。

1.  PodにPersistent Volume Claimリソースを登録して、Persistent Volumeを利用する

Pod/Persistent Volume Claim/Persistent Volume/ストレージの関連を自分なりに表現すると以下のようになります。
![PersistentVolume.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155323/38e7377b-15ec-3ef6-09b3-e07a4e47c10b.png)

## ストレージを準備

USB接続のHDDをRaspberry PIに接続して、NFSサーバーを構成するのですが、
他に良質な記事があるので、ご参照ください。

ちなみに、私は fstab の編集にミスして、Raspberry Piが起動しなくなり、
SDカードを別のLinuxマシンにマウントして、編集して直すという醜態をさらしました。
ご注意ください。

苦難を乗り越えて、NSFサーバーのIPアドレスは、192.168.0.218、エクスポートディレクトリ
は /exports/vol01 で私は準備が完了しました。

ラズパイにNFSサーバを構築する
<https://qiita.com/izewfktvy533/items/5106ea8ce110d9e2315e>

Raspberry Piに外付けSSDを増設する
<https://qiita.com/ats030/items/65c5585c5c701841525e>

## Persistent Volumeを定義する

NSFサーバーのIPアドレス、エクスポートしているディレクトリ、要領、アクセスモードを指定して、Persistent Volume リソースを定義する YAML ファイルを作成します。

```yaml:nfs-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: data-vol01
  labels:
    volume: my-data-vol01
spec:
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 1Gi
  nfs:
    server: 192.168.0.218
    path: /exports/vol01
```

YAMLファイルを apply して、Persistent Volume リソースを作成します。作成されたことは、
「kubectl get pv」で確認することができます。

```shell
$ kubectl apply -f nfs-volume.yaml 
created
# 確かに PersistentVolume リソースが作成されている
$ kubectl get pv
NAME         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
data-vol01   1Gi        RWX            Retain           Available                                   95s
```


## Persistent Volume Claimを定義

Persistent Volume リソースを要求するための、Persistent Volume Claimリソースを定義する
ためのYAMLファイルを作成します。要領、アクセスモードを指定します。

```yaml:nfs-volume-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-vol01
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      volume: my-data-vol01
```

YAML ファイルが作成できたので、Persistent Volume Claim リソースを定義します。

YAMLファイルを apply して、Persistent Volume Claimリソースを作成します。作成されたことは、「kubectl get pvc」で確認することができます。

```shell
$ kubectl apply -f nfs-volume-claim.yaml
created
# 確かに PersistentVolumeClaim リソースが作成されている
$ kubectl get pvc
NAME         STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-vol01   Bound    data-vol01   1Gi        RWX                           13s
```


## Podを作成する

```yaml:kuard-pod-col-pvc.yaml
$ cat  
apiVersion: v1
kind: Pod
metadata:
  name: kuard
spec:
 volumes:
   - name: data-vol01
     persistentVolumeClaim:
       claimName: data-vol01
 containers:
   - image: rasp-registry:5000/kuard-arm:1
     name: kuard
     volumeMounts:
       - mountPath: "/data"
         name: data-vol01
     ports:
       - containerPort: 8080
         name: http
```

最後に Podを作成します。

```shell
$ kubectl apply -f kuard-pod-col-pvc.yaml.yaml
created
```

Podに対話モードで接続して、PodからNSFサーバーにあるファイルが参照できるかを確認します。

```shell
$ kubectl exec kuard -it -- ash
# ls -al /data
```