サーバークライアント環境を構築したかったので、クライアントはmacOS上にUTM.appを使って仮想マシンで用意しました。 インストールも終わっていざクライアント環境にCLIをインストールしようとしたときにハッと気がつきました。 ARM64に対応するクライアントがないのです*1。

今使っているメインの作業環境はApple Siliconを搭載したMacです。 そんなときに思いついたのが、奥の方に眠っていたIntel Macを取り出す...のではなくて、LinuxでRosettaを使う方法です。
UTM.appでLinuxでRosettaを使う方法はドキュメントに書かれています。 下記ドキュメントや以前ブログでご紹介した ように、DebianやUbuntuであればこの方法でLinuxでRosettaを使うことができます(ホストのMacにRosetta 2がインストールされていれば)。
ではbinfmt-supportというパッケージが用意されていないLinuxディストリビューションではどうすればいいか? 調べたところ、UTM.appのGitHub Issueに書かれていた方法が参考になりました。
これを応用した方法が次のサイトに書かれていました。 なるほど、シェルスクリプトをsystemdでサービス化して実行すればいいということですね。確かに良い方法かも。
実際やってみた
環境はCentOS Stream 9ですが、別に使っているのはBashにSystemdにシェルスクリプトなので、どのLinuxディストリビューションでも同じように動作すると思います。多分。
設定前は他のアーキテクチャー向けのバイナリーは再ビルドしない限り実行できません。
$ arch aarch64 $ tar zvxf oc-4.15.12-linux-amd64.tar.gz $ ./oc --help -bash: ./oc: バイナリファイルを実行できません: 実行形式エラー $ file ./oc ./oc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=6Wt3LPExcbvpy1zXoTX2/aEmTVptuaRqAti4vYO5F/_AegSdyd611tgHkVXD3U/h6WTZ7sQ-IImPNLF7MH3, with debug_info, not stripped
設定後は問題なく、バイナリーを実行できます。
$ arch aarch64 $ mount|grep rosetta rosetta on /media/rosetta type virtiofs (ro,relatime,seclabel) $ tar zvxf oc-4.15.12-linux-amd64.tar.gz $ ./oc --help ... Usage: oc [flags] [options] Use "oc <command> --help" for more information about a given command. Use "oc options" for a list of global command-line options (applies to all commands).
問題なく動きますね。これでDebian/Ubuntu以外でもRosettaが使えるのがわかりました。 これで「ああまたaarch64だから動かない」と思わずに済みます。

今回例として使ったCLIですが、Red Hat OpenShift Container Platform for ARM64に含まれる、 OpenShift v4.15.14 Linux Crossplatform Client (amd64)のパッケージを使っています。
もう一つのCrossplatform Clientではない方は、この方法だけでは次のようにコアダンプしてしまうので注意が必要です。
$ ./oc --help rosetta error: failed to open elf at /lib64/ld-linux-x86-64.so.2 Trace/breakpoint trap (コアダンプ)
*1:ちなみにサーバーはx86_64環境です
