文章

【笔记】OrbStack 的虚拟化与容器网络分层

【笔记】OrbStack 的虚拟化与容器网络分层

在 macOS 上运行 Linux container,绕不开一个事实:container 共享 Linux kernel,而 macOS 没有 Linux kernel。OrbStack 的核心工作,是在虚拟化边界内提供 Linux 内核和 Docker/Kubernetes 环境,再把 socket、文件和网络体验接回 macOS。

本文以 OrbStack 官方文档和本机 OrbStack 2.2.1 观测为事实基础。OrbStack 是闭源产品;没有公开证据的 hypervisor、virtio、Service 转发表等内部细节只标为推断或不讨论。

1. 中心模型:Host、Linux VM、Container

flowchart TB
    M[macOS Host]
    V[OrbStack Linux VM]
    D[Docker Engine]
    K[Kubernetes]
    C1[Container]
    C2[Linux Machine]

    M <-->|socket / network / files| V
    V --> D
    V --> K
    D --> C1
    V --> C2

三层各自承担:

  • macOS Host 提供 UI、CLI 入口、文件和宿主网络;
  • Linux VM 提供 Linux kernel、虚拟设备和 Linux 用户空间;
  • Docker/Kubernetes 在 Linux 环境中创建 container namespaces、cgroups、镜像和网络。

“像本地一样使用”来自跨边界集成,不表示 container 直接运行在 macOS kernel 上。

2. 为什么必须有 Linux 虚拟化层

2.1 Container 不是跨内核虚拟机

Linux container 依赖 namespaces、cgroups、capabilities、seccomp、overlay filesystem 等 Linux 内核能力。macOS 的 XNU kernel 不能直接提供同一套 ABI。

因此在 Apple Silicon 或 Intel Mac 上运行普通 Linux image,需要某种 Linux kernel 环境。OrbStack 官方架构将 Docker engine 和 Linux machines 放在 OrbStack VM 中。

2.2 虚拟化与 container 隔离是两层

VM 隔离 macOS 与 Linux guest;container 再在 Linux 内核之上隔离进程。典型 Docker container 不是“一容器一 VM”,多个 container 会共享 OrbStack 提供的 Linux kernel。

1
2
3
macOS process
  ≠ Linux VM process
  ≠ container process

权限、网络和文件问题必须先定位发生在哪一层。

2.3 Hypervisor 具体实现不要凭感觉补齐

Apple 提供 Hypervisor.framework、Virtualization.framework 等能力,OrbStack 官方也宣传原生、轻量的虚拟化体验。但仅凭这些现象,不能推出其当前版本所有设备模型、virtqueue 布局或中断路径。

公开资料没有明确承诺的细节,应视为可能随版本改变的实现,而不是排障前提。

3. Docker 兼容层的真实边界

3.1 VM 内确实运行 Docker engine

OrbStack 官方架构明确说明:Docker engine 运行在 OrbStack VM 内,其 server socket 转发到 macOS。

本机 OrbStack 2.2.1 的 docker info 显示:

1
2
3
4
5
6
OperatingSystem: OrbStack
OSType: linux
ServerVersion: 29.4.0
Driver: overlay2
Backing Filesystem: btrfs
Runtime: io.containerd.runc.v2

因此“OrbStack 不使用 Docker Engine,只模拟 Docker API”是错误结论。macOS 上的 Docker CLI 通过当前 context 连接 VM 内 server。

3.2 Docker CLI 与 daemon 不在同一 OS

执行:

1
docker version

会看到 Client 与 Server 两部分。Client 可以是 macOS binary;Server 运行在 Linux 环境。这解释了:

  • bind mount 路径首先来自 macOS,但要映射给 Linux daemon;
  • --network host 的 host 指 Linux container host,不自动等于 macOS;
  • daemon proxy、registry mirror 和 storage driver 属于 VM 内配置;
  • Linux socket/path 不能按 macOS 本地进程理解。

3.3 Docker compatibility 不等于实现完全相同

OrbStack 以 Docker API、CLI 和 Compose 兼容为目标,但文件共享、网络转发、DNS、host networking 和 UI 集成由 OrbStack 实现。行为排障应先区分:

  • Docker API/daemon 层;
  • OrbStack 的 Host ↔ VM 集成层;
  • container 自身 Linux 配置。

4. Linux Machines 与 Docker Containers

4.1 Linux Machine 是完整发行版环境

OrbStack machines 提供可登录的 Linux 用户空间,适合 shell、systemd、开发工具和发行版包管理。它们与 Docker containers 同处 OrbStack 的 Linux 虚拟化环境,但生命周期和使用抽象不同。

4.2 Container 由 Docker engine 管理

Docker container 来自 image,由 daemon 管理 namespaces、cgroups、root filesystem 和 network。它不是 OrbStack Linux machine 的同义词。

