编程 apple/container 深度拆解:当苹果用 Swift 为每个容器造一台虚拟机——从 Virtualization.framework、Containerization 到亚秒级启动的 Mac 原生容器工程全貌(2026)

2026-07-20 12:44:17 +0800 CST views 14

apple/container 深度拆解:当苹果用 Swift 为每个容器造一台虚拟机——从 Virtualization.framework、Containerization 到亚秒级启动的 Mac 原生容器工程全貌(2026)

一句话总结:Docker Desktop 的模型是「一个大 Linux 虚拟机里塞满容器」,而 apple/container 的模型是「每个容器一台自己的轻量虚拟机」。这个看似反直觉的选择,背后是苹果对 Apple Silicon、Virtualization.framework 和安全边界的一次彻底重构。本文从进程模型、镜像格式、网络栈到实测性能,把这套 Swift 写成的容器运行时拆到底。

目录

  • 一、背景:为什么 Mac 上跑容器一直很别扭
  • 二、核心设计:一个容器 = 一台微型 VM
  • 三、架构全景:从 CLI 到 vminitd 的六层结构
  • 四、Containerization 框架内幕:Swift 如何驱动一台 VM
  • 五、镜像与文件系统:OCI 兼容与 EXT4 块设备
  • 六、网络栈:vmnet、专用 IP 与 DNS
  • 七、代码实战:从 CLI 到 Swift API
  • 八、container machine:Mac 上的 WSL2
  • 九、性能优化:亚秒级启动是怎么做到的
  • 十、和 Docker Desktop / OrbStack / Lima 的正面对比
  • 十一、限制、坑与生产建议
  • 十二、总结与展望

一、背景:为什么 Mac 上跑容器一直很别扭

先说一个所有 Mac 开发者都心知肚明、但很少认真想过「为什么」的事实:macOS 上根本没有 Linux 内核

容器(container)的本质,不是什么魔法,而是 Linux 内核提供的一组机制:

  • namespace:给进程一个「假的」视图——独立的 PID、网络、挂载点、IPC、用户、UTS(主机名)。
  • cgroups:限制并统计一组进程能用多少 CPU、内存、IO。
  • 联合文件系统(overlayfs 等):镜像分层、写时复制。

这三件套全部是 Linux 内核特性。macOS 的内核是 XNU(Mach + BSD),它压根没有 Linux 的 namespace 和 cgroups。所以「在 Mac 上原生跑 Linux 容器」这句话,从物理上就是不成立的——你必须先有一个 Linux 内核。

于是过去十年,所有 Mac 容器方案的套路都一样:

macOS
  └── 一个 Linux 虚拟机(Docker Desktop / Lima / Colima)
        ├── containerd / dockerd
        ├── Container A
        ├── Container B
        └── Container C

Docker Desktop、OrbStack、Lima、Colima,无论上层包装多漂亮,底层都是先启动一个共享的 Linux VM,再在这台 VM 里用 containerd 跑所有容器。这套模型有几个长期被诟病的问题:

  1. 资源黑洞:那台共享 VM 要预分配一大坨内存(默认经常是 4~8GB),哪怕你只跑一个 redis,它也在那儿占着。
  2. 隔离性打折:所有容器共享同一个 Linux 内核。一旦有内核级漏洞(容器逃逸),同一 VM 内所有容器都暴露。
  3. 状态耦合:VM 是个长期存活的「大锅」,日积月累各种残留状态、磁盘膨胀、时钟漂移。
  4. 文件共享慢:macOS 主机目录挂进 Linux VM,历史上 osxfs、gRPC-FUSE、virtiofs 一路优化,但跨内核的文件语义翻译始终是性能痛点。

2025 年 WWDC,苹果开源了 Containerization Framework 和基于它构建的命令行工具 container(仓库地址 github.com/apple/container)。到 2026 年,它已经拿到 40k+ Star,1.0 版本落地,成为 Mac 本地容器生态的一次范式转移。

它做的最激进的一件事,就是把上面那张图彻底改写了。


二、核心设计:一个容器 = 一台微型 VM

apple/container 的模型长这样:

macOS
  ├── VM(Container A)  ← 各自独立的轻量 Linux 内核
  ├── VM(Container B)
  └── VM(Container C)

每个容器对应一台专属的、极简的轻量级虚拟机,而不是所有容器挤在一台共享 VM 里。

