AlmaLinux 9にPodmanをインストールする

# What's？

前に、AlmaLinux 9にDocker Engine（CE）をインストールしてみました。

https://qiita.com/charon/items/a25b9dd2dea23c254182

とはいえ、RHEL互換のOSではPodmanを使う方が筋が良さそうなので、こちらもインストールして少し試してみたいと思います。

## おさらい

Red Hat Enterprise Linux 8以降、Dockerは削除されています。

> Red Hat では、RHEL 8 から Docker コンテナーエンジンと、docker コマンドが削除されました。
>
> RHEL で Docker を使用する場合は、異なるアップストリームプロジェクトから Docker を取得できますが、RHEL 8 では対応していません。

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/con_running-containers-without-docker_assembly_starting-with-containers

# Podman

PodmanのWebサイトはこちら。

https://podman.io/

Red Hat社によるPodmanのページはこちら。

https://www.redhat.com/ja/topics/containers/what-is-podman

このあたりを見ると、以下が特徴のようです。

- OCIコンテナをサポート
- デーモンレスで軽量
- ルートレスコンテナを使用可能

また、PodmanのCLI（`podman`）`docker`コマンドと似ており、`alias docker=podman`とすれば切り替えも簡単だとしています。

ドキュメントはこちら。

https://podman.io/docs

https://docs.podman.io/en/latest/

周辺ツールとしては、Podman Desktopやpodman-composeがありそうです。

