在 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"]
如果您的设置中不需要systemd此功能,则可以将其删除并将值更改RUN为sshd:
CMD ["/usr/sbin/sshd", "-D"]
所有这些操作会创建一个 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
您可能需要在此处覆盖一些其他设置。该override变量允许您更改顶级设置,而该docker变量允许您设置 Docker 特有的设置。请阅读Vagrant Docker 提供程序和Vagrant Docker 配置文档。
设置完成后,您可以使用以下命令运行 Vagrant 虚拟机:
$ vagrant up --provider=docker
如果您需要在机器内部执行其他操作,可以使用 SSH 登录:
$ vagrant ssh
sudo如果需要,你也应该能够访问。
Vagrant 不喜欢运行多个虚拟机。
我第一次运行 Vagrant 时,在意识到 Virtualbox 无法正常工作之前,它启动了但随后失败了。之后,当我尝试使用 Docker 提供程序运行 Vagrant 时,它提示我没有多个虚拟机镜像。而且由于 Virtualbox 没有运行,我也无法删除我的虚拟机镜像。
你可以直接删除这些文件.vagrant来解决这个问题。Vagrant 本身似乎没有很好的方法来解决这个问题。
您可以重新配置 Vagrant。
有时我发现我的配置会出错,对我来说,重新运行 Vagrant 配置脚本并不难。
$ vagrant up --provision
完成这些步骤后,我的一些问题就解决了。盲目地这样做并不明智,但就我而言,我只是想让它运行起来。
Docker 的公共网络桥接功能已损坏
它似乎在 Mac 上不起作用!所以如果你的 Vagrant 配置中有类似这样的内容:
config.vm.network "public_network"
试着用以下方式替换它:
config.vm.network "private_network", type: "dhcp"
对我来说,这种替代方案就足够了,但您可能还有其他要求。
你的 Linux 二进制文件必须是 arm64 架构的。
我遇到了一些问题,因为我们的配置脚本假定系统架构为amd64(Intel 和 AMD 64 位处理器)。我们几乎可以肯定,CPU 架构amd64在苹果推出 M1 芯片之前都是如此!
在 M1 芯片上运行 Linux 时,会使用其arm64自身的架构。您可以使用以下命令在 Linux 中快速获取当前机器的架构:
$ dpkg --print-architecture
我在 shell 脚本中通过设置变量使用了它:
readonly ARCH=`dpkg --print-architecture`
然后,在下载和安装二进制文件时进行替换,通常这相对简单,例如:
wget http://somedomain.com/some_binary_linux_amd64.zip
成为
wget "http://somedomain.com/some_binary_linux_${ARCH}.zip"
我学到了很多,但我仍然懂得不多。
为了让这一切正常运行,我学到了很多关于 Docker(以及如何避免错误)、Vagrant(以及如何破解它)和各种 Linux 技巧的知识。然而,我并非 Linux、Docker 或 Vagrant 的专家,我只是尽力让它们运行起来。所以,如果我在这里写的任何内容有严重错误或误导之处,请务必留言指正。
如果这对你有帮助,我很高兴听到这个消息!我之前也遇到过类似的问题,在网上到处搜索解决方法,我想肯定还有其他人跟我一样。
文章来源:https://dev.to/taybenlor/running-vagrant-on-an-m1-apple-silicon-using-docker-3fh4