[Kubernetes][Migration][Mastodon] 実家サイトへMastodon環境を移転する

引っ越すことになりました

実は、今月の中旬あたりに引っ越すことになりました。理由としては、

  • 私の体の不調で2Fより上のフロアへの移動が厳しく、1Fの部屋を探す必要があったこと
  • 同様に体の不調で、風呂の出入りが厳しいことがあり(現住居の浴槽が昔ながらの底が深いタイプ)、今風の浅い浴槽がある部屋に住みたかった
  • 現住居はペット入室厳禁物件であり、実家の親兄弟が愛犬を連れて遊びにこれない。その状況を緩和したかった
  • そもそも、現住居が老朽化して壁紙が崩れてる状況にあり、生活上支障が生じていた

というところなんですが、それで部屋を決め、引っ越すことになったわけです。

そこで困りごと

現住居から新居へものを移すわけですが、その間、新居側で回線が開通するまでの間、自宅のネットワーク環境はすべてが不通となります。実は新居では無償のインターネットサービスが払い出されていて、クライアント環境には全く困らないんですが、肝心な当ブログ、SNS周り(Pleroma, Mastodon)がその間不通になります。

我が家の場合、基幹ネットワークはフレッツ光を使用します。新居では別途光回線を引き込む必要があるため、それなりに移転には時間を要することから、別途サービスを継続できる手立てを考える必要がありました。

サイト移転

そこで実家に設置したDR環境の出番です。DR環境では、以下のESXiホストを動かしています。

DR環境スペック概要(ESXi Host Clientから抜粋)

ESXiホストが当初1台構成だったのを、自宅で使わなくなった省電力型サーバを移転させ、全体のリソースもそれなりに増強されました。というわけで、ここにKubernetes環境を最低限構成すれば、なんとか動かせるんじゃないか、せっかくコンテナ技術のメリットが活かせるのではないか?と言う考えです。

実は、Azureのサブスクリプションがあるため、AKSを導入して構成することも考えて環境は準備したのですが、使い勝手がだいぶ違うことから今回は見送ることにしました。失敗した場合のコスト増大が一番怖いですから・・・

今回想定する構成(画面下段が今回構成した箇所)

環境に制約があるため、以下のようにして対処しては居ます。

  • 分散ストレージ:リソースが全く足りないのでReadyNASで代用
  • K8s環境:1Master+2Worker構成。(構成縮小)
  • CNI環境:IPv4のみとした。IPv6は構成しない。
  • Repoサーバ:Nginxサーバと共用

既存環境では、下図のような通信を行っています。

既存環境の通信フロー

既存環境では、Route53へ問い合わせを行い、その結果Azure CDNへアクセスが行われます。キャッシュ応答出来ない場合は本拠地にあるルーター・IPS・NATを経由してNginxへたどり着き、そこからk8s上のコンテナへアクセスする形を取ります。

データはCephで構成される4ノードの分散ストレージに格納されていて、それをリポジトリサーバがRBDでマウントし、各サーバにはNFSでデータを配るようにしています。

さて、この環境を移転させます。なお、データの静止点を確保したかったので、移転作業前にすべてのサービスを停止しました。具体的にはRailsアプリケーションのPuma/Sidekiq/StreamingとRedisを停止させています。PostgreSQLは停止させていません。(この後エクスポートを行うため)

サイト移転作業の実施①

さて、サイト移転を開始します。

サイト移転手順①

①DBデータをエクスポートする
②エクスポートしたDBデータはNASへ格納する
③nginxデータおよびMastodon構成データのフルコピー実施

DBデータのエクスポートに関しては、単純にMastodon用DBの移転のみ行い、ユーザ情報などのデータ移行は行っていません。これは、過去の実績の中で、PostgreSQLからCruncy PostgreSQLへある意味誤って移行させたことがあり、DB全体の移行を仕掛けようとすると、製品ごとの互換性なのか、システムデータの移行が失敗するケースが有ったためです。

Mastodonで行うシステム上の設定は、ユーザ作成、パスワード設定などが主になるだろうと考え、移行処理はDBデータ内に留めることにしています。

データのフルコピー自体はscpやrsyncを使用すれば問題ないと思います。scpだと少々転送が重たくなるため、rsyncで移行するのが手っ取り早くてよいのかなと思います。

サイト移転作業の実施②

続いて、下図のような作業を行います。

サイト移転手順②

④リポジトリデータをDRサイトへコピー
⑤リポジトリデータと構成データ(YAML)を用いて、コンテナをDR環境上に再構築する

リポジトリデータのコピーですが、私の環境ではリポジトリサーバ上にDockerを構成していて、コンテナの初期構築はdocker-composeを使っています。コレで雛形サーバを作るわけです。
出来上がった雛形サーバは、タグ付けを行い、本番リポジトリへアップするわけですが、基本はコレと同じようなことをやるわけです。

