🐘

Docker上で動いているMastodonをkubernetesクラスタに移動した作業メモ

2021/08/11に公開

本稿のスコープ外

  • Kubernetes(以下 k8s)クラスタの構築方法
  • Mastodon の初期設定
  • kustomize のインストール

※ 多少読み替えて頂ければ、docker ではない Mastodon も移行できるはず

前提条件

  • kubectl が実行可能なこと
  • kustomize が使用可能なこと
  • 以降元 docker コンテナのファイルを持ってこれること

作業手順

実は移行自体はそれほど難しくありません。
移行が必要なのは、PostgreSQL の DB だけです。redis のデータも移行した方がよいですが、
移行しなくてもその時点の Sidekiq のジョブが失われる程度で、恐らく誰も気づきません。
※ 管理者的には、Sidekiq 画面のジョブ数がリセットされるのが残念かな?程度

kubernetes クラスタ上に Pod を生成

Deployment 定義を github に公開しています。

https://github.com/yakumo-saki/k8s-mastodon-deployment

私のインスタンスは、Glitch Edition なので Docker イメージ名が違いますが、基本的に
公開している Deployment をそのまま使用しています。
複数インスタンス持ちなので、myinstance をコピーして foundation としました。
myinstance/kustomize.yaml は以下のように書き換えました。

namePrefix: myinstance-       # Pod名の先頭にmyinstance- をつける
commonLabels:
  app: myinstance

resources:
  - ../base
configMapGenerator:
  - name: config
    env: env.production
    files:
    literals:

env.production ファイルは稼働中のインスタンスからそのまま持ってきます。

その上で、DB_HOST REDIS_HOST を変更します。

base/kustomization.yaml 変更

DB を戻し終わるまでは、Web, Streaming, Sidekiq には起動して欲しくありません。

そのため、一時的に ./base/kustomization.yaml を変更します。

resources:
  - db-service.yaml
  - db-pvc.yaml
  - db-statefulset.yaml
  - web-sidekiq-pvc.yaml
  - redis-service.yaml
  - redis-pvc.yaml
  - redis-deployment.yaml
  #- web-service.yaml             ここから下をコメントアウト
  #- web-deployment.yaml
  #- streaming-service.yaml
  #- streaming-deployment.yaml
  #- sidekiq-deployment.yaml

ここまでできたら、

myinstance ディレクトリで

$ kustomize build | kubectl apply -f -

configmap/myinstance-config-4dm8g6h6gm created
(略)

移行元インスタンス停止

(リハーサルなら止めなくてよい)
DB と Redis コンテナ以外 を停止します。

DB, redis バックアップ取得

# 移行元インスタンスのdockerが動いてるところで
$ docker exec mastodon_db_1 pg_dumpall > pg_dumpall.sql

# このコマンドはredisへのアクセスが停止します。(短時間ですが)
$ docker exec mastodon_redis_1 redis-cli save
OK

$ docker cp mastodon_redis_1:/data/dump.rdb .

pg_dumpall.sql dump.rdb ファイルは、kubectl を使用可能な PC にコピーしておいて下さい。

DB バックアップを k8s 上の DB に戻す

$ kubectl cp pg_dumpall.sql myinstance-db-0:pg_dumpall.sql

$ kubectl exec -it myinstance-db-0 sh
$$ psql
root=# \i pg_dumpall.sql
(どばっと、DUMP取込のログが出る)
root=# quit

# SQLファイルを消しておかないとサーバーの容量を食うため(コンテナ再起動で消えますが)
$$ rm pg_dumpall.sql

Redis バックアップを k8s 上の DB に戻す

redis のバックアップは、 /data/dump.rdb を上書きするだけです。
しかし、一つ落とし穴があります。 それは、redis 稼働中に dump.rdb を上書きしても、
redis をシャットダウンする際に上書きされるという罠です。
なので、一旦 redis-server を起動しないようにします。

./base/redis-deployment.yaml を編集。

<code class="language-yaml:./base/redis-deployment.yaml">(略)
     containers:
        - name: redis
          image: redis:5.0-alpine
          command: ["tail", "-f", "/dev/null"]   # この行追加(またはコメントアウト解除)
          resources:
            requests:
              memory: "16M"
          livenessProbe:
          #  exec:                               # ここをコメントアウト
          #    command:
          #    - redis-cli
          #    - ping

(略)
$ kubectl get pod して、 myinstance-redis-* のpod を探す。
$ kubectl cp dump.rdb myinstance-redis-xxxx:dump.rdb_new

$ kubectl exec -it myinstance-redis-xxxx sh

$$ ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 tail -f /dev/null    # redis-server が動いていないことを確認
   52 root      0:00 sh
   72 root      0:00 ps aux

$$ ls -lh
-rw-r--r--    1 redis    redis         92 Aug 16 05:06 dump.rdb
-rw-r--r--    1 501      dialout     5.3M Aug 16 05:28 dump.rdb_new  # 所有者が違う!

$$ cp dump.rdb_new dump.rdb
$$ chown redis.redis dump.rdb

一時的に変更した設定ファイルの復元

  • 編集した ./base/redis-deployment.yaml を元に戻します。
  • 編集した ./base/kustmization.yaml を元に戻します。

元に戻したら、いよいよ起動を行います。

kustomize build | kubectl apply -f -

動作確認

とりあえず、 curl [外向きのIP等]:3000 して何かが帰ってくれば OK とします。

リバースプロクシの設定変更

動作確認ができたら、リバースプロクシの設定を変更しましょう。

積み残し

favicon

マウントしないといけないのですが、本稿では色々と事情があり割愛しています。

蛇足

.env.production じゃなくて env.production にリネームしたのなんで?

.env.production だと ls したときに表示されないからです。 ls -a すれば見えますが。

個人的に見えないファイルが重要っていうのはあんまり好きではないので。。単純に好みですね

Discussion