随時更新します。
blobchan
Apache License 2.0
https://itsuku.xyz/log/blobchan.html
:blobcatfriedricesuperpro: :blobdance:
随時更新します。
Apache License 2.0
https://itsuku.xyz/log/blobchan.html
:blobcatfriedricesuperpro: :blobdance:
こんにちは。はんドンクラブのはんです。 この度、はんドンクラブを含む私の管理する全てのサービスのインフラを一新し、kubernetes(k8s)に統合しました。この変更により、運営コストの最適化・サービスの可視化性(オブザバビリティ)の向上・オペレーションの簡略化を達成しました。この記事では、その内容をご紹介しようと思います。はんドンクラブに直接関係ない内容も含みます。

これまでレガシーな構成で動いていたサービスを含め、Docker コンテナ化を行いました。かつ、全てのサービスを Vultr のマネージド k8s 上で稼働させています。結果、コンピューティングリソースが最適化され、コスト削減を達成しました。
また、k8s のマニフェストファイルは flux が管理しています。クラスタの設定変更や mastodon のバージョンアップも、github のプライベートリポジトリにマニフェストを push するだけで終わりです。自動同期され、ローリングアップデートが行われます。この GitOps により、オペレーション稼働の劇的な削減を達成しました。
共通のk8sクラスタでアプリを動作させるのと同時に、分散していたデータベースサーバーを1台のサーバーに集約し、postgres サーバーを共用するようにしました(現在は k8s クラスタ外でデータベースを動かしていますが、k8s 移行に向け検証中です)。コスト削減につながりました。
同時に、浮いた費用を使って、バックアップを充実させました。具体的には、WAL を含めた常時バックアップを取得して最低1週間は PITR が可能な体制を確保しました。また、フルバックアップの保管範囲を過去2世代から6世代に変更するなど、リテンションポリシーの見直しも行いました。これまで同様、安心してご利用いただければと思います。
歴史的な背景より、さまざまなサービスを複数のクラウドサービス事業者を用いてて運営しており、互いに依存している状態でした。そのため、たとえば「運用系の権威DNSが死ぬと監視系も死ぬ」など、分離が不十分でした。今回、運用系と監視系の設計を一から見直し、独立性を担保したことで、信頼性が向上しました。
| 項目 | 運用系 | 監視・バックアップ系 |
|---|---|---|
| 権威DNS | Cloudflare | AWS(Route53) |
| デリバリー | Cloudflare | AWS(Cloudflont) |
| コンピューティング | Vultr@Tokyo | AWS(lambda)、WebARENA@Osakaなど |
| オブジェクトストレージ | Wasabi@Tokyo | AWS S3@Osaka、Wasabi@Osakaなど |
今回の構成変更のうち、最も大変だったのはオブザバビリティの向上です。ざっくりと、以下のような構成です。
Object
Storage
^
+k8s-cluster----+-----------------+
| | |
| pod ----> fluent bit ----> Loki |
| | ^ |
| | | |
| +------> vmstat | |
+-------------+---------------+---+
remote write |
v |
Victoria metrics |
^ |
+------Grafana-------+
|
| Webhook
v
Discord
まず、アクセスログをはじめとした各コンテナのログは、fluent bit で収集後 loki にてラベリングし、外部 Grafana から参照しています。あわせて、fluent bit から直接 Object storage にも送付することで、アクセスログを3ヶ月以上長期保存したいというコンプライアンス上の要件も低コストで満たすことができました。
Victoria metrics は軽量な Prometheus で、k8s 関連のメトリクスを直接 remote writeする構成としました。そのためクラスタ内に Victoria metrics / Prometheus 用の PVC は不要な構成です。このメトリクスももちろん Grafana から参照しています。

各コンテナがどのくらいのリソースを必要とするのか全く検討がつかず、最初は当てずっぽうな値で request するしかありませんでした。そこで、ダミーの値でまず一度動かし、実際のメモリ利用量と pod の restart 状況を Grafana で確認して適正値に変更する… というサイクルを何度も繰り返しました。
# Request に対する実利用メモリ
sum by (pod, namespace) (container_memory_working_set_bytes{container!="", pod!=""})
/
sum by (pod, namespace) (kube_pod_container_resource_requests{resource="memory", container!=""})
# Max に対する実利用メモリ
sum by (pod, namespace) (container_memory_working_set_bytes{container!="", pod!=""})
/
sum by (pod, namespace) (kube_pod_container_resource_limits{resource="memory", container!=""})
ある設定値でトライ → Claude Code に Victoria Metrics のメトリクスと kubectl logs の権限を与えて新しい設定値を提案させる → Grafana を見ながら手動で微修正 を何度も何度も繰り返しました。その結果、なんとか予算に収まる範囲のノード数でかつ OOM killer がほぼ発生しない、かなり適正な値を導き出すことができたと思っています。
# Misskey
apiVersion: apps/v1
spec:
replicas: 1
template:
spec:
containers:
- name: web
image: misskey/misskey:2025.12.2
resources:
requests:
memory: "640Mi"
cpu: "250m"
limits:
memory: "640Mi"
cpu: "1000m"
# Mastodon
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
containers:
- name: sidekiq
image: ghcr.io/highemerly/mastodon/handon:v4.5.7
command:
- bundle
- exec
- sidekiq
- -c
- "5"
- -q
- default
resources:
requests:
cpu: 200m
memory: 432Mi
limits:
cpu: 1000m
memory: 496Mi
# Victoria Metrics Operator HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
spec:
values:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
(必要な箇所のみを抜粋: Misskey は replica: 1 でかつ OOM Kill がおきやすかったので Request = Limit。Mastodon の Sidekiq は Replica: 2 なので オーバーコミットを許容。監視系も OOM Kill をある程度許容してオーバーコミットする。全体的にCPUは気軽にオーバーコミットしまくる。また、dev系はあえてlimitsギリギリで遷移させて検証しています。)
なお、本来 k8s は、こんなカツカツで運用するものではないと認識しています。でも個人運営ですから仕方がありません。とはいえ、ローリングアップデートはできるだけの余裕はありますし、いざというときにそなえて Node を +1 するオートスケールも設定してありますからご安心ください。
アプリがどうやったら正しいクライアントIPアドレスを認識できるのか。この問題は難しかったです。なぜなら、考え得る最も複雑な構成であれば、Cloudflare・マネージドロードバランサー・Treafixの3カ所でプロキシされますので、何度も Connecting IP アドレスが変化してしまう構成だからです。
そもそも、一部サービスでは直接マネージドロードバランサー宛にアクセスさせ、一方ではんドンクラブのような大きなサービスでは Cloudflare などのCDNを経由してアクセスさせています。特に前者の構成を考慮し、マネージドロードバランサーをPROXYモードで動かすべきと判断しました。 service.beta.kubernetes.io/vultr-loadbalancer-proxy-protocol を true にしました。
併せて、Ingress は Cluster モードではなく Local モードで動かす必要もあります。Cluster モードは必ず NAT されてしまい、実IPアドレスの制御が極めて難しくなってしまうためです。一方、Local モードは、Ingress の Pod が動作している Node 宛リクエストでないとトラフィックを処理できません。当初、Local モードで運用する場合、Ingress を Daemonset にして全 Node にばらまかないといけない(何故ならば Ingress Pod のない Node が出来るとうまく動かないから)と思い込んでいました。しかし検証の末、Vultrのマネージドロードバランサーが備えるヘルスチェック機能にて、Ingress Pod が動作していない Node 宛に実際のリクエストが送られない仕様であることが分かりました。そのため、より楽でリソースも少なくて良い Local モードに切り替えました。
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
spec:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/vultr-loadbalancer-proxy-protocol: "true"
service.beta.kubernetes.io/vultr-loadbalancer-protocol: "tcp"
service.beta.kubernetes.io/vultr-loadbalancer-health-check-protocol: "tcp"
service.beta.kubernetes.io/vultr-loadbalancer-health-check-port: "80"
service.beta.kubernetes.io/vultr-loadbalancer-health-check-interval: "10"
service.beta.kubernetes.io/vultr-loadbalancer-health-check-unhealthy-threshold: "3"
spec:
externalTrafficPolicy: Local
ここまでくれば、あとは CDN からのリクエストを X-Forwarded-For で制御すれば終わりです。もちろん X-Forwarded-For は偽装できるので、Ingress の Traefik にて、信頼するIPアドレス帯の設定は必須です。
さらにややこしいことに、Misskey では、最近のアップデートにて trustProxy の設定が必須となりました。Ingress で制御しているので本来アプリ側での制御はしなくてもいいのですが、リリースノートに従って設定しました。
# Misskey 2025.12.0+
trustProxy: true
trustedProxies:
- '10.244.0.0/16'
- 以下略
ここも当初は勝手が分からず、非常に苦労しました。もちろんお金が無限にあればなにも気にしなくて良いのですが、Object Storage や Loki の容量を削減したかったので、かなりチューニングしました。

