Immich をk8sに構築する
知り合いがImmichをセルフホストしてるのを見て気になったので自分でも建ててみました。
その時にk8s初心者ながら困ったことをつらつらと書いていこうと思います。
文章の整理を効率化するため、ChatGPTとNotionAIを使用して文章を校正しているので、表現が少し不自然かもしれません。
0. K8s(k0s)構築編
特に困ったことはありませんでした。
K0sというk8sクラスタを簡単に構築できるソフトウェアを使用しました。
ただし、本番環境での使用については検討が必要なため、今後調査する予定です。
1. Immich構築
構築に約4時間を要しました。
公式ドキュメントのKubernetesの項目には、
You can deploy Immich on Kubernetes using the official Helm chart.
You can view some examples of how other people run Immich on Kubernetes, using the official chart or otherwise.
これだけの情報では十分ではありませんでした。
調べてみると、helm
を使用してデプロイする方法があることがわかりました。helm install --create-namespace --namespace immich immich immich/immich -f values.yaml
というコマンドを使用します。
ただし、
こちらの情報によると、PostgreSQL
は別途自分でセットアップする必要があります。
そこで、これもK8s上に構築することにしました。
1.1 PostgreSQL 構築 (Cloudnative PGの構築)
幸いなことに、先ほどのGitHub Issueに解決策が記載されていました。
https://github.com/immich-app/immich-charts/issues/149#issuecomment-2671165919
具体的には、
cloudnative PG
を利用して構築します。
実際にやってみると、それほど複雑ではありませんでした。
https://github.com/cloudnative-pg/cloudnative-pg/blob/main/docs/src/installation_upgrade.md
上記の2つのドキュメントを参照すれば、手順は理解できるはずです。
インストール方法は2つあり、
Helmを使用する場合はこちらのドキュメントを参照してください。
私はDirect Install
方式を選択したので、以下ではその手順を説明します。
curl -sSfL \\
<https://raw.githubusercontent.com/cloudnative-pg/artifacts/main/manifests/operator-manifest.yaml> | \\
kubectl apply --server-side -f -
驚くことに、上記のコマンドを入力するだけで完了です。
とても簡単ですね。
次に、公式の指示に従って一度テストデプロイを実行してみましょう。
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example
spec:
instances: 3
storage:
size: 1Gi
これが正常にデプロイできたら問題ないと判断できます。
一度このテスト用デプロイメントを削除してから、本番用のデプロイメントを実行します。
kind: Cluster
metadata:
name: immich-postgres
spec:
# At the time of writing, immich is only compatible with pgvecto.rs <0.4. Latest postgres image with that version is 16.5.
imageName: ghcr.io/tensorchord/cloudnative-pgvecto.rs:16.5-v0.3.0@sha256:be3f025d79aa1b747817f478e07e71be43236e14d00d8a9eb3914146245035ba
instances: 1
postgresql:
shared_preload_libraries:
- "vectors.so"
managed:
roles:
- name: immich
superuser: true
login: true
bootstrap:
initdb:
database: immich
owner: immich
secret:
name: immich-postgres-user
postInitSQL:
- CREATE EXTENSION IF NOT EXISTS "vectors";
- CREATE EXTENSION IF NOT EXISTS "cube" CASCADE;
- CREATE EXTENSION IF NOT EXISTS "earthdistance" CASCADE;
storage:
size: 4Gi
storageClass: immich-postgres
---
apiVersion: v1
kind: Secret
metadata:
name: immich-postgres-user
namespace: immich-new
type: Opaque
stringData:
username: immich
password: "FIXME"
FIXMEとなっているパスワードを適切な値に変更してからデプロイする必要があります。
大切
デプロイが完了しても、まだImmichをデプロイできる状態ではありません。
1.2 PVCのデプロイ
私はSynologyのNASをNFSとして設定して使用しました。
この設定が一番難しかったです。
必須条件:
- NAS側のボリュームと共有フォルダが既に作成されていること
設定手順:
- NASのコントロールパネルから「共有フォルダ」を開きます。
- K8sのストレージとして使用したいフォルダを選択し、「編集」をクリックします。
- 「NFS権限」タブを選択します。
- NFSサービスの有効化を求められた場合は、指示に従って有効化します。
- 「作成」を選択し、
ホスト名または IP
欄にローカルIPの範囲を入力します。
例:サーバーのIPが192.168.2.0/24
の場合、同じ値を入力します。
- 以下の設定はデフォルトのままにします:
・特権設定
・Squash設定(変更すると問題が発生する可能性があります)
・セキュリティ設定
- 「非優先ポートからの接続」と「マウントしたサブフォルダへのアクセスを許可する」にチェックを入れます。
- 設定を保存します。
- 左下に表示されるマウントパスは後で必要になるのでメモしておきます。
次に、k8s側でNFSを使用できるように設定します。
まず、NFSパッケージをインストールします:
sudo apt install nfs-common
次に、以下のコマンドでNFSプロビジョナーをセットアップします:
helm install nfs-provisioner nfs-provisioner/nfs-provisioner --set nfs.server={NASのIP} --set nfs.path={マウントパス} --set storageClass.name=nas-storage --set storageClass.defaultClass=true
最後に、Persistent VolumeとPersistent Volume Claimsを作成します。
apiVersion: v1
kind: PersistentVolume
metadata:
name: immich
namespace: immich
spec:
capacity:
storage: {容量の}
nfs:
server: {NASのIP}
path: {マウントパス}
accessModes:
- ReadWriteMany
storageClassName: nas-storage
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: immich-pvc
namespace: immich
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
volumeName: immich
storageClassName: nas-storage
このような形でPersistent VolumeとPersistent Volume Claimsを作成できます。
1.3 Immichの構築
これで準備が整いましたので、Immichの構築に進めます。
values.yaml
の設定については、
公式のものはこちら
以下に私の設定ファイル(ほぼ公式のものと同じですが)を記載します。
env:
REDIS_HOSTNAME: '{{ printf "%s-redis-master" .Release.Name }}'
DB_HOSTNAME: immich-postgres-rw.immich.svc.cluster.local
DB_USERNAME:
secretKeyRef:
name: immich-postgres-user
key: username
DB_DATABASE_NAME: immich
DB_PASSWORD:
secretKeyRef:
name: immich-postgres-user
key: password
IMMICH_MACHINE_LEARNING_URL: '{{ printf "http://%s-machine-learning:3003" .Release.Name }}'
image:
tag: v1.11
immich:
metrics:
# Enabling this will create the service monitors needed to monitor immich with the prometheus operator
enabled: false
persistence:
# Main data store for all photos shared between different components.
library:
# Automatically creating the library volume is not supported by this chart
# You have to specify an existing PVC to use
existingClaim: immich-pvc
trash:
enabled: true
days: 30
# Dependencies
redis:
enabled: true
architecture: standalone
auth:
enabled: false
# Immich components
server:
enabled: true
image:
repository: ghcr.io/immich-app/immich-server
pullPolicy: IfNotPresent
ingress:
main:
enabled: false
annotations:
# proxy-body-size is set to 0 to remove the body limit on file uploads
nginx.ingress.kubernetes.io/proxy-body-size: "0"
hosts:
- host: immich.local
paths:
- path: "/"
tls: []
machine-learning:
enabled: true
image:
repository: ghcr.io/immich-app/immich-machine-learning
pullPolicy: IfNotPresent
env:
TRANSFORMERS_CACHE: /cache
persistence:
cache:
enabled: true
size: 10Gi
# Optional: Set this to pvc to avoid downloading the ML models every start.
type: emptyDir
accessMode: ReadWriteMany
# storageClass: your-class
これを保存したら、あとは helm install コマンドを実行して待つだけでデプロイが完了するはずです。
helm install --create-namespace --namespace immich immich immich/immich -f values.yaml
困ったこと
NFSの設定を変更しすぎて権限関係が複雑になり、トラブルに
SynologyのNFSでSquashの設定をいじらない方がいいと書いたのは、この問題で2時間も苦労したからです!
もしファイルの権限回りが変になったりしたら
NFSの設定を直して、すべてを削除してから再デプロイするのがベストです。
また、Storage Classesなどのストレージ関連の設定を変更した場合も、すべてを一度削除してから再デプロイする必要があります。
私の環境では、この方法でしか問題を解決できませんでした。