はじめに
Kubernetes上でBitnami Helm Chartを使ってRedmineを構築し,永続ボリュームとしてSynology NASをNFS経由で使えるようにしました.
私が実際に構築した際の手順を記録しておきます.
この記事はRedmine を Helm で初めてデプロイする際に,最初から NFS を使った永続ボリュームを設定したい方に向けています
環境構成
- Kubernates:
v1.30.6+k3s1
- Helm:
v3.17.3
- Redmine: Bitnami Helm Chart
redmine-32.2.5
- NFSサーバ: Synology NAS
1. NFSの準備
RedmineのPVをNFSで扱うために,以下の準備を行いました.
1-1. NAS側でNFS共有ディレクトリを作成
Synology NASの管理画面で以下のようなNFS共有を作成しました.
- 共有フォルダ名:redmine-nfs
- パス:/volume1/redmine-nfs
- アクセス許可:RedmineをデプロイしているkubernetesノードのIPアドレスを許可
1-2. Kubernetesノードにnfs-commonをインストール
ノード側でNFSマウントができるように,各ノードに以下をインストールしました.
sudo apt-get install nfs-common
kubernetesクラスターを使用している場合,マスターノードだけでなく全てのノードに対してインストールを行ってください.
1-3. NFS用のProvisionerをHelmでデプロイ
Helmの nfs-subdir-external-provisioner を使用し,NFS用のStorageClassを作成しました.
NFS用のStorageClassはクラスター全体で利用できるリソースですが,それを動作させるpodを動かすためのネームスペースを作成し,そこに対してデプロイするのがいいと思います.
今回はnfsというネームスペースにデプロイしています.
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm install nfs nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --set nfs.server=<NASのIPアドレス> --set nfs.path=<共有フォルダのパス> -n nfs
1-4. StorageClassの確認
デプロイ後,以下のコマンドで nfs-client というStorageClassが追加されていることを確認しました.
kubectl get strageclass
出力例
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 207d
nfs-client cluster.local/nfs-subdir-external-provisioner Delete Immediate true 2d9h
この nfs-client を values.yaml でRedmineのPVCに指定することで,NFSへの切り替えが可能になります.
StorageClass が存在していても,NFS Provisioner が正常に動いていなければ意味がありません.
以下のコマンドでNFS Provisionerのpodが起動しているかを確認しました.
kubectl get pod -n nfs
出力例
NAME READY STATUS RESTARTS AGE
nfs-subdir-external-provisioner-6dc4f545f-c5fnw 1/1 Running 0 2d9h
2. RedmineのHelmデプロイ
2-1. values.yamlの準備
Helm チャートに含まれている values.yaml をベースに,必要な項目のみを上書きします.
この values.yaml にある設定のうち,以下のように項目を編集しました.
persistence:
storageClass: "nfs-client"
storageClassをnfs-clientと明示します.
私はRedmineとmariaDBの両方に対して個別にstorageClass: "nfs-client"と指定しましたが,このvalues.yamlにはglobal.defaultStorageClassがあるのでそこで指定してもいいかもしれません.
私は作業時にはglobal.defaultStorageClassに気が付けませんでした.
values.yaml 内では,MariaDB の root パスワード(auth.rootPassword)や,Redmine の公開用ポート番号(例:service.nodePorts.http)などの設定も指定できます
2-2. Helmリポジトリの追加と更新
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
Helm Chart の提供元は Bitnamiです.
redmine は公式チャートに含まれています.
2-3. Namespaceの作成
任意ですが,運用の管理のためにRedmine用のネームスペースの作成をお勧めします.
kubectl create namespace redmine
2-4. RedmineのHelmデプロイ
こちらのコマンドを使用してデプロイしました.
helm install my-redmine oci://registry-1.docker.io/bitnamicharts/redmine -n redmine -f values.yaml
- my-redmine:リリース名(任意に変更可能)
- -n redmine:redmineというネームスペースにデプロイ
- -f values.yaml:先ほどカスタマイズしたvalues.yamlを指定
出力例
Pulled: registry-1.docker.io/bitnamicharts/redmine:32.2.5
Digest: sha256:120baaa62fc616851a0189cab4009b08354ecdf3e543ceacb122f4c3666e1941
NAME: my-redmine
LAST DEPLOYED: Thu Jun 5 00:31:45 2025
NAMESPACE: redmine
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: redmine
CHART VERSION: 32.2.5
APP VERSION: 6.0.5
Did you know there are enterprise versions of the Bitnami catalog? For enhanced secure software supply chain features, unlimited pulls from Docker, LTS support, or application customization, see Bitnami Premium or Tanzu Application Catalog. See https://www.arrow.com/globalecs/na/vendors/bitnami for more information.
** Please be patient while the chart is being deployed **
1. Get the Redmine URL:
export NODE_PORT=$(kubectl get --namespace redmine -o jsonpath="{.spec.ports[0].nodePort}" services my-redmine)
export NODE_IP=$(kubectl get nodes --namespace redmine -o jsonpath="{.items[0].status.addresses[0].address}")
echo "Redmine URL: http://$NODE_IP:$NODE_PORT/"
2. Login with the following credentials
export REDMINE_USERNAME=user
export REDMINE_PASSWORD=$(kubectl get secret --namespace "redmine" my-redmine -o jsonpath="{.data.redmine-password}" | base64 -d)
echo Username: $REDMINE_USERNAME
echo Password: $REDMINE_PASSWORD
You can access the DB using the following password:
export MARIADB_PASSWORD=$(kubectl get secret --namespace "redmine" my-redmine-mariadb -o jsonpath="{.data.mariadb-password}" | base64 -d)
⚠ SECURITY WARNING: Original containers have been substituted. This Helm chart was designed, tested, and validated on multiple platforms using a specific set of Bitnami and Tanzu Application Catalog containers. Substituting other containers is likely to cause degraded security and performance, broken chart features, and missing environment variables.
Substituted images detected:
- docker.io/bitnami/redmine:6.0.4-debian-12-r6
- docker.io/bitnami/os-shell:12-debian-12-r42
⚠ WARNING: Original containers have been retagged. Please note this Helm chart was tested, and validated on multiple platforms using a specific set of Tanzu Application Catalog containers. Substituting original image tags could cause unexpected behavior.
Retagged images:
- docker.io/bitnami/redmine:6.0.4-debian-12-r6
- docker.io/bitnami/os-shell:12-debian-12-r42
3. 動作確認
3-1. podの起動確認
以下のコマンドを実行しました.
kubectl get pods -n redmine
my-redmine(先ほど指定したリリース名)及びmy-redmine-mariaDBのpodのSTATUSがRunningであれば正常に起動しています.
出力例
NAME READY STATUS RESTARTS AGE
my-redmine-75f8b76c9c-x99hp 1/1 Running 0 2d8h
my-redmine-mariadb-0 1/1 Running 0 2d9h
3-2. PVCの確認
以下のコマンドを実行しました.
kubectl get pvc -n redmine
- Redmine用のPVC
- MariaDB用のPVC
の両方のSTATUSがBoundと表示されていて,STORAGECLASSがnfs-clientであればNFS経由でストレージが正しく接続されています.
出力例
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
data-my-redmine-mariadb-0 Bound pvc-eb61ab83-f3b7-4696-9d80-beb34f18b289 8Gi RWO nfs-client <unset> 2d9h
my-redmine Bound pvc-e4ceff1f-83b1-483a-bc03-7f48082b3acf 8Gi RWO nfs-client <unset> 2d9h
3-3. RedmineのWebUIへのアクセス確認
以下のコマンドを実行し,EXTERNAL-IP または NodePort を確認し,ブラウザから Redmine にアクセスできるかを確認します.
kubectl get svc -n redmine
出力例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-redmine NodePort 10.43.34.142 <none> 80:XXXXX/TCP 2d9h
my-redmine-mariadb ClusterIP 10.43.32.162 <none> 3306/TCP 2d9h
XXXXXはポート番号です.values.yaml内で指定することができるので,実際のポートが環境に応じて異なります.
3-4. ファイルのアップロード確認
チケットを作成し,ファイルを添付することができるか確認します.
その後,NAS上もしくはRedmineのpod内でアップロードしたファイルが確認できれば永続化の動作も正常です.
podを再起動してもファイルが保持されているか確認してください
おわりに
RedmineをHelm ChartでKubernetesにデプロイする際に,NFSを使った永続ボリュームを利用する方法を紹介しました.
同様の構成を検討している方の参考になれば幸いです.