ラズパイで遊べるkubernetesクラスター環境を構築してみる

# はじめに
kubernetesの勉強のために好きに触れて、時には壊しても問題ない環境が欲しくないですか？
そんな夢のような環境が欲しい！と思って今回お手軽？に自宅で構築してみようと思いました。

家に使われてないラズパイありませんか？
我が家にはなぜか8個ありました。過去の浪費の賜物です！
その中でもスペックが高くて使えそうな以下4つのラズパイを使ってkubernetesクラスターを構築してみようと思います。

- RaspberryPi 4 ModelB 8GB x 3
- RaspberryPi 3 ModelB 1GB x 1

# 構築したい環境
使っていない1TBの外付けHDDもあったので、64GBのmicroSD、必要なLANケーブル、電源関係を購入して以下のような構成を構築していきます。microSDだと扱えるデータも限られるので1TBのHDDをPersistentVolumeとして使えればありがたいです。

### 構成図
<img width="600" alt="Screenshot 2022-12-12 at 8.48.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/4dec6541-d600-5a5b-a757-601799497cd8.png">

各ラズパイと用途は以下のとおりです。固定IPも以下のように設定していきます。
|ラズパイ(メモリ)|用途|IP|
|---|---|---|
|RaspberryPi 4B(8GB)|Masterノード|192.168.1.31|
|RaspberryPi 4B(8GB)|Workerノード|192.168.1.32|
|RaspberryPi 4B(8GB)|Workerノード|192.168.1.33|
|RaspberryPi 3B(1GB)|NAS|192.168.1.30|

### 物理的な完成イメージ
電源とLANケーブルの2本だけが出てますが、完成したらこの箱の中にクラスターが構築されます。
<img width="600" alt="IMG_3587.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/2330dc27-193b-4d8c-4bef-f1f660ee90ff.jpeg">

中はこんな感じ。狭いですが排熱に気をつけつつ配置しています。発熱源は主にHDDと電源です。
<img width="600" alt="IMG_3588.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/a5dc4819-9cdb-9658-b987-d2b833c4cf60.jpeg">

# ラズパイの基本設定
対象：全てのラズパイ 4台

### OSセットアップ
以下よりmicroSDにOSをセットアップするツールをダウンロードしてください。
https://www.raspberrypi.com/software/

今回はUbuntu Server 20.04.5 LTS(64-bit)を使用します。
<img width="600" alt="Screenshot 2022-12-13 at 8.08.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/d6ad4e31-98a5-b815-8bee-73e54db9b656.png">

### 初期設定
OSのセットアップが終了したらそれぞれのラズパイにmicroSDを刺して起動します。この時、各ラズパイのIPを調べる必要があります。macだとbrewでインストールできるnmapを使ってます。以下のように起動前後でコマンドを実行して追加されたIPからラズパイを確認します。https://nmap.org
```
# nmap -sP 192.168.1.0/24
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-12 09:13 JST
Nmap scan report for 192.168.1.1
Host is up (0.020s latency).
Nmap scan report for 192.168.1.2
Host is up (0.019s latency).
     ：
```

新たに追加されたIPを確認してssh接続して初期パスワードを変更後に再度ssh接続します。
※ubuntuの初期パスワードはubuntu
```
# ssh ubuntu@192.168.1.XX
```

最新に更新する。
```
$ sudo apt update
$ sudo apt upgrade
```

ホスト名等変更する。
```
$ sudo hostnamectl set-hostname <HOSTNAME>
$ sudo timedatectl set-timezone Asia/Tokyo
```

### IP固定化
まず `50-cloud-init.yaml`をコピーして、`99-cloud-init.yaml`を作成する。
```
$ sudo cp /etc/netplan/50-cloud-init.yaml /etc/netplan/99-cloud-init.yaml
```
https://qiita.com/yas-nyan/items/9033fb1d1037dcf9dba5

/etc/netplan/99-cloud-init.yamlのeth0を環境に合わせて変更する。
```
network:
    ethernets:
        eth0:
            dhcp4: false 
            dhcp6: false
            optional: true
            addresses: [192.168.1.XX/24]
            gateway4: 192.168.1.1
            nameservers:
              addresses: [192.168.1.1]
    version: 2
```

