カテゴリー
Docker Kubernetes Mastodon Ubuntu

MastodonをDocker Compose環境から、Kubernetes環境にお引っ越しした

今まで数年間、Ubuntuで立てたシングルノードのDocker Compose上でMastodonを動かしていたのだが、世の中の流れに合わせてKubernetes上に移動させた。

docker-compose.ymlから自動的にKubernetesのマニフェストファイルに変換してくれるコマンドもあるけども、勉強のために手動で1個ずつ置き換えていった。

出来上がったk8s上のMastodon構成

PostgreSQLのデータをNFS上に移動する

元々はDocker Composeのローカルストレージ上に置いていたPostgreSQLのデータをNFSの共有ディレクトリに移動させた。

  1. NFSサーバーでディレクトリを共有する
  2. 共有ディレクトリ上で新DBを初期化する
  3. 移行元のDBサーバーでpg_dumpコマンドを用いてデータをエクスポートする
  4. 新DBでエクスポートしたデータをインポートする

同じCPUアーキテクチャ&バージョンであればDBのデータディレクトリをまるごとNFS上に持って行くだけでもデータベース移行出来るのだが、今回はDBバージョンが異なるのと、このタイミングで複数のDBを統合していたのを用途ごとに分割したかったので、上記のようなエクスポート&インポートを用いている。

このとき、Docker Compose上から書き込んでいたデータが、Kubernetes上のプロセスから読めないエラーメッセージが多発したので、NFSのマウントオプションでバージョン3を使う`mountOptions: nfsvers=3`にして回避した。
※NFSv4のACLベースのアクセス権の考え方に引っかかっていた模様。NFSv3まではrwxビットだけなので。。。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-mstdnblue
  annotations:
    name: postgres-mstdnblue
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteOnce
  mountOptions:
    - nfsvers=3
  nfs:
    server: 192.168.8.253
    path: /mnt/tank/share/nfs/k8s/postgres-mstdnblue-data

PV/PVCを作る

NFSv3の共有ディレクトリをPodに引き渡すためのPVCであるが、大規模環境だとサイズや速度などで階層化しつつ均一なボリュームをまとめて作って適切にPVCで引きこむような設計をすると想像する。(その方がストレージ設計者とコンピューティングリソースの提供者の役割分担がはっきりしやすい&下のレイヤーを隠蔽しやすい)

ただ、今回の個人用の環境だとどこにどのデータがあるかはっきりしたほうが良いので、NFSディレクトリの名前とannotationsを1対1で対応させてどのPVがどういうデータを持っていて、それをどのPVCで引きこむのか分かりやすいようにしている。

名前でストレージ領域の用途が分かりやすくしたPV
名前が体を表す的なPVC

複数のテナントが相乗りするような環境だとPVが再利用されないようにしたり、データの隠匿/暗号化/リサイクル時の確実な消去なども求められるだろうなとも思ったがスルー。

Redisの移行を考える

MastodonのRedis上には他の連合(フェデレーション)を結んでいるサーバーとのトゥートの伝搬等のキューイング情報やジョブ実行状態、ユーザーが最初にアクセスしたときのホームタイムラインなどのキャッシュが保持されている。

今回は御一人様インスタンスでキャッシュやジョブ状態は飛んでしまって構わないとしたので、Redisの情報は引き継いでいかないことにした。

ConfigMapに環境変数を持ち込む

Docker Composeだとini形式(変数名=値が並んだテキストファイル)で各種プロセスに引き渡す環境変数を持っていたが、KubernetesだとConfigMapなりSecretなりにする必要がある。

地道にYAML形式に書き直すことも考えたが、面倒くさかったのでいい手がないか調べたらこんな手順が。

$ kubectl create configmap key-value-sample -n configmap-example --from-env-file=sample.ini

上記のコマンドを使ってConfigMapを作成したらenvFromでPodに引き渡すことが出来る。

v1.6 で追加された envFrom

v1.6.0 で下記のように envFrom という項目で ConfigMap または Secret の内容を一度に同名または prefix 付きの環境変数として読み込むことができようになりました。

Kubernetes: ConfigMap / Secret の内容を一度に環境変数として読み込む (envFrom)

https://qiita.com/tkusumi/items/cf7b096972bfa2810800

Mastodonの各種プロセスを起動する

Sidekiq/Streaming/Webのセットはほとんど一緒で、/mastodon/public/systemを共有しながら、bundleなりnodeでプログラムが動いている感じの構成になる。

DeploymentでNFS上のボリュームをマウントしたPodを起動して、外部公開するWebsocketなりHTTPなりのサービスエンドポイントをServiceとして定義してやれば良い。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-mstdnblue
  labels:
    app: web-mstdnblue
