Docker Desktop for Mac的实用替代方案:lima + Docker

2023/07/04更新:目前推荐使用Racher桌面版。

有了Rancher Desktop的推出,现在可以轻松实现本文中所尝试的环境设置。只需将容器运行时配置为dockerd(moby),就可以使用Docker了。

 

首先

继去年的Pull Limit之后,Docker公司再次行动起来。

 

今后如果要使用Docker Desktop,在中型以上的企业中需要使用付费计划。然而,付费计划提供的服务对开发者来说并没有太大的价值,而且在全公司范围内推行这个付费计划也可能会遇到一些困难。

注意:Docker Desktop的付费计划迁移将有截止日期延期至2022年1月31日。

目前已经有一些人在寻找Docker Desktop的替代手段,比如一些文章介绍了nerdctl、podman等替代方案。

    • containerd & Lima: Open source alternative to Docker for Mac

 

    Docker Desktopの代替方法 – Windows and Mac編

然而,由於Docker CLI和Docker REST API(Docker Engine API)存在著各種限制,這些方法在我使用Docker的場景中引發了許多問題。尤其是在使用Docker的Buildkit(例如docker build的–ssh, –secret選項)或使用Docker CLI和Docker REST API(Docker Engine API)進行操作的工具或庫(例如kind、Testcontainers)時,從實用性的角度來看,這些方法非常嚴格。

因此,在本文中,我们将介绍一种实用的替代方法:使用lima + Docker来利用Docker CLI和Docker REST API(Docker Engine API)。

主要用途

我在本地开发环境中使用Docker Desktop以满足以下用途。因此,必须能够覆盖这些使用案例。

docker buildコマンドでDockerイメージのビルドを行う。

ビルドの際にはBuildKitを利用して、–sshや–secret等のオプションも活用するプロジェクトもある。

docker runコマンドでDockerコンテナの動作検証などを行う。

必要に応じて-pオプションを指定してlocalhost:8080にアクセスすることもある。

KubernetesのController, Operatorの開発や検証を行うため、kindコマンドでKinDクラスタを立ち上げる。

クラスタにPodをデプロイし、kubectl port-forwardコマンドでPod等のエンドポイントにアクセスすることもある。

基本上只使用了Docker CLI和Docker Engine Server的部分,没有使用Docker Desktop提供的UI等等。如果需要这样的UI,建议尝试使用Visual Studio Code的Docker插件。

Lima + Docker 的基本结构

在本文中介绍的lima + Docker方法将采用以下配置:在macOS主机上使用Linux虚拟机。

    • macOSにDocker CLIを配置し、dockerコマンドを実行可能にする。

 

    • Linux VM上にDocker Engine Server (Docker Daemonとも呼ぶ)を配置する。

 

    macOSのDocker CLIがlocalhost経由のTCP通信でLinux VM上のDocker Engine Serverにアクセスできるように設定する。

当在macOS主机上执行docker命令时,该请求以及用于COPY等操作的文件等Docker上下文将被传输到Linux虚拟机上的Docker引擎服务器,然后在Docker引擎服务器上进行docker build、docker run等处理。

将其表示为构成图如下所示:

lima-docker.png

为什么需要Linux虚拟机?
尽管Docker CLI可以在Linux以外的操作系统上运行,但Docker引擎服务器基本上只能在Linux上运行。(Windows容器有点特殊,但这里暂且不谈它)
在Docker Desktop中,看起来是在Windows或macOS上运行Docker引擎服务器,但实际上是通过在后台启动Linux虚拟机,并在虚拟机上启动Docker引擎服务器来实现的。

Lima 是什么?

lima是一个在macOS上实现创建和启动Linux虚拟机的开源项目。

因为以下是与VirtualBox相比的优点,所以这次我们选择使用这个。

    • limaのツールの導入が簡単。(brew install lima)

 

    • Linux VMのセットアップが簡単。(limactl startコマンドだけでUbuntuログイン可能な状態まで)

 

    標準でmacOSホストのファイルシステム、ネットワーク(localhost)がLinux VMと共有されているため、Host <-> Guestのシームレスな連携が可能。