这初看很反直觉——虚拟机不是比容器重得多吗?为每个容器都开一台 VM,那启动速度和内存开销岂不是爆炸?

苹果的回答是三个前提条件的组合:

  1. Apple Silicon 的硬件虚拟化:M 系列芯片对 Type-2 hypervisor 有原生加速,Virtualization.framework 直接吃到硬件红利。
  2. 极致裁剪的 Guest OS:每台 VM 里跑的不是完整发行版,而是一个只包含「启动一个容器所需最小内核 + init」的镜像。启动路径被压到极短。
  3. 专门优化的初始化进程 vminitd:用 Swift 写的、静态编译的 PID 1,负责在 VM 里把容器进程拉起来。

结果就是:亚秒级(sub-second)启动 + 虚拟机级别的硬件隔离。你既拿到了接近容器的启动体验,又拿到了 VM 才有的强隔离边界。

这套模型的直接收益

维度共享 VM 模型一容器一 VM 模型
隔离边界进程级(共享内核)硬件级(各自内核)
爆炸半径一个逃逸 = 全 VM 沦陷一个逃逸 = 仅该容器
资源分配预分配大块给共享 VM按容器精确分配、用完即还
生命周期VM 长期存活、状态累积容器停 = VM 销毁,天然干净
内核定制所有容器共享一个内核理论上每容器可用不同内核

用一句话概括这个哲学转变:从「多租户共享一个内核」回到「每个负载独享一个内核」。这其实是把云厂商在 Firecracker / Kata Containers 上验证过的「microVM」思路,搬到了个人开发机上。

值得一提:AWS 的 Firecracker、Kata Containers 早就在服务端用「microVM 包住容器」来做多租户安全隔离。苹果的创新不在于「microVM」这个概念本身,而在于把它做到 Apple Silicon 本地开发场景里,并封装成一个 Docker 用户零学习成本的 CLI。


三、架构全景:从 CLI 到 vminitd 的六层结构

自顶向下,apple/container 大致可以分成六层:

┌─────────────────────────────────────────────┐
│ 1. container CLI(Swift 命令行,Docker 兼容语义)│
├─────────────────────────────────────────────┤
│ 2. container-apiserver(后台 XPC/gRPC 服务)    │
├─────────────────────────────────────────────┤
│ 3. Containerization Framework(Swift 库)      │
│    - 镜像拉取/解包(OCI)                        │
│    - VM 生命周期管理                            │
│    - 网络/存储 attach                           │
├─────────────────────────────────────────────┤
│ 4. Virtualization.framework(Apple 系统框架)   │
│    - VZVirtualMachine / VZLinuxBootLoader      │
├─────────────────────────────────────────────┤
│ 5. Hypervisor.framework + Apple Silicon 硬件   │
├─────────────────────────────────────────────┤
│ 6. Guest 内:优化内核 + vminitd(PID 1) + 容器进程│
└─────────────────────────────────────────────┘

逐层说明:

  • CLI 层container run/build/images/ps/...。命令语义刻意向 Docker 对齐,降低迁移成本。它本身很薄,主要负责解析参数、和后台服务通信。
  • apiserver 层:一个常驻的后台服务(通过 container system start 启动)。它管理所有容器的生命周期、镜像存储、网络分配。CLI 是它的客户端。
  • Containerization Framework:整个项目的心脏,一个可被第三方 App 直接引用的 Swift 包。它把「拉镜像 → 造根文件系统 → 配 VM → 启动 → attach IO」这一整条流水线封装成 Swift API。
  • Virtualization.framework:苹果自 macOS 11 起提供的高层虚拟化框架,屏蔽了 Hypervisor.framework 的底层细节,提供 VZVirtualMachine、virtio 设备、Linux 引导等能力。
  • Hypervisor.framework + 硬件:真正落到 Apple Silicon 的 EL2 虚拟化扩展。
  • Guest 内部:这是苹果下功夫最多的地方——一个被裁到极致的 Linux 内核,PID 1 是 Swift 写的 vminitd,它负责在 VM 里完成挂载根文件系统、设置网络、exec 容器主进程。

这个分层的关键设计是:Containerization 是一个「库」而不仅是「工具」。也就是说,你可以在自己的 Swift App 里 import Containerization,直接把「跑一个 Linux 容器」当成一个函数调用,而不必 fork 一个 CLI 进程。这为 IDE、CI 工具、自定义开发者工具打开了想象空间。


