阅读 1721

苹果 M1 上使用 Podman 替换 Docker Desktop

苹果 M1 上使用 Podman 替换 Docker Desktop

前言

随着近几年微服务的兴起,加上云原生的蓬勃发展,大家已经对 Docker 不在陌生。Docker Desktop 是一个可以让大家在非 Linux 系统上,使用 Docker 进行开发调试的工具,非常容易上手,安装也非常简单。在苹果 m1 芯片出来后,Docker Desktop 第一时间发布了 beta 版本,也在前一段时间升级成了正式版。但是使用过程中还是有一些问题,例如运行一些 x86 的镜像会出错。最近 Docker 公司改变了收费模式,虽然说是不影响个人/小企业开发者,但谁叫咱是大公司,还是要看看替代方案的。

Podman 是什么

Podman 是一个 RedHat 公司发布的开源容器管理工具,初衷就是 docker 的替代品,在使用上与 Docker 的相似,但又有着很大的不同。它与 Docker 的最大区别是架构。Docker 是以 C/S 架构运行的,我们平时使用的 docker 命令是只一个命令行前端,它需要调用 dockerd 来完成实际的操作,而 dockerd 默认是一个有 root 权限的守护进程。Podman 不需要守护进程,直接通过 fork/exec 的形式启动容器,不需要 root 权限。

关于 Docker 和 Podman 的比较,可以进一步查看:

  •  podman 2.0 改进与systemd的集成

  •  为什Podman值得一试

  •  Podmain rootless 的缺点

使用 Podman

在 mac 上使用 homebrew 安装 Podman 非常简单。同 Docker Desktop 一样,在 mac 上 podman 也需要虚拟机才能运行容器。podman 使用 qemu 创建 Linux 的虚拟机,所以需要一并安装,命令如下。由于国内网络问题,要有足够的耐心。

➜ brew install podman qemu1.

对于 m1 的芯片,目前 qemu 正式版本还没有支持苹果的 Hypervisor.framework 功能,如果想要 hvf 来加速虚拟机运行,就需要编译带 patch 的 qemu 版本。当然也可以用别人做好的,如下命令

# Apple silicon➜ brew install simnalamburt/x/podman-apple-silicon1.2.

安装好了这两个工具后,需要先初始化虚拟机,才能继续使用。因为要下载 coreos 的镜像,又是漫长的等待。

➜ podman machine init
Downloading VM image: fedora-coreos-34.20210901.dev.0-qemu.aarch64.qcow2.xz [>---------------------------------------] 17.5MiB / 563.0MiB1.2.

初始化完成后,还需要打开虚拟机

➜ podman machine start
INFO[0000] waiting for clients...
INFO[0000] listening tcp://0.0.0.0:7777
INFO[0000] new connection from  to /var/folders/78/svdq05m94rq29_rt9z6p_n8m0000gn/T/podman/qemu_podman-machine-default.sock
Waiting for VM ......1.2.3.4.5.6.

关于虚拟机还有如下命令

# 查看虚拟机状态➜ podman machine list
NAME                     VM TYPE     CREATED       LAST UP
podman-machine-default*  qemu        2 hours ago  Currently running# 停止虚拟机➜ podman machine stop# 删除虚拟机➜ podman machine rm# 登录进虚拟机内部➜ podman machine sshConnecting to vm podman-machine-default. To close connection, use `~.` or `exit`Warning: Permanently added '[localhost]:51569' (ECDSA) to the list of known hosts.
Fedora CoreOS 34.20210901.dev.0
Tracker: https://github.com/coreos/fedora-coreos-tracker
Discuss: https://discussion.fedoraproject.org/c/server/coreos/

Last login: Mon Sep  6 13:28:43 2021 from 192.168.127.1[core@localhost ~]$1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.

如果启动没有报错,那么就可以使用 podman 替代 docker 命令了,下列常用的命令都可以运行。还可以通过 alias docker=podman 命令无缝替换。

➜ podman pull my-image:latest
➜ podman run my-image:latest --name my-container
➜ podman ps➜ podman rm my-container1.2.3.4.

遇到的问题