まず、Grafana にて、ログ量を可視化することから始めました。Loki を利用しています。
# Line
sum by (k8s_namespace_name, k8s_pod_name) (count_over_time({job="fluent-bit"}[1h]))
# Byte
sum by (k8s_namespace_name, k8s_pod_name) (bytes_over_time({job="fluent-bit"}[1h]))
この時点で、明らかににログ量が多すぎる Pod はログレベルの調整を行いました。
apiVersion: v1 kind: ConfigMap metadata: name: mastodon-env namespace: handon-prd data: RAILS_LOG_LEVEL: "info"
また、ログレベルの調整でどうにもならない場合も多いです。fluent bit のログフィルタにてログを削除します。
# kube-probe ヘルスチェックいらない
[FILTER]
Name grep
Match kube.*
Exclude log kube-probe
まさにモグラ叩きでした。
いずれもコスト削減が主な目的となります。どれも重要なプロジェクトなので着々と進めていきたいと思います。

オブザバビリティは正義。
こんにちは。はんドンクラブのはんです。
この記事は、 はんドンクラブ2 Advent Calendar 2024 - Adventar 25日目の記事です。(大遅刻)
本来は毎年年末に1年を振り返る記事を投稿しているのですが、今年はあまりの多忙のため、全く記事を投稿する時間を作ることが出来ませんでした。ごめんね。
年が空けてしまいましたので、今年は年始のご挨拶とさせていただだければと思います。
サーバー運営に関連する主なイベントです。
2024年に最も困った問題はスパムの対応でしょう。はんドンクラブでも多くのユーザーが、他サーバーのスパムからのリプライを受け取ったのではないかと思います。ご迷惑・ご心配をおかけしまして申し訳ございませんでした。

上記が、2024年1月1日を0としたスパムアカウント(注: 厳密にはスパムではないものも若干含まれている)の増加傾向です。大きな山が3つあり、2月・10月・11月が主な攻撃をうけたタイミングです。
はんドンクラブでは、大きく2段階の対策を行い、全自動で対処できる仕組みを構築しています。
このシステムは現在も継続して動作しております。ご安心ください。
運営業務の負担削減のため、私の念願であった継続的デリバリー(CD)環境の構築が終わりました。金をかければ簡単なのですが、金をかけずにやるのが難しく試行錯誤していたので、かなりの時間を要してしまいました。
2024年7月に極めて大きな障害を発生させてしまいました。ご迷惑をおかけし、誠に申し訳ございませんでした。
現在、既に再発防止策は履行済であり、仮に同じ問題が発生しても、私のスマホにアラートが飛ぶようになっています。しかしながらこの仕組みがLINE Notifyに依存しており、2025年3月末にサービス終了予定のため、2025年2月中には別の仕組みに移行予定です。
月次の収支報告を行うようにしました。といっても、私があまりに忙しすぎて、全然出来ていないので、そのうち頑張ります・・・。
そんななかでもカンパにご賛同頂いている皆様には感謝しかありません。
| データ名 | 数字 |
|---|---|
| アカウント数 | 470 |
| アクティブユーザー数 | 148 |
| 総投稿数 | 43,761,664 |
| 総Fav数 | 3,300,688 |
| 総Bookmark数 | 16,452 |
| データベースサイズ | 43.5GB |
| メディアサイズ | 359GB |
| 順位 | 投稿数 | アカウント作成日時 |
|---|---|---|
| 1 | 224217 | 2017-04-16 03:14:45.210683 |
| 2 | 182826 | 2018-09-26 14:00:24.677902 |
| 3 | 181320 | 2017-04-19 23:46:20.721773 |
| 4 | 159205 | 2018-08-17 04:55:36.888916 |
| 5 | 153066 | 2018-08-15 15:46:57.420607 |
| 6 | 151775 | 2018-09-26 13:34:53.286009 |
| 7 | 129999 | 2018-09-06 12:13:56.291501 |
| 8 | 127005 | 2017-04-14 15:25:19.467587 |
| 9 | 121126 | 2017-04-15 02:53:53.437558 |
| 10 | 114171 | 2017-12-10 05:49:59.90627 |
| 11 | 101517 | 2017-04-15 01:58:28.244079 |
| 12 | 98689 | 2018-08-21 03:56:48.835622 |
| 13 | 93818 | 2017-04-15 02:55:00.283981 |
| 14 | 89425 | 2018-08-27 18:58:03.712292 |
| 15 | 82725 | 2018-09-09 08:15:49.611543 |
| 16 | 81794 | 2019-08-16 09:27:18.956742 |
| 17 | 69985 | 2017-04-15 02:53:10.105472 |
| 18 | 68960 | 2018-11-19 04:43:11.381105 |
| 19 | 67240 | 2018-03-21 04:27:47.006326 |
| 20 | 65751 | 2018-08-23 10:41:04.900378 |
| 21 | 65225 | 2018-11-19 04:44:53.895617 |
| 22 | 65166 | 2018-08-16 13:33:57.829532 |
| 23 | 61556 | 2018-08-16 15:52:19.943946 |
| 24 | 59511 | 2018-08-18 23:14:00.993394 |
| 25 | 59184 | 2018-08-17 12:06:59.137676 |
| 26 | 58996 | 2017-04-15 02:01:39.684488 |
| 27 | 57691 | 2018-12-13 10:31:57.524099 |
| 28 | 55977 | 2020-01-04 15:34:32.12934 |
| 29 | 54459 | 2017-10-07 06:55:04.372879 |
| 30 | 47344 | 2018-09-25 09:56:10.853888 |
| 31 | 46224 | 2018-10-19 10:33:06.773122 |
| 32 | 44907 | 2018-09-05 14:53:38.892203 |
| 33 | 39544 | 2019-05-28 10:45:38.544188 |
| 34 | 36639 | 2018-09-19 08:50:05.531581 |
| 35 | 36160 | 2017-04-25 00:18:49.618914 |
| 36 | 34256 | 2020-01-04 15:38:40.128898 |
| 37 | 34099 | 2018-04-04 14:43:53.887628 |
| 38 | 33107 | 2017-04-15 11:42:27.962394 |
| 39 | 32791 | 2018-08-16 05:59:16.471888 |
| 40 | 32744 | 2017-04-25 00:39:02.780603 |
| 41 | 32037 | 2018-04-08 13:43:48.229188 |
| 42 | 31236 | 2018-08-15 15:39:00.204377 |
| 43 | 30072 | 2019-12-14 16:12:36.803644 |
| 44 | 29878 | 2018-09-23 09:01:46.863769 |
| 45 | 29260 | 2018-08-18 01:04:57.818141 |
| 46 | 27585 | 2018-08-16 06:30:05.115409 |
| 47 | 26833 | 2018-11-02 06:18:31.772157 |
| 48 | 26234 | 2017-04-22 10:16:53.612031 |
| 49 | 24720 | 2019-03-04 12:21:16.389625 |
| 50 | 24171 | 2023-11-17 01:30:47.430285 |
開設日である2017/9/17から2025/1/1までの総投稿数の推移です。 投稿が削除されたものは含まれていません(現在のMastodonでは、自動での投稿削除機能が実装されたことで、投稿の削除がかなり頻繁に発生しています)。

