最近我把本地的容器管理引擎切换到了 Podman,本篇文章来讲讲我为什么从 Docker 切换到 Podman。
兼容 Docker
Podman 对 Docker 的兼容非常好,Podman CLI 和 Docker CLI 命令几乎一致,这样就大大降低了切换成本,你甚至可以把 Podman CLI 就当作 Docker CLI 来用。
无守护进程
Docker 有一个守护进程 dockerd 负责管理容器、镜像和网络,Docker CLI 所有的指令都是通过 dockerd 来实际执行的。
Podman 却没有这样一个守护进程来处理,Podman CLI 会启动一个 conmon 进程来管理容器的生命周期,启动 conmon 后 Podman CLI 退出了,只有 conmon 带着它管理的容器作为系统进程保留了下来。
这种无守护进程的模式带来了很多好处:
- 我的系统不用一直启动一个 dockerd 守护进程,减少了系统资源的占用。
- 不会因为 dockerd 的异常退出导致所有容器崩溃
支持 rootless
Podman 支持以普通用户运行而 docker 默认情况下是以 root 用户来运行的。当发生容器逃逸
时 Docker 能拿到 root 权限而 Podman 会将影响范围限制到用户层面,降低了风险的影响范围。
更方便的网络设计
Podman rootless 默认使用的是 slirp4netns 它仅能给单容器提供网络服务,不能提供容期间的通讯,如果想容器间进行通讯就只能通过物理机映射端口或者把容器加入到同一个 pod 进行通讯了。
Podman 4.0 以后在 rootless 下也可以使用 netavark 了,netavark 相较于 slirp4netns 网络模式除了网络性能有了巨大的提升,也为容器间通讯增加了一种新的方式。
在性能方面 netavark 的性能已经可以达到 CNI Bridge(Container Network Interface,CNI) 的 80%-95% (取决于内核和硬件),已经满足大多数的线上部署需求,考虑到 rootless 的安全性的提升,netavark 还是非常值得选择的。
使用 netavark 实现容器间通讯,可以通过 podman network create
创建一个网络,在容器启动时把容器加入到网络中 如:
podman run -dt --name webserver --network podman1 -p 8081:80 quay.io/libpod/banner
如果你追求极致的性能或能够接受 rootful 的安全风险,也可以使用 CNI Bridge 模式。只需要在 podman run ...
的前面加 sudo ,Podman 会自动走 CNI Bridge 模式,通过 ifconfig
可以看到 Podman 创建的虚拟网卡 podman...
兼容 Kubernetes
我们知道 Kubernetes 有 pod 的概念,而 Podman 里也有 pod。 那这两者是不是有什么关联呢?其实是有的,Podman 可以用 podman play kube
直接从 Kubernetes YAML 启动本地容器,也可以通过 podman generate kube
来生成 Kubernetes 的配置文件。
如果以后想使用 Kubernetes,Podman 可以以更小的成本实现迁移。
总结
Podman 以更小的资源占用,更好的隔离效果,更方便的防火墙管理以及更好的兼容 Kubernetes 吸引了我,我觉得它值得我花一些时间深入的了解,虽然他不像某些文章夸张的那样终结 Docker ,但它的一些设计思路确实给我们带来了更多的可能。
引用
https://github.com/containers/podman/blob/main/docs/tutorials/basic_networking.md