Lima 容器化实战:在虚拟机中运行 containerd、Docker、Podman 与 Kubernetes
Lima 是一个专注于运行 Linux 虚拟机(Linux VM)的轻量级工具,其核心设计目标是让用户在虚拟机内部顺畅地运行容器工作负载。本文以 Lima 仓库中的 Containers 文档 为主线,系统讲解 Lima 为容器场景内置的自动文件系统共享与端口转发能力,并给出 containerd/nerdctl、Docker、Podman、Apptainer 以及 Kubernetes 集群(单节点与多节点)的完整可复现操作步骤。读完本文,你将掌握在 macOS、Linux 等主机上通过 Lima 一键启动容器环境,并在宿主机直接使用 docker、kubectl、podman 等原生命令的实战方法。
Lima 为容器而生的设计理念
根据官方文档的定位,Lima 的设计初衷就是"在虚拟机内部运行容器",并且默认自带两项与容器工作负载高度相关的自动化能力:
- 自动文件系统共享(automatic filesystem sharing):宿主机目录自动挂载进虚拟机,容器可以直接访问宿主机文件,详见 文件系统挂载文档;
- 自动端口转发(automatic port forwarding):虚拟机内容器监听的 localhost 端口自动暴露到宿主机,让宿主机用户像访问本机服务一样访问容器服务,详见 端口转发文档。
Lima 最初的目标是向 macOS 用户推广 containerd,这也是为什么 containerd 至今仍是 Lima 的默认容器引擎(内置集成)。但文档同时明确说明:当前版本的 Lima 同样支持其他容器引擎,并且不再依赖 macOS 宿主机——也就是说,Linux、Windows(WSL2)等主机同样可以使用 Lima 运行容器。
从仓库结构可以印证这一点:templates 目录 下针对不同容器引擎提供了独立模板(docker.yaml、podman.yaml、apptainer.yaml、k8s.yaml 等),每个模板通过 cloud-init 式的 provision 脚本在虚拟机内部完成引擎安装与配置,并通过 portForwards 将虚拟机内的容器 socket 暴露到宿主机。
底层支撑:文件系统共享与端口转发
容器场景依赖的两大基础设施——文件系统共享和端口转发——正是 Lima 的强项。这两份能力由 pkg/hostagent/mount.go 与 pkg/hostagent/port.go 等模块实现。
文件系统共享(mount)
Lima 支持多种挂载方式,不同版本默认值不同:
| Lima 版本 | 默认挂载类型 |
|---|---|
| < 0.10 | reverse-sshfs + Builtin SFTP server |
| >= 0.10 | reverse-sshfs + OpenSSH SFTP server |
| >= 0.17 | reverse-sshfs + OpenSSH SFTP server(QEMU),virtiofs(VZ) |
| >= 1.0 | 9p(QEMU,非 Windows),virtiofs(VZ) |
主要的挂载类型包括:
- reverse-sshfs:宿主机作为 SFTP 服务器,但不开放任何 TCP 端口——宿主机主动向虚拟机发起 SSH 连接,让虚拟机通过 stdin 连接到宿主机的 SFTP 服务。可通过
limactl start --mount-type=reverse-sshfs或 YAML 中mountType: "reverse-sshfs"启用。其sftpDriver默认为"openssh-sftp-server"(检测到 OpenSSH SFTP Server 时,否则为"builtin")。 - 9p:基于 QEMU 的 virtio-9p-pci 设备实现(注意与 virtio-fs 无关)。配置示例:
已知限制:CentOS、Rocky Linux、AlmaLinux 内核缺少vmType: "qemu" mountType: "9p" mounts: - location: "~" 9p: securityModel: null # passthrough / mapped-xattr / mapped-file / none protocolVersion: null # 9p2000 / 9p2000.u / 9p2000.L msize: null # 默认 128KiB cache: null # none / loose / fscache / mmapCONFIG_NET_9P_VIRTIO,与 9p 不兼容。 - virtiofs:macOS 上通过 Virtualization.Framework,Linux 上通过 virtiofsd(Rust 版本)实现。要求 Lima >= 0.14 且 macOS >= 13(vz 模式),Linux 上要求 Lima >= 0.17、QEMU 4.2.0+。
- wsl2:Windows 上使用 WSL2 原生磁盘共享,根磁盘默认出现在
/mnt/$DISK_LETTER(如/mnt/c/)。
此外,mountInotify(Lima >= 0.21,实验特性)可以让宿主机侧的 inotify 事件转发进虚拟机,对 9p、virtiofs 等挂载类型生效,仅对可写挂载(writable: true)启用。
端口转发(port forwarding)
Lima 支持两种端口转发器:SSH 与 GRPC。默认值曾在 v1.0 改为 GRPC、v1.0.1 因稳定性回退为 SSH、v1.1 起又恢复为 GRPC。
- SSH 转发:
LIMA_SSH_PORT_FORWARDER=true limactl start。优点:有 VSOCK 时性能优于 GRPC;缺点:不支持 UDP 转发、宿主机需为 SSH master 派生子进程。Lima >= 2.0 时,VZ 虚拟机且 systemd >= v256(如 Ubuntu 24.10+)会使用 AF_VSOCK 通信,转发速度大幅提升;可通过--set '.ssh.overVsock=false'关闭。 - GRPC 转发:
LIMA_SSH_PORT_FORWARDER=false limactl start(Lima >= 1.0)。复用宿主与虚拟机的 GRPC 通道为每个转发请求建立隧道,同时支持 TCP 与 UDP,无 VSOCK 时性能更好。
容器场景中,端口转发正是"宿主机直接 docker run -p 127.0.0.1:8080:80 即可访问虚拟机内容器"的关键机制。
默认集成:containerd 与 nerdctl
containerd 是 Lima 的内置集成,nerdctl(contaiNERD CTL)是其配套的命令行客户端,用法与 docker 命令高度相似。
Rootless 模式(默认)
lima nerdctl run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine
或使用独立的包装命令:
nerdctl.lima run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine
- 通过
make install安装 Lima 时,nerdctl.lima命令也会以nerdctl的名称提供; - 通过
brew install lima安装时,可自行创建别名或软链接:alias nerdctl=nerdctl.lima。
Rootful 模式
limactl start --containerd=system
lima sudo nerdctl run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine
其中 --containerd=system 让 containerd 以系统服务方式运行(rootful),否则默认以用户服务方式运行(rootless)。
关闭 containerd
如果希望虚拟机内完全不启用 containerd,可在启动实例时指定:
limactl start --containerd=none
使用 Docker 模板
Lima 提供 template:docker(rootless)与 template:docker-rootful(rootful)两个内置模板。启动后通过环境变量把宿主机 docker CLI 指向虚拟机内的 Docker socket:
limactl start template:docker
export DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
docker run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine
rootful 版本只需把模板换成 template:docker-rootful、实例名换成 docker-rootful。
从 templates/docker.yaml 源码可以看到该模板的实现要点:
- 模板组合了
template:_images/ubuntu-lts与template:_default/mounts; - Lima 不托管 Docker 场景下的 containerd,显式设置
containerd.system: false、containerd.user: false; - 通过
provision脚本依次完成:写入host.docker.internal解析、安装 Docker、禁用并 mask 系统级 docker 服务以启用 rootless、通过dockerd-rootless-setuptool.sh install配置 rootless 模式; - 通过
portForwards将虚拟机内/run/user/{{.UID}}/docker.sock映射为宿主机{{.Dir}}/sock/docker.sock,这正是DOCKER_HOST指向的地址; - 模板还通过
param.containerdSnapshotter(默认true)开启 containerd 镜像快照器特性;若在 Apple Silicon 上启用了 Rosetta,还支持以--device=lima-vm.io/rosetta=cached运行 x86_64 容器并使用 Rosetta AOT 缓存。
启动完成后,模板 message 还会提示可创建 docker context:
docker context create lima-docker --docker "host=unix://{{.Dir}}/sock/docker.sock"
docker context use lima-docker
docker run hello-world
使用 Podman 模板
Podman 提供 rootless 与 rootful 两套模板,且支持三种使用方式:在虚拟机内用 podman、在宿主机用 podman --remote、在宿主机直接用 docker(兼容 Docker CLI)。
Rootless 方式(templates/podman.yaml,基于 Fedora):
limactl start template:podman
在虚拟机内使用:
limactl shell podman podman run -d --name nginx -p 127.0.0.1:8080:80 docker.io/library/nginx:alpine
在宿主机使用 podman --remote:
export CONTAINER_HOST=$(limactl list podman --format 'unix://{{.Dir}}/sock/podman.sock')
podman --remote run -d --name nginx -p 127.0.0.1:8080:80 docker.io/library/nginx:alpine
在宿主机直接使用 docker 命令:
export DOCKER_HOST=$(limactl list podman --format 'unix://{{.Dir}}/sock/podman.sock')
docker run -d --name nginx -p 127.0.0.1:8080:80 docker.io/library/nginx:alpine
Rootful 方式把模板换成 template:podman-rootful、实例名换成 podman-rootful,虚拟机内命令改为 limactl shell podman-rootful sudo podman run ...,宿主机侧 CONTAINER_HOST/DOCKER_HOST 的实例名同步替换。
从模板源码可以看到 Podman 的实现路径:provision 脚本通过 dnf -y install --best podman 安装 Podman,并以用户服务方式启用 podman.socket;portForwards 将虚拟机内 /run/user/{{.UID}}/podman/podman.sock 映射为宿主机 sock/podman.sock。模板还提示可用 podman system connection add lima-podman "unix://{{.Dir}}/sock/podman.sock" 建立远程连接并设为默认。
使用 Apptainer 模板
Apptainer(Singularity 的继任者)同样提供 rootless/rootful 两套模板。与 Docker/Podman 的守护进程模型不同,Apptainer 直接在虚拟机内运行容器:
limactl start template:apptainer
limactl shell apptainer apptainer run -u -B $HOME:$HOME docker://alpine
rootful 版本:
limactl start template:apptainer-rootful
limactl shell apptainer-rootful apptainer run -u -B $HOME:$HOME docker://alpine
其中 -u 以非 root 用户运行,-B $HOME:$HOME 将当前用户主目录绑定挂载进容器,docker://alpine 表示直接从 Docker Hub 拉取镜像。对应模板位于 templates/apptainer.yaml 与 templates/apptainer-rootful.yaml。
在 Lima 中运行 Kubernetes
Kubernetes 章节提供了单节点与多节点两种部署形态,支持 kubeadm、k3s、k0s、RKE2(experimental)、Usernetes(experimental)等多种发行版。
单节点集群
以 kubeadm(模板 template:k8s)为例:
limactl start template:k8s
export KUBECONFIG=$(limactl list k8s --format 'unix://{{.Dir}}/copied-from-guest/kubeconfig.yaml')
kubectl create deployment nginx --image nginx:alpine
kubectl create service nodeport nginx --node-port=31080 --tcp=80:80
k3s 与 k0s 的流程完全一致,只需分别使用 template:k3s、template:k0s 并把实例名对应替换。RKE2 使用实验模板:
limactl start template:experimental/rke2
export KUBECONFIG=$(limactl list rke2 --format 'unix://{{.Dir}}/copied-from-guest/kubeconfig.yaml')
kubectl create deployment nginx --image nginx:alpine
Usernetes(rootless Kubernetes,模板 template:experimental/u7s)默认不提供 NodePort,改用 kubectl port-forward:
limactl start template:experimental/u7s
export KUBECONFIG=$(limactl list u7s --format 'unix://{{.Dir}}/copied-from-guest/kubeconfig.yaml')
kubectl create deployment nginx --image nginx:alpine
kubectl port-forward deployments/nginx 8080:80
从 templates/k8s.yaml 源码可见,kubeadm 模板基于 Ubuntu LTS,依次完成:加载 overlay/br_netfilter 内核模块、配置 net.bridge.bridge-nf-call-iptables 等 sysctl、安装 kubeadm/kubelet/kubectl、为 containerd 配置 systemd cgroup 驱动与 CRI、执行 kubeadm init、安装 flannel 网络插件、移除 control-plane 污点,并通过 copyToHost 将 config.localhost(server 地址已改写为 127.0.0.1 的 kubeconfig)复制到宿主机 {{.Dir}}/copied-from-guest/kubeconfig.yaml。模板还开放了 proxy、mirror、stability、release、version、flannelVersion 等参数,便于在受限网络环境下使用代理与镜像仓库。
多节点集群
多节点集群通过将多个虚拟机接入 lima:user-v2 网络实现。目前支持多节点模式的模板包括 k8s(Lima v2.0 起)与 k3s(Lima v2.1 起)。
Lima v2.0(kubeadm 手工 join):先启动控制平面节点并生成 join 命令:
limactl start --name k8s --network lima:user-v2 template:k8s
limactl shell k8s sudo kubeadm token create --print-join-command
再启动工作节点(替换 <JOIN_COMMAND_FROM_ABOVE>):
limactl start --name k8s-1 --network lima:user-v2 template:k8s
limactl shell k8s-1 sudo bash -euxc "kubeadm reset --force ; ip link delete cni0 ; ip link delete flannel.1 ; rm -rf /var/lib/cni /etc/cni"
limactl shell k8s-1 sudo <JOIN_COMMAND_FROM_ABOVE>
Lima v2.1(kubeadm 参数化):控制面启动后同样取得 join 参数:
limactl start --name k8s --network lima:user-v2 template:k8s
limactl shell k8s sudo kubeadm token create --print-join-command
工作节点通过 --param 传入参数(对应 k8s.yaml 中 JoinConfiguration 的 url、token、discoveryTokenCaCertHash):
limactl start --name k8s-1 --network lima:user-v2 template:k8s \
--param url="https://<ADDRESS_FROM_ABOVE>" --param token="<TOKEN_FROM_ABOVE>" \
--param discoveryTokenCaCertHash="<DISCOVERY_TOKEN_CA_CERT_HASH_FROM_ABOVE>"
Lima v2.1(k3s):先启动控制面并取得 url 与 token:
limactl start --name k3s --network lima:user-v2 template:k3s
printf "https://lima-%s.internal:6443\n" k3s
limactl shell k3s sudo cat /var/lib/rancher/k3s/server/node-token
再启动工作节点:
limactl start --name k3s-1 --network lima:user-v2 template:k3s \
--param url="<URL_FROM_ABOVE>" --param token="<TOKEN_FROM_ABOVE>"
小结
围绕 Containers 文档,Lima 为容器工作负载提供了"虚拟机 + 自动挂载 + 自动端口转发"的一体化底座:默认内置 containerd/nerdctl,并针对 Docker、Podman、Apptainer、Kubernetes 提供了开箱即用的官方模板。无论是希望在 macOS 上获得接近原生的容器体验,还是在 Linux/Windows 上构建隔离的容器开发环境,甚至是快速拉起一套单节点或多节点 Kubernetes 集群用于学习与测试,都可以通过 limactl start template:<name> 一行命令完成。若要进一步定制,建议直接阅读仓库中的 templates 目录与 文件系统挂载、端口转发 两份配置文档。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.24 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python670
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#230
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python52874
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go22545
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java36351