spec:
  selector:
    matchLabels:
      app: web-mstdnblue
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: web-mstdnblue
    spec:
      hostname: web-mstdnblue
      subdomain: local
      containers:
      - image: tootsuite/mastodon
        name: web-mstdnblue
        command: ['bash']
        args: ['-c','rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000 -b 0.0.0.0']
        envFrom:
          - configMapRef:
              name: configmap-mstdnblue
        volumeMounts:
        - name: mastodon-public-mstdnblue
          mountPath: /mastodon/public/system
        envFrom:
          - configMapRef:
              name: configmap-mstdnblue
      volumes:
      - name: mastodon-public-mstdnblue
        persistentVolumeClaim:
          claimName: mastodon-public-mstdnblue-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: web-mstdnblue
spec:
  type: LoadBalancer
  selector:
    app: web-mstdnblue
  ports:
  - protocol: TCP
    port: 3000
    targetPort: 3000

最終的なマニフェスト構成

たぶん、ちゃんとした管理者のいる環境だとPVとPVC あたりに管理者の分担や責任分界線が出てきそう。

それ以外はプロセスの種類ごとに分けてはみたものの、Serviceあたりでアプリケーションエンジニアとネットワークエンジニアの縄張り争いが出そうだなとも思った。

マニフェストファイルの分け方には流儀があると感じた

まとめ

Kubernetes環境にアプリケーションを持って行くとしたら、元々Docker前提で綺麗に分かれているものでもそれなりに技量がいる。

もしもレガシーなアプリケーションを持ち込むとしたら作り直した方が早いという言説にも頷ける。

AWS上のALBから、自宅環境のKubernetesクラスターまでトラフィックを持ち込んでいるところはこの記事では省略したがTailscaleを使っていたりする。そのうち書きたい。

カテゴリー
未分類

今年のゴールデンウィークを振り返る その7

5/5 (祝・木)

AM 9:00 たばこ臭いホテルを後にして、東京に向かって帰りはじめた。途中どこで1泊するかは高速道の混雑と、自分の体力がどこまで続くかに任せることに。最低限、往路で泊まった明石は越えたいと考えていた。

https://twitter.com/imksoo/status/1522003262039216128
ラジオが「南日本放送」(MBC)なのが懐かしい

AM 10:00 人吉青井の道の駅に立ち寄る。ETC 2.0なので途中で高速を退出してもお値段が据え置きになるのはうれしい。

https://twitter.com/imksoo/status/1522024335287865344
温泉むすめも変なところで噛みつかれてたよなと……

PM 1:30 九州最後のめかりPAに立ち寄る。ここから先は本州。

本州に入ってからは山陽道の渋滞を警戒して、中国道をひたすら走り続けた。空いていてひたすら警察が見たらちょっと……な速度で走り続けるが、アップダウンもカーブも厳しいし走っても走っても広島県が長い。山陽道の方が良かったかもしれんと後悔した。

https://twitter.com/imksoo/status/1522172654844739589

PM 4:30 北広島の道の駅に。ここもETC 2.0の社会実験で退出しても料金据え置き。中国道にはヘトへとしていた。

https://twitter.com/imksoo/status/1522115337864433669

中国道も兵庫県に入ると混雑してくる。追い越し車線絶対に退かないマンにだいぶいらつくクルマが目立ちはじめる。法定速度で併走して車線に蓋をするなら大人しく走行車線に戻った方が煽られないのにな……とビタ付けで追い詰めている先行者を見ながら思った。煽られ運転も良くない。。。
エスカレーターはステップの上で歩かず手すりをつかんで立ちましょう。

PM 7:30 西宮名塩SAに到着。晩ごはんを食べる。

https://twitter.com/imksoo/status/1522164005774651392

サービスエリアで接客している人の言葉を聞いていると、関西だけ異質に違うのが分かる。九州でも東京でも標準語なのに、滋賀・大阪・兵庫あたりだけは地場の言葉が目立つ。

https://twitter.com/imksoo/status/1522176223555686400

PM 10:00 ゴールデンウィーク移動の最後の宿泊地、ユニバーサルスタジオジャパンのとなりの良いホテルに泊まることにした。ベッドもソファも大浴場も料理も、この長旅の中で一番良かった。ホテルも良いし、USJに来たくなった。

https://twitter.com/imksoo/status/1522208120566542341

625km、8時間13分ずっとハンドルを握っていてもう右手はちょっと辛い。

ここまで乗ってきたきりのさんの愛車、最新世代のBMW 3シリーズツーリングには、3眼カメラにレーダーセンサーを組み合わせた最新鋭のオートクルージング機能を持っている。それでも最終的なハンドル操作はドライバーに任されていて、特に九州道や中央道のような曲率が強いカーブが多い高速道路だと結局、ほとんどのハンドル操作をする羽目になった。それでもアクセルとブレーキだけでもクルマ任せに出来るので疲労度はだいぶ違っているのだが。