四、Containerization 框架内幕:Swift 如何驱动一台 VM

我们来看「运行一个容器」在框架内部发生了什么。概念上的流程是:

container run --rm alpine echo hello
      │
      ▼
① 解析镜像引用 alpine:latest
② 从 registry / 本地缓存拉取 OCI 镜像(manifest + layers)
③ 把 layers 解包合并成一个 rootfs
④ 把 rootfs 打包成一个 EXT4 块设备镜像(.img)
⑤ 用 Virtualization.framework 组装一台 VM:
     - VZLinuxBootLoader(kernel = 优化内核)
     - VZVirtioBlockDevice(rootfs.img)
     - VZVirtioNetworkDevice(vmnet)
     - VZVirtioConsoleDevice(stdio 透传)
⑥ 启动 VM,内核起来后 exec vminitd 作为 PID 1
⑦ vminitd 挂载 rootfs、配好网络,然后 exec `echo hello`
⑧ stdout 通过 virtio-console 透传回 host CLI
⑨ 进程退出 → VM 停机 → 清理块设备

用简化的伪 Swift 代码表达框架层大致做的事(示意,非逐字 API):

import Containerization

// 1. 准备镜像:拉取并解包为可挂载的根文件系统
let image = try await ImageStore.default.pull(reference: "docker.io/library/alpine:latest")
let rootfs = try await image.unpack()          // 合并 OCI layers

// 2. 描述一台虚拟机及其内部要跑的容器进程
var config = ContainerConfiguration(
    image: image,
    process: .init(
        arguments: ["echo", "hello"],
        environment: ["PATH": "/usr/bin:/bin"],
        workingDirectory: "/"
    )
)
config.resources = .init(cpuCount: 2, memoryBytes: 512 << 20)  // 2 vCPU / 512MB
config.rootfs = rootfs

// 3. 创建容器(内部即创建一台专属 microVM)
let container = try await Container.create(configuration: config)

// 4. 启动并附着 IO
try await container.start()
try await container.attachStdio()

// 5. 等待退出并回收
let status = try await container.wait()
try await container.delete()   // VM 销毁、块设备清理
print("exit code:", status.exitCode)

关键点在于:Container 这个对象的生命周期,就是一台 VM 的生命周期create 造 VM,start 引导内核,delete 拆掉整台机器。没有一个长期存活的「大 VM」在背后攒状态。

vminitd:Swift 写的 PID 1

传统 Linux 容器里,PID 1 往往是 shtini 或应用本身。而在 apple/container 的每台 microVM 里,PID 1 是苹果用 Swift 静态编译的 vminitd。它承担了一个 microVM init 系统该做的最小职责:

  • 挂载 /proc/sys/dev 等伪文件系统
  • 挂载作为根的 EXT4 块设备
  • 应用 namespace / 资源限制语义
  • 配置 loopback 与 virtio 网卡
  • 通过一个控制通道(vsock/gRPC)接收 host 的指令(exec、signal、resize tty)
  • exec 容器主进程并转发其 stdio、回收退出码

因为它是静态编译、职责单一,冷启动开销极小——这正是「亚秒级」的关键一环。你可以把 vminitd 理解成「microVM 世界里的 tini + containerd-shim 的合体」。


五、镜像与文件系统:OCI 兼容与 EXT4 块设备

一个常见误解是:既然是苹果自己的东西,镜像格式会不会又是一套封闭标准?

不会。apple/container 完全兼容 OCI 镜像规范。 你从 Docker Hub、GHCR、私有 registry 拉的镜像都能直接用:

container pull ghcr.io/your-org/api-server:1.2.3
container images ls

它的镜像存储、manifest 解析、layer(tar+gzip / zstd)解包都遵循 OCI Image Spec 和 Distribution Spec。这意味着你现有的 Dockerfile、CI 产物、镜像仓库全部可以复用。

真正的差异在根文件系统的组织方式

  • Docker/containerd:用 overlayfs 把多个只读 layer 叠加,再加一个可写层,容器直接跑在 host 内核的联合挂载上。
  • apple/container:因为每个容器是独立 VM,它把解包合并后的 rootfs 打包成一个 EXT4 块设备镜像(一个 .img 文件),作为 virtio-blk 设备挂给 VM,VM 内核把它挂载为 /

