0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AlmaLinux10(WSL2) + Podmanでのクロスビルド環境構築

Last updated at Posted at 2025-10-05

コンテナ開発用の環境をDebian系+DockerからRedHat系+Podmanにしようとしてるので
お試し環境構築忘備録

  • プライベートレジストリ(Docker Registry)
  • クロスビルド環境(マルチプラットフォーム)

rootless生かしてうまい具合にユーザー切り分けて運用したい

当方Dockerしか触ったことない

DockerとPodmanの違い(n番煎じなので折りたたみ)
  • Dockerのようにrootのdaemonが常駐しない
    • 起動時のコンテナ立ち上げはsystemdを使う
    • Podman の --restart は「Podman が再起動したとき」にコンテナをどうするか程度の意味なので、基本的に不要
  • sudoでrootful、つけないとrootlessで動作する
    rootful、rootlessの各ユーザは環境・設定を共有しない
    環境をまたいでコンテナ間でやり取りする場合ホストポートをつかう等必要となる
    • デフォルトnetworkのNameはpodmanだがコンテナ名での名前解決ができない
      • コンテナ名での名前解決は同じカスタムネットワーク内か同じPod内のみ
    • rootlessの場合root権限が必要なポートである1024未満のポートが利用できない
      利用したい場合はホスト側の設定で80⇒8080のようなポートフォワーディングを行う
      ※カーネルの設定を変える術はあるが非推奨
  • Podという概念がある(Kubernetes由来?)
    • 1つのPodにまとめたコンテナは同じホストに存在するようなふるまい
      • 共通のvolumeをつくれる
      • localhostでアクセスできる
      • portを競合させることができない
    • デザインパターン、アンチパターンがあるので確認

方針

  • Cockpitでサーバー管理
  • 原則rootlessのみ
    以下ユーザーを準備 sudo権限を与えない
    • svcuser サービス用ユーザー
      • systemdでコンテナ起動設定
      • login ctl enable-linger USERNAMEでセッションが終わった後もsystemdで起動したプロセスを終了させないよう設定
    • builder 一般ユーザー
      • ビルド作業、テスト用
  • 今回Podを用いるデザインパターンなし

環境

  • WSL バージョン: 2.6.1.0
    • カーネル バージョン: 6.6.87.2-1
    • Windows バージョン: 10.0.26100.6584
  • AlmaLinux 10.0
    • cockpit.x86_64 334.1-1.el10_0
    • podman.x86_64 6:5.4.0-13.el10_0
    • buildah.x86_64 2:1.39.4-2.el10_0

Install AlmaLinux on WSL2

# 今回更新しておく
wsl update
wsl --set-default-version 2
# インストールできるディストリビューション確認
wsl --list --online
wsl --install -d AlmaLinux-10

以降AlmaLinux内

初期設定

1.パッケージ一覧取得とセキュリティ更新

$ dnf list --all
$ dnf check-update
# dnf upgrade --security

2.日本語化

$ dnf -y install langpacks-ja
# localectl set-locale LANG=ja_JP.UTF-8
$ source /etc/locale.conf
$ date
2025年 10月  4日 土曜日 13:16:19 JST

WSLの場合TimeZone設定済

パッケージ導入

Cockpit - サーバー管理ツール

# dnf install cockpit
# systemctl enable --now cockpit.socket

https://localhost:9090またはhttps://${severip}:9090でアクセス

image.png
アプリケーションからPodman用のアドオンをインストールすることができる

Podman - コンテナ実行・管理エンジン

# dnf install podman

WSL2のissue対応

Podmanでコンテナをカスタムnetworkに参加させる際やQEMU導入の際に以下エラーが発生

internal:0:0-0: Error: Could not process rule: No such file or directory
Error: netavark: nftables error: nft did not return successfully while applying ruleset

WSL2側のissueとして実施日の前日にもコメントが行われていた
https://github.com/containers/podman/issues/25201

発生した際の対応策

nftablesでなくiptablesを使うように設定
/etc/containers/containers.conf

[network]
firewall_driver="iptables"

Buildah - コンテナビルドツール

# dnf install buildah

QEMU

クロスビルドに対応するためQEMUをインストールする
古いドキュメントだとqemu-user-staticが案内されているが、現在は提供されていない。
コンテナ経由で作成する。
https://docs.docker.com/build/building/multi-platform/#qemu
バイナリが/proc/sys/fs/binfmt_misc/に作成されればOKなのでrootfulで1回だけ動かす。
sudo podman run --privileged --rm tonistiigi/binfmt --install all
/proc/(仮想ファイルシステム) 内に作られるため再起動すると内容が失われる。
永続化のためにsystemdユニットファイルを作る必要があるがpodman generate systemd が対応していないため
自力で作る必要がある。

