发布于 2026-01-06 6 阅读
0

在 M1 Apple Silicon 上使用 Docker 运行 Vagrant。Docker 和 Vagrant 是亦敌亦友的关系。Vagrant 配置起来相当容易,但它不太喜欢运行多个虚拟机。你可以重新配置 Vagrant。Docker 的公共网络桥接功能存在问题。你的 Linux 二进制文件需要是 arm64 架构的。我学到了很多,但仍然知之甚少。

在 M1 Apple Silicon 上使用 Docker 运行 Vagrant

Docker 和 Vagrant 是亦敌亦友的关系。

Vagrant 配置起来非常简单。

Vagrant 不喜欢运行多个虚拟机。

您可以重新配置 Vagrant。

Docker 的公共网络桥接功能已损坏

你的 Linux 二进制文件必须是 arm64 架构的。

我学到了很多,但我仍然懂得不多。

我最近换了新工作,很幸运地配到了一台全新的搭载 M1 芯片的 MacBook Air。我从用户那里听说,即使 M1 不是英特尔芯片,但它“开箱即用”。他们说“连 Docker 都能用”。“哇!”我心想,这简直太棒了,太完美了。

第一天上班,我坐在那里准备开始工作。NPM 安装一切正常,我的 Python 包也全部安装完毕,后端和前端都运行正常,一切都太顺利了!然后我遇到了一个问题。这个应用程序需要一个服务,而这个服务是在 VirtualBox 上使用 Vagrant 运行的。

Virtualbox 目前完全不支持 Apple Silicon。而且,Virtualbox 未来是否会支持 Apple Silicon 也尚不明确。目前比较理想的替代方案是 VMware 的产品,但它目前也不支持 Apple Silicon。我真是进退两难。

但是!别担心!我发现 Vagrant 也支持 Docker。于是接下来的三天,我埋头研究文档,疯狂地在网上搜索“vagrant docker M1”、“vagrant docker config”、“vagrant docker network issue”和“vagrant docker systemctl”。在至少修改了三个不同的配置文件,并配置了一个极其复杂的系统之后,我终于成功运行了!以下是我总结的一些经验教训。

免责声明:我并非Linux /运维/DevOps专家。我的Linux经验有限,但这个问题相关的帮助资料不多,所以我只能尽力而为。

Docker 和 Vagrant 是亦敌亦友的关系。

Docker 和 Vagrant 在开发环境的搭建方式上有着截然不同的理念。Docker 的理想是极简配置,只包含运行所需单个进程所需的资源。如果需要运行更多进程,Docker 会建议你创建更多容器。而 Vagrant 则倾向于极致配置,将所有组件都安装在同一个虚拟机上,并使其协同运行。

要启动 Docker,你需要一些Dockerfile配置,本文将介绍创建 Docker 容器所需的设置。为了让我们的 Docker 容器与 Vagrant 兼容,我们将把它配置成一台传统的 Linux 机器。默认情况下,你至少需要 SSH 连接sshd(允许你通过 SSH 连接到机器)。我还安装了 SSHsystemd服务(用于运行服务)。这并非通常使用 Docker 的方式。

以下是Dockerfile我使用的:

# Docker image to use with Vagrant
# Aims to be as similar to normal Vagrant usage as possible
# Adds Puppet, SSH daemon, Systemd
# Adapted from https://github.com/BashtonLtd/docker-vagrant-images/blob/master/ubuntu1404/Dockerfile

FROM ubuntu:18.04
ENV container docker
RUN apt-get update -y && apt-get dist-upgrade -y

# Install system dependencies, you may not need all of these
RUN apt-get install -y --no-install-recommends ssh sudo libffi-dev systemd openssh-client

# Needed to run systemd
# VOLUME [ "/sys/fs/cgroup" ]
# Doesn't appear to be necessary? See comments

RUN apt-get -y install puppet

# Add vagrant user and key for SSH
RUN useradd --create-home -s /bin/bash vagrant
RUN echo -n 'vagrant:vagrant' | chpasswd
RUN echo 'vagrant ALL = NOPASSWD: ALL' > /etc/sudoers.d/vagrant
RUN chmod 440 /etc/sudoers.d/vagrant
RUN mkdir -p /home/vagrant/.ssh
RUN chmod 700 /home/vagrant/.ssh
RUN echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==" > /home/vagrant/.ssh/authorized_keys
RUN chmod 600 /home/vagrant/.ssh/authorized_keys
RUN chown -R vagrant:vagrant /home/vagrant/.ssh
RUN sed -i -e 's/Defaults.*requiretty/#&/' /etc/sudoers
RUN sed -i -e 's/\(UsePAM \)yes/\1 no/' /etc/ssh/sshd_config

# Start SSH
RUN mkdir /var/run/sshd
EXPOSE 22
RUN /usr/sbin/sshd

