Repro のサーバーサイド開発環境を M1 Mac に対応させるまでの道のり(撤退編)

f:id:yu_suke1994:20211210101708p:plain

記事執筆中に動かなくなった開発環境

Repro でサーバーサイドの開発をお手伝いしているうなすけと申します。

前回の記事を最後の脚注まで読んでくださった方はご存知でしょうが、記事執筆中にmergeされた変更によって、M1 Mac での開発環境は動かなくなってしまいました。

tech.repro.io

この記事では、一体何が原因で動かなくなってしまったのか、回避のために試したことと、結局撤退する判断をした経緯について書きます。

Repro のアーキテクチャについて

まず、なぜ動かなくなってしまったのかですが、これには Repro というサービスのアーキテクチャが関係してきます。

Repro では、ユーザーの端末やWebブラウザから送信されてくる大量のデータを取り扱うために、Kafka を使用してデータの処理を行っています。これに関しては、チーフアーキテクトによる以下の記事及びスライドにて Kafka を採用した理由について述べられています。

joker1007.hatenablog.com

そのため、サーバーサイドの開発者は必要に応じて手元のマシンで Kafka や、 Kafka に必要となる ZooKeeper や Schema Registry を起動していました。そして前述の通り、ここ最近になって Rails アプリケーションのセットアップにこれらのコンポーネントを必要とするような変更が merge されたのです。

Confluent Platform は M1 に対応していない

Kafka を手元で動作させたい、とくに Docker container として起動したい場合には、どのような選択肢があるでしょうか。弊社では、Confluent Platform として Confluent社から提供されている Docker image を使用しています。

hub.docker.com

そして、これらの Docker image は x86_64 環境のものしか提供されていません。platform: linux/amd64 の指定をしても起動することはできませんでした。対応する予定はあるようなのですが、それがいつなのかは不明1です。

github.com

Lima は救世主となるか

さて、皆さんは Docker Desktop が有料化するという発表があったときに、その代替として候補に挙げられていた Lima のことを覚えていらっしゃるでしょうか。

medium.com

Lima は macOS の Hypervisor.framework で起動した仮想マシン上で containerd 及びその CLI である nerdctl を使用する環境を簡単に構築できます。そして Lima と nerdctlのドキュメントには multi-arch についての記載があります。

github.com

これが救世主になるかと思い、試してみることにしました。が、結果としてはうまくいきませんでした。arm64のコンテナからx86_64のコンテナへの通信ができない、nerdctl composeがまだまだ発展途上である、などの困難がありました。2

まとめ

このような経緯があり、Repro のサーバーサイドの開発を M1 上で行うのはまだまだエコシステムが発展途上ということもあり厳しいと判断せざるをえませんでした3クラウド上に開発用サーバーを用意して、VS Code Remote SSH などで開発を行うのが環境構築の手間等含め現実的なのかもしれません。GitHub Codespaces も良さそうですが、使用できるリージョンに日本がまだ無いのがどのくらい使用感に影響するのかが気になっています。

しかし、撤退したものの、検証中に何度も行なった docker build コマンドの最中において MacBook が激しく熱を持ったり、冷却ファンがうなりを上げたりすることがなかったのはとても快適でした。

そして、別の選択肢としては Linux もしくは WSL があります。WSLについては、支給機は MacBook もしくは Windows ラップトップのどちらかを選択することができますが、現時点で開発メンバーのうちサーバーサイドを担当する者に Windows 機を使っている人は居ないので、WSLで開発環境が構築できるかどうかは確認できていません。今後 WSL で動くことが確認でき、Intel MacBook の在庫が無くなったら Windows 機を使ってもらうようになるかもしれません。

おまけ x86_64 と Arm のどちらでも build できる Dockerfile を書くコツ

Dockerfile において、アーキテクチャに依存した記述をしている部分はないでしょうか。具体的には LD_LIBRARY_PATH/lib/x86_64-linux-gnu/foobar を設定する、などの記述です

uname -m を使用することで、 x86_64aarch64 の値を得ることができます。これによってアーキテクチャに依存する部分を置き換えることができます。

しかし、amd64arm64 という値が欲しい場合があります。具体的には linux-headers-{amd64,arm64} package です。

この場合には、debian系という前提はありますが、 dpkg --print-architecture というコマンドによって、上記書式のアーキテクチャ文字列を取得できます。

manpages.debian.org


  1. 一応 https://github.com/confluentinc/common-docker/pull/149 にて対応される予定はありそうですが……

  2. podman ならうまくいくのかもしれませんが、検証作業に疲れてしまって試す気力がありませんでした

  3. Kafka 関連のコンポーネントを使用しない範囲であれば M1 上でも開発はできます。開発環境に限り、実行中のアーキテクチャによって処理を行うかスキップするかの分岐をする変更を行いました。