1.ユニットファイルを作成

rootコンテナとして起動するように/etc/systemd/system/binfmt-container.serviceを作成

[Unit]
Description=Register binfmt_misc using tonistiigi/binfmt
After=network.target
Requires=proc-sys-fs-binfmt_misc.mount

[Service]
Type=oneshot
ExecStartPre=/bin/mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
ExecStart=/usr/bin/podman run --rm --privileged tonistiigi/binfmt --install all
RemainAfterExit=true

[Install]
WantedBy=multi-user.target
  • ExecStartPre=/bin/mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
    先にマウントしないとpodman runが成功しても作成されなかった 起動順の問題みたい
  • oneshot 起動後すぐに終了する
  • RemainAfterExit=true サービス終了後も「アクティブとして保持」
2.ユニットを有効化して起動
$ sudo systemctl daemon-reexec
$ sudo systemctl daemon-reload
$ sudo systemctl enable binfmt-container.service
$ sudo systemctl start binfmt-container.service

再起動後確認

$ sudo systemctl status binfmt-container.service
$ ls -a /proc/sys/fs/binfmt_misc/
.   WSLInterop    qemu-arm          qemu-mips64    qemu-ppc64le  qemu-s390x  status
..  qemu-aarch64  qemu-loongarch64  qemu-mips64el  qemu-riscv64  register

qemu-* のエントリがあれば、そのアーキテクチャがエミュレーション可能。

ユーザー作成

  • サービス用ユーザーを作成
  • /srv以下にサービスのvolumeを作るため権限を与える
  • enable-linger systemdで起動したプロセスはログアウト後も終了させない
# useradd -m -s /bin/bash svcuser
# passwd svcuser
# chown svcuser:svcuser /srv
$ login ctl enable-linger svcuser
  • ビルダーユーザーを作成
# useradd -m -s /bin/bash builder
# passwd builder

コンテナ運用環境構築 (svcuserで作業)

カスタムnetworkを作成

$ podman network create infra-net
$ podman network ls
NETWORK ID    NAME        DRIVER
4e23f5ec6468  infra-net   bridge
2f259bab93aa  podman      bridge

プライベートレジストリ作成

1.Registryコンテナ作成

volume用ディレクトリ作成

$ mkdir /srv/registry
$ podman run -d \
  --name registry \
  --network infra-net \
  -p 5000:5000 \
  -v /srv/registry:/var/lib/registry:z \
  docker.io/library/registry:3

複数レジストリがあるのでdocker.io/library/registryと明示するのがよい。
コンテナをCockpitで見ることができる。Cockpit上でコンテナを作成することもできる。
image.png

http://${server_ip}/v2/_catalogまたはhttp://localhost:5000/v2/_catalogにアクセスすることでカタログが参照できる。

2.コンテナーレジストリの設定

ローカルでコンテナレジストリを参照するためのPodmanの設定を行う

RedHat公式ドキュメントが詳しい

ここだけルートユーザー# ローカルのプライベートレジストリにTLSなしでアクセスするように/etc/containers/registries.confを編集

[[registry]]
location="localhost:5000"
insecure=true

podman infoでレジストリが追加されているのがわかる

$ podman info
...
registries:
  localhost:5000:
    Blocked: false
    Insecure: true
    Location: localhost:5000
...

これでpush/pullが行える

$ podman push localhost:5000/myimage:latest
$ podman pull localhost:5000/myimage:latest

3. コンテナ永続化(systemd)

  1. コンテナが起動している場合停止
  2. 作業ディレクトリにsystemd ユニットファイル作成
    $ podman generate systemd --name registry --files --new
    $ ls
    container-registry.service
    
  3. ユニットファイルをユーザー用 systemd に配置
    $ mkdir -p ~/.config/systemd/user
    $ mv container-registry.service ~/.config/systemd/user/
    
  4. systemd にリロードして有効化
    $ systemctl --user daemon-reload
    $ systemctl --user enable --now container-registry.service
    
    • enable → ログイン時に自動起動
    • now → 今すぐ起動
  5. 確認
    $ systemctl --user status container-registry.service
    ● container-registry.service - Podman container-registry.service
        Loaded: loaded (/home/svcuser/.config/systemd/user/container-registry.service; enabled; preset: disabled)
         Active: active (running) since Sun 2025-10-05 19:04:32 JST; 8s ago
    

コンテナ開発環境構築 (builderで作業)

クロスビルド

$ pwd
/home/builder/podman-build/images/hello
$ cat Dockerfile 
FROM alpine:latest
CMD ["echo", "Hello, World!"]

--- amd64版をビルド
$ podman build --platform linux/arm64 --tag test/hello:amd64 .
--- arm64版をビルド
$ podman build --platform linux/arm64 --tag test/hello:arm64 .