注意:虽然有另一个优点,就是“整合了containerd + nerdctl,所以可以从一开始就创建和运行容器映像”,但正如前面所述,这次我们将使用Docker而不是它。

在这里,由于篇幅限制,不会详细解释关于lima的内容,请有兴趣的人查看官方存储库中的示例等。

 

请注意:关于 lima 的详细说明我们不会提供,但是当执行 lima <命令字符串> 时,意味着在 lima 虚拟机上执行命令字符串的内容。因此,lima <命令字符串> 部分可以理解为在 lima 虚拟机上操作。

安装步骤

在macOS主机上安装Docker CLI

首先,在macOS主机上安装Docker CLI。

有些人认为如果不安装Docker Desktop,则无法在macOS上安装Docker CLI,但实际上,可以从以下的网址下载的文件中包含它。由于要安装最新版的Docker Engine,因此也将下载最新版本的Docker CLI。

 

    • Intel Mac binary

 

    M1 Mac binary

请在下载完成后,将tgz文件解压并将docker/docker的二进制文件放置在已设置PATH环境变量的目录中。

这是一个在$HOME/bin目录下安装Intel Mac Binary的示例。

# Download binary
curl -OL https://download.docker.com/mac/static/stable/x86_64/docker-20.10.8.tgz

# Install Docker CLI
mkdir -p $HOME/bin
tar xzvf docker-20.10.8.tgz
mv docker/docker $HOME/bin/.
chmod 755 $HOME/bin/docker

# Check appropriate docker binary is used
which docker

# Check CLI works
docker version

只要在docker version命令下显示了客户端的信息,就可以了(服务器的信息不会显示出错误)。

为了使lima虚拟机上的Docker Engine与TCP通信,需要在macOS主机上设置Docker的环境变量。在这里,我们向$HOME/.profile中添加了DOCKER_HOST的设置。

请注意:在Lima虚拟机上设置的Docker Engine Server中,我们将配置Docker守护程序以便可以通过macOS上的localhost(127.0.0.1)进行访问。

echo  "export DOCKER_HOST='tcp://127.0.0.1:2375'" >> $HOME/.profile
source $HOME/.profile

架设Lima虚拟机和Docker引擎服务器的设置步骤。

注意:lima VM指的是使用lima创建的Linux虚拟机。

准备lima虚拟机

首先,在lima上创建并启动Linux虚拟机,然后在lima虚拟机上设置Docker Engine。

在自建软件中安装lima,然后启动lima虚拟机。

# Install lima
brew install lima

# Create & start lima VM
# NOTE: Select 'Open an editor to override the configuration' to change resource setting if necessary.
limactl start

# Running command in VM with `lima`
lima uname -r

注意:默认设置下,分配给虚拟机的资源稍微多一些(例如,CPU 4核,内存4GB),因此,如果您想更改设置,请在执行limactl start时选择打开编辑器以覆盖配置,并修改YAML配置文件。(链接)

通过这个步骤,Lima虚拟机已经成功创建并启动。

另外,由于Lima VM在macOS启动时不会自动启动,所以如果需要自动启动,则需要根据需要进行相应的设置。

在Lima虚拟机上安装Docker Engine服务器。

接下来,在Lima VM上安装Docker Engine Server。

# Install Docker on lima VM
curl -fsSL https://get.docker.com | lima

# Setup docker user to run without sudo (Need to restart lima VM; restarting dockerd won't work)
lima sudo gpasswd -a $USER docker
limactl stop; sleep 5; limactl start

# Check docker command works on macOS Host
lima docker version

只要在lima docker version命令的结果中同时显示Client和Server的信息且没有错误,就是OK的。

配置以与macOS 的Docker CLI 进行通信

最后,将macOS主机上的Docker CLI配置为能够接受来自Docker Engine Server API的TCP通信访问。

