akkomaを自分でビルドしてarm64/amd64が混在したkubernetesクラスタにデプロイする

経緯

自宅でkubernetesクラスタを構築し、長年の課題だった自宅サーバの可用性が大幅に向上した。これでやっとサービスの公開に移れる。ということで、今回は前々から立てたかったmastodon互換1のおひとり様インスタンスとしてakkoma2インスタンスを構築することにした。

で、構築の過程で以下のような問題が発生したのでそれについてまとめておく。

本記事で扱うこと

本記事で扱わないこと

バージョン情報

マルチアーキテクチャなイメージのビルト

gitリポジトリのpull、チェックアウト

公式のリポジトリにDockerfileも入っているので、クローンする

$ git clone https://akkoma.dev/AkkomaGang/akkoma.git -b stable
$ cd akkoma

今後のことを考え、イメージはちゃんとバージョン管理しておきたかったので、確認する。

$ git log --oneline --graph
* ebfb617b2 (HEAD -> stable, origin/stable) Update .woodpecker/build-amd64.yml
* 0af8e9313 (tag: v3.10.4) bump version
* 98a64ab14 Mix format
* 94d1af2c4 Disallow nil hosts in should_federate
* 43c5fd5db bullseye build (you owe me for this one)

厳密には1コミット進んでいるが、v3.10.4が最新のステーブルのバージョンと考えてよさそう。

イメージ/マニフェストのビルド

我が家のクラスタはamdとarmが混在している3ため、マルチアーキテクチャなイメージを作る。

$ podman buildx build --platform linux/arm64,linux/amd64  --manifest akkoma:v3.10.4  --format docker .

gitea リポジトリへのプッシュ・デプロイ

イメージのdocker互換レジストリへのアップロード

作ったマニフェストをkubernetesクラスタからアクセスできるレジストリにアップロードする。 今回はすでに稼働中のプライベートなgiteaに掲載することにした。

$ podman manifest push --format v2s2 akkoma:v3.10.4 gitea.example.com/fluo10/akkoma:v3.10.4

kubernetesへのデプロイ

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: akkoma
  name: akkoma-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: akkoma
  template:
    metadata:
      labels:
        app: akkoma
    spec:
      containers:
      - name: akkoma
        image: gitea.example.com/fluo10/akkoma:v3.10.4
        ports:
        - containerPort: 4000
          name: akkoma-port
        volumeMounts:
        - mountPath: /opt/akkoma
          name: akkoma-volume
          subPath: akkoma
        env:
        - name: MIX_ENV
          value: prod
        - name: DB_USER
          value: akkoma
        - name: DB_NAME
          value: akkoma
        - name: DB_HOST
          value: postgresql.example.com
      volumes:
      - name: akkoma-volume
        persistentVolumeClaim:
          claimName: akkoma-pvc

これでイメージがプルできることは確認できた。
まだ初期設定ができていないので、このままでは、当然ちゃんとは動かない。

volumeをマウントしながらコンテナで作業

akkomaの初期設定はコマンドで行う必要がある。kubenetesの場合は当然永続ボリュームをマウントしたうえでコンテナ内で実行するという形になるのだが、docker runpodman runとちがい、kubectl runはボリュームをマウントするためのオプションがない。代わりに--overridesというオプションでコンテナの設定を渡せるのだが、このオプションはファイルではなく平文で指定する必要がありどうしても長くなる。 ということで、以下のようなシェルスクリプトにした。

#!/bin/bash
kubectl run akkoma-manage -i --namespace public --rm -ti --overrides='
{
    "metadata": {
        "namespace": "public"
    },
        "spec": {
            "containers": [
            {
                "name": "akkoma",
                "image": "gitea.example.com/fluo10/akkoma:v3.10.4",
                "stdin": true,
                "stdinOnce": true,
                "args": [
                    "sh"
                ],
                "tty": true,
                "volumeMounts": [{
                    "mountPath": "/opt/akkoma",
                    "name": "akkoma-volume",
                    "subPath": "akkoma"
                }]
            }
            ],
            "volumes": [{
                "name":"akkoma-volume",
                "persistentVolumeClaim": {
                    "claimName": "akkoma-pvc"
                }
            }]
        }
}
'  --image=gitea.example.com/fluo10/akkoma:v3.10.4 --restart=Never 

これを実行すると、shでコンテナ内に入ることができる。
あとは公式のマニュアルに沿って初期設定し、podを再起動(削除)すれば動く。

参考


  1. mastodon互換というとmastodonが標準という誤解を招きそうで良くないとは思うが、一番メジャーなので。 ↩︎

  2. akkomaはpleromaの派生。選んだ理由はmastodonがおひとり様サーバーとしてはメモリを使いすぎるのと、linuxカーネルの開発チームが採用したとのことで、十分にステーブルだろうという推測。 ↩︎

  3. といってもワーカーノードは現時点ではすべてラズパイではあるが。 ↩︎