在 Laptop 環境使用 Podman (含 Windows & MacOS)

在 Laptop 環境使用 Podman (含 Windows & MacOS)

2020年初曾經試過在 Mac 上面直接跑 Podman,可惜那時還沒有找到足夠的教學資料引導,就放棄了在我的 Mac 上使用 Podman 做打包,最近因為要回學校講課,就找了一找,沒想到還真的被我找到這篇文章:在 macOS 中使用 Podman,但文章內容有些指令的部分需要勘誤,索性寫一篇來紀錄過程。

Podman 介紹以及 Podman,和 Docker 差異點

差異的部分其實已經有許多人寫過相關的文章了,我這邊重新整理一下幾個重點:

這是 Docker 的架構圖

upload successful

這是 podman 的架構圖

upload successful
圖源來自:Avengers of Container World - Episode 1: Podman Hands-On

1. 沒有 daemon, 預防單點故障(SPOF,Single Point of Failure)

最主要的差異在於 Podman 並不是透過 daemon 服務的方式去跟 kernel 溝通,當初 Docker 設計這個架構是基於傳統的 client/server 架構,Docker daemon 會負責控制所有 child process,所以當這個 Docker daemon 一死,底下的 child process,也就是那些容器,會全部掛掉

2. 不需要 Root User 使用權限也可以運行容器

有關於 Rootless Container 的概念,Red Hat 的 Principal Product Manager - Containers -Scott McCarty 有給出一篇 understanding-root-inside-and-outside-container解釋為何 Rootless Container 對企業的環境來說至關重要。

主要也是因為沒有統一的 Daemon 去創建 contianer process(不是用 rootlinux 創建檔案等使用上會有限制),所以使用 podman 在創建 container 時可以自由使用不同 uid & gid 去管理這個 container process。

3. podman 為啥叫 podman,因為它可以跑 pods

Docker 可以做到的事情,podman 都可以做到。所以乾脆有使用者直接 alias podman='docker' 也不意外(笑) 。但有一點是,podman 可以跑 pods:

意味著我可以一次在 pod 裡面運行N個容器,並且也可以透過 podman 管理!

在非 Linux 平台使用 Podman 要注意的事

很遺憾的是,現在在非 Linux 的平台上面,Podman 還是要透過 Client 連進虛擬機的方式管理容器。

Podman 和 Docker 在 Linux 上都利用了 Linux Kernel 原生支援的容器方式實現資源和環境的隔離。然而在 MacOS 和 Windows 的環境下,在最初我們仍需要先行安裝 VirtualBox 或是 Vagrant 才能開啟虛擬機(比方說 ubuntu, centos),並且在上面運行容器,在 Windows 環境下還要先開啟 Hyper-V,實際的操作方法可以參考 浦島太郎的水族缸 - WSL, Docker, Virtual Box on Hyper-V

但後來 Docker 改採用輕量的虛擬化框架 HyperKit 改善在 MacOS 上運行容器的效能,而在 Windows 上,始於 Windows 1809 版開始支援容器 以 Process 隔離模式 的方式啟動來改善效能,或是可以參照這篇 How to install Docker on Windows 10 or 7 without Hyper-V 用 Docker Toolbox 來運行容器。

