0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HelmでRedmineをデプロイする際にNFSを使った永続ボリュームを設定する方法

Posted at

はじめに

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を使った永続ボリュームを利用する方法を紹介しました.
同様の構成を検討している方の参考になれば幸いです.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?