在macOS上用Colima代替Docker
Colima 是 macOS 上最直接的本地容器运行时方案之一。它通过 Lima 启动一个 Linux 虚拟机,在这层 Linux 环境里运行 Docker、containerd,以及可选的 k3s Kubernetes,再把这些能力暴露给宿主机上的 docker、 kubectl 和其他常用客户端。本文整理 Colima 在 macOS 上的工作原理、安装方法、推荐配置、验证步骤以及几个最常见的运维注意事项。
容器并不是“比虚拟机更轻的 macOS 进程”。容器依赖 Linux 内核提供的 Namespace、cgroups、OverlayFS 等机制。macOS 不提供这套 Linux 内核接口,因此在 macOS 上运行 Linux 容器时,底层一定存在一个 Linux 虚拟机。
这也是理解 Colima 的关键前提。它并没有绕过虚拟化,而是把虚拟化这一层做得更轻、更透明:用 Lima 管理 Linux 虚拟机,用 Colima 负责容器运行时和宿主机 CLI 的集成。
Colima 可以视为 Lima 之上的一层开发者友好封装。Lima 负责虚拟机、文件共享和端口转发,Colima 负责在虚拟机中配置容器运行时,并把它无缝接到宿主机工作流里。
从使用者视角看,Colima 有三个特征最重要:
- 它在 macOS 上提供 Docker、containerd 和可选 Kubernetes 的本地运行环境。
- 它直接复用宿主机上的命令行客户端,而不是强制引入一个单独的桌面应用工作流。
- 它支持多 Profile,每个 Profile 都是一台独立虚拟机,适合把轻量 Docker 环境和启用 Kubernetes 的环境分开管理。
在 macOS 上做本地容器开发,问题通常不在“能不能跑起来”,而在于环境是否足够可控。Colima 的价值主要体现在三个方面:
- 结构更清晰。宿主机 CLI、Linux 虚拟机、容器运行时三层边界明确,排障时更容易定位问题落在哪一层。
- 控制更细。CPU、内存、磁盘、架构、Kubernetes、网络和挂载方式都可以用命令行或 YAML 配置。
- 更接近工程化使用。它天然适合脚本化、Profile 隔离、CI 风格的命令流,而不是围绕 GUI 操作组织工作。
如果机器上已经装有 Docker Desktop,也不一定必须先卸载。更重要的是明确当前激活的 Docker context,避免命令误连到错误的 daemon。
在 macOS 上,最简单的安装方式是 Homebrew。Docker runtime 需要宿主机安装 Docker CLI;如果要启用 Kubernetes,还需要 kubectl。
|
1 |
brew install colima docker kubectl |
首次启动可以先使用默认配置验证链路是否正常:
|
1 2 3 |
colima start docker run --rm hello-world docker ps |
如果只想把它作为 Docker daemon 使用,这一步已经足够。若需要本地 Kubernetes,可以在启动时直接打开:
|
1 2 |
colima start --kubernetes kubectl get nodes |
如果系统里同时存在多个 Docker daemon,先确认当前 context:
|
1 2 |
docker context ls docker context use colima |
Colima 支持用命令行参数临时配置,也支持用 YAML 保存持久配置。日常使用中,最稳妥的入口通常是 colima start --edit:它会打开当前 Profile 的配置文件并在保存后启动实例。
下面是一份适合本地开发的通用示例。它移除了项目私有镜像源和业务环境假设,只保留公共环境下最常见、最有价值的选项。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
cpu: 4 memory: 8 disk: 100 arch: host runtime: docker kubernetes: enabled: true k3sArgs: - --disable=traefik network: address: true vmType: vz vmOpts: vz: rosetta: true mountType: virtiofs provision: - mode: system script: | apt-get update apt-get install -y vim curl htop git make dnsutils net-tools iputils-ping telnet |
cpu、 memory 和 disk 决定虚拟机资源上限。默认值足够启动容器,但一旦本地要同时跑数据库、消息队列、应用服务和 K3s,默认配置往往会很快触顶。
kubernetes.enabled: true 会在虚拟机内启用 k3s。对本地开发来说,这是最省事的单节点 Kubernetes 方案。关闭 Traefik 的原因也很直接:很多工程已经自带 Ingress Controller 或者只需要最小可用集群,不需要额外的默认入口组件。
network.address: true 会给虚拟机分配一个可从宿主机访问的地址。这个地址对调试虚拟机本身、从宿主机直接探测 VM 内服务、或者排查网络路径非常有用。
vmType: vz 表示在较新的 macOS 上使用 Apple Virtualization Framework。对现代 macOS 机器,这通常是更自然的选择。若机器较旧,或者当前工作流依赖不兼容的虚拟化特性,再退回 qemu。
vmOpts.vz.rosetta: true 适用于 Apple Silicon 机器上需要频繁运行 linux/amd64 用户态二进制的场景。它解决的不是容器“能不能启动”的问题,而是跨架构开发时的兼容性和执行效率问题。
mountType: virtiofs 决定宿主机目录如何挂载到虚拟机。现代 macOS 配合 vz 时,选择 virtiofs 通常是合理默认值。
provision 则用于给 VM 预装少量排障工具。把这类依赖放进 VM 启动脚本,而不是手工进入系统逐个安装,环境才是可重建的。
如果希望为后续新建 Profile 预设默认值,可以编辑 $HOME/.colima/_templates/default.yaml。这个文件的角色是默认模板,而不是当前实例的唯一真实配置。对已经存在的 Profile,最直接的方式仍然是用 colima start --edit 或者删除后重建。
配置完成后,先检查虚拟机状态:
|
1 |
colima status |
如果启用了 network.address,并且宿主机安装了 jq,可以直接取出 VM IP:
|
1 2 3 |
export COLIMA_VM_IP=$(colima status -j | jq -r .ip_address) echo "$COLIMA_VM_IP" ping "$COLIMA_VM_IP" |
随后验证 Docker 和 Kubernetes 两条控制链是否都可用:
|
1 2 3 |
docker ps kubectl config get-contexts kubectl get nodes |
若需要进入底层虚拟机排查问题,可以直接 SSH:
|
1 |
colima ssh |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 启动默认 Profile colima start # 启动并启用 Kubernetes colima start --kubernetes # 查看所有 Profile colima list # 停止当前实例 colima stop # 删除当前实例及其容器数据 colima delete -f |
当你修改了底层创建期参数,例如架构、运行时或虚拟机类型,而变更没有按预期生效时,最常见的原因不是配置语法错误,而是这些参数属于创建期决策。这类参数通常需要删除实例后重建。
很多“Cannot connect to the Docker daemon”问题,本质上不是 Colima 没有启动,而是本地 docker CLI 仍然连着别的 context。优先检查 docker context ls,再决定是否切到 colima。
使用 Docker runtime 时,在同一个 Colima 实例里构建或拉取的镜像可以被 Kubernetes 直接使用。这对本地调试非常方便,因为不需要把每次本地构建都重新推到远端仓库。若切换为 containerd runtime,则镜像管理方式会随之变化,调试路径也应按 containerd 的 namespace 语义理解。
network.address: true 让宿主机能直接访问虚拟机 IP,这对排障很有用,但常规应用访问仍应优先通过容器端口映射完成。应用层服务应该通过 -p HOST:CONTAINER 或 Kubernetes Service/Ingress 暴露,而不是把 VM IP 当成唯一访问入口。
如果你的目标只是“在 macOS 上拥有一个可脚本化、可重建、可启用 Kubernetes 的本地 Linux 容器环境”,Colima 基本就是最短路径。它尤其适合以下几类场景:
- 需要在 macOS 上长期维护本地 Docker 与 K3s 开发环境。
- 希望把运行时控制逻辑写进脚本、Makefile 或项目 bootstrap 流程。
- 需要按项目拆分多个隔离环境,例如一个轻量 Docker Profile 加一个启用 Kubernetes 的 Profile。
- 需要在 Apple Silicon 上兼顾原生 ARM 开发与部分 amd64 兼容需求。
Leave a Reply