这样设计的原因很直接:VM 需要的是一个「块设备」,而不是 host 上的一个目录树。block device + EXT4 是 Linux 内核最成熟、最快的根文件系统路径,避免了跨内核文件语义翻译的开销。

代价是:镜像层的写时复制、去重要在「造 img」这一步处理,而不是靠运行时的 overlayfs。框架会缓存已解包的层,尽量复用,避免每次 run 都重新拼装整块镜像。

构建镜像

container build 使用兼容 Dockerfile 的构建流程:

# Dockerfile
FROM golang:1.24-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app ./cmd/server

FROM alpine:3.20
COPY --from=build /out/app /usr/local/bin/app
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/app"]
container build -t my-api:dev .
container run --rm -p 8080:8080 my-api:dev

命令语义和 Docker 几乎一致,这是苹果刻意做的「零学习成本迁移」。


六、网络栈:vmnet、专用 IP 与 DNS

网络是「一容器一 VM」模型带来的另一个有趣变化。

在 Docker Desktop 里,容器网络是那台共享 Linux VM 内部的 bridge/veth,host 要访问容器得靠端口转发(-p)在 VM 边界打洞。

在 apple/container 里,每台容器 VM 都是 macOS 眼中一个独立的网络端点。它借助 macOS 的 vmnet 框架给每个容器 VM 分配一个专属 IP(在 1.0 时代通常落在一个专用子网里,例如 192.168.64.0/24 这类范围)。

这带来一个非常舒服的能力:你可以直接用 IP 访问容器,而不必强依赖端口映射

container run -d --name web nginx
container ls
# 输出里会显示每个容器分到的 IP,例如 192.168.64.3

curl http://192.168.64.3     # 直接访问,无需 -p 转发

同时它提供了容器名到 IP 的本地 DNS 解析,容器之间可以按名字互访。对于「起一组服务、彼此调用」的本地开发场景,这比在共享 VM 里配 bridge 网络要直观得多。

需要注意的现实约束:

  • 端口映射(-p)在早期版本上有平台限制,某些 macOS 版本对 vmnet 的能力支持不同,直连 IP 反而是更稳的路径。1.0 之后对端口发布做了增强。
  • 直连 IP 是「本机可达」,不是「局域网其他机器可达」——它走的是 macOS 主机内部的 vmnet 虚拟网络。

七、代码实战:从 CLI 到 Swift API

7.1 安装与初始化

apple/container 通过发布的 .pkg 安装(需要 Apple Silicon + 较新 macOS)。安装后先启动后台系统服务:

# 启动后台 apiserver(管理容器/镜像/网络)
container system start

# 查看状态
container system status

7.2 日常命令(Docker 用户无缝上手)

# 拉镜像
container pull alpine:3.20

# 前台跑一个一次性容器
container run --rm alpine echo "hello from a microVM"

# 后台常驻 + 命名 + 资源限制
container run -d --name redis \
  --cpus 2 --memory 512m \
  redis:7-alpine

# 进入容器
container exec -it redis sh

# 查看运行中的容器(含各自 IP)
container ls

# 日志
container logs -f redis

# 停止 & 删除(VM 随之销毁)
container stop redis
container rm redis

# 镜像管理
container images ls
container image rm alpine:3.20

7.3 host ↔ 容器文件传输:container cp

1.0 版本补上了很多人期待的 cp 命令:

# 从 host 拷进容器
container cp ./config.toml redis:/etc/redis/config.toml

# 从容器拷出到 host
container cp redis:/data/dump.rdb ./backup/dump.rdb

7.4 用 TOML 声明式配置

1.0 引入了基于 TOML 的配置文件,让「一个容器的完整定义」可以版本化管理:

# app.container.toml
image = "my-api:dev"

[process]
args = ["/usr/local/bin/app", "--port", "8080"]

[process.env]
LOG_LEVEL = "info"
DATABASE_URL = "postgres://db:5432/app"

[resources]
cpus = 2
memory = "1g"

[[mounts]]
source = "./data"
destination = "/var/lib/app"

7.5 直接调用 Swift 库(进阶)

如果你在写自己的 macOS 开发者工具,可以绕过 CLI 直接 import Containerization

import Containerization
import Foundation

