[02] [k8s]オンプレで静的プロビジョニングを実践してみる (NFS環境)


# 概要

Kubernetes (k8s) の動的プロビジョニングの動作確認のために、
次を実践して、下表の通り 1マスタ・1ノードのオンプレ上に NFS を構築した.
・[[01] オンプレでの動的プロビジョニング用 NFS サーバの構築手順メモ (サーバ側)](https://qiita.com/robozushi10/items/d0ac81161b576104e1ca)
・[[02] オンプレでの動的プロビジョニング用 NFS サーバの構築手順メモ (クライアント側)](https://qiita.com/robozushi10/items/2059127eb7dcafe8a52d)


本記事では **オンプレ上で k8s を使って静的プロビジョニングを実践したときの手順** を記す.

|No|用途|ノード名|形態|IP|OS|NIC|備考|
|:--|:--|:--|:--|:--|:--|:--|:--|
|1|k8sマスタ|PC1|物理ホスト|192.168.10.115|Ubuntu18.04|eno1|NFSサーバである.<br/>/export/nfs を公開している.|
|2|k8sノード|node01|物理ホスト|192.168.10.84|Ubuntu18.04|eno1|NFSクライアントにする|


# 参考にしたサイトおよび書籍

|URL|備考|
|:--|:--|
|https://www.server-world.info/query?os=Ubuntu_20.04&p=nfs&f=1||
|[15Stepで習得 Dockerから入るKubernetes](http://www.ric.co.jp/book/contents/book_1161.html)|K8s だけでなく、Ansible, Vagrant, GlusterFS のことなども学べる.|
|https://github.com/takara9/vagrant-k8s|[『15Stepで習得 Dockerから入るKubernetes』](http://www.ric.co.jp/book/contents/book_1161.html)の著者が公開されている GitHub.<br/>Vagrant や Ansible コードを公開してくださっている.|
|https://github.com/takara9/vagrant-kubernetes|同上|
|https://github.com/takara9/codes_for_lessons|同上|
|https://nextpublishing.jp/book/12197.html|『解体kubeadm　フェーズから読み解くKubernetesクラスタ構築ツールの全貌』を参考にして 1マスタ・1ノードを構築した.|
|http://netstars.co.jp/kubestarblog/kubestarblog5/k8s/|5.《一目で分かる K8s 永続的なストレージプロセス》|
|https://qiita.com/YasuhiroABE/items/2e18bb546beea4660a99||



# 手順

## 1. PV と PVC のマニフェストを作成する

下図左が PV, 下図右が PVC である.
storageClassName の名称は、両マニフェストで一致していれば何でも良い.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/1024d1d2-d1ab-b5fd-f851-34a261b18730.png)

## 2. NFS サーバが公開するディレクトリ下にサブディレクトリを 100個作成する

下表 No 1 の物理PC での操作である.

|No|用途|ノード名|形態|IP|OS|NIC|備考|
|:--|:--|:--|:--|:--|:--|:--|:--|
|1|k8sマスタ|PC1|物理ホスト|192.168.10.115|Ubuntu18.04|eno1|NFSサーバである.<br/>/export/nfs を公開している.|

### 検証用ディレクトリの作成

検証用に 100個のディレクトリを作っておく.

`/export/nfs/pv0001/` 〜 `/export/nfs/pv0100/` を作成する

```bash
$ bash -c 'for i in `seq -w 0001 0100`; do sudo mkdir -p /export/nfs/pv$i; done'
```

### アクセス権を付与しておく

検証用なので、余計な問題が生じないように 777 にしておく.

```bash
$ sudo chmod 777 /export/nfs/pv*
```

## 3. PV 用マニフェスト「nfs-pv0001.yml」を作成する

### 公式ドキュメント

https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistent-volumes


### nfs-pv.yml

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce #! Once: 一度に読み書きできるノードは1つだけ
  persistentVolumeReclaimPolicy: Retain
  storageClassName: pv0001
  nfs:
    path: /export/nfs/pv0001
    server: 192.168.10.115
```

## 4. マニフェスト「nfs-pv0001.yml」を適用する

```bash
$ kubectl apply -f nfs-pv0001.yml 
persistentvolume/pv0001 created
```


## 5. 現在の PV の状態を見る (kubectl get pv -o wide)

```bash
$ kubectl get pv -o wide
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE   VOLUMEMODE
pv0001   5Gi        RWO            Retain           Bound    default/my-pvc0001                           73m   Filesystem
```

## 6. PVC 用のマニフェスト「nfs-pvc0001.yml」を作成する

### 公式ドキュメント

https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims

### nfs-pvc0001.yml

下記 💊 は、後述する「nfs-pod0001.yml」における 💊 と対応している.

```yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc0001 #! 💊
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 5Gi
  storageClassName: pv0001

```

## 7. PVC 用のマニフェスト「nfs-pvc0001.yml」を適用する

```yaml
$ kubectl apply -f nfs-pvc0001.yml
```

## 8. 現在の pv, pvc の状態を確認する

```bash
$ kubectl get pv,pvc -o wide
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE   VOLUMEMODE
persistentvolume/pv0001   5Gi        RWO            Recycle          Bound    default/my-pvc0001   pv0001                  14s   Filesystem

NAME                               STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
persistentvolumeclaim/my-pvc0001   Bound    pv0001   5Gi        RWO            pv0001         2s    Filesystem
```

## 9. Pod「nginx」から /export/nfs/pv0001 をマウントするためのマニフェスト「nfs-pod0001.yml」を作成する

### nfs-pod0001.yml

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
spec:
  containers:
    - name: my-nginx
      image: nginx
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 80
          name: web
      volumeMounts:
      - mountPath: /usr/share/nginx/html
        name: nginx-volume
  volumes:
    - name: nginx-volume
      persistentVolumeClaim:
        # 作成した PVC 名
        claimName: my-pvc0001 #! 💊 
```

## 10. Pod「nginx」から /export/nfs/pv0001 をマウントするためのマニフェスト「nfs-pod0001.yml」を適用する

```bash
$ kubectl apply -f nfs-pod0001.yml
```

## 11. PV, PVC, Pod の状態を見る (kubectl get pv,pvc,pod -o wide)

下記🌟より、PVC と PV が存在している.
また、🛑 から Pod「my-nginx」が稼働している.

```bash
$ kubectl get pv,pvc,po -o wide
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE   VOLUMEMODE
persistentvolume/pv0001   5Gi        RWO            Retain           Bound    default/my-pvc0001🌟                         77m   Filesystem

NAME                               STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
persistentvolumeclaim/my-pvc0001   Bound  🌟pv0001   5Gi        RWO                           77m   Filesystem

NAME                              READY   STATUS        RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
pod/my-nginx                      1/1   🛑Running       0          5m44s   10.244.1.95   node01    <none>           <none>
略
```

## 12. 動作確認をする

### Pod「my-nginx」にログインする

```bash
$ kubectl exec -it my-nginx -- bash
```

### 192.168.10.115 の /export/nfs/pv0001 をマウントしていることを確認する

下記🛑より、マウントに成功している.

```bash
root@my-nginx:/# df -hT
Filesystem                        Type     Size  Used Avail Use% Mounted on
overlay                           overlay   39G  3.7G   36G  10% /
tmpfs                             tmpfs     64M     0   64M   0% /dev
tmpfs                             tmpfs    3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/sda1                         ext4      39G  3.7G   36G  10% /etc/hosts
shm                               tmpfs     64M     0   64M   0% /dev/shm
192.168.10.115:/export/nfs/pv0001 nfs      912G  273G  594G  32% /usr/share/nginx/html🛑
tmpfs                             tmpfs    3.9G   12K  3.9G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                             tmpfs    3.9G     0  3.9G   0% /proc/acpi
tmpfs                             tmpfs    3.9G     0  3.9G   0% /proc/scsi
tmpfs                             tmpfs    3.9G     0  3.9G   0% /sys/firmware
```

### マウントポイント「/usr/share/nginx/html/.」にデータを作成する

```bash
root@my-nginx:/# pwd > /usr/share/nginx/html/sample
root@my-nginx:/# date >> /usr/share/nginx/html/sample
root@my-nginx:/# cat /usr/share/nginx/html/sample 
/
Sat Jun 12 01:00:42 UTC 2021
```

### Pod「my-nginx」を削除する

```bash
$ kubectl delete -f nfs-pod0001.yml 
pod "my-nginx" deleted

$ kubectl get pod my-nginx
Error from server (NotFound): pods "my-nginx" not found
```

### Pod「my-nginx」を再度作成し、再び /export/nfs/pv0001/ をマウントする

```bash
$ kubectl apply -f nfs-pod0001.yml 
pod/my-nginx created

$ kubectl get pod my-nginx -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
my-nginx   1/1     Running   0          5s    10.244.1.96   node01   <none>           

$ kubectl get pv,pvc -o wide
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE    VOLUMEMODE
persistentvolume/pv0001   5Gi        RWO            Retain           Bound    default/my-pvc0001                           103m   Filesystem

NAME                               STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE    VOLUMEMODE
persistentvolumeclaim/my-pvc0001   Bound    pv0001   5Gi        RWO                           103m   Filesystem

```


### Pod「my-nginx」にログインして前回作成した /usr/share/nginx/html/sample が残っているかを確認する

```bash
root@my-nginx:/# cat /usr/share/nginx/html/sample 🛑
/
Sat Jun 12 01:00:42 UTC 2021
```
　

以上.