分散SNSを使って技術を覚える

2019年12月12日 木曜日

「分散SNSを使って技術を覚える」のイメージ
IIJ Engineers blog読者プレゼントキャンペーン

Twitterフォロー&条件付きツイートで「バリーくんぬいぐるみ」を抽選で20名にプレゼント!
応募期間は2019/11/29~2019/12/31まで。詳細はこちらをご覧ください。
今すぐツイートするならこちら→ フォローもお忘れなく!

IIJ 2019 TECHアドベントカレンダー 12/12(木)の記事です】

久しぶりに書きました。

どうもこんばんわ。九州支社で働くとみです。お久しぶりです。
実は2016年に一つ記事を投稿したのですが、実に3年半経過した今になってアドベントカレンダーの話が聞こえてきたので、久方ぶりに書いてみることにしました。

当時はこんな記事なんかを書いてたわけですが、この記事を書いてから3年間色々あったので、その中の一つを書いてみようかなと思います。

3年間で覚えたことを並べてみる

2016年当時はTHE ON-PREMISEと言われてもおかしくないような、どインフラなエンジニアをやっていました・・・。
仕事でももちろん検証環境があり、それを活用して勉強しますが、個人責任でやったほうが楽なものなどに関しては、自宅に型落ちのエンタープライズ機器を配して実際に構築してみるなど色々やってきています。(下図はそんな自宅に設置しているサーバ機器)
クラウドはどちらかというと「よくわかんなーい」という状態で、そもそも興味を抱くことがありませんでした。

さすがにこのインフラの仕事を始めて当時でも13年続けており、当時の年齢としても「アラフォー」&「厄年」が近づいてきてるような年齢です(今はもう40突破済み)んで、技術的に飽和するのかなーと思ってました。(当時はバックエンドなインフラばかり扱っていて、OSプラットフォームやハードウェア、ストレージを中心に触ってました)
やっぱり技術者として歩むには少し限界が見えてきたのかなー、今後はマネジメントかぁーとか漠然と考えていたりもしました。