而 Podman 在工具的發展完整度和對兩大平台整合度目前來講還不及 Docker 完備,但在 Mac 上我們可以使用 HyperKit、在 Windows 上面我們也可以善用 WSL 建立虛擬機 來使用,或者你也可以在 MacOS 上用 Paralles 開 Windows 虛擬機體驗巢狀虛擬化(X。

在 Mac 上用 Podman Client

這篇文章主要參考來自掘金繁體版 - 在 macOS 中使用 Podman,我會直接安裝 multipass 使用 MacOS 的 Hyperkit 去幫我建立一個 ubuntu VM。

  1. 必須先安裝 Podman Client
1
2
3
4
5
brew install --cask podman

# 這裡會下載最新版 podman v2.2.1,如果之前安裝過,請重新安裝
brew reinstall podman
brew link podman
  1. 再來安裝 multipass
1
brew  install --cask multipass
  1. 開一個新的 Ubuntu VM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 這邊建議是 disk 給到 20GB, memory 給到至少3G,否則你會發現容器根本跑不起來
# -n : 指定啟動 VM 的名字
# -c : 分配 CPU 數量
# -d : 設定磁碟容量
# -m : 設定記憶體容量
multipass launch -c 2 -d 10G -m 2G -n podman


# 列出正在運行的虛擬機
hazel@Hazels-MacBook-Pro > ~ > multipass list
Name State IPv4 Image
podman Running 192.168.64.3 Ubuntu 20.04 LTS

# 透過 multipass shell 進到名為 podman 的 VM 內
hazel@Hazels-MacBook-Pro > ~ > multipass shell podman
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-60-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

System information as of Wed Jan 13 01:59:09 CST 2021

System load: 0.67 Processes: 123
Usage of /: 13.0% of 9.52GB Users logged in: 0
Memory usage: 9% IPv4 address for enp0s2: 192.168.64.3
Swap usage: 0%


1 update can be installed immediately.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable


To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
  1. 在 VM 內下載 Podman
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/ /
ubuntu@podman:~$ curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key | sudo apt-key add -
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1093 100 1093 0 0 634 0 0:00:01 0:00:01 --:--:-- 633
OK

# 套件更新升級
ubuntu@podman:~$ sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease
Get:2 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
Get:3 http://security.ubuntu.com/ubuntu focal-security InRelease [109 kB]
Get:4 https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04 InRelease [1634 B]
...
Reading package lists... Done
ubuntu@podman:~$ sudo apt-get -y upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
...

# 安裝 podman
ubuntu@podman:~$ sudo apt-get -y install podman
  1. 檢查 Podman 的 Socket 是否處於 listeng 狀態
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 查看 podman.socket 檔案是否處於監聽(listening)狀態
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

# systemd 會啟動同名的 service:podman.service,以接管該 podman.socket
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
Environment=LOGGING="--log-level=info"
ExecStart=/usr/bin/podman $LOGGING system service

# 設定開機啟動 podman.socket
ubuntu@podman:~$ sudo systemctl enable podman.socket --now
Created symlink /etc/systemd/system/sockets.target.wants/podman.socket → /lib/systemd/system/podman.socket.
  1. 將 Mac 上的 public key: ~/.ssh/id_rsa.pub 加進去 VM 的 /root/.ssh/authorized_keys 裡,讓 podman client 可以透過 ssh 的方式連到 VM 的 socket
1
2
3
4
5
6
7
8
9
10
11
12
# 加完之後,新增遠端連線
hazel@Hazels-MacBook-Pro > ~ > podman system connection add ubuntu --identity ~/.ssh/id_rsa ssh://root@192.168.64.3/run/podman/podman.sock

# 列出遠端連線
hazel@Hazels-MacBook-Pro > ~/Downloads > podman system connection list
Name Identity URI
ubuntu* /Users/hazel/.ssh/id_rsa ssh://root@192.168.64.3:22/run/podman/podman.sock

# 列出 VM 裡的映像檔
✘ hazel@Hazels-MacBook-Pro > ~/Downloads > podman images
REPOSITORY TAG IMAGE ID CREATED SIZE

  1. 測試運行容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 登入 DockerHub 
hazel@Hazels-MacBook-Pro > ~/Downloads > podman login docker.io

# 拉取測試容器
hazel@Hazels-MacBook-Pro > ~/Downloads > podman pull docker.io/hazel910159/testcase1:latest
Trying to pull docker.io/hazel910159/testcase1:latest...

# 列出 VM 裡的映像檔
hazel@Hazels-MacBook-Pro > ~/Downloads > podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/hazel910159/testcase1 latest 528088d05c4b 10 months ago 686 MB

# 測試運行容器,測試成功
hazel@Hazels-MacBook-Pro  ~/Downloads  podman run 528

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.5.RELEASE)

在 Windows 上用 Podman Client

  1. 首先一樣去下載 podman client for Windows

upload successful

  1. 下載完之後解壓縮,就會看到 podman.exe

upload successful

  1. 在 Windows 上面可以透過 cmd.exe(與 MS-DOS 指令相同,與 Linux 指令對照表可參照 A Comparison of Common DOS and Linux Commands) 或 PowerShell 跑 podman 指令

cmd.exe 用 podman.exe <command>
upload successful

powershell 用 ./podman.exe <command>
upload successful

  1. 在 Windows 上面需要開啟 ssh-agent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PS C:\Users\hazel\Downloads> Get-Command ssh

CommandType Name Version Source
----------- ---- ------- ------
Application ssh.exe 7.7.2.1 C:\Windows\System32\OpenSSH\ssh.exe


PS C:\Users\hazel\Downloads> get-service ssh*

Status Name DisplayName
------ ---- -----------
Disabled ssh-agent OpenSSH Authentication Agent


PS C:\Users\hazel\Downloads> Start-Service ssh-agent

# 加完記得檢查一下
PS C:\Users\hazel\Downloads> ssh-add -l
2048 SHA256:XXX C:\Users\hazel/.ssh/id_rsa (RSA)
  1. 之後可以照著上面 Mac 的步驟如法炮製建立 podman connection,但我這邊是用 Parallels on Mac,自己有 Windows Server 的人可以用 WSL, 一樣把公鑰加入 VM 的 authorized_keys 就可以用了。

Referecne