rke2クラスタをオンプレに構築したはいいが、PVCが使えないのでLonghornを導入してPodに外付けのストレージをアタッチできるようにします。
インストール
インストール要件のチェック
いろいろ要件があるようなのでチェック
-
Installation Requirements | Longhorn
- containerd v1.3.7+
- Kubernetes >= v1.25
-
open-iscsiがインストールされていること、iscsidデーモンが起動していること - NFSv4クライアントがインストールされていること
- ファイルシステムが
ext4XFSのいずれかであること -
bashcurlfindmntgrepawkblkidlsblkがインストールされていること
sudo apt update && sudo apt install -y open-iscsi nfs-common gawk util-linux
helmでインストール
コントロールノードにストレージがスケジューリングされるのは困るので、ストレージスケジュール対象のノードにラベルを設定します。
kubectl label node <WORKER_NODE> node.longhorn.io/create-default-disk=true
リポジトリの追加
helm repo add longhorn https://charts.longhorn.io
helm repo update
helm search repo longhorn
# NAME CHART VERSION APP VERSION DESCRIPTION
# longhorn/longhorn 1.10.1 v1.10.1 Longhorn is a distributed block storage system ...
values.yamlの作成
values.yaml
# https://github.com/longhorn/longhorn/blob/master/chart/values.yaml
defaultSettings:
# "node.longhorn.io/create-default-disk=true" ラベルが付与されたノードに対してのみ、デフォルトのディスクを作成します
createDefaultDiskLabeledNodes: true
persistence:
defaultClass: true
# レプリカを2つのノードに分散させる設定
defaultClassReplicaCount: 2
インストール
CHART_VERSION="1.10.1"
helm upgrade -i longhorn longhorn/longhorn \
--namespace longhorn-system \
--create-namespace \
--version ${CHART_VERSION} \
-f values.yaml
http://longhorn-frontend.longhorn-system.svc.cluster.local:80 にWeb UIが公開されるので見たければIngressを設定
動作確認
namespace作成
kubectl create namespace sample-longhorn
ブロックストレージとして直接マウントする方式
- ブロックストレージとして直接マウントします。
- 1つのPodからしかマウントできません。
- DBなど高速なI/Oが必要なアプリケーション向けです。
longhorn-block-vol.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-block-pvc
namespace: sample-longhorn
spec:
accessModes:
- ReadWriteOnce # ReadWriteOnceはブロックボリューム用 (1Podにのみマウント可能)
storageClassName: longhorn
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: longhorn-block-app
namespace: sample-longhorn
spec:
replicas: 1
selector:
matchLabels:
app: longhorn-block-app
template:
metadata:
labels:
app: longhorn-block-app
spec:
restartPolicy: Always
containers:
- name: write-date
image: busybox
# 5秒ごとに /data/test.log に現在時刻を追記し続けるコマンド
command: ["/bin/sh"]
args: ["-c", "echo 'Longhorn Volume Test Start' >> /data/test.log; while true; do date >> /data/test.log; sleep 5; done"]
volumeMounts:
- name: longhorn-vol
mountPath: /data
volumes:
- name: longhorn-vol
persistentVolumeClaim:
claimName: longhorn-block-pvc
kubectl apply -f longhorn-block-vol.yaml
PodがRunning、PVCがBoundになっていることを確認します。
kubectl get -n sample-longhorn pod -l app=longhorn-block-app
# NAME READY STATUS RESTARTS AGE
# longhorn-block-app-97f949f49-j5hhw 1/1 Running 0 12m
kubectl get -n sample-longhorn pvc longhorn-block-pvc
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
# longhorn-block-pvc Bound pvc-9843f92a-8222-476f-bc9c-2890dd681477 1Gi RWO longhorn <unset> 13m
Pod内でファイルが追記されていることを確認します。
kubectl -n sample-longhorn exec -it deployment/longhorn-block-app -- tail -f /data/test.log
# Thu Dec 4 14:34:40 UTC 2025
# Thu Dec 4 14:34:45 UTC 2025
# Thu Dec 4 14:34:50 UTC 2025
# ...
削除
kubectl delete -f longhorn-block-vol.yaml
NFSとしてマウントする方式
- Longhornが提供するNFSサーバーを介してマウントします。
- 複数のPodからマウントできます。
- 共有ストレージが必要なアプリケーション(Nginxの静的コンテンツなど)向けです。
longhorn-shared-vol.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-shared-pvc
namespace: sample-longhorn
spec:
accessModes:
- ReadWriteMany # ReadWriteManyは共有ボリューム用 (複数Podにマウント可能)
storageClassName: longhorn
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: longhorn-shared-app
namespace: sample-longhorn
spec:
replicas: 2
selector:
matchLabels:
app: longhorn-shared-app
template:
metadata:
labels:
app: longhorn-shared-app
spec:
containers:
- name: busybox
image: busybox
# どのPodが書いたかわかるようにホスト名を追記するテスト
command: ["/bin/sh"]
args: ["-c", "while true; do echo \"$(hostname) writing to shared vol\" >> /data/test.log; sleep 5; done"]
volumeMounts:
- name: longhorn-vol
mountPath: /data
volumes:
- name: longhorn-vol
persistentVolumeClaim:
claimName: longhorn-shared-pvc
kubectl apply -f longhorn-shared-vol.yaml
PodがRunning、PVCがBoundになっていることを確認します。
kubectl get -n sample-longhorn pod -l app=longhorn-shared-app
# NAME READY STATUS RESTARTS AGE
# longhorn-shared-app-5cbf97764d-bltk5 1/1 Running 0 42s
# longhorn-shared-app-5cbf97764d-mg6kc 1/1 Running 0 42s
kubectl get -n sample-longhorn pvc longhorn-shared-pvc
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
# longhorn-shared-pvc Bound pvc-cb11d9a9-9604-41b4-b5e2-c9644182f4dc 1Gi RWX longhorn <unset> 60s
Pod内でファイルが追記されていることを確認します。
kubectl -n sample-longhorn exec -it deployment/longhorn-shared-app -- tail -f /data/test.log
# longhorn-shared-app-5cbf97764d-bltk5 writing to shared vol
# longhorn-shared-app-5cbf97764d-mg6kc writing to shared vol
# longhorn-shared-app-5cbf97764d-bltk5 writing to shared vol
# longhorn-shared-app-5cbf97764d-mg6kc writing to shared vol
# ...
削除
kubectl delete -f longhorn-shared-vol.yaml