Docker for MacからLimaへの乗り換え

Docker
Published

March 12, 2022

Modified

March 12, 2022

はじめに

私は普段、コンテナ実行環境を使ってデータ解析を行っている。

コンテナを用いることでホスト環境から隔離された環境で解析用プログラムをインストールして実行できるため、さまざまなプログラムを使って解析する際に、それぞれのプログラムが依存するライブラリの衝突を気にしなくてすむという利点がある。 そのため、実際の運用では解析プログラムをインストールしたイメージから、データを入れたディレクトリをマウントする形でコンテナを作成し、解析結果を出力するという形で使用している。

これまでコンテナの実行にはDockerを使ってきたが、今回別のコンテナ実行環境であるLima + nerdctlに乗り換えることにした。

なぜ乗り換えるか

PCを買い替えたことが契機となった。

これまでも、Docker for MacはマウントされたVolume上のファイルアクセスが遅いらしいということは知っていて、自分のような使い方の場合には遅くなる場合があることはわかっていた。 それでも、chacheddelegetedというオプションを設定することで、一貫性を犠牲にしてファイルアクセスの速度が早くするよう工夫して使っていたのだが、PCを新調した際に思ったほどCPUの使用率が上がらなかったため、原因はなにかネットで検索して調べてみた。

色々調べていると、Apple silicon搭載Macでは、Docker for Macは遅いという記事をいくつか見つけ、またDocker以外の選択肢で改善するという話もあったため乗り換えてみることにした。

いくつかある選択肢のから、LimaというLinux virtual machineでは、nerdctlというdockerコマンドと互換性のあるプログラムが使えて、移行のオーバーヘッドが少なそうだったので試してみることにした。

インストール手順

  1. homebrewを使ってインストールする。
```{bash}
brew update
brew install lima
```
  1. バージョンなどの確認
```{bash}
limactl --version
#> limactl version 0.8.3

limactl --help
#> Lima: Linux virtual machines
#> 
#> Usage:
#>   limactl [command]
#> 
#> Examples:
#>   Start the default instance:
#>   $ limactl start
#> 
#>   Open a shell:
#>   $ lima
#> 
#>   Run a container:
#>   $ lima nerdctl run -d --name nginx -p 8080:80 nginx:alpine
#> 
#>   Stop the default instance:
#>   $ limactl stop
#> 
#>   See also example YAMLs: /opt/homebrew/share/doc/lima/examples
#> 
#> Available Commands:
#>   completion  Generate the autocompletion script for the specified shell
#>   copy        Copy files between host and guest
#>   delete      Delete an instance of Lima.
#>   edit        Edit an instance of Lima
#>   help        Help about any command
#>   info        Show diagnostic information
#>   list        List instances of Lima.
#>   prune       Prune garbage objects
#>   shell       Execute shell in Lima
#>   show-ssh    Show the ssh command line
#>   start       Start an instance of Lima. If the instance does not exist, open an editor for creating new one, with name "default"
#>   stop        Stop an instance
#>   sudoers     Generate /etc/sudoers.d/lima file for enabling vmnet.framework support
#>   validate    Validate YAML files
#> 
#> Flags:
#>       --debug     debug mode
#>   -h, --help      help for limactl
#>   -v, --version   version for limactl
#> 
#> Use "limactl [command] --help" for more information about a command.
```
  1. VMの設定を修正(ここではdefault.yamlとする)
  • CPU、メモリなどのリソースと、書き込み可能ディレクトリを設定
  • 指定していないディレクトリには書き込めない。
  1. LimaのVMを作成・起動する
```{bash}
limactl start default.yaml # VMの起動
limactl list # 作成したVMを確認
```
  1. dockerで作成したイメージをnerdctlにロードする。
  • 自分で作成したイメージをDockerfile内のFROM命令に入れていると、nerdctl buildできなかったので、docker buildでイメージを作成して、nerdctlに読み込む。
  • dockerで作ったイメージをdocker saveでtarに出力。
  • nerdctl load --platform {arm64|amd64}でロード。

感想

手持ちのデータで、STARを使ってマッピング速度を比較した結果がこちら。

  • docker w/ delegeted option: 60 M reads per hour
  • lima + nerdctl: 227 M reads per hour

かなり早くなった。移行してよかったと思う。

自分の技術では、コンテナイメージ作成も含めてLima + nerdctl上で完結させられなかったのが残念だが、nerdctlとdockerの互換性の高さから使い勝手に大きな変化がなく、そこはすんなり移行できたのはよかった。

その他

他アーキテクチャのエミュレート

  • 別のCPUアーキテクチャのイメージが使えるように、以下のリンク先のコード実行
  • https://github.com/containerd/nerdctl/blob/master/docs/multi-platform.md
```{bash}
sudo systemctl start containerd
sudo nerdctl run --privileged --rm tonistiigi/binfmt --install all
```

FIFOサポート

  • Limaで使用しているrsshfsというファイルシステムではFIFOをサポートしていない?
  • STAR--readFilesCommandを使うときにはFIFOでないといけないので、これをやめてプロセス置換を使う。
  • https://github.com/alexdobin/STAR/issues/831

2022/3/11追記

  • 上手くVMが起動できず。参照しているイメージが更新されて何かバグが入った?
  • 以下のissueにある通り、Lima VMの設定ファイル中のimagesをcurrentから20220204に変更した。
    • https://github.com/lima-vm/lima/issues/712

2023/9/26追記

現在はDocker for Macがかなり使い心地がよくなったので戻している。