Podmanで3パターンのコンテナ作成を試してみる（macOS）

# はじめに
本記事ではPodmanの導入と3パターンのコンテナ作成を実施します。

パターン1：[runコマンドでコンテナ作成](#runコマンドでコンテナ作成)
パターン2：[podman-composeを利用したコンテナ作成](#podman-composeを利用したコンテナ作成)
パターン3：[KubernetesYAMLファイルを利用したコンテナ作成](#kubernetesyamlファイルを利用したコンテナ作成)

# 前提条件
- MacBook利用
- Homebrewインストール済み

## Podman導入
Homebrewバージョン確認
```shell
hoge@hoge ~ % brew --version
Homebrew 4.2.20
```
podmanのパッケージを検索
```shell
hoge@hoge ~ % brew search podman
==> Formulae
podman                     podman-tui                 modman
podman-compose             pod2man                    todoman

==> Casks
podman-desktop                           postman

If you meant "podman" specifically:
It was migrated from homebrew/cask to homebrew/core.
```
podmanインストール
```shell
hoge@hoge ~ % brew install podman
.
.
.
You have 2 outdated formulae installed.

==> Downloading https://ghcr.io/v2/homebrew/core/podman/manifests/5.2.0-1
######################################################################### 100.0%
==> Fetching podman
==> Downloading https://ghcr.io/v2/homebrew/core/podman/blobs/sha256:e84bb90cd35
######################################################################### 100.0%
==> Pouring podman--5.2.0.sonoma.bottle.1.tar.gz
==> Caveats
        In order to run containers locally, podman depends on a Linux kernel.
        One can be started manually using `podman machine` from this package.
        To start a podman VM automatically at login, also install the cask
        "podman-desktop".

zsh completions have been installed to:
  /usr/local/share/zsh/site-functions
==> Summary
🍺  /usr/local/Cellar/podman/5.2.0: 201 files, 76.5MB
==> Running `brew cleanup podman`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
.
.
.

```
podmanバージョン確認
```shell
hoge@hoge ~ % podman --version
podman version 5.2.0
```
podman machineの初期化
```shell
hoge@hoge ~ % podman machine init
```
:::note 
私は一度podmanをインストールした事があったためか、以下のようにエラーになりました。
```shell
Error: podman-machine-default: VM already exists
```
:::
podman machineの一覧を確認
```shell
hoge@hoge ~ % podman system connection list
Name                         URI                                                         Identity                                                            Default     ReadWrite
podman-machine-default       ssh://core@127.0.0.1:64368/run/user/501/podman/podman.sock  /Users/hoge/.local/share/containers/podman/machine/machine  false       true
podman-machine-default-root  ssh://root@127.0.0.1:64368/run/podman/podman.sock           /Users/hoge/.local/share/containers/podman/machine/machine  true        true
```
podman machineの起動
```shell
hoge@hoge ~ % podman machine start
Starting machine "podman-machine-default"
API forwarding listening on: /var/folders/86/s0w_2fg54s1cx05ktfcrnmb40000gn/T/podman/podman-machine-default-api.sock

Another process was listening on the default Docker API socket address.
You can still connect Docker API clients by setting DOCKER_HOST using the
following command in your terminal session:

        export DOCKER_HOST='unix:///var/folders/86/s0w_2fg54s1cx05ktfcrnmb40000gn/T/podman/podman-machine-default-api.sock'

Machine "podman-machine-default" started successfully
```

## runコマンドでコンテナ作成
```shell
hoge@hoge ~ % podman run --rm hello      
Resolved "hello" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull quay.io/podman/hello:latest...
Getting image source signatures
Copying blob sha256:81df7ff16254ed9756e27c8de9ceb02a9568228fccadbf080f41cc5eb5118a44
Copying config sha256:5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0
Writing manifest to image destination
!... Hello Podman World ...!

         .--"--.           
       / -     - \         
      / (O)   (O) \        
   ~~~| -=(,Y,)=- |         
    .---. /`  \   |~~      
 ~/  o  o \~~~~.----. ~~   
  | =(X)= |~  / (O (O) \   
   ~~~~~~~  ~| =(Y_)=-  |   
  ~~~~    ~~~|   U      |~~ 

Project:   https://github.com/containers/podman
Website:   https://podman.io
Desktop:   https://podman-desktop.io
Documents: https://docs.podman.io
YouTube:   https://youtube.com/@Podman
X/Twitter: @Podman_io
Mastodon:  @Podman_io@fosstodon.org
```
:::note
上記はコンテナの作成&起動ができることを確認したらコンテナを削除するように`--rm`オプションを指定しています。
:::
イメージは残っているので確認
```shell
hoge@hoge ~ % podman images
REPOSITORY            TAG         IMAGE ID      CREATED       SIZE
quay.io/podman/hello  latest      5dd467fce50b  2 months ago  787 kB
```
イメージ削除
```shell
hoge@hoge ~ % podman rmi 5dd467fce50b
Untagged: quay.io/podman/hello:latest
Deleted: 5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0
```

## podman-composeを利用したコンテナ作成
podman-compose インストール
```shell
hoge@hoge ~ % brew install podman-compose
==> Downloading https://formulae.brew.sh/api/formula.jws.json
################################################################################################################################################################################### 100.0%
.
.
.
==> Installing podman-compose
==> Pouring podman-compose--1.2.0.sonoma.bottle.tar.gz
🍺  /usr/local/Cellar/podman-compose/1.2.0: 61 files, 656.7KB
==> Running `brew cleanup podman-compose`...
.
.
.
```
バージョン確認
```shell
hoge@hoge ~ % podman-compose --version
podman-compose version 1.2.0
podman version 5.2.0
```
podman-compose.yamlファイル作成
※ `podman`フォルダの作成は必須でありません
```shell
hoge@hoge ~ % mkdir podman && cd podman
hoge@hoge podman % vi podman-compose.yaml
hoge@hoge podman % cat podman-compose.yaml 
version: '3'
services:
  web:
    container_name: nginx
    image: nginx:latest
    ports:
      - 8080:80
```

podman-compose.yamlをもとにコンテナ作成&起動
```shell
hoge@hoge podman % podman-compose up -d
60448b43f362892d9faea16df2b0e42c0af1da3d7335cf258b25af4b75c36b92
Resolving "nginx" using unqualified-search registries (/etc/containers/registries.conf.d/999-podman-machine.conf)
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob sha256:472851929ad734a0bbf2e262059d7d1521d7c1904af3b10e520e18b372e3455c
Copying blob sha256:9c4e4e507b087ba76a77cf447d57a609d08dbcdbbc96abb64877658cf12bbc76
Copying blob sha256:ca3474dd2ca6ca60337319448fe246d55f7ed8f3078b31132924b325f3859f8d
Copying blob sha256:85664e7b25d67d4815e113b34e88c828da06da435971470524631239915ad891
Copying blob sha256:e9d00ba15cc0967faaecc85ea2acdc033a103a018a26b09e54479d344ad06674
Copying blob sha256:e4fff0779e6ddd22366469f08626c3ab1884b5cbe1719b26da238c95f247b305
Copying blob sha256:ed60582f2661431435c1a1c94e7573d69357d633961280cebaf6aac9988afa5e
Copying config sha256:900dca2a61f5799aabe662339a940cf444dfd39777648ca6a953f82b685997ed
Writing manifest to image destination
9f4b398e88015a126b3435578e9ca2aa9af4c117462cae8c5d4f1f3e18d6bfee
```
コンテナの起動を確認
```shell
hoge@hoge podman % podman ps
CONTAINER ID  IMAGE                           COMMAND               CREATED        STATUS        PORTS                         NAMES
9f4b398e8801  docker.io/library/nginx:latest  nginx -g daemon o...  3 seconds ago  Up 3 seconds  0.0.0.0:8080->80/tcp, 80/tcp  nginx
```
以下にアクセス
http://localhost:8080

![スクリーンショット 2024-08-14 14.20.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624418/623d0f13-c96e-5e94-f3d4-c0777ac71299.png)

コンテナやイメージを全て削除
```shell
hoge@hoge podman % podman stop --all
9f4b398e88015a126b3435578e9ca2aa9af4c117462cae8c5d4f1f3e18d6bfee
hoge@hoge podman % podman rm --all
9f4b398e88015a126b3435578e9ca2aa9af4c117462cae8c5d4f1f3e18d6bfee
hoge@hoge podman % podman rmi --all
Untagged: docker.io/library/nginx:latest
Deleted: 900dca2a61f5799aabe662339a940cf444dfd39777648ca6a953f82b685997ed
hoge@hoge podman % podman pod rm --all
60448b43f362892d9faea16df2b0e42c0af1da3d7335cf258b25af4b75c36b92
```
## KubernetesYAMLファイルを利用したコンテナ作成
YAMLファイルを生成するために、まずはpodとコンテナを手動で作成していきます。
<br>
pod作成
```shell
hoge@hoge ~ % podman pod create -p 8080:80 --name nginx-pod                      
3d597bc635ae65d280fe0a3071dc947b6d2cb6f9101f8c7666306029150e0f7d
```
pod確認
```shell
hoge@hoge ~ % podman pod ps                                                      
POD ID        NAME        STATUS      CREATED        INFRA ID      # OF CONTAINERS
3d597bc635ae  nginx-pod   Created     6 seconds ago  086919058a9b  1
```
コンテナを作成して、podに追加
```shell
hoge@hoge ~ % podman run -dt --pod nginx-pod --name nginx nginx:latest 
3eceefaf1cffcc2d82169eb16e8d2bf0de3e5d425db1dbe7a256070b0874efbd
```
コンテナ確認
```shell
hoge@hoge ~ % podman ps
CONTAINER ID  IMAGE                                    COMMAND               CREATED         STATUS        PORTS                 NAMES
086919058a9b  localhost/podman-pause:5.1.2-1720569600                        46 seconds ago  Up 4 seconds  0.0.0.0:8080->80/tcp  3d597bc635ae-infra
3eceefaf1cff  docker.io/library/nginx:latest           nginx -g daemon o...  4 seconds ago   Up 4 seconds  0.0.0.0:8080->80/tcp  nginx
```
pod確認
```shell
hoge@hoge ~ % podman pod ps                                                      
POD ID        NAME        STATUS      CREATED        INFRA ID      # OF CONTAINERS
3d597bc635ae  nginx-pod   Created     6 seconds ago  086919058a9b  2
```
:::note
nginx-pod （pod）に対してnginx（container）を追加したので、`# OF CONTAINERS`が2になっています。
今回はコンテナ一つだけですが、この要領で複数のコンテナをpodに追加することができます。
:::

以下にアクセス
http://localhost:8080

![スクリーンショット 2024-08-14 14.20.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624418/623d0f13-c96e-5e94-f3d4-c0777ac71299.png)

コンテナの起動もうまくできているので、、
作成したpodとコンテナの情報をYAMLファイルとして生成していきます。

YAMLファイル（Kubernetesマニフェスト）生成
```shell
hoge@hoge podman % podman generate kube -f ./nginx-pod.yaml nginx-pod       
hoge@hoge podman % cat nginx-pod.yaml 
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-5.1.2
apiVersion: v1
kind: Pod
metadata:
  annotations:
    io.kubernetes.cri-o.SandboxID/nginx: 086919058a9b046190977af86b82af15607e79b03d5c7a80ab6653841d7c85b8
  creationTimestamp: "2024-08-14T05:39:09Z"
  labels:
    app: nginx-pod
  name: nginx-pod
spec:
  containers:
  - args:
    - nginx
    - -g
    - daemon off;
    env:
    - name: TERM
      value: xterm
    image: docker.io/library/nginx:latest
    name: nginx
    ports:
    - containerPort: 80
      hostPort: 8080
    tty: true
```

コンテナやイメージを全て削除(手順省略)

生成したYAMLファイルをもとにpodとコンテナを作成&起動
```shell
hoge@hoge podman %　podman kube play nginx-pod.yaml
```
pod確認
```shell
hoge@hoge podman % podman pod ps
POD ID        NAME        STATUS      CREATED         INFRA ID      # OF CONTAINERS
b2e87c255b45  nginx-pod   Running     14 seconds ago  0a9e5f9d5fdc  2
```
コンテナ確認
```shell
hoge@hoge podman % podman ps
CONTAINER ID  IMAGE                                    COMMAND               CREATED         STATUS         PORTS                 NAMES
0a9e5f9d5fdc  localhost/podman-pause:5.1.2-1720569600                        22 seconds ago  Up 15 seconds  0.0.0.0:8080->80/tcp  b2e87c255b45-infra
9260720804ce  docker.io/library/nginx:latest           nginx -g daemon o...  15 seconds ago  Up 15 seconds  0.0.0.0:8080->80/tcp  nginx-pod-nginx
```
:::note
YAMLファイル生成前に作成したpodとコンテナが再び作成できています。
生成したYAMLファイルでコンテナを作成すると、コンテナ名(nginx)の前にpod名(nginx-pod)が付与されるみたいですね。
:::


以下にアクセス
http://localhost:8080

![スクリーンショット 2024-08-14 14.20.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624418/623d0f13-c96e-5e94-f3d4-c0777ac71299.png)
動作確認も完了です。

以降の手順は必要に応じて実施して下さい。
## podman machine 停止&削除
起動中のコンテナがあれば停止
```shell
hoge@hoge ~ % podman stop nginx-pod-nginx
nginx-pod-nginx
hoge@hoge ~ % podman ps                  
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES
```
コンテナやイメージを全て削除(手順省略)

podman machine 停止
```shell
hoge@hoge ~ % podman machine stop
Machine "podman-machine-default" stopped successfully
```
podman machine 削除
```shell
hoge@hoge ~ % podman machine rm
The following files will be deleted:


/Users/hoge/.config/containers/podman/machine/applehv/podman-machine-default.json
/var/folders/86/s0w_2fg54s1cx05ktfcrnmb40000gn/T/podman/podman-machine-default.sock
/var/folders/86/s0w_2fg54s1cx05ktfcrnmb40000gn/T/podman/podman-machine-default-gvproxy.sock
/var/folders/86/s0w_2fg54s1cx05ktfcrnmb40000gn/T/podman/podman-machine-default-api.sock
/var/folders/86/s0w_2fg54s1cx05ktfcrnmb40000gn/T/podman/podman-machine-default.log
Are you sure you want to continue? [y/N] y
```
podman machine　確認
```shell
hoge@hoge ~ % podman system connection list
Name        URI         Identity    Default     ReadWrite
```

## podman削除
podmanとpodman-composeをアンインストール
```shell
hoge@hoge ~ % brew uninstall podman podman-compose
Uninstalling /usr/local/Cellar/podman/5.2.0... (201 files, 76.5MB)
Uninstalling /usr/local/Cellar/podman-compose/1.2.0... (83 files, 1MB)
.
.
.
```

podmanおよびpodman-composeが存在しないことを確認
```shell
hoge@hoge ~ % brew list
```

# おわりに
podmanを利用したコンテナの作成という点にフォーカスを当てて検証してみました。
今回は簡易なコンテナしか作成していませんので、気になるコンテナ間の連携などについてはまた今度調べてみようと思います。

# 参考文献
- [Podmanを始めたい](https://qiita.com/ymd65536/items/b224f3b59b16984c469b)
- [【podman machine】macOS上でPodmanを実行する新コマンドの紹介](https://rheb.hatenablog.com/entry/podman-machine)