macOS で x86_64 な Linux を使う
はじめに
こんにちは。DMS 開発部の吉村です。DMS 開発部ではニコニコ動画やニコニコ生放送の配信基盤を開発しており、動画のアップロードを受け付けたり、視聴に適したフォーマットに変換してユーザーの皆様にお届けしています。私自身はその中でもインフラ周りの構築を担当しています。
普段は Apple Silicon で macOS を使用していますが、ソフトウェアを開発していると x86_64 (AMD64) のツール群が必要になる時があります。Docker でも x86_64 のバイナリを動かすことができますが、systemd も含めた一式が欲しい場合に高速な x86_64 の環境を用意する方法をご紹介していきます。
仕組み
今回使用する構成としては次のようになっており、端的にいうと systemd-nspawn と Rosetta 2 というものを使って x86_64 のコンテナを動かします。コンテナという言葉から分かる通り、x86_64 の Linux Kernel は動いておらず、技術的には Docker と似たものになります。
- aarch64 (ARM64) macOS
- aarch64 VM
- aarch64 Linux
- systemd-nspawn + Rosetta 2
- x86_64 Distribution
VM は lima を使用する場合と UTM を使用する場合で解説します。事前にインストールしておいてください。
Linux は aarch64 のホストでは Ubuntu 24.04 を、x86_64 コンテナでは Ubuntu 22.04 を使用します。22.04 を利用する理由は、執筆時点で 24.04 だと journald や logind がクラッシュしてしまうためです。これについては原因が判明して解決すれば Ubuntu 24.04 にできますが、ここでは安全な方を使用します。古い環境の動作確認を行う場合、例えば x86_64 のディストリビューションに CentOS 7 を使用するといったことも可能ですが、CentOS 7 の深い知識が必要になります。
systemd は Linux の管理を行うソフトウェアであり、systemd-nspawn は systemd が持つコンテナ機能です。
Rosetta 2 は x86 の命令を ARM の命令に変換する仕組みで、macOS に備わっているものです。通常のソフトエミュレータに比べて非常に高速に動くところが特徴です。
事前準備
Rosetta 2
今まで Rosetta を使ったことがない場合は次のコマンドでインストールしておきます:
(macOS)
|
|
VM (lima の場合)
VM の設定を用意します:
ubuntu.yaml
|
|
VM を起動して、シェルに繋ぎます:
(macOS)
|
|
VM (UTM の場合)
次の Linux ISO をあらかじめダウンロードしておきます。ただし執筆時点の UTM 4.6.4 では ISO サイズが小さな cloudimg 版が動作しない ため、Server 版の ISO を使用します:
https://cdimage.ubuntu.com/releases/24.04/release/ubuntu-24.04.2-live-server-arm64.iso
UTM を起動し、メインウィンドウから「新規仮想マシンを作成」を実行します:

「仮想化」を選択します:

「Linux」を選択します:

次の設定を入力します:
- Apple 仮想化を使用
- Rosetta を有効にする
- 起動ISOイメージ
- ubuntu-24.04-server-cloudimg-arm64.img

あとはそのまま進めて「保存」を実行してください。保存が完了したら VM を起動して Ubuntu をインストールしておきます。注意点としては Apple 純正 JIS キーボードを使用している際にキーボードレイアウトに English
以外を選択すると _
や /
が入力できなくなるため、English
でインストールしてください。
インストールが完了したら VM 内で Rosetta を有効化します:
(aarch64 Ubuntu)
|
|
もし Ubuntu Server の minimal 版など、エディタが入っていないものをインストールした場合は、必要なエディタもインストールしておいてください。
Ubuntu の構築
aarch64 版 Ubuntu の上に x86_64 版 Ubuntu を構築します。ついでに Ubuntu の中で Docker も使えるようにしておきます。
要素としてはコンテナを実行する systemd-nwpawn と、Ubuntu を構築する debootstrap の2つです。systemd-nwpawn は systemd-container
というパッケージで提供されています。debootstrap は Debian 系のディストリビューションの ISO やコンテナイメージを作成するために使用します。
可変な部分としては Ubuntu のバージョンである jammy
と、コンテナ名の ubuntu-x86
程度ですが、そのままでよければ基本的にはコピペで大丈夫です:
(aarch64 Ubuntu)
|
|
これで /var/lib/machines/ubuntu-x86
にコンテナが出来上がりましたが、パスワードがないとログインできないため root ユーザーのパスワードの設定とコンテナ内でネットワークと Docker が使えるように準備します。
(aarch64 Ubuntu)
|
|
root ユーザーのパスワードを設定します。ここでは割愛しますが必要に応じて root 以外のユーザーを作成するのもこのタイミングです:
(x86_64 Ubuntu)
|
|
ネットワークと Docker の準備を行ってコンテナから抜けます:
(x86_64 Ubuntu)
|
|
コンテナが完成したため aarch64 版Ubuntu に戻ってきて systemd-nspawn の設定を行います。ここではネットワークは仮想化せずにホストネットワークをそのまま使います:
(aarch64 Ubuntu)
|
|
x86_64 版 Ubuntu へのログインと終了
前述の x86_64 版 Ubuntu の構築時にも扱いましたが、x86_64 版 Ubuntu を起動せずに次のコマンドで直接コンテナに入ることができます:
(aarch64 Ubuntu)
|
|
これは chroot
に近い使い方です。
コンテナに直接入るのではなく systemd とその他サービス類を起動してログインシェルを経由するには、手動で起動する方法と、自動的に起動する方法があります:
(aarch64 Ubuntu)
|
|
コンテナを終了するには次のように行います:
(aarch64 Ubuntu)
|
|
ログインシェルでのログインは次のように行います:
(aarch64 Ubuntu)
|
|
ログインシェルを経由した場合は exit
してもログインシェルに戻るだけなので、コンテナから抜け出すには control+]
を3回押します。同様の説明は machinectl login
の時にも書かれています:
Connected to machine ubuntu-x86. Press ^] three times within 1s to exit session.
ログインシェルが煩わしい場合は直接ログインすることもできます。パスワードも不要です:
(aarch64 Ubuntu)
|
|
こうすると exit
してもログインシェルに戻ることはありません。
Docker
x86_64 コンテナ内でも arm64 (aarch64) の Docker イメージが優先されます。x86_64 のイメージを優先するには ~/.bashrc
などで DOCKER_DEFAULT_PLATFORM
を指定する必要があります:
~/.bashrc (x86_64 Ubuntu)
|
|
おわりに
Raspberry Pi や Apple Silicon の登場以降 ARM に対応したアプリケーションが増えて不便しなくなってきましたが、まだたまに x86 が必要になることがあります。Docker の中でも systemd を動かす方法はあるのですが、Docker はストレージのパフォーマンスの扱いが難しかったりネットワーク周りも考えることが増えるため、別の解として systemd-nspawn をご紹介しました。Rosetta を前提とした ISO やコンテナイメージがないことで構築手順が少々煩雑なので、将来公式のイメージが公開されることを願ってやみません。
株式会社ドワンゴでは、教育事業、ニコニコ事業、モバイル事業など様々なサービス、コンテンツを一緒につくるメンバーを募集しています。 ドワンゴに興味がある・または応募しようか迷っている方がいれば、気軽に応募してみてください。