@main
struct RunOnce {
    static func main() async throws {
        let image = try await ImageStore.default.pull(
            reference: "docker.io/library/python:3.12-alpine"
        )

        var cfg = ContainerConfiguration(image: image, process: .init(
            arguments: ["python3", "-c", "print(2**64)"]
        ))
        cfg.resources = .init(cpuCount: 1, memoryBytes: 256 << 20)

        let c = try await Container.create(configuration: cfg)
        try await c.start()
        try await c.attachStdio()
        let st = try await c.wait()
        try await c.delete()
        print("exit:", st.exitCode)
    }
}

这种「把容器当函数调」的能力,是它区别于纯 CLI 工具最有工程价值的地方。


八、container machine:Mac 上的 WSL2

apple/container 里有个容易被忽略的另一半:container machine

如果说 container run 是「跑一个进程级容器」,那 container machine 就是「跑一个完整、长期存活的 Linux 开发环境」——它的定位更接近 Windows 的 WSL2,而不是 Docker:

# 创建一个长期存活的 Linux 环境
container machine create dev --distro ubuntu

# 进入
container machine ssh dev

# 它会自动把你的 macOS $HOME 挂进去,支持 systemd

关键特性:

  • 自动挂载 macOS $HOME:你的代码、dotfiles 直接可见,编辑在 Mac、编译运行在 Linux。
  • 支持 systemd:可以在里面跑需要 init 系统的服务(数据库、消息队列的原生 Linux 版本)。
  • 长期存活:和一次性容器不同,machine 是持久的开发沙箱。

这填补了一个真实空白:很多后端开发者其实想要的不是「打包发布用的容器」,而是「一个跟 macOS 深度集成、但内核是 Linux 的干净开发环境」。过去大家用 Lima/Multipass 拼,现在苹果给了官方答案。


九、性能优化:亚秒级启动是怎么做到的

「每容器一 VM 还能亚秒级启动」是这个项目最反直觉、也最值得拆解的工程成就。几个关键手段:

9.1 极简 Guest 内核

Guest 里跑的不是 Ubuntu/Debian,而是一个为容器场景专门配置、裁掉绝大多数驱动和子系统的 Linux 内核。内核体积小、初始化路径短,kernel decompress → init 的时间被压到最低。

9.2 Swift 静态编译的 vminitd

PID 1 不是重量级 init(systemd/openrc),而是单一职责、静态链接的 vminitd。没有服务依赖图解析、没有一堆 unit 要拉起,起来就干活。

9.3 Apple Silicon 硬件虚拟化直通

Virtualization.framework 底层是 Hypervisor.framework,直接吃 M 系芯片的虚拟化扩展。vCPU 调度、内存虚拟化都有硬件加速,不走软件模拟。

9.4 virtio 半虚拟化设备

块设备用 virtio-blk、网卡用 virtio-net、控制台用 virtio-console。virtio 是「Guest 知道自己在 VM 里」的协作式接口,绕开了模拟真实硬件的开销,IO 路径短。

9.5 镜像层缓存复用

解包后的 rootfs 层会被缓存。第二次跑同一镜像时,不需要重新拉取和重新拼 EXT4 块,直接复用缓存的块设备模板,run 到进程起来的时间显著缩短。

9.6 按需资源,用完即还

因为 VM 生命周期 = 容器生命周期,内存是按容器实际配置分配、容器退出即归还给 macOS。不像共享 VM 那样一次性圈走一大块内存长期不放。这对「同时开一堆小容器」的开发机内存压力友好得多。

一个粗略的心智模型对比:

启动阶段共享 VM(Docker Desktop)apple/container
首次冷启动需先启动整台大 VM(数秒~十几秒)后台服务已就绪后,单容器亚秒级
后续容器快(复用大 VM,直接起容器)每容器起一台微 VM,仍亚秒级
内存占用大 VM 常驻,预分配按容器分配、退出即还
隔离共享内核各自内核

十、和 Docker Desktop / OrbStack / Lima 的正面对比

维度Docker DesktopOrbStackLima/Colimaapple/container
底层模型共享 Linux VM优化的共享 VM共享 VM一容器一 microVM
语言Go 为主闭源GoSwift
是否开源部分/商业授权闭源商业开源完全开源(Apache-2.0)
隔离强度进程级(共享内核)进程级进程级硬件级(独立内核)
商业授权大企业需付费付费免费免费开源
OCI 兼容
Apple Silicon 优化一般一般原生极致
可作为库嵌入是(Swift 包)
直连容器 IP需端口转发支持需转发原生支持
生态成熟度极高(compose 等)成长中

