/

在 macOS 上使用 Podman

前言

Podman 相較於 Docker 有許多優勢,本文為在 macOS 上初次使用 Podman 之簡短紀錄。過程中不探究太深入的 Podman 運作原理,單純依照一般運行 container 的思想來使用 Podman,看看會遇到什麼問題

安裝

Podman 與 Docker 一樣有桌面版本與非桌面版本,桌面版本多了 UI 可供查看,挑選一種喜歡的安裝即可

桌面版:

brew install podman-desktop

非桌面版:

brew install podman

檢查安裝版本:

podman version

1
2
Cannot connect to Podman. Please verify your connection to the Linux system using `podman system connection list`, or try `podman machine init` and `podman machine start` to manage a new Linux VM
Error: unable to connect to Podman. failed to create sshClient: Connection to bastion host (ssh://core@localhost:52568/run/user/1000/podman/podman.sock) failed.: dial tcp [::1]:52568: connect: connection refused

馬上遇到第一個問題,按照提示使用 podman machine init 來建立 Linux VM,運作原理猜測與 Docker on macOS 類似,不過 Docker Desktop 不用手動建立 VM

檢查是否有啟動 podman 需要的 VM:

podman machine list

1
2
NAME                     VM TYPE     CREATED         LAST UP        CPUS        MEMORY      DISK SIZE
podman-machine-default* qemu 37 minutes ago 3 minutes ago 1 2.147GB 10.74GB

可以看到 VM 已經被正確啟動(而且是使用 qemu 來啟動的),但依照報一樣的錯誤。後來查了 issue#12728 發現 Podman 嘗試使用 $SSH_AUTH_SOCK 變數設定的 address 來連線,可以取消設置該變數來解決該問題

1
unset SSH_AUTH_SOCK

(請依照你的 shell 放置到對應的檔案中)

接下來就可以看到 Podman 的版本資訊:

1
2
3
4
5
6
7
8
9
10
11
12
13
Client:
Version: 3.4.1
API Version: 3.4.1
Go Version: go1.17.2
Built: Wed Oct 20 05:14:42 2021
OS/Arch: darwin/amd64

Server:
Version: 4.1.1
API Version: 4.1.1
Go Version: go1.18.3
Built: Wed Jun 15 22:31:58 2022
OS/Arch: linux/amd64

使用

搜尋 Image:

podman search busybox

依照 output 可以發現預設是去搜尋 docker hub (hub.docker.com)

1
2
3
4
5
INDEX       NAME                                         DESCRIPTION                                                                                STARS       OFFICIAL    AUTOMATED
docker.io docker.io/library/busybox Busybox base image. 2660 [OK]
docker.io docker.io/rancher/busybox 0
docker.io docker.io/ibmcom/busybox 0
......

下載 Image 到本地:

podman pull busybox

執行 busybox image:

1
2
3
4
5
podman run -it --rm busybox
/ #
/ #
/ #
/ # exit

使用起來與 Docker 並無二異

發現

registries 設定檔案

故意拉一個不存在的 image

podman pull this-is-error

1
Resolving "this-is-error" using unqualified-search registries (/etc/containers/registries.conf.d/999-podman-machine.conf)

會發現 podman 透過 /etc/containers/registries.conf.d/999-podman-machine.conf 設定來決定完整的 Image 名稱(因為沒有指定 registry 理論上無法定位該 Image 位置)

到 VM 中檢查一下該檔案,就可以發現原來是預設找不到 image 就去 docker.io

1
2
3
4
5
6
7
8
9
10
11
❯ podman machine ssh
Connecting to vm podman-machine-default. To close connection, use `~.` or `exit`
Warning: Permanently added '[localhost.nctu.edu.tw]:52568' (ED25519) to the list of known hosts.
Fedora CoreOS 36.20220703.2.1
Tracker: https://github.com/coreos/fedora-coreos-tracker
Discuss: https://discussion.fedoraproject.org/tag/coreos

Last login: Thu Jul 7 01:50:15 2022 from 192.168.127.1
[core@localhost ~]$ cat /etc/containers/registries.conf.d/999-podman-machine.conf
unqualified-search-registries=["docker.io"]
[core@localhost ~]$

另外也發現其他 registries 的設定檔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[core@localhost containers]$ cd /etc/containers/registries.conf.d
[core@localhost registries.conf.d]$ ls
000-shortnames.conf 999-podman-machine.conf
[core@localhost registries.conf.d]$ cat 000-shortnames.conf
[aliases]
# almalinux
"almalinux" = "docker.io/library/almalinux"
"almalinux-minimal" = "docker.io/library/almalinux-minimal"
# Arch Linux
"archlinux" = "docker.io/archlinux/archlinux"
# centos
"centos" = "quay.io/centos/centos"
# containers
"skopeo" = "quay.io/skopeo/stable"
"buildah" = "quay.io/buildah/stable"
"podman" = "quay.io/podman/stable"
"hello" = "quay.io/podman/hello"
"hello-world" = "quay.io/podman/hello"
# docker
"alpine" = "docker.io/library/alpine"
"docker" = "docker.io/library/docker"
"registry" = "docker.io/library/registry"
"swarm" = "docker.io/library/swarm"

可以發現原來有些 image 是透過 alias 的方式來決定位置的

Port Forward 顯示不正常

1
2
3
4
5
6
7
8
9
10
❯ podman run -itd -p 8888:80 nginx
be5cb3e60f7b714e3b9c3462610675dd8cc7eaf0c048cdef7c3c8ea011979096

❯ podman run -itd -P nginx
9a2adbd0e86c0083ad0af5bccedc7f5dbaa3b64599c982368f8e64b301eac25d

❯ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be5cb3e60f7b docker.io/library/nginx:latest nginx -g daemon o... 17 seconds ago Up 18 seconds ago 0.0.0.0:0->0/tcp unruffled_bouman
9a2adbd0e86c docker.io/library/nginx:latest nginx -g daemon o... 3 seconds ago Up 4 seconds ago 0.0.0.0:0->0/tcp laughing_wiles

podman ps 中看不到被 binding 出來的 Ports 有些不方便

不過透過 podman inspect 還是找得出來

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
❯ podman inspect be5cb3e60f7b | grep -A5 "PortBindings"
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "8888"
}

❯ podman inspect 9a2adbd0e86c | grep -A5 "PortBindings"
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "45521"
}

至於一些複雜的用法暫時還沒有測試過,也不確定差異是否很大

我想最大的差異可能還是會在 networking 的部分,Podman 官方也有給出一頁介紹來說明 Podman 的網路架構

這部分就等到有時間研究完之後再來補上使用心得了 😅