4.3 二者通过明确网络入口互访

官方文档为 Linux machine 提供:

  • host.orb.internal:访问 macOS host 服务;
  • docker.orb.internal:访问从 Docker container 发布的端口。

这类域名是跨网络边界的稳定入口,比猜测 VM gateway IP 更可靠。

5. 文件系统要分三种来源

5.1 Container image layer

镜像层和 container writable layer 位于 VM 内 Docker storage。当前本机显示 overlay2 叠加在 btrfs backing filesystem 上,这是本机版本的现场事实,不是所有版本永远固定的存储格式。

5.2 Named volume

Docker named volume 由 VM 内 daemon 管理,适合数据库和 Linux 权限语义敏感的数据。它通常不会直接表现为 macOS 项目目录。

5.3 Bind mount

bind mount 把 macOS 文件路径暴露给 Linux container。中间经过 OrbStack 文件共享实现,因此性能、文件监听、大小写、owner/mode、xattr 和 socket 等行为可能与原生 Linux filesystem 不完全一致。

1
macOS path → OrbStack file sharing boundary → Linux mount → container path

看到 container 内路径并不意味着它和 VM 本地文件具有相同底层存储。

5.4 排障先识别 mount 类型

1
2
3
4
docker inspect <container>
docker volume inspect <volume>
mount
stat <path>

构建缓存慢、watch 不触发或权限异常时,先判断是 image layer、named volume 还是 host bind mount,再分析边界。

6. 网络至少有三层地址空间

6.1 macOS Host 网络

浏览器、IDE 和本地服务运行在 macOS。127.0.0.1 在这里指 macOS loopback。

6.2 OrbStack VM 网络

Linux VM 有自己的 network namespace、接口、路由和 DNS 集成。container 的默认 gateway 通常在 Linux 侧,而不是 macOS 默认网关。

6.3 Container 网络

Docker bridge 或其他 network driver 为 container 分配独立 network namespace 和 IP。container 内 127.0.0.1 只指当前 container。

1
macOS localhost ≠ VM localhost ≠ container localhost

OrbStack 的产品体验会自动转发和解析部分入口,但不会消除这三个作用域。

7. 从 macOS 访问 Container

7.1 发布端口

标准 Docker 入口是:

1
docker run --rm -p 8080:80 nginx

OrbStack 将发布端口接到 macOS,使 localhost:8080 可访问 container 服务。数据路径概念上是:

1
macOS socket → OrbStack forwarding → VM/Docker published port → container

具体转发组件属于内部实现,不必假定一定是某个用户态 proxy 或某组 iptables 规则。

7.2 Container domain

OrbStack 为 container 提供自动 domain,官方文档描述了 *.orb.local 与自动 HTTPS 等能力。它把名称解析和访问入口做成产品层功能,减少记忆动态 container IP 的需要。

domain 可用不表示所有应用都接受该 Host header,也不替代应用自身 TLS、cookie domain 和 CORS 配置。

7.3 直接 IP 与发布端口是不同入口

OrbStack 支持增强的 container networking,包括从 macOS 访问 container IP 的能力。即便如此,生产可移植配置仍应优先使用 Docker port publishing 或服务发现,而不是硬编码运行时 IP。

8. 从 Container 访问 macOS

8.1 使用稳定域名

container 访问 macOS 服务时,使用官方支持的 host domain,例如 Docker 兼容的 host.docker.internal。Linux machine 则使用 host.orb.internal

1
curl http://host.docker.internal:3000

不要在 container 内使用 localhost:3000 期待访问 macOS;它只会访问 container 自己。

8.2 服务必须监听可达地址

即使域名解析正确,macOS 服务若只绑定某个受限 interface、防火墙阻止连接,或应用拒绝来源,请求仍会失败。

排障链路是:DNS → route → host forwarding → macOS listen socket → application policy。

8.3 VPN 与 DNS 是集成能力,不是透明保证

官方说明 OrbStack virtual network stack 会适配 macOS VPN 和 DNS。不同企业 VPN、split DNS、packet filter 和代理仍可能产生特殊行为,应以现场 digroutecurl -v 验证。

9. Container 之间的网络

同一个 user-defined Docker network 内,container 通常通过 Docker DNS 使用 service/container name 通信:

1
2
3
4
5
services:
  app:
    depends_on: [db]
  db:
    image: postgres

app 应连接 db:<port>,而不是 localhost:<port>。这部分主要是 Docker network 语义,OrbStack 提供兼容运行环境。

不同 Docker network 是否互通,由 network attachment、routing 和 firewall 决定。*.orb.local 是 Host 访问便利入口,不应替代 container 内部 service discovery。

10. Kubernetes 仍是独立编排层

10.1 Kubernetes 运行在 Linux 环境