# Start Systemd (systemctl)
CMD ["/lib/systemd/systemd"]
Enter fullscreen mode Exit fullscreen mode

如果您的设置中不需要systemd此功能,则可以将其删除并将值更改RUNsshd

CMD ["/usr/sbin/sshd", "-D"]
Enter fullscreen mode Exit fullscreen mode

所有这些操作会创建一个 Docker 容器,但它的工作方式与普通的 Docker 容器不同。它更像是一台虚拟机。这意味着使用常规的 Docker 命令很难管理它。一旦关闭,也很难再次启动。最好使用 Vagrant 来控制它。我已经多次不得不删除容器并使用 Vagrant 重新创建它。

Vagrant 配置起来非常简单。

要使用 Dockerfile 运行 Vagrant,只需添加一些配置即可:

Vagrant.configure(2) do |config|

# ... your existing config

  # Custom configuration for docker
  config.vm.provider "docker" do |docker, override|
    # docker doesnt use boxes
    override.vm.box = nil

    # this is where your Dockerfile lives
    docker.build_dir = "."

    # Make sure it sets up ssh with the Dockerfile
    # Vagrant is pretty dependent on ssh
    override.ssh.insert_key = true
    docker.has_ssh = true

    # Configure Docker to allow access to more resources
    docker.privileged = true
  end

# ...

end
Enter fullscreen mode Exit fullscreen mode

您可能需要在此处覆盖一些其他设置。该override变量允许您更改顶级设置,而该docker变量允许您设置 Docker 特有的设置。请阅读Vagrant Docker 提供程序Vagrant Docker 配置文档。

设置完成后,您可以使用以下命令运行 Vagrant 虚拟机:

$ vagrant up --provider=docker
Enter fullscreen mode Exit fullscreen mode

如果您需要在机器内部执行其他操作,可以使用 SSH 登录:

$ vagrant ssh
Enter fullscreen mode Exit fullscreen mode

sudo如果需要,你也应该能够访问。

Vagrant 不喜欢运行多个虚拟机。

我第一次运行 Vagrant 时,在意识到 Virtualbox 无法正常工作之前,它启动了但随后失败了。之后,当我尝试使用 Docker 提供程序运行 Vagrant 时,它提示我没有多个虚拟机镜像。而且由于 Virtualbox 没有运行,我也无法删除我的虚拟机镜像。

你可以直接删除这些文件.vagrant来解决这个问题。Vagrant 本身似乎没有很好的方法来解决这个问题。

您可以重新配置 Vagrant。

有时我发现我的配置会出错,对我来说,重新运行 Vagrant 配置脚本并不难。

$ vagrant up --provision
Enter fullscreen mode Exit fullscreen mode

完成这些步骤后,我的一些问题就解决了。盲目地这样做并不明智,但就我而言,我只是想让它运行起来。

Docker 的公共网络桥接功能已损坏

它似乎在 Mac 上不起作用!所以如果你的 Vagrant 配置中有类似这样的内容:

config.vm.network "public_network"
Enter fullscreen mode Exit fullscreen mode

试着用以下方式替换它:

config.vm.network "private_network", type: "dhcp"
Enter fullscreen mode Exit fullscreen mode

对我来说,这种替代方案就足够了,但您可能还有其他要求。

你的 Linux 二进制文件必须是 arm64 架构的。

我遇到了一些问题,因为我们的配置脚本假定系统架构为amd64(Intel 和 AMD 64 位处理器)。我们几乎可以肯定,CPU 架构amd64在苹果推出 M1 芯片之前都是如此!

在 M1 芯片上运行 Linux 时,会使用其arm64自身的架构。您可以使用以下命令在 Linux 中快速获取当前机器的架构:

$ dpkg --print-architecture
Enter fullscreen mode Exit fullscreen mode

我在 shell 脚本中通过设置变量使用了它:

readonly ARCH=`dpkg --print-architecture`
Enter fullscreen mode Exit fullscreen mode

然后,在下载和安装二进制文件时进行替换,通常这相对简单,例如:

wget http://somedomain.com/some_binary_linux_amd64.zip
Enter fullscreen mode Exit fullscreen mode

成为

wget "http://somedomain.com/some_binary_linux_${ARCH}.zip"
Enter fullscreen mode Exit fullscreen mode

我学到了很多,但我仍然懂得不多。

为了让这一切正常运行,我学到了很多关于 Docker(以及如何避免错误)、Vagrant(以及如何破解它)和各种 Linux 技巧的知识。然而,我并非 Linux、Docker 或 Vagrant 的专家,我只是尽力让它们运行起来。所以,如果我在这里写的任何内容有严重错误或误导之处,请务必留言指正。

如果这对你有帮助,我很高兴听到这个消息!我之前也遇到过类似的问题,在网上到处搜索解决方法,我想肯定还有其他人跟我一样。

文章来源:https://dev.to/taybenlor/running-vagrant-on-an-m1-apple-silicon-using-docker-3fh4