🐳

Appleシリコン時代のDocker高速化戦略 - Windows 11をリモートビルダーとして活用しよう!

に公開

Appleシリコン時代のDocker高速化戦略

はじめに

Appleシリコン搭載のMacは素晴らしいパフォーマンスを発揮してくれていますが、コンテナ開発においては大きな課題があります。

一般的に用いられる linux/amd64 アーキテクチャ向けのコンテナをビルドする場合、QEMU(エミュレーション)やRosetta 2(apple virtualization frameworkを使う場合)を利用しなければならないことです。これには以下のような問題があります:

  • ビルド速度が極端に遅くなる
  • 特定のパッケージでビルドが失敗することがある
  • システムリソースを大量に消費する

こうした問題を解決する強力な手段が Docker Desktopのリモートビルダー機能 です。
この記事では、メインマシンとしてAppleシリコンMac、サブマシンとしてWindows 11(x64版)を利用し、マルチプラットフォームコンテナを高速かつ効率的にビルドする環境を構築する方法を解説します。
サブマシンのスペックは問いませんが、古いPCだとRosetta 2を使ったエミュレーションよりも遅い場合はあります(この場合はビルド並列化の恩恵のみ受けられます)。

リモートビルダーのメリット

リモートビルダーを導入することで得られる主なメリットは以下の通りです:

  1. ネイティブアーキテクチャでのビルド

    • x86_64(amd64)アーキテクチャのWindowsマシンでlinux/amd64イメージを高速ビルド
    • ARMアーキテクチャのMacでlinux/arm64イメージを高速ビルド
  2. 並列ビルドによる時間短縮

    • 複数アーキテクチャのビルドを同時並行で実行可能
    • ビルド時間が大幅に短縮(単一マシンで順次ビルドする場合と比較して)
  3. エミュレーション問題からの解放

    • QEMUやRosetta 2での互換性問題によるビルド失敗を回避
  4. ローカルマシンの負荷軽減

    • リソース消費の大きいビルドプロセスを別マシンにオフロード
    • 開発マシンの動作が軽快に保たれる(かも)

リモートビルダーのシステム構成

以下の図は、AppleシリコンMacとWindows 11を連携させたリモートビルダーのシステムアーキテクチャです。

では、実際にリモートビルダーを設定していきましょう!

前提条件

この記事では、以下の環境を前提としています:

  • メインマシン: Appleシリコン搭載Mac (M1シリーズ以降)

    • Docker Desktop for Mac がインストール済み
    • macOS Monterey 以降
  • サブマシン(リモートビルダー用): Windows 11

    • x64(amd64,x86_64)アーキテクチャ
    • Docker Desktop for Windows または Docker Engine がインストール済み
    • OpenSSHサーバーをインストール可能な権限
  • ネットワーク環境:

    • 両マシンが同一ネットワーク上にあるか、インターネット経由で接続可能
    • 必要なポート(デフォルトでは22番)が通信可能

まずはWindowsマシンをリモートビルダー仕様にする

OpenSSHサーバーのインストールと設定

  1. OpenSSHサーバーのインストール

Windows 11では、「設定」アプリから簡単にOpenSSHサーバーをインストールできます:

設定 > アプリ > オプション機能 > 機能の追加 > OpenSSHサーバー を選択してインストール

もしくはPowerShellを管理者権限で起動し、以下のコマンドを実行します:

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

Windows 11にバンドルされているOpenSSHのバージョンは若干古いため、最新の機能を利用したい場合はpreview版をインストールすることも可能です。PowerShell/Win32-OpenSSHから入手可能です。

  1. SSHサービスの起動と自動起動設定

PowerShellを管理者権限で起動し、以下のコマンドを実行:

# SSHサービスを起動
Start-Service sshd

# 自動起動を設定
Set-Service -Name sshd -StartupType 'Automatic'
  1. ファイアウォールの設定

PowerShellを管理者権限で起動し、以下のコマンドを実行:

# SSHのファイアウォールルール確認
Get-NetFirewallRule -Name *ssh*

# ルールがなければ作成(自動生成されているはずですが念のため)
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

公開鍵認証の設定

  1. 公開鍵保存用ディレクトリの作成

PowerShellを管理者権限で実行:

# ユーザーディレクトリ内に.sshフォルダを作成(存在しなければ)
$UserProfile = "$env:USERPROFILE"
$SSHFolder = "$UserProfile\.ssh"
if (!(Test-Path $SSHFolder)) {
    New-Item -Path $SSHFolder -ItemType Directory
}

# 権限を設定
icacls $SSHFolder /inheritance:r
icacls $SSHFolder /grant ${env:USERNAME}:"(F)"
  1. 認証設定の構成

以下のコマンドを実行して、SSH設定を編集します:

# デフォルトではsshd_configはここにあります
$configPath = "C:\ProgramData\ssh\sshd_config"

# バックアップを作成
Copy-Item $configPath "$configPath.bak"

# 公開鍵認証を有効化 (コメントアウトされている設定を有効化)
(Get-Content $configPath) -replace '#PubkeyAuthentication yes', 'PubkeyAuthentication yes' | Set-Content $configPath

# 認証鍵のパスを指定
Add-Content $configPath "`nAuthorizedKeysFile .ssh/authorized_keys"

# サービス再起動
Restart-Service sshd

Macでの準備(メインマシン)

SSH鍵ペアの生成と共有

  1. SSH鍵の生成