のべ登録ユーザーの推移となります(=削除されたユーザの数も加算されてしまっています)。 継続的に新規ユーザーにも登録頂いていることがわかります。

至極当たり前の傾向なのですが、フォローイングとフォロワーの数には正の相関があります。たくさんフォローしようね。

現時点ではんドンクラブが認知しているリモートサーバー毎のユーザー数ランキングです。 あくまではんドンクラブが認知しているユーザーに限るので、認知していない場合はカウントされていません。

いかがでしたか?
2024年は私の人生で最も忙しい年でした。理由は2人目の子供が生まれたことです。育児の大変さはまあ2倍くらいになるかな・・・と思っていたら、実際は3倍以上だったんですよね。そのため、正直なところ、はんドンクラブの運営に関する作業はほとんど実施できませんでした。ごめんなさい。しかし今年は、年初よりいくつかのシステム的に重要なアップデートも予定しているので、引き続き頑張りたいと思います。
今年もはんドンクラブをどうぞよろしくお願いいたします。
こんばんは。はんドンクラブのはんです。
はんドンクラブでは、昨年インフラを刷新しました。その目的の一つは、CI&CDを実現できる環境づくりです。
CI&CDとは、継続的インテーグレーション・継続的デリバリー の略で、ざっくりと言うと「実装変更(コーディング)・テスト・本番適用までを自動化すること」です。一般には、CI&CDを実現することで、サービスデリバリーのアジリティ向上、ならびにサービス品質の維持・向上ができると考えられています。特に後者については、個人運営のサーバーであることを考慮しても、大幅に作業負担を軽減できますので、他の作業に時間を使えるようになり、結果的にサービス品質の維持・向上に向けた作業ができる、という訳です。
ただ、最初に申し上げておくと、残念ながらはんドンクラブは全ての作業をCI&CD化した訳ではありません。これは、意図があって自動化したくない作業、言い換えると「私が目で実行結果を確認し、その後に心を込めてエンターキーを押したい作業」があるためです。ただし、自動化したかった箇所について、特にデリバリー作業に関連する作業については、私の手作業はほとんどなくなりました。
そこで、今日は、特にはんドンクラブのデリバリー作業の自動化に関連した、いくつかの技術を紹介したいと思います。正直、まったく難しいことはしていません。そのため、あまり読み応えはないと思います。

手で作業する箇所は4つ(図中、青矢印で記載)のみです。本当は全部自動化できたのですが、Mastodonプロセスのログ確認やブラウザによるアクセス確認を人力で行いGoサインを出したかったので、あえて何回か止めています。
さて、キーポイントとなる技術を2つ紹介します。
Mastodonは本来、Dockerコンテナのイメージが公開されています。かつ、githubには docker-compose.yml も掲載されています。そのため、少々の設定をして docker compose up -d と打つだけで、実はサーバーの運用が可能な状態になります。
しかし、はんドンクラブでは、ソースコードをそれなりに修正しています。かつ、様々なパフォーマンスチューニングを行いたかったため、dockerはあえて使っていませんでした*1。以上の理由と運用面を考慮し、ホストサーバー上で直接プロセスを動かしていました。

今回の移行で、上の図のとおり再docker化を行いました。これは、はんドンクラブの独自DockerイメージをビルドしGithubにプッシュすることで、自動リリースを容易にするためです。
このDocker化により、大幅な変更が無いMastodonへのアップデート(バグFix、セキュリティパッチ等)への追従であれば、ソースコードのマージ・Dockerイメージのビルド・ステージング環境へのデプロイまで、完全自動化できるようになりました。
# ソースコードのマージ
$ git checkout -b ${UPSTREAM_BRANCH} ${TAG}
$ git checkout -b ${HANDON_CI_BRANCH} ${HANDON_PROD_BRANCH}
$ git rebase ${UPSTREAM_BRANCH}
# ビルド
$ docker image build -t ghcr.io/highemerly/mastodon/handon:handon-nightly .
$ docker push ghcr.io/highemerly/mastodon/handon:handon-nightly
# デプロイ(ステージング環境)
$ docker compose pull
$ docker compose restart
ところで、自動化したといっても、やってることは実は上記だけです(実際のコードにはエラー処理がありますが、わかりやすさのためにこの記事では記載を省略しています)。
なお、はんドンクラブのDockerイメージは、handon-nightly タグ と handon-latest タグの2つを運用しています。 docker-compose.yml を書き分けることで、ステージング環境では handon-nightly を、本番環境では handon-latest を使っています。そして、handon-nightly には 検証なしで 気軽にプッシュ しますが、handon-latest へのプッシュは各種目視確認を得て実施する運用ルールとしています。
# docker-compose.yml のイメージ (ステージング環境)
services:
web:
image: ghcr.io/highemerly/mastodon/handon:handon-nightly
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
ports:
- '127.0.0.1:3000:3000'
volumes:
- ./public/system:/mastodon/public/system
depends_on:
- pgbouncer
余談です。当初はk8s化を考えていました。しかし、事前検証の結果、コスト面でのデメリットが大きく、今回は見送ることとしました。サーバーの規模が倍以上になる場合は、再度k8s化を検討したいと思っています。
2023年のインフラ移行前後で、ロードバランシングの実現方式が変わりました。先の構成図のとおり、移行前のフロントエンドは3インスタンス、移行後のフロントエンドは2インスタンスで運用されています*2が、エンドユーザーからのリクエストを分配する方法は、以下のようになっていました。