それから今日まで、まぁ色々ありました。で、とあるきっかけがあり、こんな技術を覚えだしました。意外と人間ってやればできるもんだ。

  • ネットワーク(BGP, IPv6, AS・・どちらかというとWAN系)
  • お触り程度だけど開発言語(Python3, C#)
  • コンテナ(Docker, Kubernetes)/CNI(Calico, Flannel, WeaveNet)
  • CDNやリバースプロキシ、証明書の取り扱いなど

こうした経験が意外にも現在流行りのパブリッククラウドを理解していく一つの助けになっていて、クラウドへシフトすることに悲観をするでもなく、かなり広範囲に技術習得をしながらお仕事にも趣味にも対応することができていて結構楽しいです。また、今後も技術者であろうという心を持ち続ける契機にもなりました。
その技術視野を広げるのに良いきっかけになったのが今回お話しする『分散SNS』という奴です。

分散SNSとは?

一般には「Mastodon( https://github.com/tootsuite/mastodon )」というキーワードのほうが分かりやすいのかもしれないですね。多分分散SNSを実現するソフトウェアの中で最も名の知れたものがそれです。

「Mastodonって息してるの?」という話も見かけるのですが、Mastodonってそれ自体は単なるSNSサーバを構成するためのソフトウェアに過ぎず、コミュニティそれ自体は、現状Activity Pubというプロトコルを使用した複数のSNSサーバで構成されている、連合的なコミュニティが該当します。(最近こうした全体像に対してFediverseという言葉が使われていることを知りました。また、ActivityPub以外にも連合形成できるプロトコルは幾つかあるようです。)

流行った2017年はmstdn.jp, Pawoo, ニコフレといった巨大なSNSサーバが日本にあり、そこにTwitterから抜けた人が殺到して盛り上がっていたのですが、今はそうした巨大なSNSサーバよりも、連合コミュニティの特性を生かした多数の中小規模SNSサーバ間でリモートフォローを利用したコミュニケーションをとるほうがだいぶ主体的になってるような気がします(特に技術者系のコミュニケーションを見てると)

ActivityPub

ActivityPubはW3C勧告も行われているソーシャルネットワーキングサービスにおける、SNS間のデータ送受信における共通規約です。
根幹には同様にW3C勧告されているActivityStreamsという仕組みがあり、JSONフォーマットに基づく送受信時のデータの要素:値に対して定められたデータをREST APIを用いてやり取りすることにより、異なるSNSサーバソフトウェア間の情報交換を可能にしたものです。下図は例としてユーザがクライアントから何かつぶやいたときの動作を簡単に図示したものです。

ざっくり、データフォーマットはチュートリアルから読み取った限りではこんな感じで実装されてました。各データで定義するTypeの値によってさまざまなアクションをとることが可能になっていますし、TO/CCの設定を変えることで、その発言の公開範囲を変更することが可能になっているようです。

これを主だったソフトウェアではWebsocketを使用したStreaming機能で行っており、それゆえ昔Twitterも行っていたような「リアルタイムなタイムライン配信」を可能にしています。ただ、あくまでデータフォーマットおよび処理単位となるオブジェクトに対する規約であるため、実装方式は各ソフトウェアでまちまちですし、オブジェクトに対する扱いもActivityPubで定めた規約さえ守ればカスタマイズされた状態で実装されていることもあるのかなと思います。

様々なソフトウェア

当然Mastodon以外にもそうしたプロトコルを利用したSNSサーバソフトウェアがあり、他にはこんなのがあります。(当然掲載しているもの以外にも沢山あるよ。)
実はActivityPub自体にはクライアントからサーバに対する定義も作られているのですが、どうやらクライアントからサーバは独自の仕組み(Mastodonの場合、Mastodon APIのことを指すのかなと思う)で実装、サーバ間の連合アクセスにActivityPubを使用しているケースが多いように見受けられます。

  • GNU Social ( https://gnu.io/social/ )
    最古参の分散SNSソフトウェアであり、Ostatusというプロトコルを用いて他のSNSサーバと連携をする仕組みだった(Mastodonも初期バージョンは同様だった)が、2018年にActivityPubに切り替え、現在も他のSNSサーバと連携することが可能になっている。PHPベースで作成されている。
  • Pleroma ( https://pleroma.social/ )
    Elixirというプログラミング言語で書かれた分散SNSソフトウェア。非常に軽量でリソース消費が少ないのがウリらしい。Mastodonとの互換性が結構高く、Mastodon向けに作られたアプリケーションが動く点は便利だと思う。
  • Misskey( https://join.misskey.page/ja/ )
    Node.jsベースで組まれた国産の分散SNSソフトウェア。ActivityPubによって他のSNSサーバと連携する。私が現在使っているのはこれ。Webインタフェースの機能が多彩で、見た目的なところは一番扱いやすいような気がする。ゲーム機能も搭載されている。
  • WordPress ActivityPub Plugin( https://ja.wordpress.org/plugins/activitypub/ )
    ある意味番外編ですが、WordpressをActivityPubに対応させて、記事のフォローをしたりできる機能があります。

自分が分散SNSをやってる訳

私はこれが大盛り上がりしていた2017年4月頃にたまたまこの存在を知り、5月頃にMastodonを組み入れたサーバを立ち上げて遊ぶようになりました。当初は単なるユーザとして入ったということもあり、「こんなんすぐ飽きられるやろ」と思ったりしたんですが、「リモートフォロー」という仕組みと「連合タイムライン」というものに惹かれ、自分でサーバを立ててみることにしました。

分散SNSは先に述べたような「連合」の機能を活用して、私のSNSサーバが独りぼっちでも、「リモートフォロー」という機能を使用することで、他のSNSサーバ上のユーザをフォローすることができ、ブースト/リノート(Twitterで言うリツイート)ができ、もちろんFavoriteもつけることができます。

サーバを立てることで、実に多くのサーバと連携して、それなりに多くのトラフィックをサーバに呼び込み、どこに負荷がかかってるのか、どういうプロトコルでどういうメッセージが飛び交うのか、サーバ構成において効率を高める方法はないか?といった多くの学びポイントを見つけることができたかなと思います。

それこそが、私が未だに分散SNSサーバを継続させている理由です。当時のSNSサーバは私のオペミスで消失してしまったんですが、その後Misskeyという別のActivityPubを使用するソフトウェアを利用して再建しています。

分散SNSで学んだこと

Mastodonのアーキテクチャを節穴な私の視点で書くとこんな感じです。(2018年頃の知識で止まってますので最新はもう少し違うんだろうか)

ユーザはリバースプロキシを経由して原則ウェブフロントエンドへアクセスします。
そこで書き込まれた文はデータベースへ蓄えられるとともにジョブスケジューラの管理下に置かれます。
Redis上のキャッシュに送り込まれます。それがStreamingサーバにてWebSocketを通じて連携するサーバへ順次配信され、結果としてリアルタイムでそのSNSで発言する内容がタイムラインに反映されていくという動きをしているようです。
やり取りされる際に使われるプロトコルが先ほど述べましたActivityPubというもので、実際ログを覗いてみると、JSONフォーマットで書かれたメッセージが飛び交っていました。

このアーキテクチャの特徴として、自分にヒットしたのが

  • 恒常的にそれなりのネットワークトラフィックが発生する(負荷増減の挙動をリアルに見れる)
  • 恒常的にそれなりのディスクIOが発生する(負荷増減の挙動をリアルに見れる)
  • Sidekiqは水平分散できる(スケールアウトしやすい)
  • Docker-composeファイルが配置されていて、大まかな構成が見てわかる
  • 画像キャッシュをCDNに置いて負荷軽減が図れる
  • Activity Pubが導入されてからは、サーバを過去時点に復旧してもすぐ疎通が図れる(Ostatusの頃はトークン期限が終了するまで、連合組んでたインスタンスと疎通できなかった)

というところでした。
分散SNSを通じて得た視野というのは非常に広範囲で深く、ある意味人生史上最強の衝撃を与えたに近いものがあったのですが、特にこのソフトウェアをきっかけに一気に視野を広げたのはほかでもないコンテナでした。

コンテナとネットワーク

このソフトウェアはDockerでの運用も想定しているため、さっと環境が組めるようにDocker-compose用のYAMLファイルも配置されています。コンテナとして何が必要か、どこにデータを配置するかといった設定も見ることができ、構成の大まかな内容をおさえることができました。(下図は2018年4月頃にGithub上のMastodonにあったDocker-composeファイルを読んだ結果です。検索機能であるElasticsearchは含んでません)

また、アプリケーション部分は水平分散が非常に容易であり、Sidekiqなどは役割単位で起動させることができますし、数を増やせば自動的に自身のSNSサーバ配下に加えて性能強化が行えます。下図のようにコンテナをばらすことで、アプリケーションのコンテナ(青枠)は簡単にスケールアウトできます。

ちょうど職場の上長から「こんなのがあるらしい」と名前だけ聞いていて気になって触り始めていたのがKubernetesでした。Kubernetes(k8s)は最近色々なところで知られるようになってきたんじゃないかと思うのですが、コンテナホストを複数台並べてクラスタを構成し、管理することのできるコンテナオーケストレータの一種です。それまで単一VMで構成していたサーバをオーケストレーターの中に放り込むことで容易に状況に合わせてリソース使用量を調整できるなーなどと考えまして、このアプリケーションをKubernetesに放り込んでみたのが2018年5月頃です。

2017年5月に建てた時点では単一サーバにすべての機能を詰め込んだオールインワンパッケージでしたが、最終的に2018年11月頃の最大構成としては以下の通りとなっています。
ちょうどオブジェクトストレージを利用している人も多く、自宅で出来るオブジェクトストレージとしてオープンソースが公開されているCephも、この時試しに実装して仕様の把握をしたり、オブジェクトストレージというのがどんなところに注意が必要なのか・・・を学んだりしました。

また、上記にもあるように、Kubernetesを構築する過程でCNIの一つであるProject Calicoに触れました。
CNIとは、Container Network Interface の略称であり、Kubernetesに限らずコンテナホスト間でコンテナネットワークを形成するためのインタフェース及びネットワーク構造を指します。
CNIってどの製品も特色があって、「これぞSDN」という一つの形を見せているようなものが多いです。
この時使用した「Project Calico」はほぼL3に依存して通信を行い、その経路制御をBGPだけでやってるという面白い仕組みになっています。BGPというと「なんだかネットワーク屋さんが取り扱う途方もないものだなー」位だったのが、今はもうクラウドに対する閉域網を構成する際に欠かせないプロトコルになってきていることからも、実はクラウド関連のSIを行うにあたり必要な技術要素になっており、コンテナに興味を抱いたというのは本当に偶然だったけど大きいことだなーと感じています。
ここからSDNって面白そう・・って印象を受けてLagopus触る->Pythonおもしろそう->Ansibleもっとおもしろそう->・・・という方向に興味を持って行ったというのもこの時期だったりします。

コンテナからつながったこと

コンテナ関連の技術やネットワークの技術を覚えていくことで、それが実務側に貢献できたと考えるのがMicrosoft Azureを中心としたパブリッククラウドの理解でした。
それまで、クラウドに関してはIaaS/SaaSは何とか理解できるものの、PaaSがどんなものか、なぜ開発者はPaaSを求めるのか?というのが良く分からなかったんですが、コンテナに触れることで成程と分かったのは、

  • 環境をプラットフォーム丸ごと含めてセッティングしたうえで提供できること
  • コンテナの作成・破棄が非常に迅速であること
  • 開発箇所を細かくバラすことで開発箇所を明確に分けられること(環境分離的なところが大きいのかなぁ)
  • IDE環境って本当に便利なんだなぁ(勉強用途でVisual Studio CodeなりEclipseなり入れてみましたが、十数年前で時が止まってる私には衝撃だった)

というところかなぁ。他にも例えばAzure WebAppだと

  • デプロイメントスロットはリンククローン的なイメージでコンテナを作るから、切り替えが楽(スロットのスワップとか)
  • スケール操作もPortal経由で数値決めてボタンポチーで簡単に調整できる
  • アプリケーションデプロイは色々方式があるけれど、Gitも使えるしVisualStudioの配信機能もあるし、バージョン管理含めてだいぶ楽に運営できそうな気がする

ステートレスなサービスであれば簡単にサーバをスケール出来るのも多いかなと思いますし、それをほぼ意識せずに済む。そりゃこれが望まれるわけだ・・と感じました。
ただ、PaaSそれ単独で何も対策せずに動かすと結構セキュリティリスクが大きいということも分かりました。何しろすべてがパブリックIPで動作するから。なにも設定してなければ世界に向かって作って生まれたその日からフル公開です。それが許される業界もあるのだとは思うのですが、許されぬ業界もあり、そうしたところはやっぱり意識付けが必要なのかなと感じました。
PaaSのように抽象化されたところでもインフラの技術なりがある程度わかることは必要であり、重要なんだなということを知ることもできました。

これからも技術を追いかけられる人でありたい

私はいつか年齢を重ねるうちに技術を手放さなければならなくなるのではないだろうか?と、当社に入る前までは思ってました。

まさか

  • うわさで聞いたSNSをのぞき込んで
  • 知りもしないWebアプリケーションの世界に首を突っ込み
  • 実際に自分で組んでみてこりゃ面白いと感じ
  • リソース利用方法に疑問をもってコンテナに手を出し
  • コンテナの話題から雑談でKubernetesを知り
  • 自身のSNSシステムをKubernetesに組み込み
  • Kubernetesの技術要素であるCNIの技術からBGPの使い方を覚え
  • とどめにパブリッククラウドの扱い方を学び、それで飯食ってる

とは当時の自分だと絶対思わないんじゃないかな。それこそ点と点が線でつながる瞬間を垣間見たような気がします。
そうして色んな初挑戦系のものに取り組み続けた結果、意外にもまだ技術畑でゴリゴリと機能検証を進めたり、知らなかった技術知見の収集は継続出来ていて。意外と続けられるものなんだなーと感じています。

また、直接仕事に結びつかないところではあるけど、いろいろ開発関連のわずかな知識ではあるけれど、これを生かして開発ベンダーの方とコミュニケーションをとる際、少しは開発者側の目線に近づいてコミュニケーションが取れるようにはなりました。いろんな方面に連携をとれるというのは中々にありがたいスキルなんだなぁ・・・と感じています。

いつ、どこに、どんなきっかけが埋まってるかわからない。私自身人生の中で嫌と言うほどその経験をしてきましたが、「分散SNS」という、ある意味千載一遇のきっかけは大切にしたいなと思っています。

参考文献

当記事はいくつかの記事を参考に記載させていただきました。知識習得の際に参照したサイトを以下の通り掲載します。

  1. マストドン日本語Wiki( https://ja.mstdn.wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8 )
  2. 鯖缶工場(自分でSNSサーバを立てたい人向けの紹介記事/ https://nacika.com/entry/2018/10/06/043139/ )
  3. ActivityPubの概要( mstdn.jpを運営していたぬるかるさんの記事/ https://qiita.com/nullkal/items/accc5d62836a930b3cd9)
  4. ActivityStreams 2.0( https://www.w3.org/TR/activitystreams-core/ )
  5. ActivityPub ( https://www.w3.org/TR/activitypub/ )
  6. Fedibird ( Fediverse と言う物をもう少し広めたい人が作ったSNSサーバ /https://fedibird.com/about )
  7. The Desk ( デスクトップクライアントの一つ / https://thedesk.top/ )
    • ブラウザUIに関してはいずれのサーバソフトウェアも秀逸なのですが、複数アカウントを制御したい場合にクライアントソフトウェアが色々あるので、その一つを紹介してみました

とみ

2019年12月12日 木曜日

地方拠点の一つ、九州支社で細々と働いています。オンプレミス環境の仮想化インフラ・ストレージに関する提案・設計および構築業務を中心に対応しています。2018年あたりからMicrosoft Office365/Azureにも手を出しました。

Related
関連記事