在使用的过程中碰到两个诡异的问题

  1. podman machine init 执行失败,打印 Error: exit status 1 。如果忽略它,podman machine start 时会报如下日志

INFO[0000] waiting for clients...
INFO[0000] listening tcp://0.0.0.0:7777
INFO[0000] new connection from to /var/folders/78/svdq05m94rq29_rt9z6p_n8m0000gn/T/podman/qemu_podman-machine-default.sock
Waiting for VM ...
qemu-system-aarch64: -drive file=/Users/aaa/.local/share/containers/podman/machine/qemu/podman-machine-default_ovmf_vars.fd,if=pflash,format=raw: Could not open '/Users/aaa/.local/share/containers/podman/machine/qemu/podman-machine-default_ovmf_vars.fd': No such file or directory
Error: dial unix /var/folders/78/svdq05m94rq29_rt9z6p_n8m0000gn/T/podman/podman-machine-default_ready.sock: connect: connection refused
ERRO[0003] cannot receive packets from , disconnecting: cannot read size from socket: EOF
ERRO[0003] cannot read size from socket: EOF1.2.3.4.5.6.7.8.

查了一番之后发现,在初始化虚拟机的时候,用到了dd命令。这个命令苹果版的和gnu版的实现不一致,苹果版的bs参数只接收小写单位,而gnu版的只接收大写的单位。而我用的是 gnu 版本的,所以执行到这里一定会错。随把它从 PATH 中移出去,问题就解决了。

// [https://github.com/containers/podman/blob/main/pkg/machine/qemu/options_darwin_arm64.go#L26](https://github.com/containers/podman/blob/main/pkg/machine/qemu/options_darwin_arm64.go#L26)func (v *MachineVM) prepare() error {
	ovmfDir := getOvmfDir(v.ImagePath, v.Name)
	cmd := []string{"dd", "if=/dev/zero", "conv=sync", "bs=1m", "count=64", "of=" + ovmfDir}
	return exec.Command(cmd[0], cmd[1:]...).Run()}1.2.3.4.5.6.
  1. 运行 podman run nginx 报错 Error: short-name resolution enforced but cannot prompt without a TTY

这个错误看起来很奇怪,得先了解什么 short-name 才能理解。它指的是镜像的名字,镜像名字前没有域名的就是短名字。docker 碰到这种情况会在前面加上  docker.io/ ,但是 podman 没有这个操作。据说是因为安全原因,避免拉错镜像,所以给它做了二次确认的功能,但是因为使用的控制台不支持,所以没有展示出来,直接失败了。这个功能还可以修改配置文件控制是否开启。

但是奇怪的是,执行 centos 不会有这样的提示,执行 nginx 就会报错。这是因为 podman 对一些系统级的镜像有特殊对待,它维护了一个镜像名到镜像仓库的对应关系。详见:

  •  镜像的短名称

  •  收集镜像短名称的仓库

  •  从 docker 迁移到 Podman

  1. podman run -p 不能暴露端口

➜ podman run --rm -it --publish 8000:80 docker.io/library/nginx:latest &
➜ curl http://localhost:8000

curl: (7) Failed to connect to localhost port 8000: Connection refused1.2.3.4.

这是 podman 转发端口端口的 bug,预计 v3.3.2 会修复。

有一个 workaround 的办法是,在执行的时候加上--network bridge 。例如:

➜ podman run --rm -it --publish 8000:80 --network bridge docker.io/library/nginx:latest1.

 https://github.com/containers/podman/issues/11396

还有个办法是修改配置文件,文件路径是~/.config/containers/containers.conf,在[containers] 内加上rootless_networking = "cni"

总结

在 M1 上体验 podman 的过程不够平顺,还没有覆盖全部功能就已经碰到不少问题。除了本身 bug 不少外,它使用的 Coreos 镜像还是 beta 版,也存在不稳定的可能性。但是,Podman 的代码比较规整,能比较快的阅读并定位问题,社区对问题的修复速度也很快。背后还有红帽这样的大公司支撑,还是很有希望达到一个稳定状态。

关于运行速度,感觉很赞,没有完全虚拟机的笨重感。

Podman 相对于 docker 还多了一些的功能,比如 pod 功能,还需要进一步深度体验。%


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