- [Podman Desktop](https://podman-desktop.io/)
- [podman-compose](https://github.com/containers/podman-compose)

今回は、AlmaLinux 9にPodmanをインストールしてみます。

# 環境

今回の環境は、こちら。

```shell
$ cat /etc/os-release
NAME="AlmaLinux"
VERSION="9.2 (Turquoise Kodkod)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.2"
PLATFORM_ID="platform:el9"
PRETTY_NAME="AlmaLinux 9.2 (Turquoise Kodkod)"
ANSI_COLOR="0;34"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:almalinux:almalinux:9::baseos"
HOME_URL="https://almalinux.org/"
DOCUMENTATION_URL="https://wiki.almalinux.org/"
BUG_REPORT_URL="https://bugs.almalinux.org/"

ALMALINUX_MANTISBT_PROJECT="AlmaLinux-9"
ALMALINUX_MANTISBT_PROJECT_VERSION="9.2"
REDHAT_SUPPORT_PRODUCT="AlmaLinux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.2"


$ uname -srvmpio
Linux 5.14.0-284.30.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Sep 12 09:28:32 EDT 2023 x86_64 x86_64 x86_64 GNU/Linux
```

# Podmanをインストールする

こちらに従って、Podmanをインストールしてみます。

https://podman.io/docs/installation

対象はLinuxなので、こちらを見るとCentOS向けのものを参考にすればよさそうです。

[Podman Installation Instructions / Installing on Linux](https://podman.io/docs/installation#installing-on-linux)

パッケージを確認。

```shell
$ dnf info podman
メタデータの期限切れの最終確認: 0:00:07 前の 2023年09月23日 16時50分53秒 に実施しました。
利用可能なパッケージ
名前         : podman
エポック     : 2
バージョン   : 4.4.1
リリース     : 13.el9_2
Arch         : x86_64
サイズ       : 14 M
ソース       : podman-4.4.1-13.el9_2.src.rpm
リポジトリー : appstream
概要         : Manage Pods, Containers and Container Images
URL          : https://podman.io/
ライセンス   : ASL 2.0 and GPLv3+
説明         : podman (Pod Manager) is a fully featured container engine that is a simple
             : daemonless tool.  podman provides a Docker-CLI comparable command line that
             : eases the transition from other container engines and allows the management of
             : pods, containers and images.  Simply put: alias docker=podman.
             : Most podman commands can be run as a regular user, without requiring
             : additional privileges.
             :
             : podman uses Buildah(1) internally to create container images.
             : Both tools share image (not container) storage, hence each can use or
             : manipulate images (but not containers) created by the other.
             :
             : Manage Pods, Containers and Container Images
             : podman Simple management tool for pods, containers and images

```

では、インストール。

```shell
$ sudo dnf install podman
```

バージョンを確認。

```shell
$ podman --version
podman version 4.4.1
```

ヘルプ。

```shell
$ podman --help
Manage pods, containers and images

Usage:
  podman [options] [command]

Available Commands:
  attach      Attach to a running container
  auto-update Auto update containers according to their auto-update policy
  build       Build an image using instructions from Containerfiles
  commit      Create new image based on the changed container
  container   Manage containers
  cp          Copy files/folders between a container and the local filesystem
  create      Create but do not start a container
  diff        Display the changes to the object's file system
  events      Show podman system events
  exec        Run a process in a running container
  export      Export container's filesystem contents as a tar archive
  generate    Generate structured data based on containers, pods or volumes
  healthcheck Manage health checks on containers
  help        Help about any command
  history     Show history of a specified image
  image       Manage images
  images      List images in local storage
  import      Import a tarball to create a filesystem image
  info        Display podman system information
  init        Initialize one or more containers
  inspect     Display the configuration of object denoted by ID
  kill        Kill one or more running containers with a specific signal
  kube        Play containers, pods or volumes from a structured file
  load        Load image(s) from a tar archive
  login       Login to a container registry
  logout      Logout of a container registry
  logs        Fetch the logs of one or more containers
  machine     Manage a virtual machine
  manifest    Manipulate manifest lists and image indexes
  mount       Mount a working container's root filesystem
  network     Manage networks
  pause       Pause all the processes in one or more containers
  pod         Manage pods
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image from a registry
  push        Push an image to a specified destination
  rename      Rename an existing container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Removes one or more images from local storage
  run         Run a command in a new container
  save        Save image(s) to an archive
  search      Search registry for image
  secret      Manage secrets
  start       Start one or more containers
  stats       Display a live stream of container resource usage statistics
  stop        Stop one or more containers
  system      Manage podman
  tag         Add an additional name to a local image
  top         Display the running processes of a container
  unmount     Unmounts working container's root filesystem
  unpause     Unpause the processes in one or more containers
  unshare     Run a command in a modified user namespace
  untag       Remove a name from a local image
  update      update an existing container
  version     Display the Podman version information
  volume      Manage volumes
  wait        Block on one or more containers

Options:
      --cgroup-manager string       Cgroup manager to use ("cgroupfs"|"systemd") (default "systemd")
      --conmon string               Path of the conmon binary
  -c, --connection string           Connection to use for remote Podman service
      --events-backend string       Events backend to use ("file"|"journald"|"none") (default "file")
      --help                        Help for podman
      --hooks-dir strings           Set the OCI hooks directory path (may be set multiple times) (default [/usr/share/containers/oci/hooks.d])
      --identity string             path to SSH identity file, (CONTAINER_SSHKEY)
      --log-level string            Log messages above specified level (trace, debug, info, warn, warning, error, fatal, panic) (default "warn")
      --namespace string            Set the libpod namespace, used to create separate views of the containers and pods on the system
      --network-cmd-path string     Path to the command for configuring the network
      --network-config-dir string   Path of the configuration directory for networks
      --noout                       do not output to stdout
  -r, --remote                      Access remote Podman service
      --root string                 Path to the root directory in which data, including images, is stored (default "/home/user/.local/share/containers/storage/libpod")
      --runroot string              Path to the 'run directory' where all state information is stored
      --runtime string              Path to the OCI-compatible binary used to run containers. (default "crun")
      --runtime-flag stringArray    add global flags for the container runtime
      --ssh string                  define the ssh mode (default "golang")
      --storage-driver string       Select which storage driver is used to manage storage of images and containers
      --storage-opt stringArray     Used to pass an option to the storage driver
      --syslog                      Output logging information to syslog as well as the console (default false)
      --tmpdir string               Path to the tmp directory for libpod state content.

                                    Note: use the environment variable 'TMPDIR' to change the temporary storage location for container images, '/var/tmp'.
                                     (default "/run/user/1000/libpod/tmp")
      --transient-store             Enable transient container storage
      --url string                  URL to access Podman service (CONTAINER_HOST) (default "unix:/run/user/1000/podman/podman.sock")
  -v, --version                     version for podman
      --volumepath string           Path to the volume directory in which volume data is stored (default "/home/user/.local/share/containers/storage/volumes")
```

コマンドのリファレンスは、こちらを見る、でも良さそうです。

https://docs.podman.io/en/latest/Commands.html

確かに、Dockerとそっくりですね。

# Podmanを使ってみる

それでは、インストールしたPodmanを使ってみましょう。

## コンテナを起動する

コンテナを起動。nginxで試してみます。

```shell
$ podman container run -it --rm --name nginx nginx:1.25.2-bookworm
```

どのイメージを使うか聞かれました。

```shell
? Please select an image:
  ▸ registry.access.redhat.com/nginx:1.25.2-bookworm
    registry.redhat.io/nginx:1.25.2-bookworm
    docker.io/library/nginx:1.25.2-bookworm
```

今回はDocker Hubのものを選択。

起動しました。

```shell
2023/09/23 07:57:13 [notice] 1#1: nginx/1.25.2
2023/09/23 07:57:13 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/09/23 07:57:13 [notice] 1#1: OS: Linux 5.14.0-284.30.1.el9_2.x86_64
2023/09/23 07:57:13 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 524288:524288
2023/09/23 07:57:13 [notice] 1#1: start worker processes
2023/09/23 07:57:13 [notice] 1#1: start worker process 24
2023/09/23 07:57:13 [notice] 1#1: start worker process 25
```

確認…しようと思ったのですが、コンテナのIPアドレスを確認しようとすると値が入っていません。

```shell
$ podman inspect nginx | grep IPA
               "IPAddress": "",
```

なるほど、ではローカルの80ポートから転送しようとすると、権限が不足していて失敗します。

```shell
$ podman container run -it --rm --name nginx -p 80:80 nginx:1.25.2-bookworm
Error: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied
```

これはrootで実行していないからですね。

https://github.com/containers/podman/blob/main/docs/tutorials/basic_networking.md

というわけで、root権限が不要なポートでマッピングします。

```shell
$ podman container run -it --rm --name nginx -p 8080:80 nginx:1.25.2-bookworm
```

今度はOKでした。

```shell
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

なるほど、Dockerとは少し感覚が違いますね。

root権限で実行すると特権ポートでも起動できるようになりますが（それはそう）、これはちょっと違うと思います。

```shell
$ sudo podman container run -it --rm --name nginx -p 80:80 docker.io/library/nginx:1.25.2-bookworm
```

また、先程は`nginx:1.25.2-bookworm`のような形でコンテナを指定していましたが、ドキュメントを見ていると使用するレジストリがわかる形で記述するのが良さそうですね。

```shell
$ podman container run -it --rm --name nginx -p 8080:80 docker.io/library/nginx:1.25.2-bookworm
```

https://podman.io/docs

https://docs.podman.io/en/latest/Introduction.html

あと、ふつうに使う時は`-d`でバックグラウンドでコンテナを実行し続けることの方が多いでしょうか。

```shell
$ podman container run -dt --name nginx -p 8080:80 docker.io/library/nginx:1.25.2-bookworm
```

## コンテナイメージを作成してみる

次に、コンテナイメージを作成してみましょう。

https://docs.podman.io/en/latest/markdown/podman-build.1.html

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/9/html/building_running_and_managing_containers/proc_building-a-container-inside-a-podman-container_assembly_running-skopeo-buildah-and-podman-in-a-container

コンテナイメージの定義は、`Containerfile`または`Dockerfile`で行うようです。

今回は`Containerfile`で作成してみます。

```dockerfile:Containerfile
FROM docker.io/library/nginx:1.25.2-bookworm
```

ビルド。

```shell
$ podman image build -t user/nginx:1.25.2-bookworm .
```

実行。

```shell
$ podman container run -it --rm --name nginx -p 8080:80 user/nginx:1.25.2-bookworm
```

OKですね。

```shell
2023/09/23 08:18:53 [notice] 1#1: nginx/1.25.2
2023/09/23 08:18:53 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/09/23 08:18:53 [notice] 1#1: OS: Linux 5.14.0-284.30.1.el9_2.x86_64
2023/09/23 08:18:53 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 524288:524288
2023/09/23 08:18:53 [notice] 1#1: start worker processes
2023/09/23 08:18:53 [notice] 1#1: start worker process 24
2023/09/23 08:18:53 [notice] 1#1: start worker process 25
```

イメージの一覧。

```shell
$ podman image ls
REPOSITORY               TAG              IMAGE ID      CREATED     SIZE
localhost/user/nginx     1.25.2-bookworm  61395b4c586d  2 days ago  191 MB
docker.io/library/nginx  1.25.2-bookworm  61395b4c586d  2 days ago  191 MB
```

作成したイメージは、`localhost`の配下にいるようですね。

## pod

Podmanは、podというコンテナのグループを管理する機能があるようです。

https://docs.podman.io/en/latest/markdown/podman-pod.1.html

このあたりは、また別のタイミングで見てみたいと思います。

# 最後に

Podmanを試してみましたが、Dockerと完全に同じ感覚で使えるかというとそれなりに違いがありそうなので、こちらはこちらで慣れが必要そうですね。

またドキュメントについては、RHELのドキュメントを見た方がわかりやすいのではないか？という気がするのですが、どうでしょうか。

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/9/html/building_running_and_managing_containers/assembly_running-skopeo-buildah-and-podman-in-a-container