移行前は、(一応)DNSラウンドロビン です。注意点として、はんドンクラブの通常のHTTPS通信は全てCloudFlare経由であり、エンドユーザーからのDNSクエリを受けても実際のサーバーのIPアドレスが応答されるわけではなく、CloudFlareのエッジサーバのIPアドレスが応答されます。よって、CloudFlareがオリジンサーバへリクエストを送る際のロードバランシングアルゴリズム(たぶん、ラウンドロビン)に従って割り振られているだけで、正確にはDNSラウンドロビンとは少し性質が異なります。すなわち、普通のDNSラウンドロビンのように、エンドユーザーの選出アルゴリズムに依存する訳ではありません。

一方、移行後は、Vultrのマネージドロードバランサーを使います。Least Connectionsで分散を行います。マネージドロードバランサーの採用によって、継続的デリバリーとは直接関係ありませんが、セッションのPersistenceの担保(注: はんドンクラブではMastodonが発行するCookieを使っています)・ハートビートによる各インスタンスの死活監視・TLS処理のオフロードなどを実現しました。でも、それだけでなく、継続的デリバリーの観点でも非常に重要な構成変更です。
このロードバランサーに$10/Monthの追加経費がかかっていますが、やむを得ません。
今回の構成変更が継続的デリバリーに有益である理由を説明するため、まずはメンテナンス方法を説明したいと思います。Mastodonのアップデートなどを行う場合、通常はmastodon-webプロセスの再起動が必要となります。しかし当然、再起動時、数十秒〜数分の通信断が発生してしまいます。

従来のはんドンクラブでは、このサービス中断を防ぐための工夫をしています。でも、CloudFlareでのロードバランシングアルゴリズムがよく分からないため、実際にロードバランシングを行っているCloudFlareでの解決は期待できませんでした*3。そのため、ホスト側のnginxでバックエンドの設定を変え、VPCを経由して生きている他サーバーのプロセスへ飛ばす 処理を行っていました。
ただ、この方法では、nginxの設定変更を行いreload*4しても、おそらくnginxの仕様で現行のTCPセッションのバックエンド側の接続先は変更されないようです。つまり、いつまで待っても旧セッションが使われ続けてしまうことがあります。加えて、そもそもこの方法は、ホスト自身のメンテナンス(例:カーネルアップデートに伴う再起動など)に対応できませんよね。
以上から、オペレーションが複雑で、かつ完全ではない状態でした。つまり、自動化に向いた構成ではありませんでした。

移行後はより単純です。マネージドロードバランサーの設定を変えるだけです。これでサービスを止めることなく、プロセスまたはホストのメンテナンスが可能です。
実際には、websocketの通信は瞬断してしまう場合があることが分かっています。しかし、少なくともMastodonのWebクライアントは、すぐに再接続が行われることを確認しています。よって、ユーザー体験への影響は一切なく、仮にホストの再起動が必要な状況でもサービスを一切止めることなくデプロイができるのです。
さて、実際にメンテナンスへ移行する場合に、マネージドロードバランサの設定を変更する必要があります。
マネージドロードバランサはVultrが提供しているRest APIがあり、設定の差分のみをPATCHで送信することができます。そのため、例えばHost1とHost2で運用している際に、Host1のアップデート作業を行うため切り離したい場合には、以下のコマンドを発行すればOKです。
$ curl -i "https://api.vultr.com/v2/load-balancers/${LB_ID}" \
-X PATCH \
-H "Authorization: Bearer ${VULTR_API_KEY}" \
-H "Content-Type: application/json" \
--data '{
"instances": [
"'${HOST2_ID}'"
]
}'
HTTP/2 204
server: nginx
date: ・・・(Snipped)
これで30秒も待てば、全てのセッションが新しい設定(この例だと、 $HOST2_ID のインスタンス)に向かいます。
なお、実際に切り戻しが行われたかどうかは、インスタンスのnginxのアクセスログを監視し、本当にアクセスがなくなったことを確認しています。これは、Vultr側の反映ラグを考慮したものです。Rest APIでマネージドロードバランサー側の設定を取得することもできますが、その結果から反映が終わったように見えていても、実際にはマネージドロードバランサーの設定が終わっていないことがあるようです。
これまでのリリース作業は、軽微なリリースであっても、1時間以上の作業を要していました。しかし、この仕組みを構築したことで、実作業は10分程度に抑えることができています。また、軽微なオペレーションミス(例:特定インスタンスのみアップデート作業を忘れてしまう)も防げるようになったと考えています。
運用に関する課題は他にもたくさんあります。継続的な改善に取り組んでいきたいと思います。引き続き、はんドンクラブをよろしくお願いいたします。
こんにちは。はんドンクラブのはんです。
早いものでもう年末ですね。そして、はんドンクラブも早いもので、もう7周年が見えてきました。私はプライベートの時間が皆無の状態が続いておりあまりアクティブではありませんが、皆様にはたくさんサーバーを使って頂いてありがとうございました。
今年を簡単に振り返って、年末のご挨拶とさせて頂ければと思います。来年も引き続きよろしくお願いします!