【イメージの確認】
# docker images
->今回のケースでは、このイメージリストの中に構築した時点のDocker imageがあった。
 よって、そのイメージに直接タグ付けをし、プッシュする方針をとった。

【イメージのタグ付け】
# docker tags <リポジトリサーバ上のImage名> <DR環境リポジトリサーバへのタグ>
->基本的には、名称は極力本番環境に合わせたほうが良いと思う。
 例えば:本番=libra.bluecore.net:5000/mstdn-engine:20180903a ならば、
 DR環境では: kaimon.bluecore.net:5000/mstdn-engine:20180903a と命名する。

【イメージのpush】
# docker push <DR環境リポジトリサーバのタグ名>

あとは、各コンテナを作成する時に使った本番用YAMLファイルをベースに、あれこれファイルをいじっていきます。主な変更箇所は以下のとおりです。

  • リソース消費量の調整
    先述したように、DR環境はかなりジリ貧構成である耐え、そのまま本番環境の構成を設置しようとすると死にます。なので、ちゃんと実態に即したリソース消費量(特に上限)を設定する必要があります。
  • NFSサーバのパス指定変更
    NFSサーバは異なるものを使用するので、それに合わせてパラメータを変更します。主に修正すべきパラメータはPersistent Volumeのリソースかなと思います。
  • Sidekiq キュー数の調整
    本番環境では気前よく、キュー総数170を誇る、無駄な巨大インスタンスに仕上がってましたが、DR環境でそんなことをしたらサーバのLoad Averageが20超えとかして死んでしまうので、それは慎むようにしました。

ところで、今回一番トラブったのはここでして、DB及びRedisに関しては思いの外すんなり構築できていました。問題はAP(Puma/Sidekiq/Streaming)です。

実は、k8sのデフォルト設定において、イメージのPull処理時間に上限があることがわかりました。なんとその時間たったの1分。それを修正するには、イメージPull処理の実態であるKubeletの設定変更が必要であることを知りました。

対象ファイル: /etc/systemd/system/kubelet.service.d

Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml
--image-pull-progress-deadline 10m"
※太字箇所を「追加」する感じになる

このようにして、イメージPullの許容時間を10分(10m)に変更した所、コンテナ作成が正常にできるようになったことを確認しました。この状況に気づくのに2時間ぐらいかかりまして、サービスダウン時間が長引きました・・

サイト移転作業の実施③

次はこんな感じです(なんだかモー適当)

サイト移転手順③

⑥DBデータをインポートする
⑦Redisを再構築する
⑧.env.productionファイルの修正
⑨APコンテナ群の起動、Nginxの起動
⑩権威DNSレコードの修正

ここまで来たらもう、後はノリと勢いの世界でして、覚えておくべきはDBの初期構築手順ぐらいですかね・・

【psql環境へのアクセス】
# psql -h 192.168.239.142 -p 32432
postgresql=#

【ユーザの作成】
postgresql=# create user mastodon password '********';

【DBの作成】
postgresql=# create database mastodon owner=mastodon encoding=utf8;
この時点でpsqlコンソールから抜けておく。
【DBデータのインポート】
# psql -U mastodon -h 192.168.239.142 -p 32432 mastodon < /nfs/dataabase-bk/20181004_175935_mastodon.sql

Redisは既存データは潰し、ゼロクリアでの再構築をすることになりました。

APコンテナはリソースにあまり余裕が無い場合は、一気に立ち上げずにひとつずつ立ち上げることが上策です。特に初回起動ではイメージのPull作業が入りますので、場合によってはイメージデータの取り合いになり、いつまで立ってもコンテナが起動しません。

最後に権威DNSレコードの変更を行います。設定変更するのはたったの一箇所で、「Azure CDNが参照しているオリジンサーバ用FQDNのIPアドレス」です。これをDR環境のアドレスに変更し、Nginxへ到達できるようになれば、後はActivity Pubでのデータ送受信が正常にできているか、内部サイトで挙動を確認し、問題無ければ作業完了といったところです。

移転した後の状況

タイムラインの時間ずれが解消するまでに、およそ8時間程度はかかったと思います。これは、Sidekiqのキューを少し細めに絞っていることが要因かなと思います。

それでも、キューを絞ったことが功を奏したようで、LoadAverageの値も比較的落ち着いており、安心して扱えるかなという状態にはなってきました。

Kubernetesは平常時はとてもサクサクと軽く動作する良い製品なのですが、フェールオーバーなど、クラスタ間をまたがる「制御」を必要とする処理には何よりも最優先でリソースを消費します。それが原因で、コンテナがリソース不足でダウンしたりなどすることもあるので、くれぐれもリソース計画には十分ご注意ください。