有没有办法在 Apple Silicon M 上 运行 amd64/linux 虚拟机?

Is there any way to run an amd64/linux VM on Apple Silicon M?

我正在用Go写一个关于透明代理的程序,但是syscall.SetsockoptInt(int(s), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1)只支持amd64/linux(其他版本没有常量syscall.SOL_IPsyscall.IP_TRANSPARENT).

所以即使我在 M1 上 运行 并行 VM (arm64/linux),我仍然无法成功构建我的程序。有什么办法可以解决吗?

我不确定问题的本质是什么。 IP_TRANSPARENT 特定于 Linux(OS 内核),因此任何使用它的代码 必须 运行 on Linux。调试(一个 运行ning 过程)也必须在 Linux 上进行——我希望原因现在很明显。

但这不影响构建:在 Linux 上构建时应该可以工作 如果 您的 Go 版本在其 [= 中定义了 IP_TRANSPARENT 14=]包。

这意味着:

  • 运行 为 linux/amd64 构建的程序在带有 Linux 来宾的 VM 上使用 syscall.IP_TRANSPARENT 应该可以工作。
  • 使用 Linux 来宾从 VM 上的源代码构建该程序应该可行。

但是在非本地平台(如果我理解正确的话,在我们的例子中是 darwin/arm64)构建的“普通”将不起作用,这可能是您混淆的根源。
基本上,当您在 darwin/arm64 上构建源代码时,编译器 定位, 读取并解释所有期望生成适合其工作平台的可执行映像文件的源代码在; syscall 包高度依赖 OS,可以认为对于不同的 GOOS/GOARCH 组合是不同的。 它的 darwin/arm64 的“版本”根本不能包含符号 IP_TRANSPARENT 因为达尔文内核不“知道”它。

因此,如果您的问题只是在 for linux/amd64 工作时 on darwin/arm64,答案是 cross-compilation.
使用 Go,它是通过让工具链看到 GOOS and/or GOARCH 环境变量的显式设置来完成的——不同于假定的默认值。
在你的情况下你可以做

$ GOOS=linux GOARCH=amd64 go build

它会生成一个可执行映像文件,供 linux/amd64 使用,并且在处理源代码时,编译器将使用目标平台的定义,而不是它 运行 所在的平台.

然后您可以将生成的可执行映像文件复制(或通过其他方式提供)到来宾的文件系统并运行它在那里——它应该可以正常工作。

您可以通过

对当前的 Termial 会话进行此类更改“永久”
$ export GOOS=linux
$ export GOARCH=amd64

TL;DR

  • 要为非本机平台构建,请使用交叉编译;您不需要任何类型的虚拟机。
  • 或者您可以“本地”构建,但随后您需要将 go 安装到 VM 上的来宾 运行ning 中,并在那里提供项目的源代码。
  • 要运行非本机系统的可执行文件,您必须使用 VM(或某种模拟器)。