毎年恒例のトゥート数ランキングです。ご自身のアカウントは、投稿数とアカウント作成日から推察してくださいね。
| 順位 | 投稿数 | アカウント作成日 |
|---|---|---|
| 1 | 201855 | 2017-04-16 03:14:45.210683 |
| 2 | 180558 | 2018-09-26 14:00:24.677902 |
| 3 | 170488 | 2017-04-19 23:46:20.721773 |
| 4 | 144721 | 2018-08-17 04:55:36.888916 |
| 5 | 143760 | 2018-08-15 15:46:57.420607 |
| 6 | 130197 | 2018-09-26 13:34:53.286009 |
| 7 | 130018 | 2018-09-06 12:13:56.291501 |
| 8 | 123509 | 2017-04-14 15:25:19.467587 |
| 9 | 112150 | 2017-04-15 02:53:53.437558 |
| 10 | 109947 | 2017-12-10 05:49:59.90627 |
| 11 | 98689 | 2018-08-21 03:56:48.835622 |
| 12 | 85726 | 2017-04-15 02:55:00.283981 |
| 13 | 82749 | 2017-04-15 01:58:28.244079 |
| 14 | 72268 | 2018-09-09 08:15:49.611543 |
| 15 | 71733 | 2018-08-27 18:58:03.712292 |
| 16 | 67688 | 2018-11-19 04:43:11.381105 |
| 17 | 66028 | 2019-08-16 09:27:18.956742 |
| 18 | 65248 | 2018-03-21 04:27:47.006326 |
| 19 | 65226 | 2018-11-19 04:44:53.895617 |
| 20 | 64825 | 2018-08-16 13:33:57.829532 |
| 21 | 61868 | 2017-04-15 02:53:10.105472 |
| 22 | 58590 | 2018-08-16 15:52:19.943946 |
| 23 | 57801 | 2018-08-23 10:41:04.900378 |
| 24 | 55970 | 2020-01-04 15:34:32.12934 |
| 25 | 54454 | 2017-10-07 06:55:04.372879 |
| 26 | 54139 | 2017-04-15 02:01:39.684488 |
| 27 | 53552 | 2018-08-17 12:06:59.137676 |
| 28 | 52384 | 2018-08-18 23:14:00.993394 |
| 29 | 51289 | 2018-12-13 10:31:57.524099 |
| 30 | 45939 | 2018-09-25 09:56:10.853888 |
| 31 | 44749 | 2018-10-19 10:33:06.773122 |
| 32 | 38632 | 2018-09-05 14:53:38.892203 |
| 33 | 35690 | 2018-09-19 08:50:05.531581 |
| 34 | 35684 | 2019-05-28 10:45:38.544188 |
| 35 | 35603 | 2017-04-25 00:18:49.618914 |
| 36 | 33925 | 2020-01-04 15:38:40.128898 |
| 37 | 33107 | 2017-04-15 11:42:27.962394 |
| 38 | 32501 | 2017-04-25 00:39:02.780603 |
| 39 | 32030 | 2018-08-16 05:59:16.471888 |
| 40 | 30343 | 2018-04-08 13:43:48.229188 |
| 41 | 30125 | 2018-08-17 17:18:24.625016 |
| 42 | 28576 | 2018-08-15 15:39:00.204377 |
| 43 | 27750 | 2018-08-18 01:04:57.818141 |
| 44 | 27585 | 2018-08-16 06:30:05.115409 |
| 45 | 26833 | 2018-11-02 06:18:31.772157 |
| 46 | 26293 | 2018-09-23 09:01:46.863769 |
| 47 | 26198 | 2017-04-22 10:16:53.612031 |
| 48 | 24601 | 2019-03-04 12:21:16.389625 |
| 49 | 23972 | 2018-04-04 14:43:53.887628 |
| 50 | 23818 | 2018-09-07 20:46:42.100261 |
ちなみに、2019年以降にアカウントを作成した方に限ってランキングを作ってみました。以下のようになりました。
| 順位 | 投稿数 | アカウント作成日 |
|---|---|---|
| 1 | 66028 | 2019-08-16 09:27:18.956742 |
| 2 | 55970 | 2020-01-04 15:34:32.12934 |
| 3 | 35684 | 2019-05-28 10:45:38.544188 |
| 4 | 33925 | 2020-01-04 15:38:40.128898 |
| 5 | 24601 | 2019-03-04 12:21:16.389625 |
| 6 | 23793 | 2019-12-14 16:12:36.803644 |
| 7 | 18957 | 2019-01-20 15:15:23.96502 |
| 8 | 10076 | 2019-09-02 12:25:39.220573 |
| 9 | 8719 | 2022-07-20 23:09:32.295987 |
| 10 | 8652 | 2019-01-18 04:15:22.984582 |
| 11 | 8545 | 2021-12-12 00:40:17.976319 |
| 12 | 7687 | 2020-05-25 11:16:53.155869 |
| 13 | 7551 | 2020-05-25 08:10:05.992741 |
| 14 | 4812 | 2023-02-14 03:48:49.693808 |
| 15 | 3516 | 2020-02-29 11:07:49.071021 |
| 16 | 3125 | 2023-08-19 13:13:11.328339 |
| 17 | 2606 | 2019-06-04 14:20:41.999689 |
| 18 | 2449 | 2022-05-18 14:50:13.033206 |
| 19 | 2430 | 2019-04-05 04:23:31.871571 |
| 20 | 2412 | 2023-02-02 23:59:45.34248 |
| 順位 | フォロワー | (参考)投稿数 |
|---|---|---|
| 1 | 817 | 123509 |
| 2 | 441 | 201855 |
| 3 | 432 | 130018 |
| 4 | 415 | 391 |
| 5 | 397 | 61868 |
| 6 | 326 | 20770 |
| 7 | 324 | 30343 |
| 8 | 322 | 109947 |
| 9 | 312 | 54139 |
| 10 | 269 | 671 |
| 11 | 250 | 112151 |
| 12 | 229 | 32030 |
| 13 | 209 | 85727 |
| 14 | 208 | 38632 |
| 15 | 207 | 4762 |
| 16 | 203 | 144723 |
| 17 | 198 | 72268 |
| 18 | 198 | 12860 |
| 19 | 194 | 52384 |
| 20 | 186 | 27585 |
| 21 | 184 | 130197 |
| 22 | 184 | 8652 |
| 23 | 183 | 64825 |
| 24 | 175 | 33107 |
| 25 | 174 | 17864 |
| 順位 | 利用量(GB) |
|---|---|
| 1 | 19.0426854630932212 |
| 2 | 16.2412302158772945 |
| 3 | 12.8786057466641068 |
| 4 | 9.1862531360238791 |
| 5 | 8.8057373138144612 |
| 6 | 6.3584921630099416 |
| 7 | 5.7975652972236276 |
| 8 | 5.7018317887559533 |
| 9 | 5.3196726590394974 |
| 10 | 4.8284646151587367 |
| 11 | 4.6705092173069715 |
| 12 | 4.4955962570384145 |
| 13 | 4.1477874331176281 |
| 14 | 3.9942653700709343 |
| 15 | 3.9166470151394606 |
| 16 | 3.8486613761633635 |
| 17 | 3.8317625029012561 |
| 18 | 3.6665426520630717 |
| 19 | 3.4228599537163973 |
| 20 | 3.3217734936624765 |
| 21 | 3.2794725243002176 |
| 22 | 3.2305235359817743 |
| 23 | 2.7993793683126569 |
| 24 | 2.7909871954470873 |
| 25 | 2.7644846774637699 |
| 順位 | サーバー名 | アカウント数 |
|---|---|---|
| 1 | misskey.io | 23707 |
| 2 | mastodon.social | 18510 |
| 3 | mstdn.jp | 13528 |
| 4 | pawoo.net | 9618 |
| 5 | fedibird.com | 4520 |
| 6 | mastodon.online | 2083 |
| 7 | mstdn.social | 1783 |
| 8 | 非公開 | 1740 |
| 9 | m.cmx.im | 1399 |
| 10 | vivaldi.net | 1335 |
| 11 | noagendasocial.com | 1278 |
| 12 | fosstodon.org | 1232 |
| 13 | mas.to | 1169 |
| 14 | sushi.ski | 1149 |
| 15 | poa.st | 1113 |
| 16 | misskey.design | 1025 |
| 17 | mastodon-japan.net | 1013 |
| 18 | chaos.social | 983 |
| 19 | best-friends.chat | 902 |
| 20 | mastodon.art | 889 |
| 21 | hachyderm.io | 862 |
| 22 | misskey.cf | 812 |
| 23 | nijimiss.moe | 805 |
| 24 | mastodon.cloud | 730 |
| 25 | mastodon.world | 707 |
みなさんこんにちは。はんドンクラブ管理人のはんです。
本日は先日発生したストリーミング障害に関するお詫びと、発生原因や再発防止策のご報告をさせていただきます。
長期間にわたりストリーミングサービスが停止し、ご不便をおかけして申し訳ございませんでした。
| 日時(JST) | 時系列 |
|---|---|
| 8/29 22:43 | サーバー移転作業が終了し動作確認を開始 |
| 8/29 23:04 | サーバー移転の動作確認が完了(このタイミングから障害が発生) |
| 8/29 23:05 | ユーザー申告により問題が発生していることを認知 |
| 8/29 23:30 | Redisサーバーの設定変更を行いDebugログが取得できる状態になった |
| 8/29 23:36 | RedisサーバーとStreamingコンテナ間のTCPコネクションに異常がある可能性を発見 ※結果的にこれが根本原因の一つでした |
| 8/30 00:13 | 解析の結果、影響範囲軽減に有効だと判断し、 【暫定対処(1) 5分おきにStreamingコンテナを再起動】 を開始(このタイミングから障害が緩和) |
| 8/31 23:32 | TCPコネクションの異常がStreamingの更新されない事象と本障害が直接関連していると断定し、対処策を本格的に検討開始 |
| 9/1 00:25 | 【対処案(1) ARPキャッシュTTL/TCP KeepAlive時間の調整】 を実行、同時に 暫定対処(1) を一時中断 |
| 9/1 00:30 | 対処案(1) 実行後に事象が再発したため、不十分と判断し、暫定対処(1) を再開 |
| 9/4 23:01 | 解析の結果、根本原因(後述する原因A・B・Cとその因果関係)を断定 |
| 9/4 23:22 | 【対処案(2) クラウドサービスのVPC設定変更等】 を実施、監視を継続 |
| 9/4 23:59 | 対処案(2)の効果が見られたと判断し、暫定対処(1) を中断 |
| 9/5 06:16 | 対処案(2) 実行後に最初に事象が再発(一時的に障害が悪化) |
| 9/5 09:02 | 暫定対処(1) を再開(障害が再度緩和) |
| 9/5 14:14 | 【対処案(3) コンテナのネットワーク設定変更】 を実行、暫定対処(1) を中断(障害が完全に回復) |
| 9/5 22:37 | 対処案(3) により事象が完全に回復したと判断、ユーザ周知 |
結果的にサービス影響は以下のとおりとなります。
データセンター内のサーバー間の通信(TCPコネクション)が不安定となり再接続が行われた場合、MastodonがRedisのSubscribe要求を再送しますが、Redisの上限値である1024*1024を超過して送出する場合があり、かつMastodonがRedisサーバーのエラーを正しくハンドリングできていないためにタイムラインの情報がStreamingで更新できない状態となりました。
まずは構成を説明します。

