[Mac] 使用 Podman 取代 Docker

[Mac] 使用 Podman 取代 Docker

在 Mac 上我一直都是使用 Docker Desktop 來跑 Docker Engine,

不過它的效能總覺得不甚理想,

常常 CPU 吃很高 (不過也許這就是要在 Mac 上開 Linux VM 的宿命)…

 

最近聽到同事在說 Podman 這個工具,

可以不用一直常駐跑一個 daemon,與 docker 相容性也不錯,

那就來試試看吧~

 

1. 安裝 Podman

在 Mac 上用 Homebrew 來安裝 Podman:

brew install podman

 

裝好後執行  podman info ,目前是不行的,

因為我們還沒有 Linux VM:

$ podman info

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 socket: Get "http://d/v4.7.2/libpod/_ping": dial unix ///var/folders/tc/h5mk5_ts4278q5r3bk_1vxc00000gp/T/podman-run--1/podman/podman.sock: connect: no such file or directory

 

2. 安裝 Podman Machine

先看一下  podman machine 有哪些參數可用:

$ podman machine

Manage a virtual machine

Description:
  Manage a virtual machine. Virtual machines are used to run Podman.

Usage:
  podman machine [command]

Available Commands:
  info        Display machine host info
  init        Initialize a virtual machine
  inspect     Inspect an existing machine
  list        List machines
  os          Manage a Podman virtual machine's OS
  rm          Remove an existing machine
  set         Set a virtual machine setting
  ssh         SSH into an existing machine
  start       Start an existing machine
  stop        Stop an existing machine

 

接著就可以先執行  podman machine init 來建立一台 Linux VM,

它看起來是會抓一個 CoreOS 的 QEMU 映像檔下來,

所以應該是用 QEMU 來跑這 VM 的:

$ podman machine init

Downloading VM image: fedora-coreos-39.20231101.2.1-qemu.x86_64.qcow2.xz: done
Extracting compressed file: podman-machine-default_fedora-coreos-39.20231101.2.1-qemu.x86_64.qcow2 [==================>---] 544.9MiB / 620.5M
Extracting compressed file: podman-machine-default_fedora-coreos-39.20231101.2.1-qemu.x86_64.qcow2: done
Image resized.
Machine init complete
To start your machine run:

    podman machine start

 

執行  podman machine start 來啟動 VM:

$ podman machine start

Starting machine "podman-machine-default"
Waiting for VM ...
Mounting volume... /Users:/Users
Mounting volume... /private:/private
Mounting volume... /var/folders:/var/folders

This machine is currently configured in rootless mode. If your containers
require root permissions (e.g. ports < 1024), or if you run into compatibility
issues with non-podman clients, you can switch using the following command:

        podman machine set --rootful

API forwarding listening on: /Users/testuser/.local/share/containers/podman/machine/qemu/podman.sock

The system helper service is not installed; the default Docker API socket
address can't be used by podman. If you would like to install it run the following commands:

        sudo /usr/local/Cellar/podman/4.7.2/bin/podman-mac-helper install
        podman machine stop/usr/local/Cellar/podman/4.7.2/bin/podman-mac-helper; podman machine start/usr/local/Cellar/podman/4.7.2/bin/podman-mac-helper

                You can still connect Docker API clients by setting DOCKER_HOST using the
following command in your terminal session:

        export DOCKER_HOST='unix:///Users/testuser/.local/share/containers/podman/machine/qemu/podman.sock'

Machine "podman-machine-default" started successfully

 

我想要容易直接有 root 權限,減少一些未來的麻煩,

所以要先把 VM 停下來、設定成 rootful、再重新啟動 VM:

podman machine stop
podman machine set --rootful
podman machine start

 

跑  podman info 看一下目前的狀態:

$ podman info

