GitHubで公開されているEMLinux 3.1にPodmanをインストールしてみた

# はじめに
[以前の記事](https://qiita.com/fukunagt/items/dc2abc58b9f67a3a48b3)ではEMLinux 3.1にDockerをインストールしましたが、Dockerがインストールできたら、次はPodmanを試したくなりました。「これもいきもののサガか…」ということで、EMLinux 3.1にPodmanをインストールしてみました。

# 構成図
```
+--------------------------------+
| +----------------------------+ |
| | +------------------------+ | |
| | | +--------------------+ | | |
| | | | +----------------+ | | | |
| | | | | NGINX          | | | | |
| | | | +----------------+ | | | |
| | | | Podman             | | | |
| | | +--------------------+ | | |
| | |  EMLinux 3.1           | | |
| | +------------------------+ | |
| | QEMU                       | |
| +-+--------------------------+ |
|   |                            |
| +-+----+                       |
| | tap0 |                       |
| +-+----+                       |
|   |                            |
| +-+----------------------+     |
| | virbr0 (192.168.122.1) |     |
| +------------------------+     |
|                                |
| Ubuntu Server 　　　　　　      |
+--------------------------------+
```

# 各ソフトウェアのバージョン
## Ubuntu Server
```
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
```

## QEMU
```
$ qemu-system-aarch64 --version 
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.28)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
```

# EMLinuxのビルドに必要なパッケージのインストール
1. 以下の記事を参考に、EMLinuxのビルドに必要なパッケージをインストールしてください。
   - [DockerおよびDocker Comoseのインストール](https://qiita.com/fukunagt/items/117bbe20a14584320edc#docker%E3%81%8A%E3%82%88%E3%81%B3docker-comose%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
   - [qemu-user-staticのインストール](https://qiita.com/fukunagt/items/117bbe20a14584320edc#qemu-user-static%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

# meta-emlinuxリポジトリのクローン
1. meta-emlinuxのリポジトリのクローン先のディレクトリを作成してください。
   ```sh
   mkdir -p /home/emlinux/github/emlinux/bookworm/podman/repos
   ```
1. 以下のディレクトリに移動してください。
   ```sh
   cd /home/emlinux/github/emlinux/bookworm/podman
   ```
1. 以下の記事を参考に、meta-emlinuxのリポジトリをクローンしてください。
   - [meta-emlinuxリポジトリのクローン](https://qiita.com/fukunagt/items/117bbe20a14584320edc#qemu-user-static%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

# カスタムレイヤーの作成
1. 以下のディレクトリに移動してください。
   ```sh
   cd /home/emlinux/github/emlinux/bookworm/podman/repos
   ```
1. 以下のディレクトリを作成してください。
   ```
   meta-custom/
   ├── conf
   │   └── layer.conf
   ├── COPYING.MIT
   ├── README
   └── recipes-podman
       ├── configure-podman
       │   ├── configure-podman.bb
       │   └── files
       │       ├── containers.conf
       │       └── set-proxy.sh
       └── images
           └── emlinux-image-base.bbappend
   ```
   - layer.conf
     ```
     #
     # layer profile
     #

     BBPATH .= ":${LAYERDIR}"

     BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
             ${LAYERDIR}/recipes-*/*/*.bbappend"

     BBFILE_COLLECTIONS += "custom"
     BBFILE_PATTERN_custom = "^${LAYERDIR}/"
     BBFILE_PRIORITY_custom = "30"

     LAYERSERIES_COMPAT_custom = "next"

     LAYERDIR_custom = "${LAYERDIR}"     
     ```
   - COPYING.MIT
     - 以下のファイルをコピーしてください。
       - https://github.com/miraclelinux/meta-emlinux/blob/warrior/COPYING.MIT
   - README
     ```
     # This directory contains the files to install Docker on EMLinux.
     ```
   - configure-podman.bb
     ```
     FILESEXTRAPATHS:prepend := "${FILE_DIRNAME}/files:"

     DESCRIPTION = "Setup script for Podman"

     DEBIAN_DEPENDS = "podman"

     inherit dpkg-raw

     SRC_URI = " \
         file://containers.conf \
         file://set-proxy.sh \
     "

     do_install() {
         install -v -d ${D}/etc/profile.d
         install -v -m 755 ${WORKDIR}/set-proxy.sh ${D}/etc/profile.d/
         install -v -d ${D}/etc/containers
         install -v -m 644 ${WORKDIR}/containers.conf ${D}/etc/containers/
     }
     ```
   - containers.conf
     ```
     [engine]
     cgroup_manager="cgroupfs"
     events_logger="file"
     ```
   - set-proxy.sh
     ```
     #!/bin/sh
     PROXY=http://<proxy serverのIPアドレス>:<ポート番号>
     export HTTPS_PROXY=${PROXY}
     export no_proxy='127.0.0.1'
     ```
   - emlinux-image-base.bbappend
     ```
     # Add user
     USERS += "emlinux"
     USER_emlinux[password] = "emlinux"
     USER_emlinux[flags] = "create-home clear-text-password"
     USER_emlinux[home] = "/home/emlinux"
     USER_emlinux[shell] = "/bin/bash"

     # Add packages for Podman
     IMAGE_PREINSTALL:append = " \
         ca-certificates \
         connman \
         containernetworking-plugins \
         dbus-x11 \
         podman \
         slirp4netns \
         uidmap \
     "
     ```

# EMLinuxのビルド
1. meta-emlinux/dockerに移動し、run.shを実行してください。
   ```sh
   cd /home/emlinux/github/emlinux/bookworm/podman/repos/meta-emlinux/docker
   ```
   ```sh
   ./run.sh
   ```
1. コンテナにログイン後、環境変数を設定してください。
   ```sh
   source repos/meta-emlinux/scripts/setup-emlinux build 
   ```
1. viコマンドで、conf/bblayers.confの末尾に以下を追記してください。
   ```
   BBLAYERS += "${TOPDIR}/../repos/meta-custom"
   ```
1. meta-customレイヤーが追加されていることを確認してください。
   ```
   $ bitbake-layers show-layers
   NOTE: Starting bitbake server...
   layer                 path                                      priority
   ==========================================================================
   meta                  /home/build/work/build/../repos/isar/meta  5
   meta-emlinux          /home/build/work/build/../repos/meta-emlinux  12
   isar-cip-core         /home/build/work/build/../repos/isar-cip-core  6
   meta-custom           /home/build/work/build/../repos/meta-custom  30
   ```
1. viでconf/local.confを開き、末尾に以下を追記してください。
   ```
   # ARM64
   MACHINE = "qemu-arm64"
   
   # Setup for Podman
   IMAGE_INSTALL:append = " configure-podman"

   # Extra space for rootfs in MB
   ROOTFS_EXTRA = "10240"   
   ```
1. EMLinuxをビルドしてください。
   ```sh
   bitbake emlinux-image-base
   ```
1. ビルド完了後、exitコマンドでコンテナからログアウトしてください。
   ```
   build@82fa043f8378:~/work$ exit 
   exit
   ```

# tap0の作成
1. 以降の作業はsudo権限があるユーザで行ってください。
1. 仮想ブリッジvirbrを有効化するため、libvirt-daemon-systemをインストールしてください。
   ```sh
   sudo apt install libvirt-daemon-system
   ```
1. 以下のコマンドを実行し、tap0を作成してください。
   ```sh
   sudo ip tuntap add tap0 mode tap
   ```
   ```sh
   sudo ip link set tap0 promisc on
   ```
   ```sh
   sudo ip link set dev tap0 master virbr0
   ```
   ```sh
   sudo ip link set dev tap0 up
   ```   

# EMLinuxの起動
1. 以下のディレクトリに移動してください。
   ```sh
   cd /home/emlinux/github/emlinux/bookworm/podman/build
   ```
1. run.shファイルを作成してください。
   ```sh
   touch run.sh
   ```
   ```sh
   chmod +x run.sh
   ```
1. vimでrun.shファイルを以下のように編集してください。
   ```
   qemu-system-aarch64 \
   -net nic \
   -net tap,ifname=tap0,script=no \
   -drive id=disk0,file=./tmp/deploy/images/qemu-arm64/emlinux-image-base-emlinux-bookworm-qemu-arm64.ext4,if=none,format=raw \
   -device virtio-blk-device,drive=disk0 -show-cursor -device VGA,edid=on \
   -device qemu-xhci \
   -device usb-tablet \
   -device usb-kbd \
   -object rng-random,filename=/dev/urandom,id=rng0 \
   -device virtio-rng-pci,rng=rng0 \
   -nographic \
   -machine virt \
   -cpu cortex-a57 \
   -m 2G \
   -serial mon:stdio \
   -serial null \
   -kernel ./tmp/deploy/images/qemu-arm64/emlinux-image-base-emlinux-bookworm-qemu-arm64-vmlinux \
   -initrd ./tmp/deploy/images/qemu-arm64/emlinux-image-base-emlinux-bookworm-qemu-arm64-initrd.img \
   -append 'root=/dev/vda rw highres=off console=ttyS0 mem=2G ip=dhcp console=ttyAMA0'
   ```
1. suコマンドで、sudo権限があるユーザに切り替えてください。
1. run.shを実行してください。
   ```sh
   sudo ./run.sh
   ```
   - パスワードを問われる場合には、sudo権限があるユーザのパスワードを入力してください。
1. emlinuxユーザでログインしてください。パスワードは、local.confに指定したパスワードを使用してください。
   ```
   EMLinux3 login: emlinux
   Password: 
   ```
1. IPアドレスが割り振られていることを確認してください。
   ```
   emlinux@EMLinux3:~# ip a
   (snip)
   2: enp0s1: <BROADCAST,MULTICAST,DYNAMIC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.77/24 metric 1024 brd 192.168.122.255 scope global dynamic enp0s1
       valid_lft 3523sec preferred_lft 3523sec
   (snip)
   ```
1. コンテナイメージの検索が行えるか確認してください。
   ```
   emlinux@EMLinux3:~$ podman search docker.io/library/nginx 
   NAME                     DESCRIPTION
   docker.io/library/nginx  Official build of Nginx.
   ```
1. 以下のコマンドを実行し、NGINXのコンテナを起動してください。
   ```sh
   podman run -it -d --name nginx-test -p 8080:80 docker.io/library/nginx
   ```
1. コンテナホストからcurlコマンドで、NGINXにアクセスできることを確認してください。
   ```
   $ curl 192.168.122.77:8080 --noproxy 192.168.122.77
   <!DOCTYPE html>
   <html>
   <head>
   <title>Welcome to nginx!</title>
   (snip)
   ```

# さいごに
EMLinux 3.1のレシピをカスタマイズし、Podmanをインストールしてみました。Dockerと異なり、必要なパッケージを探すのに苦労しましたが、何とかコンテナを動かすことができました。

# 補足
## rootユーザでのpodman実行
- rootユーザで`podman run`を実行した場合、iptablesのエラーが発生し、コンテナの起動に失敗します。
  ```
  Error: unable to start container "e95b86d5d0459e380e12f56884e7d1bbbbcc611afd516de5a24478b955ad6694": plugin type="bridge" failed (add): cni plugin bridge failed: running [/usr/sbin/iptables -t nat -A CNI-2f1f117c0a814259c69ff56a -d 10.88.0.4/16 -j ACCEPT -m comment --comment name: "podman" id: "e95b86d5d0459e380e12f56884e7d1bbbbcc611afd516de5a24478b955ad6694" --wait]: exit status 1: Warning: 
  iptables: No chain/target/match by that name.  
  ```

## ログイン後のpodman実行時の警告
- ログイン後の初回podmanコマンド実行時に、以下の警告が出力されますが、2回目以降は出力されません。現時点では実害が無いので、別途調査してみようと思います。
  ```
  emlinux@EMLinux3:~$ podman ps 
  CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES
  WARN[0001] Failed to add pause process to systemd sandbox cgroup: Process org.freedesktop.systemd1 exited with status 1 
  emlinux@EMLinux3:~$ podman ps 
  CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES
  ```

## カスタムレイヤーの作成について
[上述の手順](#カスタムレイヤーの作成)の場合、ディレクトリやファイルを作成していただく必要があります。

同手順を[GitHub](https://github.com/takaaki-fukunaga/EMLinux/blob/main/doc/jp/Install-Podman-on-EMLinux31_jp.md)にも掲載しております。GitHubの手順はlayerをダウンロードする手順となっています。上述の手順で「ディレクトリやファイルの作成が面倒だなぁ…」と思われた方は、GitHubに記載の手順をご利用ください。