要因となった動作を説明するには、メインホスト (=Streamingコンテナが動いているホスト)と Redisホスト が登場します。他にMastodonを構成するために必須なPostgresホストなどもありますが、今回の障害要因に関係ないため、この記事では記載を省略します。
メインホスト である host名 prd-host1 および prd-host2 は、Dockerでいくつかのコンテナが動いています。その中の一つがstreamingコンテナです。コンテナはbridgeでVPCに繋がっており、このbridgeではNATが行われます。
Redisホスト であるhost名 prd-redis は Redisが直接ホストで動いており、メインホストと同様にVPCに繋がっています。
さて、事象が発生するメカニズムは以下のとおりです(ただし、後の解析で、①②は③を誘発する要因の1つでしかなく、必要条件ではないことが分かっています)。

①②の後に100%で③が発生しています。しかし前述のとおり、③は①②のARPキャッシュTTL切れ有無によらず、発生する場合がありました。そのため、③が発生する契機は完全には解明できていません。
④はSubscribe量によるため、アクティブユーザー数によって発生する場合と発生しない場合がありました。私の感覚では10分の1〜5分の1程度です。④が発生した後、継続して⑤⑥が発生する確率は100%です。
特に負荷が高い状況でなくとも、当初は60秒に1度全てのTCPコネクションをリセットする送出していました。このTCPリセット送出の要因は、ホストの可能性とStreamingコンテナの可能性があります。実際にはキャプチャをVPCに接続しているNICでしか取得できなかった(=bridge側インターフェースで取得できなかった)ため断定はしておりませんが、他のコンテナで同様の問題が発生していないことから、Streamingコンテナが送出元と想定しています。
○パケットキャプチャの例
![]()
○Redisサーバー側
12249:M 05 Sep 2023 13:24:54.971 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:55.034 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:55.083 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:55.083 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:55.274 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:55.285 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:55.679 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:55.888 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:55.988 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:56.190 - Reading from client: Connection reset by peer 12249:M 05 Sep 2023 13:24:56.218 - Reading from client: Connection reset by peer
送出している原因は断定できていません。しかし、当初はARPを契機にTCP RSTを送出していたため、ARPが一つの要因であることに間違いはありません。メインホストはRedisサーバーからAPRリプライを受け取った直後100ms以内でTCP RSTを送出していました。これは再現率100%です。しかし、MACアドレスの変動などは見受けられなかったため、この原因は不明です。
一方、ARPキャッシュ時間を長くしても、この問題は完全には解消されませんでした。そのため、TCPの何らかのタイムアウト値の設定が悪く、例えばKeep Aliveの不具合が発生しているものだと考えました。DockerをBridgeで接続していたことで間にNATが居たわけですが、このNATが原因で、タイムアウトの瞬間がほぼ同時に発生しTCPクライアント・サーバー間で状態の認識に齟齬が発生した可能性が高いと考えています。
MastodonのStreamingプロセスの実装上、一度TCPコネクションが切断されても再度TCPコネクションを張り直し、Redisに対してSubscribeしていた内容を再度Subscribeしようとします。この実装自体に問題はありません。
しかしながら、このSubscribeを1リクエスト(1パケット)にまとめて送る仕様のようで、稀にRedisサーバーが受け取れる上限を超えて送ってしまうようです。具体的には、Redisサーバーはmulti bulkリクエストを送る場合に1024*1024までというサイズ制限があるのに、MastodonのStreamingプロセスはこれを無視して全ての要求を一度に送ってしまう ことが原因です。
○Redisサーバー側
29 Aug 2023 23:51:51.721 - Protocol error (unauth mbulk count) from client: id=502 addr=192.168.1.9:60128 fd=58 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=1122 qbuf-free=31646 argv-mem=0 obl=55 oll=0 omem=0 tot-mem=61440 events=r cmd=NULL user=default. Query buffer during protocol error: '*39..$9..SUBSCRIBE..$28..timeline:access_token:XXXXXX..$17..time' (... more 994 bytes ...) ':XXXXX..$14..timeline:XXXXX..$28..timeline:XXXXX:notifications..'
※ユーザIDを含む部分はログ上でマスクしています。
○Streamingプロセス側
ERR! Redis Client Error! Error: read ECONNRESET
ERR! Redis Client Error! at TCP.onStreamRead (node:internal/stream_base_commons:217:20)
ERR! Redis Client Error! Error: read ECONNRESET
ERR! Redis Client Error! at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
ERR! Redis Client Error! errno: -104,
ERR! Redis Client Error! code: 'ECONNRESET',
ERR! Redis Client Error! syscall: 'read'
ERR! Redis Client Error! }
MastodonのStreamingプロセスは大変イケてなくて、一度RedisサーバーにSubscribe要求を断られても、それを再送するということをしません。プロセス内部的には、Subscribeされた状態だと認識しているのです。これを再度Subscribeさせるためには、TCPコネクションを完全に切断するか、プロセス毎を起動するしかありません(もっとも、TCPコネクションを完全に切断してしまうと、原因Bをもう一度引き起こすので解決しないのですが)。
StreamingコンテナのみTCPポート4000番(Streamingプロセスが利用するポート)をホストに直接接続する構成変更を行い、本件の解決を行いました。