既にある鍵ペアを使用する場合は、この手順はスキップしてください。

Macのターミナルで以下のコマンドを実行:

# 鍵を生成(すでに持っている場合はスキップ可能)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 生成された鍵を確認
ls -la ~/.ssh
  1. 公開鍵のWindows 11マシンへの転送
# scp コマンドで転送する場合
scp ~/.ssh/id_ed25519.pub username@windows-ip-address:C:/Users/username/.ssh/authorized_keys

# または ssh-copy-id を使う場合(追加インストールが必要かも)
ssh-copy-id -i ~/.ssh/id_ed25519.pub username@windows-ip-address

または、以下の方法でも転送できます:

  1. macOSのターミナルで cat ~/.ssh/id_ed25519.pub を実行してコンテンツをコピー

  2. Windows 11で .ssh/authorized_keys ファイルを作成し、コピーした内容を貼り付け

  3. SSH接続テスト

ssh username@windows-ip-address

正常に接続でき、パスワード入力なしでログインできれば成功です。

Docker Desktopのリモートビルダー設定

リモートビルダーはBuildKit(docker buildx)の機能です。Docker Desktopで簡単に設定できます。

  1. Docker Desktopの起動と設定画面へのアクセス

Macで Docker Desktop を起動し、設定画面を開きます。

  1. Dockerエンジン設定の確認

「Docker Engine」タブで、以下のように buildx 関連の設定が入っているか確認します:

{
  "builder": {
    "gc": {
      "enabled": true,
      "defaultKeepStorage": "20GB"
    }
  },
  "experimental": true,
  "features": {
    "buildkit": true
  }
}

設定がなければ追加し、「Apply & Restart」をクリックします。

  1. リモートビルダーの追加

Docker Desktopのメニューから:

  • Settings > Builders を選択
  • 「+」ボタンを押して新しいビルダーを追加

以下の情報を入力:

  • Name: 「Windows11-Builder」など識別しやすい名前
  • Driver: 「docker-container」
  • Driver options:
    network=host
    
  • Node name: 任意の名前(例:「windows-amd64」)
  • Node endpoint: ssh://username@windows-ip-address
  • Platform: linux/amd64
  1. ビルダーのアクティブ化

追加したリモートビルダーを選択して「Use」または「Set default」をクリックします。

リモートビルダーを使った分散ビルドの流れ

リモートビルダーを使った分散ビルドの流れを図で表すと、次のようになります。

マルチアーキテクチャビルドを試す

シンプルなテストケース

Docker Desktopの設定が完了したら、実際にマルチアーキテクチャビルドをテストしてみましょう。

  1. テスト用Dockerfileの作成
FROM alpine:latest
RUN uname -m > /arch.txt
CMD cat /arch.txt
  1. マルチプラットフォームビルドの実行
docker buildx build --platform linux/amd64,linux/arm64 -t mytest:latest --push .

ローカルのイメージストアで直接利用したい場合はloadオプションを使います:

docker buildx build --platform linux/amd64,linux/arm64 -t mytest:latest --load .
  1. ビルド結果の確認
# ARM64(Macネイティブ)
docker run --platform linux/arm64 mytest:latest
# 出力: aarch64

# AMD64(Windowsリモートビルダー)
docker run --platform linux/amd64 mytest:latest
# 出力: x86_64

Dockerfileの内容やPCのスペックによってパフォーマンス差は異なります。特にloadオプションを付けた場合にはイメージの転送などに時間がかかる場合もありますが、総じてビルド時間の短縮を実感できるはずです。

トラブルシューティング

SSH接続の問題

  • エラー: Permission denied (publickey)

    • 解決策: 公開鍵が正しくWindows側の.ssh/authorized_keysに設置されているか確認
    • Windows側のOpenSSHの権限設定を確認
  • エラー: Connection refused

    • 解決策: Windowsでsshdサービスが起動しているか確認
    • ファイアウォール設定を確認

Dockerビルドの問題

  • エラー: failed to solve: rpc error: code = Unknown

    • 解決策: リモートマシンのDocker Engineが正常に動作しているか確認
    • SSH接続経由でDockerコマンドが実行できるか確認
  • エラー: error: failed to solve: failed to compute cache key

    • 解決策: リモートビルダーのキャッシュをクリア
    • コンテキスト共有の設定を見直す

まとめ

Appleシリコン搭載MacとWindows 11マシンを組み合わせることで、マルチプラットフォーム(linux/amd64, linux/arm64)のコンテナを高速かつ並列でビルドできる環境を構築することができます。

この構成の主なメリットをまとめると:

  1. ビルド時間の大幅短縮

    • ネイティブアーキテクチャでのビルドによる高速化
    • 並列ビルドによる時間効率の向上
  2. 安定性の向上

    • QEMUやRosetta 2でのエミュレーションによるビルド失敗を回避
    • 各アーキテクチャにネイティブ対応したビルド環境の活用
  3. 開発体験の向上

    • メインのMacマシンの負荷軽減
    • マルチプラットフォーム開発におけるテストの容易さ

一度設定してしまえば、日々のコンテナビルド作業が格段に効率化され、開発生産性の向上につながります。待ち時間の短縮でストレスフリーな開発環境が実現できます!

もし手元に別のマシンがあれば、こうした形でリソースを有効活用し、より快適なコンテナ開発環境を構築してみてはいかがでしょうか?

Discussion