跳到主要内容

Apple Container实践

概述

苹果在2025年6月的全球开发者大会(WWDC)上发布了 ContainerizationContainer CLI,这是一个在 Mac 上以轻量级虚拟机方式创建和运行 Linux 容器的工具。这是开发者在 macOS 上运行 Linux 容器方式的重大转变,因为这一新的开源容器化框架消除了对 Docker 等第三方工具的需求。这个基于 Swift 的框架将在 macOS 26 中直接提供原生的 Linux 容器支持,标志着苹果以安全、性能和隐私为关注点进入了容器化领域

随着 2025 年 9 月 macOS 26 正式版的发布,Apple Container 已经正式成为 macOS 的一部分。本文将详细介绍 Apple Container 的一些实践,包括介绍、安装和使用方法

架构之VM-per-Container

Apple Container 采用 VM-per-Container 架构,这意味着每个容器都运行在一个独立的轻量级虚拟机中。这种设计提供了更高的隔离性和安全性,因为每个容器都有自己的内核和资源。与传统的容器化技术(如 Docker)共享主机内核不同,Apple Container 的这种架构可以防止容器之间的相互影响,提高了系统的稳定性和安全性。

Container 和底层的 Containerization 包集成了 macOS 的多个关键技术和框架:Virtualization 框架用于管理 Linux 虚拟机及其附加设备;vmnet 框架用于管理容器连接的虚拟网络;XPC 用于进程间通信;Launchd 用于服务管理;Keychain 服务用于访问注册表凭据;统一日志系统用于应用程序日志记录。

核心组件:

  • container CLI - 用户交互的命令行界面
  • container-apiserver - 后台服务进程,管理所有容器操作
  • container-runtime-linux - 为每个容器启动的专用运行时助手
  • vminitd - 在 VM 内部运行的最小化 init 系统,负责挂载文件系统、启动容器化进程

为了在没有标准库的环境中实现这一点,Apple 使用 Swift 的 Static Linux SDK 从 macOS 直接交叉编译静态 Linux 二进制文件,结合 musl 提供静态链接支持

优势

安全性

Apple 的 Containerization 框架为每个 Linux 容器提供了硬件级隔离,而不是依赖传统的基于命名空间的容器运行时。这从根本上解决了传统容器共享内核带来的安全隐患。

安全优势:

  • VM 级隔离:每个容器都有独立的内核,消除了容器逃逸风险
  • 最小化攻击面:使用最少的核心工具和动态库
  • 无共享内核漏洞:不受宿主内核漏洞的影响

传统容器运行时在所有容器之间共享宿主内核,通过内核漏洞或容器逃逸漏洞创造了潜在的攻击向量。通过将每个容器放置在自己的轻量级 VM 中,Apple 消除了困扰容器安全十多年的共享攻击面

原生macOS集成

Container 不仅仅是另一个 Docker 克隆;它是重新构想在 Mac 上容器化可以是什么样子。与可能依赖更重的 Linux 虚拟机或跨平台兼容层的其他解决方案不同,container 是从零开始为 Apple Silicon 构建的。这是一个直接与 Apple 原生 Virtualization.framework 对话的 Swift 应用程序。

原生集成优势:

  • 无需 Rosetta 2 模拟层:运行时本身不涉及仿真
  • 深度系统集成:与 Xcode、Swift Package Manager 等工具自然配合
  • 统一日志系统:所有诊断输出集成到 macOS 熟悉的日志系统中
  • Keychain 集成:安全存储注册表凭据

性能

  • 快速启动:秒级容器启动时间
  • 资源高效:轻量级 VM 设计,最小化资源占用
  • 优化的文件系统访问:使用 EXT4 块设备提供高性能访问
  • 针对 Apple Silicon 优化:充分发挥 M 系列芯片的性能

兼容性

  • Apache 2.0 许可:完全开源,鼓励社区贡献
  • OCI 兼容:可以使用任何标准容器注册表的镜像
  • 互操作性:构建的镜像可以在任何 OCI 兼容应用中运行

使用

环境说明

  • 设备:MacBook Pro (M4, 2024)
  • 操作系统:macOS 26.1 (Tahoe)

安装

GitHub Release 页面下载最新的签名安装包,双击 .pkg 文件安装即可

启动并验证

首次运行时会提示下载并安装默认的容器 Linux 内核,输入y并回车继续。

初次使用可以参考官方的tutorial来快速上手