在lima虚拟机中使用编辑器打开/etc/docker/daemon.json文件并进行创建。以下是使用vim的示例。

lima sudo vim /etc/docker/daemon.json

将上述的JSON文件内容按以下方式进行描述并保存(设置为同时接受TCP通信和Unix套接字)。

{"hosts": ["tcp://127.0.0.1:2375", "unix:///var/run/docker.sock"]}

为了避免与默认的Docker守护程序参数冲突,我们将创建一个用于覆盖systemd设置的文件。下面是一个使用vim的示例。

lima sudo mkdir -p /etc/systemd/system/docker.service.d/
lima sudo vim /etc/systemd/system/docker.service.d/override.conf

请将上述的override.conf文件内容按照以下方式记录并保存。

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd

最后将应用设置。

lima sudo systemctl daemon-reload
lima sudo systemctl restart docker.service

通过以上步骤,lima VM的Docker Engine服务器配置已完成。

确认行动

macOS主机和Lima虚拟机的设置已经完成。

请在macOS主机上执行以下命令,确保Client和Server的信息都能正常显示。

docker version

如果能够正常运行并确认,那么在最初介绍的“主要用途”中提到的用例中可以无问题地使用。此外,由于可以访问Docker Engine API,虽然尚未确认,但我认为可以从macOS主机上使用Java的Testcontainers库等。

当然我没有对所有docker命令或选项进行验证,所以如果在docker命令、选项或其他方面出现无法正常工作的情况,请在评论中共享相关信息。

附赠品

想要使用docker-compose的人

因为我没有使用docker-compose,所以在设置步骤中没有包含docker-compose的安装步骤。

然而,docker-compose的二进制文件可以从GitHub的发布页面上下载,因此您可以从这里下载适用于Mac的正确二进制文件并将其放置在已配置PATH的目录中,以便进行使用。
(已确认使用docker-compose up命令进行简单示例的正常运行)。

 

为何podman和nerdctl不可行?

有些人可能会尝试完全将CLI替换为podman或nerdctl,但是podman和nerdctl与Docker CLI、Docker REST API(Docker Engine API)、BuildKit等的兼容性和支持并不完美。

如果你正在使用像Testcontainers这样的库,它利用了Docker的Buildkit或Docker REST API(Docker Engine API),那么替换为podman和nerdctl可能是不可能的,或许非常困难。

例如,可以提到以下问题作为Docker CLI和BuildKit兼容性的示例。

    • podmanではBuildKitが使えないため、docker buildにおける–sshなどのオプションが使えない。

Issueなどを見る限りは対応も進んでいるように見るが、対応時期や互換性がどこまであるかが不明。

nerdctlはdocker psにおける–filterなどのオプションが使えない。kind CLIではこういったオプションも使用しているため、正常にKinDクラスタの操作ができない問題がある。

我认为在未来,我们会建立一个不依赖Docker的生态系统,但目前由于处于过渡期,我们不得不在一定程度上依赖Docker。

在Virtual Box上行不通吗?

如果您使用Virtual Box来创建Linux虚拟机,并在该虚拟机上进行所有操作,我认为这是可以接受的。但是,在这种情况下,由于GUI编辑器和IDE等也需要在Linux虚拟机上运行,可能会导致性能和电池寿命方面的不满意,所以对我个人来说不太理想。

另一种方法是将“如将编码等工作放在macOS上,将docker build等工作放在Linux虚拟机上”进行角色分配。然而,在这种情况下,需要进行文件同步设置以使主机与虚拟机之间同步。还需要同步各种秘密信息,如SSH密钥等。

如果需要进行真正的开发和验证工作,即使使用Virtual Box也可以,但对于需要Docker来进行简单操作的保守运营等工作人员来说,Virtual Box可能会显得过于繁琐,很难推荐。
(本次写这篇文章,也是因为需要一种实用且门槛低的替代方法)

广告
将在 10 秒后关闭
bannerAds