うえのこは一人でエキストラソファに寝てくれた。広いふかふかのベッドで一人でぐっすり寝れた。

5/6 (金)

ホテルの最上階にある露天風呂(大浴場)に入る。良い天気だ。後は東京に帰るだけになった。

https://twitter.com/imksoo/status/1522366498924232705
https://twitter.com/imksoo/status/1522382286309658625
ユニバ情報がホテルでも見られるのはすげー

PM 10:00 ホテルを出発する。

https://twitter.com/imksoo/status/1522406572445503489

AM 12:00 名神を抜けて、草津PAにて休憩。ここからは新名神から伊勢湾岸道を通って新東名で名古屋をスルーする。

PM 3:00 駿河湾沼津SAまで来る。片側3車線+法定速度120km/hの高規格な高速道路の恩恵はすさまじい。

https://twitter.com/imksoo/status/1522461597972664320

PM 5:30 東名からC2へ抜ける大橋JCTで事故渋滞を食らったりもしつつも、東京料金所まで来た。やっと帰ってきた。

PM 6:00 行きつけのガソリンスタンドでセルフ洗車する。往復3000kmぐらいをひたすら高速道路を疾走していたせいでフロントガラスには虫のぶつかってきた痕跡が酷すぎた。

https://twitter.com/imksoo/status/1522513781363904512
https://twitter.com/imksoo/status/1522525497418149891

PM 7:00 いつもの近所のコスモ石油のスタンドで最後の給油をした。アプリ会員+マイSS登録+クーポンQRやらでリッター129円で入れられるのは本当にありがたい。

PM 8:00 近所の回転寿司屋で経済を回す。このまま家に帰っても1週間放置された空っぽの冷蔵庫しかない。

https://twitter.com/imksoo/status/1522532769615687680

PM 9:00 近所のスーパーで最低限の食材だけ買って退散。

PM 10:00 家に帰り着く。疲れた。

最終日は503km、7時間42分のドライブとなった。

まとめ

4/29から5/6までのドライブ移動の総計2679km、延べ49時間ほどの運転時間となった。たぶんに人生で今後、ここまで連日長距離を運転し続けることはないと思う。良い経験になった。

https://twitter.com/imksoo/status/1522174652352671744

カテゴリー
未分類

今年のゴールデンウィークを振り返る その6

5/4 (休・水)

朝一番から本葬儀。最期のお別れをした。

火葬場も他の家族とバッティングすることなく昼前には収骨まで終わる。いろいろとバタバタしたけども終わった感。

https://twitter.com/imksoo/status/1521705193410244613
https://twitter.com/imksoo/status/1521673820695846912

また溜まってきた洗濯物を街中のコインランドリーに突っ込んで久々に一人で中央駅近辺を一人でぶらついてお昼を食べた。精進した。

https://twitter.com/imksoo/status/1521711598833860608
https://twitter.com/imksoo/status/1521716180783837185

自分が鹿児島市内に住んでいたのは新幹線が全面開通するよりもずっと前だった。新幹線が出来てもストロー現象で福岡に全部持って行かれるんじゃないか?と言われて寂れていく一方であった。ただ、観光業でだいぶ持ち直したようだ。
至る所で再開発ビルが建ち並んで、タワーマンションもどきのような大きなマンションも出来て、子育て支援の保育所や公園、公的支援の仕組みなどが充実して中心部だけを見ると、鹿児島市がだいぶ輝いているようだ。(ニュータウンもある程度は新陳代謝できているようだ、取り付け道路のアスファルトはボロボロになっているところも目立ってはいるが最低限の手入れはされている)

りくちゃさんは土産物店でお目当ての化粧品を買えたようだ。帰り支度をはじめる。鹿児島で最期に泊まるホテルを押さえた。魚料理が有名らしく美味しかった。

https://twitter.com/imksoo/status/1521816662982283265

この日は市内の中心部をぶらぶらしたのでそんなにドライブしなくて済んだ。49km、2時間20分。

東京を出るときは8000kmちょっとだったはずのオドメーターが1万キロを越えそうになっている。ゴールデンウィーク前にこんなことになるなんて想像だにしてなかった。

https://twitter.com/imksoo/status/1521799502385999872

手違いでホテルの喫煙部屋を取ってしまい、臭いに悶絶しながら寝ることになった。ベッドもツイン1個で狭い。あんまりちゃんと寝られないまま寝た。

https://twitter.com/imksoo/status/1521814867476246530