~ container system start
Verifying apiserver is running...
No default kernel configured.
Install the recommended default kernel from [https://github.com/kata-containers/kata-containers/releases/download/3.17.0/kata-static-3.17.0-arm64.tar.xz]? [Y/n]: y
Installing kernel...
~ container --version
container CLI version 0.7.1 (build: release, commit: 420be74)
~ container ls -a
ID IMAGE OS ARCH STATE ADDR CPUS MEMORY

设置本地 DNS 域名

Container 包含一个嵌入式 DNS 服务,简化了对容器化应用的访问,可以很方便地通过域名访问容器,而不需要手动查找和使用容器的 IP 地址。可以通过 <container-name>.<domain-name> 进行访问,例如 myapp.local

# 创建test域(需要管理员权限, 配置一个名为 test 的本地 DNS 域名,在 /etc/resolver 目录下创建包含域配置的文件,并告诉 macOS DNS 解析器重新加载其配置文件)
sudo container system dns create test

# 设置默认域
container system property set dns.domain test

# 现在可以通过域名访问容器
container run -d --name myapp nginx:latest

# 访问方式
curl http://myapp.test

运行容器

# 运行nginx容器
container run --rm --name nginx-test nginx:latest

访问容器

基于 VM-per-Container 架构,每个容器都有自己的 IP 地址,且可以直接在宿主机通过该 IP 地址或上面的本地域名方式进行访问

~ container ls
ID IMAGE OS ARCH STATE ADDR CPUS MEMORY
nginx-test docker.io/library/nginx:latest linux arm64 running 192.168.64.2 4 1024 MB
~ curl http://192.168.64.2
~ curl http://nginx-test.test

构建镜像

apple container 同样支持使用 Dockerfile 来构建镜像,首先编写如下的 Dockerfile 文件

~ mkdir web-test
~ cd web-test
~ cat > Dockerfile << EOF
FROM docker.io/python:alpine
WORKDIR /content
RUN apk add curl
RUN echo '<!DOCTYPE html><html><head><title>Hello</title></head><body><h1>Hello, world!</h1></body></html>' > index.html
CMD ["python3", "-m", "http.server", "80", "--bind", "0.0.0.0"]
EOF

构建镜像

~ container build --tag web-test --file Dockerfile .
[+] Building 33.4s (7/7) FINISHED
... 0.2s
Successfully built web-test:latest

运行镜像

~ container image ls
NAME TAG DIGEST
web-test latest 7f1b83d975ea0e5b67647e20...
container run --name my-web-server -d --rm web-test

访问容器

~ container ls
ID IMAGE OS ARCH STATE ADDR CPUS MEMORY
my-web-server web-test:latest linux arm64 running 192.168.64.4 4 1024 MB
~ curl http://192.168.64.4
~ curl http://my-web-server.test

查看容器资源

~ container stats my-web-server
~ container stats --no-stream my-web-server

查看容器日志

~ container logs my-web-server

停止容器

~ container stop my-web-server

推送镜像到仓库

~ container registry login some-registry.example.com
~ container image tag web-test some-registry.example.com/fido/web-test:latest
~ container image push some-registry.example.com/fido/web-test:latest

多架构镜像构建

Apple Container 目前也支持多架构镜像的构建,可以通过 --platform 参数指定目标架构

~ container build --tag web-test-amd64 --platform linux/amd64 .

代理

Apple Container 支持通过环境变量配置 HTTP/HTTPS 代理,例如加速镜像的拉取操作

export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080

停止服务

~ container system stop

卸载服务

官方提供了一个卸载脚本,停止服务后,通过脚本一键卸载

~ container system stop
~ curl -fsSL https://raw.githubusercontent.com/apple/container/refs/heads/main/scripts/uninstall-container.sh -o uninstall-container.sh
~ sudo bash uninstall-container.sh -d # 删除所有数据,包含用户数据目录
~ sudo bash uninstall-container.sh -k # 不删除用户数据目录

命令合集

以下是 Apple Container 命令与我们熟悉的 Docker 命令的对照参考

功能Docker 命令Apple Container 命令
拉取镜像docker pull alpinecontainer image pull alpine
列出镜像docker imagescontainer image ls
删除镜像docker rmi alpinecontainer image rm alpine
给镜像打标签docker tag alpine myalpinecontainer image tag alpine myalpine
查看镜像详情docker inspect alpinecontainer image inspect alpine
清理未使用镜像docker image prunecontainer image prune
运行容器docker run alpinecontainer run alpine
交互式运行docker run -it alpine shcontainer run -it alpine sh
后台运行docker run -d nginxcontainer run -d nginx
命名容器docker run --name web nginxcontainer run --name web nginx
自动删除docker run --rm alpinecontainer run --rm alpine
端口映射docker run -p 8080:80 nginxcontainer run -p 8080:80 nginx
环境变量docker run -e VAR=value alpinecontainer run -e VAR=value alpine
资源限制docker run --cpus 2 -m 1G alpinecontainer run --cpus 2 -m 1G alpine
列出容器docker pscontainer ls
列出所有容器docker ps -acontainer ls -a
停止容器docker stop mycontainercontainer stop mycontainer
启动容器docker start mycontainercontainer start mycontainer
删除容器docker rm mycontainercontainer rm mycontainer
在容器中执行命令docker exec -it web shcontainer exec -it web sh
查看容器详情docker inspect webcontainer inspect web
查看容器日志docker logs webcontainer logs web
构建镜像docker build -t myimg .container build -t myimg .
指定 Dockerfiledocker build -f custom.df .container build -f custom.df .
设置构建参数docker build --build-arg KEY=val .container build --build-arg KEY=val .
登录注册表docker logincontainer registry login
推送镜像docker push myimgcontainer image push myimg
创建网络docker network create mynetcontainer network create mynet
列出网络docker network lscontainer network ls
删除网络docker network rm mynetcontainer network rm mynet
创建卷docker volume create myvolcontainer volume create myvol
列出卷docker volume lscontainer volume ls
删除卷docker volume rm myvolcontainer volume rm myvol
查看版本docker --versioncontainer --version
启动服务-container system start
停止服务docker system stopcontainer system stop
查看系统日志-container system logs