跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Shell / Bash

MacOS 下通过 HyperKit 运行 Podman 的方法

MacOS 下无法直接运行 Podman,需借助虚拟化技术。演示利用 HyperKit 和 Multipass 创建轻量级 Ubuntu 虚拟机,在其中安装 Podman 并开启远程 API。客户端通过 SSH 免密登录连接虚拟机中的 Podman Socket,实现类似 Docker Desktop 的体验。相比 Docker Desktop,此方案资源占用更低,适合需要在 macOS 上高效使用 Podman 的用户。

猫巷少女发布于 2025/1/19更新于 2026/6/919 浏览
MacOS 下通过 HyperKit 运行 Podman 的方法

前言

Podman 是一个无守护程序与 Docker 命令兼容的下一代 Linux 容器工具,该项目由 RedHat 主导。Podman 一直以来只能跑在 Linux 系统上,macOS 和 Windows 只能通过 CLI 远程连接 Podman 的 API 来管理容器。对于 Podman 来说,想要在 macOS 上运行也只能通过虚拟化来实现。

HyperKit 介绍

HyperKit 是一个具有 hypervisor 能力的轻量级虚拟化工具集,包含了基于 xhyve(The BSD Hypervisor)的完整 hypervisor。HyperKit 设计成上层组件诸如 VPNKit 和 DataKit 的接口。xhyve 是 基于 bhyve 的 Mac OS X 移植版本。

我们知道,Docker 在 Linux 上利用了 Linux 原生支持的容器方式实现资源和环境的隔离,直接利用宿主内核,性能接近原生。然而,在 macOS 上却仍然需要虚拟化的技术。早期的 Docker 干脆直接在开源的 VirtualBox 中构建虚拟机,性能低下。后期的 Docker 基于轻量化的虚拟化框架 HyperKit 开发,据说性能得到很大提升。

本文将介绍如何通过 HyperKit 来使用 Podman。方法也很简单,先通过 Hyperkit 创建一个轻量级虚拟机,然后在虚拟机中安装 Podman,并开启 remote API,最后在本地通过 CLI 连接虚拟机中的 Podman。这和 macOS 中的 Docker 实现原理是一样的,只不过 Podman 是没有 Daemon 的,与 Docker 相比可以节省不少资源。

2. 安装 HyperKit

你可以自己下载源代码编译 HyperKit,但我不建议这么做,不同的 macOS 版本会遇到各种各样的错误。我这里推荐两种超级简单的方法:

  1. 直接通过安装 Docker 来获得 HyperKit,因为 Docker Desktop on Mac 就是基于 HyperKit 实现的,所以安装 Docker Desktop on Mac 就能够获得完整的 HyperKit 运行环境。整个过程会非常顺畅和简单。安装完 Docker 之后可以永远不用打开 Docker,直接使用 HyperKit 就好。或者你可以直接卸载 Docker,卸载之前先把 hyperkit 二进制文件备份出来,因为卸载 Docker 也会删掉 hyperkit 二进制文件。
  2. 直接通过安装 Multipass 来获得 HyperKit。Multipass 是 Canonical 公司(Ubuntu)开发的基于不同操作系统内建原生 Hypervisor 实现的工作站。由于 Windows(Hyper-V),macOS(hyperkit)和 Linux(KVM)都原生支持 hypervisor,这样通过 multipass shell 命令就能够在一个 shell 中实现创建运行 Ubuntu 虚拟机。在 macOS 平台,默认的后端是 hyperkit,需要 macOS Yosemite (10.10.3) 以上版本并且需要安装在 2010 以后生产的 Mac 设备。安装方法很简单:
$ brew cask install multipass 

安装好了之后可以在 /Library/Application Support/com.canonical.multipass/bin/ 目录下找到 hyperkit 二进制文件。

3. 创建虚拟机

你可以直接通过 hyperkit 来创建虚拟机,但参数比较复杂,有兴趣的自己研究吧。我推荐直接通过 multipass 来创建,命令特别简单:

$ multipass launch -c 2 -d 10G -m 2G -n podman 
  • -n : 指定启动实例名字
  • -c : 分配 CPU 数量
  • -d : 设置磁盘容量
  • -m : 设置内存容量

第一次启动虚拟机的时候会去拉取镜像,国内网速可能会很慢。

查看已经启动的虚拟机:

$ multipass list Name State IPv4 Image podman Running 192.168.64.2 Ubuntu 20.04 LTS 

进入虚拟机:

$ multipass shell podman Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-52-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Sun Nov 8 19:30:29 CST 2020 System load: 0.0 Processes: 119 Usage of /: 13.4% of 11.46GB Users logged in: 0 Memory usage: 11% IPv4 address for enp0s2: 192.168.64.2 Swap usage: 0% 0 updates can be installed immediately. 0 of these updates are security updates. Last login: Sun Nov 8 17:38:31 2020 from 192.168.64.1 ubuntu@podman:~$

4. 安装 Podman

在虚拟机中安装 Podman:

ubuntu@podman:~$ . /etc/os-release ubuntu@podman:~$ echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list ubuntu@podman:~$ curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key | sudo apt-key add - ubuntu@podman:~$ sudo apt-get update ubuntu@podman:~$ sudo apt-get -y upgrade ubuntu@podman:~$ sudo apt-get -y install podman 

5. 建立 Podman Socket

Podman 依赖于 systemd 的 socket activation 特性。假设 Daemon B 依赖于 Daemon A,那么它就必须等到 Daemon A 完成启动后才能启动。socket activation的思想就是:Daemon B 启动时其实并不需要 Daemon A 真正运行起来,它只需要 Daemon A 建立的 socket 处于 listen 状态就 OK 了。而这个 socket 不必由 Daemon A 建立,而是由 systemd 在系统初始化时就建立。当 Daemon B 发起启动时发起连接,systemd 再将 Daemon A 启动,当 Daemon A 启动后,再将 socket 归还给 Daemon A。

Podman 会通过 podman.socket 先创建一个处于监听状态的 socket 文件 /run/podman/podman.sock,当有进程向该 socket 发起连接时,systemd 会启动同名的 service:podman.service,以接管该 socket。先看看 podman.socket 和 podman.service 长啥样:

ubuntu@podman:~$ sudo systemctl cat podman.socket # /lib/systemd/system/podman.socket [Unit] Description=Podman API Socket Documentation=man:podman-system-service(1) [Socket] ListenStream=%t/podman/podman.sock SocketMode=0660 [Install] WantedBy=sockets.target ubuntu@podman:~$ sudo systemctl cat podman.service # /lib/systemd/system/podman.service [Unit] Description=Podman API Service Requires=podman.socket After=podman.socket Documentation=man:podman-system-service(1) StartLimitIntervalSec=0 [Service] Type=notify KillMode=process ExecStart=/usr/bin/podman system service 

设置开机自启 podman.socket,并立即启动:

ubuntu@podman:~$ sudo systemctl enable podman.socket --now 

确认 socket 是否正处于监听状态:

ubuntu@podman:~$ podman --remote info host: arch: amd64 buildahVersion: 1.16.1 cgroupManager: systemd cgroupVersion: v1 conmon: package: 'conmon: /usr/libexec/podman/conmon' path: /usr/libexec/podman/conmon version: 'conmon version 2.0.20, commit: ' cpus: 2 ...

客户端 CLI 设置

接下来所有的设置,如不作特殊说明,都在 macOS 本地终端执行。

Podman 远程连接依赖 SSH,所以需要设置免密登录,先生成密钥文件:

$ ssh-keygen -t rsa # 一路回车到底 

然后将本地的公钥 ~/.ssh/id_rsa.pub 追加到虚拟机的 /root/.ssh/authorized_keys 文件中。

安装 Podman CLI:

$ brew install podman 

添加远程连接:

$ podman system connection add ubuntu --identity ~/.ssh/id_rsa ssh://root@192.168.64.2/run/podman/podman.sock 

查看已经建立的连接:

$ podman system connection list Name Identity URI podman* /Users/Ryan/.ssh/id_rsa ssh://root@192.168.64.2:22/run/podman/podman.sock 

由于这是第一个连接,所以被直接设置为默认连接(podman 后面加了 *)。

测试远程连接是否可用:

$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman pull nginx:alpine Trying to pull docker.io/library/nginx:alpine... Getting image source signatures Copying blob sha256:188c0c94c7c576fff0792aca7ec73d67a2f7f4cb3a6e53a84559337260b36964 Copying blob sha256:9dd8e8e549988a3e2c521f27f805b7a03d909d185bb01cdb4a4029e5a6702919 Copying blob sha256:85defa007a83f817a511310cca4aca6681b721d44dc9428265959d75 Copying blob sha256:f2dc20663cd74df8fea6d41d3cefe209979e8dbcceb4893ec9eadcc10bc14 Copying blob sha256:0ca2de669571a8bd36e41f03fffa98e53819be7575cb8cd1cb0705b845939 Copying config sha256:e5dcd7aa4b5e5d2df8152b9e58aba32005edd9b269816f5d8b7ced535743d16c Writing manifest to image destination Storing signatures e5dcd7aa4b5e5d2df8152b9e58aba32005edd9b269816f5d8b7ced535743d16c $ podman image ls REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/nginx alpine e5dcd7aa4b5e 2 days ago 23.3 MB 

现在我们就可以直接在本地用 podman 愉快地玩耍了!

如果你建立了多个连接,可用使用 --connection 参数指定远程连接,或者使用 podman system connection default <NAME> 来设置默认的远程连接。

最后,我们来看看 hyperkit 的内存占用:

物理内存只占用了 921M,如果你觉得这个内存占用很多,不妨去对比下 Docker Desktop 的内存占用。

目录

  1. HyperKit 介绍
  2. 2. 安装 HyperKit
  3. 3. 创建虚拟机
  4. 4. 安装 Podman
  5. 5. 建立 Podman Socket
  6. 客户端 CLI 设置
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于 Vue3 与 Spring Boot 的若依框架快速搭建指南
  • Linux 进程信号处理机制与操作系统运行原理解析
  • Java 与 Kotlin 泛型核心难点解析
  • Ubuntu 20.04 安装 Ollama 及 Open WebUI 部署大语言模型教程
  • LLaMA-Factory YAML 配置详解与参数调优实战
AI 编程工具定价对比:Cursor、Windsurf、Kiro、Zed 及 VS Code
  • Spring AI 深入解析 MCP 上下文协议、开发与部署安全实践
  • 小米 MiLoco 本地协同智能助手部署实战
  • Rust 异步代码的测试与调试实践
  • Java 基础进阶:数据类型与面向对象
  • Stable Diffusion 3.5 FP8 在博物馆展览视觉设计中的应用
  • OpenClaw QQ 机器人接入指南
  • OpenClaw QQ 机器人接入完整指南
  • 大语言模型经典论文清单:OpenAI、Google 与开源系列
  • ThreadLocal 原理与内存泄漏机制详解
  • OpenClaw Skills 安装与实战:打造你的 AI 技能工具箱
  • 自律计划第九期回顾与思考
  • OpenVLA 深度解析:Prismatic VLM 架构下的离散化动作预测
  • GitHub Copilot 最新演进:从代码补全到需求理解
  • 动态规划详解:核心思想与经典案例
  • 相关免费在线工具

    • Base64 字符串编码/解码

      将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

    • Base64 文件转换器

      将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

    • Markdown转HTML

      将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

    • HTML转Markdown

      将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

    • JSON 压缩

      通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

    • JSON美化和格式化

      将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online