弊社運営インスタンスichiji.socialも先日、公式Ver2.4.1になりました。

アプデ内容の和訳を公開していくことにしたので、今回はv2.4.1の主な機能を日本語でお届けします。

オリジナルの公式ドキュメント(英語)はこちら
マストドン公式アップデートv2.4.1

v2.4.1日本語訳 (主な内容のみ)

「削除&再作成」機能追加 (#7735)

もう送っちゃったトゥートの誤字脱字に気付いたとき、そのトゥートを”削除して再作成”出来るようになります。
元トゥートに含まれていた、添付ファイルを含むすべてのデータが編集・再作成でき、新しいトゥートとして扱われるので、ブースト、お気に入り、リプライもリセットされます。

デフォルトカラムが改良 (#7676)

モバイルでは、デフォルト配置のカラムに、プロフィール、環境設定、セキュリティ設定へのリンクがより目立つように表示され、上のタブバーに記載されているタイムラインやカラムへのリンクは省略されています。

デスクトップでは、新規ユーザーがアプリを使い始めやすいようにデフォルト配置のカラムリンクを「見つける」と「個人用」に分類しています。ブロック済みユーザー・ミュート済みユーザー・ドメインブロックへのリンクは、自分のプロフィールのドロップダウンメニューに移動しました。

どちらのレイアウトでも、カラム下部のスタイルが変更されています。
FAQ・ユーザーガイド・アプリリストへのリンクが、「ホットキー」・「このインスタンスについて」・「利用規約」・「ドキュメント」・「ログアウト」に置き換えられました。
「ドキュメント」に、FAQ・ユーザーガイド・アプリのリストが入っています。

メールバリデーションが改良(#7631)

サインアップのときに、入力されたメールアドレスに MX レコードが存在することを確認します。 MX レコードが存在すれば、実在するメールアドレスであることが想定されます。さらに、 MX レコードをメールドメインのブラックリストと照合することで、たくさんのドメインを同じメールサーバに向けているスパム業者をブロックできるようになっています。

「{ドメイン}からのすべてを隠す」動作の改善(#7765, #7773)

確認ダイアログで、ドメインをブロックするときに何が起きるかについて説明するようになりました。
そのドメインからの、フォロワーを外したり、新しいフォロワーやフォローリクエストを防いだり、トゥートを公開TLでは見えないようにしたり、自分のホームTLでトゥートのブーストを見えないようにしたり、あらゆる通知やメンションを見えないようにしてくれます。
既にフォローしているドメインのユーザーをアンフォローすることはなく、それはそのままホームTLや通知に表示されます。

プロフィールTLからブロック・ミュートされたユーザーを除外(#7747)

要望が多かったので、ブロック・ミュートされたユーザーのブーストはあなたのプロフィール画面に表示されなくなりました。

Elephant-Friend--Curious-


主な機能の和訳は以上です。

以降は、弊社運営インスタンスichiji.socialでの、本verへのアプデ作業にあたって内部で行われていたことのあれそれを綴ります。

余談ですが、創作活動界隈の方からは「創作支援事業やってる会社」の印象が強いのか、弊社のエンジニアリングの技量を心配する声を見かけてびっくりしたのが筆者は記憶に新しくて、一応これだけは言わせてください。創作支援事業より長くやってきている分野なので、普通にご安心ください。

弊社(フィフス・フロア)は、もともとシステム開発分野で会社をスタートしているぐらいです。

Elephant-Friend--Troubled-

2.0.0→2.4.0のアップデート&改修!

今回、長らく 2.0.0 のままだった Mastodon のバージョンを、2.4.0 にアップデートしました!

その前にメンテを何度か挟み、継続的なアップデートのために解消したい問題をいくつか対処しました。
ここでは、問題が起きていた背景と、それを解消するために実施したメンテナンスの概要を説明します!

背景

実は ichiji.social では、以下のような問題が起きてました。

  1. 5月中旬から末にかけて、ichiji.social にアクセスできなくなる障害が2度発生し、全体的に挙動が不安定になっていた
  2. Mastodon 自体のバージョンの更新や、バナーを設置する変更のようなアップデートのたびに、アクセスできなくなる時間(= ダウンタイム)が生じてしまっていた

1 は言わずもがな”サービスの安定稼働”という点で課題になるし、2 の影響で、継続的にアップデートを繰り返していくには、このままだとどうにもやりづらい状況でした。
なので、Mastodon を自体 2.0.0 から 2.4.0 へアップデートする前に、まずこれらの問題を解決する必要がありました。

1 は、サーバの管理に使っている Kubernetes というシステム(の古いバージョン)に問題があるのではないかと考えられたので、そのソフトウェアのアップデートを実施しました。
2 は、「ローリングアップデート」という仕組みが正しく働くようにして、ダウンタイムを0にするための対応を行いました。

次の項から、それぞれシステム的にもうちょっと詳しく(表現的にも正しく)説明します。

対策1.Kubernetesのアップデート

ichiji.social は、Kubernetes(以下 k8s)と呼ばれるコンテナオーケストレーションシステムの上で動いています。

メンテナンス以前の ichiji.social が動いている k8s(のノード)のバージョンは、1.6.4 と、その当時の最新バージョンである 1.8.8 と比べてだいぶ古くなっていました。
一般に、ソフトウェアはバージョンが進むにつれて機能が増えたり、安定性が増したりするので、k8s 1.6 系で動いていた ichiji.social は、相対的に不安定であった可能性がありました。

しかし、k8s のような「基盤」に当たるソフトウェアは、気軽にアップデートができません。
何故かというと、アップデートによって不具合などが生じたら、その基盤の上で動くシステム全体に影響が出るからです(OS のアップデートなどもそうですよね)。

そういう理由で、弊社では k8s のアップデートには慎重になっていたのですが、障害もあったことから急ぎアップデートを実施することにし、1.6.4 → 1.8.8 へとバージョンアップさせました。

ichiji.social では Google Kubernetes Engine (以下 GKE) というマネージドの k8s クラスタを使っているため、バージョンアップの実作業としては、実は GKE の Web の管理画面からボタンを何個かポチポチと押していくだけです。

2fbd9a06-d9b8-b1e7-5515-09a1828c2299

ドキドキしながらアップデートの様子を見守ることになりましたが、メンテナンスは問題なく完了。
マイナーバージョンが 2 違うにもかかわらず、特に問題なく移行できたのでした。
今後はもっと k8s クラスタのバージョンアップを信用していいかもしれません。

このメンテナンスを実施してから2週間以上経ちますが、今のところ安定して稼働しています!

対策2.ローリングアップデートの有効化

ichiji.social では、ローリングアップデート(複数台のサーバを用意し、そのうち少なくとも1台が稼働している状態を保ちながら、順番にアップデートを適用していく手法)がうまく働いておらず、なにかアップデートを適用するたびにダウンタイムが生じていました。

先述した k8s にもローリングアップデートの機能があり、それ自体は有効化していましたが、それでもダウンタイム(502エラー)が生じることがあったので、
原因を調べてみると、どうやら「ローリングアップデートはされているものの、(アップデートが適用されたばかりの)まだ準備ができていないサーバに対しても通信が繋がれてしまっている」ようでした。
準備ができる前にあれそれ言われても、サーバーとしては応答することができないから、結果として502 エラーになってしまっていた、というわけですね。

つまり、問題は k8s がサーバの状態(稼働中かそうでないか)を判断できなかったことにあったのです。

Podから正しく判断されるようにする

k8s には、各コンテナが「稼働中」か「停止中」かを判断する仕組みとして、livenessProbereadinessProbe という設定項目[1]があります。

簡単に言えば、コンテナに何かしらの「ちょっかい」を出してみて、ちゃんと反応が得られればそのコンテナを「稼働中」と判断する仕組みです。
まずはこの設定を見直しました。

以下は、設定を見直した後の、Pod と呼ばれる k8s のリソースの設定の一部です。

        livenessProbe:
          tcpSocket:
            port: 80
        readinessProbe:
          tcpSocket:
            port: 80

Pod はコンテナの 80 番ポートに TCP 接続を試みて、接続が確立されれば、そのコンテナを「稼働中」と判断します。

(ちなみに、tcpSocket 以外に httpGet という、HTTP でのリクエストを試みるオプションもあります。)

これで Pod に対しては、コンテナが「稼働中」かそうでないかを正しく知らせることができるようになりました。

Ingressから正しく判断されるようにする

これだけではまだ、 502 エラーが発生します。
k8s にはもう一つコンテナの稼働状況を見張っているリソースがあります。
Ingress です。

Ingress は、外からの HTTP 通信を一手に引き受けて、”然るべきコンテナ(Pod)”へ通信を仲介するという役割を持っているリソースです。

この「然るべき」というのは、端的には「稼働中の」ということなんですが、Ingress から見て「稼働中」かどうかは、上記の livenessProbereadinessProbe とは別に設定する必要がありました。

Ingress から見て「稼働中」と判断されるためには、「HTTP で / にリクエストを送られたら、それが 200 を返すこと」という条件があります[2]。
これは固定の条件で、設定で変えることができません。

200 というのも厳密で、例えば 302 のようなリダイレクトのレスポンスではダメです。

ichiji.social では、Nginx をリバースプロキシとして立てているため、一番最初に HTTP リクエストを受け取るのは Nginx になります。

Nginx の設定を以下のように変えて、アプリケーションサーバ(が稼働していれば)から 200 が返るように設定しました。

  if ( $http_user_agent ~* googlehc ) {
    rewrite ^.*$ /about break;
  }

googlehc というのは、Ingress が「稼働中」かどうかを見に来るときのリクエストのユーザーエージェントに設定される値です。

Ingress がチェックしに来たら、rewrite を使ってリクエストを /about に振り向けています。
/about に振り向けているのは、/ にリクエストすると /about へリダイレクトされてしまう(302 が返る)ためです。

これで、Ingress からも Pod からも「稼働中」かそうでないかが適切に判定されるようになり、ローリングアップデートもうまく動くようになりました。

今後は、細かい修正などはダウンタイム無しで行えるようになるので、より快適に ichiji.social をお使い頂けるというわけです!💪

参考文献

[1] https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
[2] https://stackoverflow.com/questions/39294305/kubernetes-unhealthy-ingress-backend

2.4.1へのアップデート

大きな改修は上記の 2.0.0 → 2.4.0 のアップデートのときに(前準備として)行いましたが、2.4.1 へのアップデートに際しても、若干調整の必要がある部分が実はありました。

あわせてご紹介です!

新「スタート」カラムへの対応

2.4.1 で、「スタート」カラムの構成や見た目が少し変更になりました。(和訳アプデ内容にもある#7676です!)

これまでずらずらと並んでいたメニューが整理されて、最低限の項目だけが表示されるようになりました。
また、「見つける」「個人用」のようなグループごとにまとめられるようになりました。

比較はこちら。お気づきでしたか?

⬇️旧メニュー

d6af0f89-5ea3-51d2-4d0b-5c233bf7bf58

⬇️新メニュー

11fa60c3-3985-6516-d83a-b6d1b1b793d8

ichiji.social では、このメニューに「#自己紹介」「#作品紹介」というタグへのリンクが独自に設置されています。

単純に 2.4.1 へアップデートしただけでは、これらの追加メニューのせいで、以下のように表示が崩れてました。

894b5705-f362-ef72-9198-62a9c50e88c4

これには2つ問題点がありました。

  1. 「#自己紹介」「#作品紹介」がグループの外に出てしまっている
  2. メニューが途中で切れてしまっている

2はスクショだとちょっとわかりにくいと思うんですけど、本当は「ダイレクトメッセージ」の下にもいくつかメニューがあるのに、その上にフッターが重なって切れちゃってます。(1個前のスクショと見比べるとわかりやすいかも)。

メニュー部分は JavaScript (React) で表示されていて、当該部分のコードは app/javascript/mastodon/features/getting_started/index.js にあります。

ここの解決のために、この部分は以下のように書き換えてます。

      navItems.push(
        <ColumnSubheading key={i++} text={intl.formatMessage(messages.discover)} />,
        <ColumnLink key={i++} icon='vcard-o' text='#自己紹介' to='/timelines/tag/自己紹介' />, // ①
        <ColumnLink key={i++} icon='book' text='#作品紹介' to='/timelines/tag/作品紹介' />, // ①
        <ColumnLink key={i++} icon='users' text={intl.formatMessage(messages.community_timeline)} to='/timelines/public/local' />,
        <ColumnLink key={i++} icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' />,
        <ColumnSubheading key={i++} text={intl.formatMessage(messages.personal)} />
      );

      height += 34*2 + 48*4; // ②

※翻訳を考慮していないので、コードにベタに日本語が書いてあります

①と②が、今回の改修で変更した部分です。

①の部分が、「#自己紹介」「#作品紹介」を適切な場所に表示させるためのコードです。
navItems.push で、メニューに表示させる項目を追加できます。
<ColumnSubheading> が「見つける」などのグループ名を表示する項目で、
<ColumnLink> が「ローカルタイムライン」などのリンク項目です。

「#自己紹介」や「#作品紹介」は、「ローカルタイムライン」などと同じく「見つける」の仲間として、その下に表示するようにしました。

②の部分は、メニュー全体の高さを計算している部分です。
<ColumnSubheading> は 高さ34px、
<ColumnLink> は 高さ48px で、
navItems.push が何個あるかで高さも計算されています。

もともとは <ColumnLink> は2個しかなかったので 48*2 となっていましたが、4個に増えたので 48*4 に変更してあります。

これで、メニューが途中で切れずに、ちゃんときれいに表示されるようになっています!やったね!

おわりに

いかがだったでしょうか?

…というこの記事を書いている時点では、実は公式から2.4.2がもうリリースされてしまってます!たいへん!

でもパッチレベルのアプデを毎回全部拾って細々アプデ作業をするかどうかは検討の余地もある…といったところで悩み中でもあります。

今後もなるべくわかりやすく、こういった記事をちょくちょくあげていこうと思うので、ご意見ご要望があればお知らせください!

まーけでした!