host:
  arch: amd64
  buildahVersion: 1.32.0
  cgroupControllers:
  - cpuset
  - cpu
  - io
  - memory
  - hugetlb
  - pids
  - rdma
  - misc
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: conmon-2.1.7-3.fc39.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.7, commit: '
  cpuUtilization:
    idlePercent: 77.24
    systemPercent: 14.31
    userPercent: 8.45
  cpus: 1
  databaseBackend: boltdb
  distribution:
    distribution: fedora
    variant: coreos
    version: "39"
  eventLogger: journald
  freeLocks: 2048
  hostname: localhost.localdomain
  idMappings:
    gidmap: null
    uidmap: null
  kernel: 6.5.9-300.fc39.x86_64
  linkmode: dynamic
  logDriver: journald
  memFree: 1592528896
  memTotal: 2048520192
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: aardvark-dns-1.8.0-1.fc39.x86_64
      path: /usr/libexec/podman/aardvark-dns
      version: aardvark-dns 1.8.0
    package: netavark-1.8.0-2.fc39.x86_64
    path: /usr/libexec/podman/netavark
    version: netavark 1.8.0
  ociRuntime:
    name: crun
    package: crun-1.11-1.fc39.x86_64
    path: /usr/bin/crun
    version: |-
      crun version 1.11
      commit: 11f8d3dc9fc4bb8a0adcff5ba8bd340f24612701
      rundir: /run/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +LIBKRUN +WASM:wasmedge +YAJL
  os: linux
  pasta:
    executable: /usr/bin/pasta
    package: passt-0^20231004.gf851084-1.fc39.x86_64
    version: |
      pasta 0^20231004.gf851084-1.fc39.x86_64
      Copyright Red Hat
      GNU General Public License, version 2 or later
        <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
      This is free software: you are free to change and redistribute it.
      There is NO WARRANTY, to the extent permitted by law.
  remoteSocket:
    exists: true
    path: /run/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: false
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: true
  serviceIsRemote: true
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.2.2-1.fc39.x86_64
    version: |-
      slirp4netns version 1.2.2
      commit: 0ee2d87523e906518d34a6b423271e4826f71faf
      libslirp: 4.7.0
      SLIRP_CONFIG_VERSION_MAX: 4
      libseccomp: 2.5.3
  swapFree: 0
  swapTotal: 0
  uptime: 0h 1m 56.00s
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries:
  search:
  - docker.io
store:
  configFile: /usr/share/containers/storage.conf
  containerStore:
    number: 0
    paused: 0
    running: 0
    stopped: 0
  graphDriverName: overlay
  graphOptions:
    overlay.mountopt: nodev,metacopy=on
  graphRoot: /var/lib/containers/storage
  graphRootAllocated: 106769133568
  graphRootUsed: 2324676608
  graphStatus:
    Backing Filesystem: xfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Supports shifting: "true"
    Supports volatile: "true"
    Using metacopy: "true"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 0
  runRoot: /run/containers/storage
  transientStore: false
  volumePath: /var/lib/containers/storage/volumes
version:
  APIVersion: 4.7.0
  Built: 1695838680
  BuiltTime: Thu Sep 28 02:18:00 2023
  GitCommit: ""
  GoVersion: go1.21.1
  Os: linux
  OsArch: linux/amd64
  Version: 4.7.0

 

3. 使用 Podman 啟動容器

Podman 的用法和 Docker 差不多,

下面指令是在背景跑一個 httpd 的容器,並且將本機的 8080 port 映射到容器的 80 port:

$ podman run -dt -p 8080:80/tcp docker.io/library/httpd

Trying to pull docker.io/library/httpd:latest...
Getting image source signatures
Copying blob sha256:6a3b76b70f7385a99e72877fac4d1e00f4466859ed3ea50891bab80908e22c0b
Copying blob sha256:578acb154839e9d0034432e8f53756d6f53ba62cf8c7ea5218a2476bf5b58fc9
Copying blob sha256:c1a8c8567b78fc222c60d83831081d5578fd80e6c30ee0bcf8a79019824301a1
Copying blob sha256:10b9ab03bf458e12adc435ae235b1f58f473fea23c2cdf6d88407d92a4a51c41
Copying blob sha256:74dbedf7ddc012b3398b2c645974f1f6e30a9592fef541d02faf456e40b67bc4
Copying config sha256:7f6a969e81a54d01e2fc08fd45025badf8f2418d3530a3a484b77ab826a1b4a7
Writing manifest to image destination
cc6028fb57848297da81b80a8f9bd784ff6b9770399f7da6f5715bd764c51a1c

 

執行  podman ps 可以查看執行中的容器:

$ podman ps

CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS         PORTS                 NAMES
cc6028fb5784  docker.io/library/httpd:latest  httpd-foreground  18 seconds ago  Up 17 seconds  0.0.0.0:8080->80/tcp  xenodochial_merkle

 

4. 使用 Docker 指令操控 Podman 容器

剛剛跑起來的 Podman 容器,直接跑  docker ps 是看不到的,

因為 docker 指令會去連結它預設的一個 Unix socket,和 Podman 用的不是同一個:

$ docker ps

Cannot connect to the Docker daemon at unix:///Users/testuser/.docker/run/docker.sock. Is the docker daemon running?

 

記得剛剛在 podman machine start 的訊息中,有看到一個 DOCKER_HOST 的環境變數。

把它拿來設定後,再執行  docker ps ,就可以成功連線看到容器囉:

$ export DOCKER_HOST='unix:///Users/testuser/.local/share/containers/podman/machine/qemu/podman.sock'

$ docker ps
CONTAINER ID   IMAGE          COMMAND              CREATED          STATUS          PORTS     NAMES
cc6028fb5784   httpd:latest   "httpd-foreground"   14 minutes ago   Up 14 minutes   80/tcp    xenodochial_merkle

 

以上就是簡單的 Podman 安裝與使用方法,

之後會盡量使用 Podman 來取代 Docker 看看,

再觀察看是不是有哪些異同之處呢?~

 

參考資料:Podman Installation

(本頁面已被瀏覽過 94 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料