诚实地讲结论:

  • 要马上进生产工作流、依赖 docker-compose、需要跨平台一致体验 → 现阶段 Docker Desktop / OrbStack 仍更省心,生态完整。
  • 纯 Apple Silicon 本地开发、看重隔离与资源效率、想要开源免费、甚至想把容器能力嵌进自己的 Swift 工具 → apple/container 是更有前途的选择,且更新迭代很快。

它对商业产品(尤其 OrbStack、Docker Desktop 的付费模式)构成实打实的压力:当苹果亲自下场、免费开源、还和硬件深度绑定时,「Mac 上跑容器」这件事的默认选项正在被改写。


十一、限制、坑与生产建议

工程上要清醒,别被「苹果亲儿子」的光环冲昏头。当前阶段的现实约束:

  1. 只支持 Apple Silicon:Intel Mac 无缘。它的整套优化都建立在 M 系芯片的虚拟化能力上。
  2. 需要较新的 macOS:部分能力(尤其网络端口发布、vmnet 行为)在不同 macOS 版本上表现不同,1.0 前的版本端口映射限制更明显。生产前务必按官方 README 核对系统版本要求。
  3. compose 生态尚不完整:多容器编排、docker-compose.yml 直接复用的体验还在补齐中。复杂本地拓扑目前仍是 Docker/OrbStack 更顺。
  4. 一容器一 VM 的 overhead 权衡:单容器内存有 VM 基线开销;跑成百上千个极小容器的密度场景,未必比共享内核模型省。它的甜点是「中等数量、看重隔离」的开发负载。
  5. Windows/Linux 无缘:这是 macOS 独占方案,团队若跨平台,得接受工具链不统一。
  6. 块设备镜像的磁盘占用:EXT4 img 的复用策略决定磁盘效率,注意定期 container image prune 清理缓存层。

给团队的落地建议:

  • 先在个人开发机试点,替换「起单个依赖服务(redis/postgres/mysql)」这类场景,收益最直接。
  • CI/生产继续用现有 OCI 流水线——镜像完全兼容,不用改 Dockerfile。
  • 想做 Mac 原生开发者工具的团队,重点关注 Containerization 这个 Swift 库,它才是长期护城河。
  • 别一次性全量迁移,把它当成「Apple Silicon 上更好的本地容器运行时」,而不是「Docker 的完全替代」。

十二、总结与展望

apple/container 最值得记住的,不是「苹果又开源了个工具」,而是它背后那个清晰的判断:在 Apple Silicon 上,为每个容器造一台微型虚拟机,不再是奢侈,而是可行且更优的默认选择。

它把三件事捏到了一起:

  1. microVM 的强隔离——这是云厂商用 Firecracker 验证过的方向,苹果把它带到了本地开发机。
  2. Swift + Virtualization.framework 的深度整合——不是套壳 Linux VM,而是从 PID 1(vminitd)到块设备到网络的全栈自研。
  3. 对开发者零学习成本的 CLI + 可嵌入的库——既讨好 Docker 老用户,又给工具开发者留了口子。

它现阶段还不完美:生态在补、compose 未全、仅限 Apple Silicon。但方向是对的,迭代很快,而且免费开源。对每天在 M 系 Mac 上写后端、跑依赖服务的开发者来说,它已经值得纳入你的工具箱认真试一轮。

更大的看点在于趋势:当「安全隔离」从「多容器共享一个内核」重新回到「每个负载独享一个内核」,容器与虚拟机之间那条泾渭分明的界线,正在被 microVM 悄悄抹平。apple/container 是这条趋势线上,离普通开发者最近的一个样本。

Docker 要慌的其实不是这一个工具,而是它代表的那个问题:当硬件虚拟化足够快、足够便宜,我们还需要用「共享内核」去换性能吗? 苹果给出的答案是——在 Apple Silicon 上,不需要了。


本文基于 2026 年 apple/container 1.0 及其公开架构资料整理,涉及具体命令与系统版本要求请以官方 README 为准。技术选型请结合团队实际场景权衡。

推荐文章

Rust async/await 异步运行时
2024-11-18 19:04:17 +0800 CST
Redis和Memcached有什么区别?
2024-11-18 17:57:13 +0800 CST
MySQL 主从同步一致性详解
2024-11-19 02:49:19 +0800 CST
Gin 框架的中间件 代码压缩
2024-11-19 08:23:48 +0800 CST
程序员茄子在线接单