または

--- amd64版をビルド
$ buildah bud --arch amd64 -t test/hello2:amd64 .
--- arm64版をビルド
$ buildah bud --arch arm64 -t test/hello2:arm64 .

--- 確認
$ podman inspect localhost/test/hello:amd64 | grep Architecture
          "Architecture": "amd64",
$ podman inspect localhost/test/hello:arm64 | grep Architecture
          "Architecture": "arm64",

マルチアーキテクチャイメージのマニフェストを作るとCockpitのPodman管理画面がエラーとなる
マニフェストを削除すれば復旧する

マルチアーキテクチャーイメージのビルド(失敗)

RHELのマニュアル見るとpodman buildでのビルド方法が書いてある
4.9. マルチアーキテクチャーイメージのビルド

$ podman build --platform linux/arm64,linux/amd64 --manifest test/hello .
[linux/arm64] STEP 1/2: FROM alpine:latest
...
[linux/arm64] COMMIT
--> d8874c695a2e
[linux/amd64] STEP 1/2: FROM alpine:latest
...
[linux/amd64] COMMIT
--> ebd3963ef97e
ebd3963ef97e220d6bcdf944d51fe06e9349d306c74ad8ba3e8288fedca59c4f
$ podman images
REPOSITORY                TAG         IMAGE ID      CREATED        SIZE
<none>                    <none>      ebd3963ef97e  3 minutes ago  8.6 MB
localhost/test/hello      latest      af7fd5600141  3 minutes ago  1.05 kB
<none>                    <none>      d8874c695a2e  3 minutes ago  8.79 MB
docker.io/library/alpine  latest      9234e8fb04c4  2 months ago   8.61 MB

📦 ebd3963ef97e ← amd64用のイメージ
📦 d8874c695a2e ← arm64用のイメージ
📦 af7fd5600141 ← マニフェスト (両方をまとめた仮想イメージ)
ができた

しかし

  • マニフェストの中を見てもarm64がいない
  • cockpit-podmanがクラッシュする

上記イメージをpodman rmiで削除すれば復旧する

buildahでも同様

--- amd64版をビルド
$ buildah bud --arch amd64 -t test/hello:amd64 .
--- arm64版をビルド
$ buildah bud --arch arm64 -t test/hello:arm64 .
--- マニフェスト作成(この段階でcockpit-podmanでイメージが見れない) ---
$ buildah manifest create test/hello
--- マニフェスト追加 ---
$ buildah manifest add test/hello test/hello:amd64
$ buildah manifest add test/hello test/hello:arm64

プライベートレジストリへのpush

$ podman images
REPOSITORY                TAG         IMAGE ID      CREATED         SIZE
localhost/test/hello      amd64       8f12cba7d171  4 seconds ago   8.6 MB
localhost/test/hello      arm64       c8752c6caa0f  17 seconds ago  8.79 MB
docker.io/library/alpine  latest      9234e8fb04c4  2 months ago    8.61 MB
$ podman tag localhost/test/hello:amd64 localhost:5000/test/hello:amd64
$ podman tag localhost/test/hello:arm64 localhost:5000/test/hello:arm64
$ podman push localhost:5000/test/hello:amd64
Getting image source signatures
Copying blob 418dccb7d85a done   |
Copying config 8f12cba7d1 done   |
Writing manifest to image destination
$ podman push localhost:5000/test/hello:arm64
Getting image source signatures
Copying blob 0b83d017db6e done   |
Copying config c8752c6caa done   |
Writing manifest to image destination

確認

$ curl -s http://localhost:5000/v2/_catalog
{"repositories":["test/hello"]}
$ curl -s http://localhost:5000/v2/test/hello/tags/list
{"name":"test/hello","tags":["amd64","arm64"]}
マルチアーキテクチャイメージ失敗
$ podman manifest create localhost/test/hello:latest
$ podman manifest add localhost/test/hello:latest localhost/test/hello:amd64
$ podman tag localhost/test/hello:latest localhost:5000/test/hello:latest
$ podman push localhost:5000/test/hello:latest
Getting image source signatures
Copying blob 5f70bf18a086 done   |
Copying blob 418dccb7d85a done   |
Copying config bbb84b0839 done   |
Writing manifest to image destination
$ curl -X GET http://localhost:5000/v2/_catalog
{"repositories":["test/hello"]}
[hijiri@powerPC srv]$ curl -X GET http://localhost:5000/v2/test/hello/manifests/latest
{"errors":[{"code":"MANIFEST_UNKNOWN","message":"OCI manifest found, but accept header does not support OCI manifests"}]}

イメージが消えなくなったのですべてのイメージを削除

podman system prune -a --force
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?