当然ですが、発生を根絶するためには、ワークフロー後段の原因から対処を検討すべきです。
そこでまず、原因Cの対処を考えましたが、断念しました。この修正のためにはMastodonの実装の確認・修正が必要ですが、Streamingのコードを読んだことすらなかったので、時間的/スキル的制約から取りえない手段でした。
次に原因Bの対処を考えます。Redisサーバーの1024*1024制限はソースコードにハードコードされており、confファイルでは変更できないことが分かりました。ということは、原因Bと同様に、この修正のためにはMastodonの実装の確認・修正が必要です。
以上から、障害認知後の初期段階から、原因Aを修正する方法のみを中心に検討を進めていました。
発生直後から、1分単位でTCPコネクションが頻繁に切れていることはわかっており、かつUbuntuで1分のタイマ値として思いつくものがARPキャッシュ・TCP Keep Aliveしかありませんでした。 そして、取得したパケットキャプチャから、ARPのタイミングとTCP RSTのタイミングが100ms以内であることを特定していましたので、まずはARPキャッシュを1日に延長することにしました。
echo xxxx >/proc/sys/net/ipv4/neigh/default/gc_stale_time
若干の影響軽減は認められたものの、根本解決はしませんでした。 これは、前述のとおり、①②のARPシーケンスは原因Aの発生原因の1つでしかなかったからです。
なお、そのほか、Kernel上でTCP Keepaliveの調整をいくつか試しましたが、こちらは効果はありませんでした。
sudo sysctl -w net.ipv4.tcp_keepalive_time=xxxx sudo sysctl -w net.ipv4.tcp_keepalive_intvl=xxxx
他に同じ事象で困っている鯖缶がいないということは、クラウド事業者側の問題ではないかと疑いました。そこで、VPCの異常を疑いました。
他社のVPSサービスで費用を払い忘れるとネットワーク帯域を絞られた経験があったので、その可能性を考え、費用を先行してデポジットしようとしました。すると、そもそもクレジットカードの支払いに失敗しており、先月分の支払いができてない状態になっていました・・・。

当初、この支払いにより障害の回復が行われたように見えていました。しかしこれも原因Aの発生確立を高める事象の1つでしかなかったようで、すぐに頻発しました。結果的に、対処案(1)ほどの効果はなかったと評価しています。
余談: 当初VultrのVPC2.0をつかっていたのですが、これだとProxy ARPをしている人がいるように見えて気持ち悪かったので、VPC1.0に戻しました。しかし、この処置により改善は見られませんでした。
主に切り分けを目的として、ネットワーク経路の被疑箇所を減らすべきだと考えました。よって、NATを除去すべきだと考えました。
具体的には、StreamingコンテナのみTCPポート4000番(Streamingプロセスが利用するポート)をホストに直接接続することで、切り分けを行おうとしました。実際には、docker-compose.yml に network_mode の設定を加え、docker compose down && docker compose up -d しました。
streaming:
network_mode: "host"
この変更は効果があり、結果的に一度も問題が再発せず、障害が解決しました。
早い段階でメカニズムを解明し、かつ原因Aの対処案策定に絞れたことは評価できると考えています。しかしながら、以下の理由により、具体的な対処案策定には時間を要してしまいましたので、改善が必要だと考えています。
対処案策定から実行までの時間に問題はありませんでした。
加えて、例えばVPC等に障害が起こった場合に、原因A以外の原因で原因Bが発生し、結果的に同一障害が発生してしまうリスクは残っています。 すなわち、原因B・原因Cの本格対処が不要となったわけではありませんので、原因Bの発生を検知したらStreamingコンテナを自動再起動するようなスクリプトの開発が必要 だと考えています。
事前に発見できなかったのかという観点での再発防止です。 負荷がある程度ある状態でないと再現しない問題だったとはいえ、開発環境でも複数回再現していた痕跡がありました。
そのため、開発環境での試験項目に長期安定性試験を加え、Streamingの確認をより入念に行うようにします。
もうすこし日常的に運動をして、免疫を付けたいと思います。よい運動の方法について、慎重に検討を重ねております。
また、子供(1歳)に、帰宅後は手をよく洗うようにお願いしたところ、「はい」と返事しました。これで大丈夫でしょう。
スクリプトの開発は概ねできていますが、いくつか技術的な問題があり、苦戦中です。力業で解決できる見込みなので、2023年10月中に完了予定です。
今回はご迷惑をおかけして申し訳ありませんでした。ひきつづき、はんドンクラブをよろしくお願いいたします。
もし引き続き調子が悪い方がいらっしゃれば個別にご連絡をお願いいたします。
はんドンクラブ(handon.club)へようこそ! 管理人のはん(@highemerly@handon.club)です。
数あるMastodonサーバーから、この「はんドンクラブ」を見つけてくださり、ありがとうございます。Mastodonは、Twitterと非常に似たサービスですが、意外と異なる部分もあります。ですから、もしかしたら、少しだけ取っつきにくいと感じる方もいらっしゃるかもしれません。この記事では、そんな方が悩みやすいポイントとその解説をまとめました。
決して、はんドンクラブを使う前に必ず読んでください、という訳ではありません。でも、もしMastodonを使うのが初めてで、不安なことがある方は、是非この記事を読んでみてください!
上記の投稿のとおり、PCでもスマホでも、最初はWeb(ブラウザ)を使うことをオススメします。
MastodonのWebは、とってもよくできています。更に、アカウント作成直後にログインすると、フォローするユーザーをオススメしてくれます。でも、アプリやクライアントはこのオススメユーザーに対応していない場合が多いので、最初のフォローだけでもブラウザで済ませちゃうことをオススメしているのです。