OrbStack 可以启用本地 Kubernetes,提供 cluster、nodes、Pods、Services 和 Ingress 等对象。macOS 上的 kubectl 通过 kubeconfig 访问 VM 内 control plane。

10.2 Service 语义不因 OrbStack 消失

Pod IP 是易变端点,Service 提供稳定 virtual IP/DNS 与后端选择。OrbStack 可能优化具体数据路径,但没有公开证据时,不应断言它“完全不用 kube-proxy”或用某种固定 O(1) 转发表替换标准组件。

先用 Kubernetes 对象和现场状态判断:

1
2
3
4
kubectl get nodes,pods,svc -A -o wide
kubectl get endpointslices -A
kubectl get ingress -A
kubectl -n kube-system get pods

10.3 Host 访问有产品集成

OrbStack 提供 Kubernetes domain、port/Service 访问和自动 HTTPS 等集成。它们处在 macOS ↔ cluster 边界,不能与 cluster 内 Pod-to-Pod 或 Service routing 混为一谈。

11. Rosetta 与 CPU 架构

在 Apple Silicon 上,VM 和原生 container 通常是 arm64。运行 linux/amd64 image 可能涉及指令翻译;OrbStack 支持 Rosetta 相关能力以改善兼容性。

但三个概念要分开:

  • image manifest 是否包含 arm64;
  • Docker 选择了哪个 platform;
  • guest 中 amd64 binary 如何被翻译执行。

出现 exec format error 或性能问题时检查:

1
2
3
uname -m
docker image inspect <image>
docker run --platform linux/amd64 ...

不要把 architecture translation 与 container virtualization 当成同一层。

12. 如何用观测代替闭源猜测

12.1 确认 Client/Server 边界

1
2
3
docker context show
docker version
docker info

这能确认当前 CLI 是否连接 OrbStack、server OS/kernel、storage driver 和 runtime。

12.2 确认 Container 视角

1
2
3
4
docker inspect <container>
docker exec <container> ip addr
docker exec <container> ip route
docker exec <container> cat /etc/resolv.conf

12.3 确认 Host 视角

1
2
3
lsof -nP -iTCP:<port> -sTCP:LISTEN
curl -v http://localhost:<port>
dig <container>.orb.local

12.4 区分事实等级

等级示例
官方承诺VM 内运行 Docker engine;支持特定 domain 与 networking 功能
现场观测当前 kernel version、storage driver、runtime、route
合理推断某次连接大概率经过 Host↔VM 转发
无证据猜测固定 virtqueue 数量、私有 proxy 算法、Kubernetes 内部转发表

架构笔记应把前三类明确区分,并删除第四类。

13. 常见误区

13.1 “Container 直接跑在 macOS 上”

Docker CLI 在 macOS,不代表 Linux process 使用 macOS kernel。daemon 和 container 位于 OrbStack Linux 环境。

13.2 “OrbStack 没有 Docker engine”

官方架构与本机 docker info 都确认 VM 内有 Docker server。OrbStack 的差异主要在虚拟化和集成层,不是删除 Docker engine。

13.3 “localhost 能跨所有层”

每个 network namespace 有自己的 loopback。跨 macOS、VM、container 要使用发布端口或官方 host domain。

13.4 “Bind mount 就是原生 Linux 目录”

Host bind mount 跨越 macOS/Linux 文件共享边界,与 VM 内 named volume 的语义和性能不同。

13.5 “产品更快一定来自某个已知内核技巧”

性能结果可能来自启动、资源管理、文件共享、网络、缓存和 UI 多层优化。没有 profiling 与公开证据时,不应归因到某个特定 virtio 或 proxy 实现。

14. 复习索引

  1. OrbStack 用 Linux VM 提供 container 所需的 Linux kernel;
  2. Docker engine 运行在 VM 内,macOS Docker CLI 通过转发 socket 调用它;
  3. macOS、VM、container 各有网络与 localhost,OrbStack 用 domain 和 forwarding 改善跨层体验;
  4. image layer、named volume 和 host bind mount 位于不同存储边界;
  5. Linux machine、Docker container 和 Kubernetes Pod 是不同生命周期抽象;
  6. 闭源架构应优先写官方承诺和可重复观测,不用猜测私有实现填满链路。

15. 核验入口

  • OrbStack Architecture:VM、Linux machines 与 Docker engine 的关系;
  • OrbStack Docker Network:port forwarding、container domains、Host 访问、VPN/DNS;
  • OrbStack Machines Network:host.orb.internaldocker.orb.internal
  • OrbStack Files:macOS 文件共享与 Linux machine/container 文件访问;
  • OrbStack Kubernetes:本地 cluster 和 Host 集成;
  • docker version/info/inspectorb version:当前安装版本的现场证据。
本文由作者按照 CC BY 4.0 进行授权