HN 日本語サマリー

← 一覧へ戻る
インフラ・DevOps

私のサーバーは今や電話だ

My server is a phone now (seg6.space)

455 pointsby seg6215 コメント

要約

著者はHetzner VPSの代わりに、CMF Phone 1をパーソナルサーバーとして活用することにした。当初はLinuxディストリビューションを直接インストールしようとしたが、ハードウェアドライバの問題で失敗した。最終的に、Android上でTermuxをホスト環境として利用し、Androidのドライバを活かしつつLinuxアプリケーションを実行する方式で成功を収めた。このシステム全体はAnsibleで管理されている。

全文翻訳

しばらくの間、私のパーソナルインフラは小さなHetzner VPSで稼働していました。いくつかのWebアプリケーション、リモートブラウザのSurf、Caddy、そして通常のサポートキャストが動いていました。特に深刻なものではありませんでした。それは機能していましたが、私はその支払いが好きではありませんでした。私が実行しているアプリの一つであるSurfは、この妥協を無視しがたくしていました。最も安価な共有マシンは、Chromeが実際の作業を行うまでは問題ありませんでしたが、その時点ではリソース不足を感じました。専用CPUマシンはその問題を解決しますが、毎月個人用ブラウザのために疑問のある財務上のコミットメントとなるほどの費用がかかります。別のマシンを購入することも魅力的な逃げ道ではありませんでした。DRAMの価格は完全に馬鹿げていたので、十分なメモリを備えた新しいボックスを組み立てることは特にタイミングが悪く感じられました。中古のミニPCを探し、使用していないときにデスクトップをサーバーに変えることを briefly 考えました。それから、私がすでに所有しているCMF Phone 1を思い出しました。8つのARMコア、8GBのRAM、128GBのフラッシュメモリ、Wi-Fi 6、5Gモデム、そして内蔵バッテリーバックアップ。これらすべてが、引き出しの中に座っているには過剰資格があると感じるSoCに接続されています。そして、私はすでにその代金を支払っていました。それを埃払いしてしばらくいじった後、その電話をサーバーに変えることにしました。今日、それはSurfとその管理されたChromeインスタンス、私の個人財務トラッカー、画面共有サービス、そして少数の小さなWebアプリケーションを実行しています。それらは再起動を乗り越え、Gitからデプロイされ、電話がネットワーク間を移動しても到達可能であり、これがVPSを実際に置き換えたマシンとなりました。 最初の悪いアイデア: Androidの置き換え このアイデアの最もクリーンなバージョンは、通常のLinuxディストリビューションをフラッシュすることでした。CMF Phone 1にはpostmarketOSのデバイスポートがあり、起動し、デバイスページには無謀な人を楽観的にさせるのに十分な緑色のボックスがあります。私はその人になりました。私があまり注意を払わなかったのは、壊れているとマークされたすべてのもの、つまりWi-Fi、Bluetooth、ハードウェアアクセラレーション、そして電話を小さなサーバーとして役立つものにする他のほとんどの機能でした。私はpostmarketOSのスプラッシュスクリーンと黒いディスプレイまでしか到達できませんでした。その時点で、私はサーバーも電話も持っていませんでした。 ストックのNothing OSの復旧は、それ自体がサイドクエストになりました。フラッシュユーティリティはWindowsを必要としたため、QEMUにWindowsをインストールし、USBパススルーとMediaTekドライバと格闘し、フラッシュツールがハングするのを見て、最終的にプロセスを実際のWindowsインストールに移動して工場イメージを復元しました。この途中で、電話がソフトブリックされ、黒い画面しか表示されなかった瞬間があり、私は本当に完璧なデバイスをペーパーウェイトに変えてしまったと思いました。それは復活し、教訓を得ました: Androidはすでにこのハードウェアのすべての部分に対して動作するドライバを持っています。Wi-Fi、電源管理、バッテリー、GPU、モデム、そしてすべての奇妙なベンダー固有の詳細がすでに機能しています。より従来のユーザー空間を追求するためにこれらすべてを捨てることは間違った取引でした。私は実際に電話を通常のLinuxマシンにする必要はありませんでした。Androidがハードウェア固有の作業をうまく行い続ける間、Linuxアプリケーションを確実に実行する必要がありました。 Termuxはホストオペレーティングシステムです 2回目の試みでは、ストックのAndroidを維持し、Termuxをホスト環境として扱いました。TermuxはOpenSSH、runit、Caddy、Cloudflared、パッケージ管理、そして十分に通常のUnixツールを提供してくれます。Termux:Bootは再起動後にスーパーバイザーとSSHを起動します。Tailscaleは電話に安定したプライベートアドレスを提供するため、私のtailnet上のどのマシンからでも、ssh cmfと実行するだけで済みます。 Termuxは仮想マシンではありません。そのプロセスは依然としてAndroidのLinuxカーネルに対して実行されますが、そのBionicベースのユーザー空間は通常のDebianインストールとは十分に異なるため、既存のLinuxアプリケーションイメージをそのままドロップすることはできません。しかし、その分割は有用であることが判明しました。Termuxは小さなホスト制御プレーンのままで、各アプリケーションは期待するLinuxファイルシステムを持ち込むことができます。実際のアプ​​リケーションはrunitによって監視されています。Androidのバッテリー管理は、通常のジョブには非常に優れていますが、サーバーを装うデバイスには非常に悪いです。そのため、私のAnsibleビルドはAndroidホストプロファイルも適用しました。これは、永続的なウェイクロックをインストールし、ライトおよびディープアイドルを無効にし、Termux、Termux:Boot、およびTailscaleをバックグラウンド制限から免除し、子プロセス制限を無効にし、Wi-Fiサスペンションを防ぎ、Tailscaleを常にオンのVPNとして構成します。リカバリチェーンは、個々の設定よりも重要です。Androidが起動し、常にオンのVPNがTailscaleを復元し、Termux:Bootがrunitを起動し、runitがすべての常駐サービスを起動し、ヘルスチェックがローカルおよびパブリックパスを検証します。電話は私が気づくのを待つことなく再起動できます。 Android起動 -> Tailscale常時オンVPN -> Termux:Boot -> runit -> 常駐サービス -> ローカルおよびパブリックヘルスチェック これは従来のLinuxサーバーではありません。systemdはなく、通常のDockerデーモンもなく、そのように見せかける理由もありません。しかし、それは非常に有能なユーザーランドがその上に座っているLinuxカーネルであり、それは十分であることが判明しました。 2番目の悪いアイデア: proot 私のアプリケーションのほとんどは、すでにLinux ARM64 OCIイメージとして出荷されていました。proot-distroは、アプリケーション自体を変更することなく、Debianの下でそれらを驚くほど簡単に実行できるようにしました。PRootはファイルシステムとプロセス操作をユーザー空間でインターセプトし、通常のTermuxプロセスにDebianルートファイルシステム内にいると思わせます。これはコンテナの境界ではありません。すべては依然としてAndroidのカーネル、ネットワーク名前空間、およびTermux UIDを共有します。しかし、アプリケーション互換性レイヤーとしては、ルート権限も特別なカーネルも必要としないため、非常に有用です。通常のWebサービスは当初、この方法で問題なく動作していました。私の各アプリケーションは、検証済みのルートファイルシステム、ループバックポート、およびrunitサービスを取得しました。CaddyはTermuxで直接実行され、ホスト名をそれらのポートにルーティングしました。パフォーマンス/レイテンシに敏感なSurfブラウザのワークロードは例外でした。プロセスを開始したり、ライブラリを開いたり、パスを歩いたり、ブラウザプロファイルを読み取ったり、キャプチャデータをシャッフルしたりするたびに、PRootのユーザー空間翻訳レイヤーを通過しました。CPUは利用可能でしたが、Chromeは効率的にそれに到達できませんでした。そこで、私は電話をルート化しました。Androidを置き換えるためではなく、同じDebianファイルシステムを適切にマウントし、実際のchrootでそこに入るためです。runitは依然としてTermuxからのライフサイクルを管理し、設定は同じ場所から来ており、アプリケーションデータは依然としてTermuxストレージにありました。ワークロードは、PRootを介してネイティブシステムコールでAndroidカーネルに到達するようになりました。改善は微妙ではありませんでした!そのパスがしっかりした後、PRootの下で小さな常駐プログラムを残しておくことはあまり意味がなくなりました。それらは今、同じ方法で実行されています。私のワークステーションは、各ARM64イメージを正確なダイジェストに解決し、そのファイルシステムをエクスポートします。Ansibleはそれを電話に検証してインストールします。小さなルートヘルパーは、プライベートマウント名前空間を作成し、必要なパスをバインドし、chrootでファイルシステムに入り、権限を降格させ、元のイメージのエントリポイントを開始します。Dockerもコンパイラも電話に存在する T必要はありません。これらは依然として互換性環境であり、セキュリティ境界ではありません。常駐プログラムはAndroidのカーネルとネットワークスタックを共有しますが、プライベートマウント名前空間は主にマウントとクリーンアップを予測可能に保ちます。また、VirGLとAndroid Vulkanを介してDebianのグラフィックススタックを電話のMali GPUにブリッジしようと、はるかに長い時間を費やしました。ハードウェアコンポジットチェックマークと破損したページ、そしてパフォーマンスの低下を同時に得ました…退屈なソフトウェアレンダリングパスの方がパフォーマンスが良いことが判明しました。 インフラストラクチャ!シェル履歴の山ではない この時点で、電話はすべてを実行できましたが、私は1週間で忘れてしまうようなコマンドから組み立てられたペットサーバーを望んでいませんでした。私はホスト全体をAnsible管理状態に移行しました。バージョン、サービス定義、ルート、電源設定、シークレット、ヘルスチェックはすべて1つのプライベートリポジトリにあります。デプロイフローはほぼ次のとおりです。リリースまたはOCIイメージ -> Gitでピン留めされたチェックサム/ダイジェスト -> SSH経由のAnsible -> 電話上のバージョン管理されたファイル -> アトミックな現在のシンボリックリンク -> runitサービス -> ローカルヘルスチェック -> パブリック