では、オススメユーザーの探し方について、具体的にご説明します。最初のページ(図左)で、気になるユーザーを見つけ、フォローボタンを押すだけです。もしこの画面が出なかった場合や、しばらくMastodonを使ってみた後にまたオススメユーザーを見たい場合は、画面右メニューの「#(エクスプローラー)」を開いて「おすすめ」をクリックしてください。ほぼ同じ画面(図右)に飛べます。ユーザの選出方法は若干違うのですが、十分参考になると思います。


加えて、ローカルタイムライン(左)という機能もあります。これは、あなたが誰もフォローしていなくても、はんドンクラブに登録しているユーザーの公開投稿が全て勝手に流れてくるタイムラインです。このローカルタイムラインからユーザーを見つけるのもまた良いかもしれません。ちなみに、連合タイムライン(右)という似た機能もありますが、流量が多すぎるため、最初は見なくてよいですよ。
いかがでしょう。フォローを増やせましたでしょうか? もし何か分からないことがあれば、先の投稿にあったとおり、何でも気軽に聞いてください。実はこれが一番伝えたかったことです。 お気軽に管理人のはん(@highemerly@handon.club)宛にリプライを頂ければ、手が空いたときにお返しします!
ここまでで、私の伝えたかったことは終わりました。以下はもう読まなくて良いので、適当に触ってみてくださいね!
・・・。まあ、それでももっと知りたいという方のために、もう少しだけ続けますね。

まずはとりあえず投稿してみましょう。 初期設定でかつ誰にもフォローされていなければ、はんドンクラブのローカルタイムラインにだけ流れ、他のサーバーには流れません。 気楽に挨拶でもしておきましょう。
もしかしたら、ローカルタイムラインを監視している暇人がフォローしてくれるかもしれません。気に入った方であれば、フォローを返してみてくださいね。それか、フォロー有無に関係なく、ローカルタイムラインに投稿している他の人の投稿にリプライを送ってみてもといいかもしれませんね。
はんドンクラブ所属のユーザーであれば、ローカルタイムラインで誰でもあなたの投稿を見ることができます。時間が経つと、他のサーバーでも見えるようになるでしょう。
でも、 設定変更により、Twitterの鍵垢と同じように、あなたが許可した人にしか投稿を見せなくすることができます。 ただ、Mastodonは高機能な故にすこしだけ複雑な設定が必要です。すなわち、
の2つが別々に設定できるようになっており、Twitterの鍵垢と同じことをするには両方の設定を変えなくてはならないです。
具体的には、各投稿毎の公開範囲設定を「フォロワー限定」にして、かつ、アカウントの設定で「承認制アカウントにする」にする必要があります。 長くなるので、具体的な設定方法の説明は省略させてください(知りたい方はリプライしてください)。
ちなみに、一見複雑でめんどくさそうに思えますが、この「各投稿毎に公開範囲を設定できる」という仕様は慣れるととても便利です。例えば、普段は鍵垢として運用しながら、拡散したい投稿だけ公開投稿とすることができますよね。
なお、投稿毎の公開範囲は以下の4つが選べるようになっています。
| 投稿ごとの公開範囲 | 概要 |
|---|---|
| 公開 | 初期設定/通常の公開投稿 |
| 非収載 | ローカルタイムラインには流れないが、アカウントページからは誰でも閲覧できる |
| フォロワー限定 | フォローされているユーザーしか閲覧できない |
| 指定された相手のみ | いわゆる「ダイレクトメッセージ(DM)」 |
4つの違いは少し難しいので、まずは気にせず初期設定のまま、「公開」投稿をするのがオススメです。繰り返しですが、「フォロワー限定」の投稿をしても、アカウントの設定で「承認制アカウントにする」を有効にしていない場合、誰でも許可なくフォローできる状態ですので、結果的にその投稿は誰でも見れてしまいますからご注意ください。
フォローできます。ですから、他のサーバーのアカウント作成を急ぐ必要はありません。
Mastodonサーバーには連合という機能があり、はんドンクラブ以外のサーバーと勝手に連携して動く仕組みになっています。つまり、あなたは、はんドンクラブ以外のサーバーの人ともコミュニケーションを取ることができます。ただ、ローカルタイムラインには他のサーバーの投稿は流れませんから、そのユーザーのIDをどうにかして仕入れてきてフォローする必要があります。
フォローしたいユーザーのIDは、短縮形ではなく正確なIDを知る必要があります。ここで、「正確な」IDというのは、@username@domain のように、@マークが2つある形式のことです。例えば、あなたの登録したIDが donmi で、登録先がはんドンクラブなら、あなたの正確なIDは @donmi@handon.club となります。所属するサーバーが異なれば短縮形のIDはかぶる可能性がある、つまり @donmi@example.com と @donmi@handon.club が別の人かもしれないので、正確なIDが必要なんです。技術的には、メールアドレスに近いです。いずれにせよ、この正確なIDをフォローしたいユーザーに直接聞くなどして、あらかじめ控えておいてください。

後は簡単です。教えてもらった正確なIDをエクスプローラの検索窓に打ち込み、Enterキーを押します。すると、そのユーザーが表示されるはずです。その画面でフォローしちゃいましょう。
ちなみに、フォローしたいユーザーがMastodon以外のソフトウェア、例えばMisskeyやPleromaといった他の分散型SNSを使っていても、はんドンクラブからフォローできます。ですから、はじめてMastodonに登録したあなたは、他のサーバーにアカウントを作る必要はありません。 もちろん、使いこなしてきた後、他のサーバーの雰囲気を知りたいとか、Misskeyをやってみたいとか、そういった用途でアカウントを増やすことはよいと思います。

以上です!
まきはらさんのとてもわかりやすいまとめです。この記事との重複もありますが、ぜひどうぞ。
はんドンクラブでは、他のMastodonサーバーにない独自機能を実装しています。詳しくはこちらをどうぞ。