ラズパイを再起動し、設定した固定IPでssh接続する。
```
$ sudo reboot
```

hostsの設定
`/etc/hosts`に以下を設定する。
```
# kubernetes nodes
192.168.1.30	nas-01
192.168.1.31	master-01
192.168.1.32	worker-01
192.168.1.33	worker-02
```

# kubernetesの共通セットアップ
対象：Masterノード、Workerノード用3台

### IPv6無効化
[公式ドキュメント](https://kubernetes.io/ja/docs/concepts/services-networking/dual-stack/)よりIPv6/IPv4のデュアルスタックというのが出来るようですが今回は無効化します。
`ip -6 a`でIPv6設定が表示されないことを確認する。
```
$ sudo vi /etc/sysctl.conf

<以下追記>
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

$ sudo sysctl -p
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
$ ip -6 a 
```

### iptablesがブリッジを通過するトラフィックを処理できるようにする 
[公式ドキュメント](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#iptablesがブリッジを通過するトラフィックを処理できるようにする)より
```
# br_netfilterモジュールがロードされていることを確認
$ sudo modprobe br_netfilter
$ lsmod | grep br_netfilter
br_netfilter           32768  0
bridge                323584  1 br_netfilter

$ cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sysctl --system
```

### iptablesがnftablesバックエンドを使用しないようにする
[公式ドキュメント](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#iptablesがnftablesバックエンドを使用しないようにする)より

>Linuxでは、カーネルのiptablesサブシステムの最新の代替品としてnftablesが利用できます。iptablesツールは互換性レイヤーとして機能し、iptablesのように動作しますが、実際にはnftablesを設定します。このnftablesバックエンドは現在のkubeadmパッケージと互換性がありません。(ファイアウォールルールが重複し、kube-proxyを破壊するためです。)

```
# レガシーバイナリがインストールされていることを確認してください
sudo apt-get install -y iptables arptables ebtables

# レガシーバージョンに切り替えてください。
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo update-alternatives --set arptables /usr/sbin/arptables-legacy
sudo update-alternatives --set ebtables /usr/sbin/ebtables-legacy
```

### swapをoffにする
[公式ドキュメント](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)より
> - Swapがオフであること。kubeletが正常に動作するためにはswapは必ずオフでなければなりません。

デフォルトでoffでした。環境によってonの場合はoffにしてください。
```
$ free
              total        used        free      shared  buff/cache   available
Mem:        7996680      793396     5748204        4232     1455080     6929472
Swap:             0           0           0
```

### cgroupsの有効化
無効(右端の値が0)の場合は有効(右端の値が0)にしてください。
```
$ cat /proc/cgroups | grep memory
memory	0	104	0

$ sudo vi /boot/firmware/cmdline.txt
# 改行せず最後尾にスペースを開けて追加する
cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory

$ sudo reboot
$ cat /proc/cgroups | grep memory
memory	10	89	1
```

### CRIランタイムとしてcontainerdをインストール
[公式ドキュメント](https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/#containerd)より


#### 必要な設定の追加
手順通り実施する。
```
cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

# 必要なカーネルパラメータの設定をします。これらの設定値は再起動後も永続化されます。
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

sysctl --system
```

#### containerdのインストール
手順通り実施する。
注意：「## Dockerのaptリポジトリの追加」において、ラズパイなので`arch=amd64`を`arch=arm64`にしてます。
```
# (containerdのインストール)
## リポジトリの設定
### HTTPS越しのリポジトリの使用をaptに許可するために、パッケージをインストール
apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common

## Docker公式のGPG鍵を追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -

## Dockerのaptリポジトリの追加
add-apt-repository \
    "deb [arch=arm64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
    stable"

## containerdのインストール
apt-get update && apt-get install -y containerd.io

# containerdの設定
mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# containerdの再起動
systemctl restart containerd
```

### kubeadm、kubelet、kubectlのインストール
[公式ドキュメント](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#kubeadm-kubelet-kubectlのインストール)より
手順通り実施する。
```
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
```

# Masterノードの設定
対象：Masterノード用1台


### コントロールプレーンノードのkubeletによって使用されるcgroupドライバーの設定
[公式ドキュメント](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#コントロールプレーンノードのkubeletによって使用されるcgroupドライバーの設定)より
手順通り実施する。
```
$ sudo vi /etc/default/kubelet
KUBELET_EXTRA_ARGS=--cgroup-driver=containerd #追加する
```

### クラスターの作成
[公式ドキュメント](https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/#systemd)より
以下コマンドを実行してクラスターを作成します。
※環境に応じて`--apiserver-advertise-address`は変更してください。
```
$ sudo kubeadm init --apiserver-advertise-address=192.168.1.31 --pod-network-cidr=10.244.0.0/16
```

最後に出てくるメッセージ`kubeadm join ~`は他のノードを追加する時に必要なのでコピーする。
```
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.1.31:6443 --token XXXXXXXXXXXXXXXX \
	--discovery-token-ca-cert-hash sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

メッセージ中にある以下を実行する。
```
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

`export KUBECONFIG=/etc/kubernetes/admin.conf`とあるが実施せず以下実行する。
※実施ているubuntuはroot userではないので。
```
$ echo 'export KUBECONFIG=$HOME/.kube/config' >> ~/.bashrc
$ source ~/.bashrc
```

### CNIはFlannelを入れる
[公式ドキュメント](https://github.com/flannel-io/flannel#deploying-flannel-manually)より
今回はCNIとしてFlannelを使用します。
```
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
```

ここまで来るとmasterノードでPodが起動してるのが確認できます。
※ステータスがRunningになるまで少し時間かかる場合あります。
```
$ kubectl get pod -A -o wide
NAMESPACE      NAME                                READY   STATUS    RESTARTS   AGE     IP             NODE        NOMINATED NODE   READINESS GATES
kube-flannel   kube-flannel-ds-sj5wp               1/1     Running   0          2m21s   192.168.1.31   master-01   <none>           <none>
kube-system    coredns-787d4945fb-6wczc            1/1     Running   0          9m29s   10.244.0.2     master-01   <none>           <none>
kube-system    coredns-787d4945fb-rzk72            1/1     Running   0          9m29s   10.244.0.3     master-01   <none>           <none>
kube-system    etcd-master-01                      1/1     Running   0          9m43s   192.168.1.31   master-01   <none>           <none>
kube-system    kube-apiserver-master-01            1/1     Running   0          9m41s   192.168.1.31   master-01   <none>           <none>
kube-system    kube-controller-manager-master-01   1/1     Running   0          9m39s   192.168.1.31   master-01   <none>           <none>
kube-system    kube-proxy-g8p6k                    1/1     Running   0          9m29s   192.168.1.31   master-01   <none>           <none>
kube-system    kube-scheduler-master-01            1/1     Running   0          9m45s   192.168.1.31   master-01   <none>           <none>
```

# Workerノードの設定
対象：Workerノード用2台

クラスターにWorkerノードを追加します。
先程、クラスター作成時にコピーしたコマンドをWorkerノードで実行します。
```
$ sudo kubeadm join 192.168.1.31:6443 --token XXXXXXXXXXXXXXXX \
	--discovery-token-ca-cert-hash sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
```

追加後はmasterノードでPodの起動状況が確認できます。
2台分が追加されてます。
```
~$ kubectl get pod -A -o wide
NAMESPACE      NAME                                READY   STATUS    RESTARTS   AGE     IP             NODE        NOMINATED NODE   READINESS GATES
kube-flannel   kube-flannel-ds-sj5wp               1/1     Running   0          13m     192.168.1.31   master-01   <none>           <none>
kube-flannel   kube-flannel-ds-w75g6               1/1     Running   0          93s     192.168.1.33   worker-02   <none>           <none>
kube-flannel   kube-flannel-ds-zwz87               1/1     Running   0          8m22s   192.168.1.32   worker-01   <none>           <none>
kube-system    coredns-787d4945fb-6wczc            1/1     Running   0          20m     10.244.0.2     master-01   <none>           <none>
kube-system    coredns-787d4945fb-rzk72            1/1     Running   0          20m     10.244.0.3     master-01   <none>           <none>
kube-system    etcd-master-01                      1/1     Running   0          20m     192.168.1.31   master-01   <none>           <none>
kube-system    kube-apiserver-master-01            1/1     Running   0          20m     192.168.1.31   master-01   <none>           <none>
kube-system    kube-controller-manager-master-01   1/1     Running   0          20m     192.168.1.31   master-01   <none>           <none>
kube-system    kube-proxy-g8p6k                    1/1     Running   0          20m     192.168.1.31   master-01   <none>           <none>
kube-system    kube-proxy-pbdlk                    1/1     Running   0          93s     192.168.1.33   worker-02   <none>           <none>
kube-system    kube-proxy-rxpcn                    1/1     Running   0          8m22s   192.168.1.32   worker-01   <none>           <none>
kube-system    kube-scheduler-master-01            1/1     Running   0          20m     192.168.1.31   master-01   <none>           <none>
```

追加したnodeにROLESのラベルがついてないのでつけます。
```
$ kubectl get node
NAME        STATUS   ROLES           AGE     VERSION
master-01   Ready    control-plane   23m     v1.26.0
worker-01   Ready    <none>          11m     v1.26.0
worker-02   Ready    <none>          4m18s   v1.26.0

$ kubectl label node worker-01 node-role.kubernetes.io/worker=worker
$ kubectl label node worker-02 node-role.kubernetes.io/worker=worker
$ kubectl get node
NAME        STATUS   ROLES           AGE   VERSION
master-01   Ready    control-plane   29m   v1.26.0
worker-01   Ready    worker          17m   v1.26.0
worker-02   Ready    worker          10m   v1.26.0
```

# NASの構築
対象：NAS用1台

### openmediavaultのインストール
今回はNAS構築用にUIから設定できるopenmediavaultを使用します。
[公式ドキュメント](https://docs.openmediavault.org/en/stable/installation/on_debian.html)より
手順書通り実施する。
Install the openmediavault keyring manually:
```
apt-get install --yes gnupg
wget -O "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc" https://packages.openmediavault.org/public/archive.key
apt-key add "/etc/apt/trusted.gpg.d/openmediavault-archive-keyring.asc"
```


Add the package repositories:
```
cat <<EOF >> /etc/apt/sources.list.d/openmediavault.list
deb https://packages.openmediavault.org/public shaitan main
# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan main
## Uncomment the following line to add software from the proposed repository.
# deb https://packages.openmediavault.org/public shaitan-proposed main
# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan-proposed main
## This software is not part of OpenMediaVault, but is offered by third-party
## developers as a service to OpenMediaVault users.
# deb https://packages.openmediavault.org/public shaitan partner
# deb https://downloads.sourceforge.net/project/openmediavault/packages shaitan partner
EOF
```

Install the openmediavault package:
```
export LANG=C.UTF-8
export DEBIAN_FRONTEND=noninteractive
export APT_LISTCHANGES_FRONTEND=none
apt-get update
apt-get --yes --auto-remove --show-upgraded \
    --allow-downgrades --allow-change-held-packages \
    --no-install-recommends \
    --option DPkg::Options::="--force-confdef" \
    --option DPkg::Options::="--force-confold" \
    install openmediavault-keyring openmediavault

omv-confdbadm populate
```

### openmediavaultにログイン
ブラウザよりNAS用ラズパイのIPにアクセスするとログインが表示されるので初期パスワードでログインします。
ユーザー名：admin、パスワード：openmediavault
※必要に応じてパスワードは変更してください。
<img width="600" alt="Screenshot 2022-12-12 at 12.18.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/9ea8bde7-4e3f-e2bd-38a0-b9201f70b9e7.png">

### ssh接続の有効化
インストール後にNAS用ラズパイへのssh接続が無効になるので有効にします。
<img width="600" alt="Screenshot 2022-12-12 at 12.29.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/778170b6-bcba-db6a-b446-badab84a41df.png">

<img width="600" alt="Screenshot 2022-12-12 at 12.28.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/a6e8d93b-687d-bf9c-0f57-89ef9301e4b6.png">


### HDDをext4フォーマット
フォーマット済のHDDをラズパイに接続して電源入った状態にしてください。
使用済HDDだったのでMacのDisk UtilityでexFATフォーマットしました。
<img width="600" alt="Screenshot 2022-12-11 at 18.39.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/981c10af-38d7-2f5c-3f05-bcf9a9c9a291.png">

デバイスが認識されてることを確認します。
<img width="600" alt="Screenshot 2022-12-12 at 12.38.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/1e94c7e6-4d5f-9563-9be6-8f690328b8f8.png">

パーティション作成します。
```
![Screenshot 2022-12-13 at 16.14.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/3c6c3bbb-0b44-30b6-e6b5-4d70fe2e1ba8.png)
$ sudo fdisk /dev/sda

Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/sda: 931.53 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: External HDD
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 779AF008-0746-478D-9FA0-9AF8650064ED

Device      Start        End    Sectors   Size Type
/dev/sda1      40     409639     409600   200M EFI System
/dev/sda2  411648 1953523711 1953112064 931.3G Microsoft basic data

Command (m for help): d
Partition number (1,2, default 2):

Partition 2 has been deleted.

Command (m for help): g
Created a new GPT disklabel (GUID: AF19F8A0-B693-1740-BBD2-5C14480F685A).

Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-1953525134, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-1953525134, default 1953525134): 1953525134

Created a new partition 1 of type 'Linux filesystem' and of size 931.5 GiB.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
```

ext4でフォーマット
```
$ sudo mkfs.ext4 /dev/sda
mke2fs 1.45.5 (07-Jan-2020)
Found a gpt partition table in /dev/sda
Proceed anyway? (y,N) y
Creating filesystem with 244190646 4k blocks and 61054976 inodes
Filesystem UUID: e87a5965-da7d-41b3-98e3-d031c333a6e9
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
	4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
	102400000, 214990848

Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done
```

### 共有フォルダ設定

プラス+ > ▶マウント よりマウントします。
<img width="600" alt="Screenshot 2022-12-13 at 16.15.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/9f874e8c-abc4-830d-f4cd-368f47064084.png">

共有フォルダ設定をします。
<img width="600" alt="Screenshot 2022-12-13 at 16.21.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/5724065e-33b3-3969-ede1-eaf1468b4365.png">

NFSを有効にします。
<img width="600" alt="Screenshot 2022-12-13 at 16.55.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/c789d715-d800-cd50-9481-02704294c126.png">

NFSでの共有設定をします。
<img width="600" alt="Screenshot 2022-12-13 at 16.27.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/9bf11d98-b7fd-9ecb-34f4-4ec3034db51c.png">

ユーザーやグループに対して共有フォルダの権限を設定します。
※画面はユーザーに対して権限設定してます。
<img width="600" alt="Screenshot 2022-12-13 at 16.29.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/108a379b-2a2e-174a-48a0-6fb58d59cf60.png">

NAS用ラズパイからもHDDを確認
共有設定したHDDが確認できます。
```
$ df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/sda       ext4      916G   48K  870G   1% /srv/dev-disk-by-uuid-15e6566b-02d7-45be-9ad2-7d2a943d885a
```

## クラスターからNASにアクセスできるようにする
Masterノードでnfs共有設定をする。
```
$ sudo apt-get install nfs-common
$ sudo mkdir /mnt/nas
$ sudo mount 192.168.1.30:share /mnt/nas
$ df -hT
Filesystem          Type      Size  Used Avail Use% Mounted on
192.168.1.30:/share nfs4      916G     0  870G   0% /mnt/nas
```

## クラスターからNASへアクセス確認する
Masterノードでファイルを作成して確認する。
```
$ touch /mnt/nas/test.txt
```

絶対パスを取得する。
<img width="600" alt="Screenshot 2022-12-13 at 17.03.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173398/be210cdf-32f8-51fa-1a79-d5739fc6c1bc.png">

NASでファイルを確認する。
```
$ ls -l /srv/dev-disk-by-uuid-15e6566b-02d7-45be-9ad2-7d2a943d885a/share
total 0
-rw-rw-r-- 1 ubuntu users    0 Dec 13 17:02 test.txt
```

# さいごに
壊したり再構築したり自由に出来る環境が出来上がりました。最低限で構築したので、現在品薄状態のラズパイの販売が再開したらさらにノードを追加したり行きたいと思います。これでしばらく遊べそうです。