podmanをEndeavourOSに入れてみた

2022年6月19日

コンテナに関してちょっと調べていたところ、dockerが有償化になったとの話があり、個人的に使っている文には問題なさそうなのだけどせっかくなのでdockerと互換性があるpodmanを導入してみようと思い、そのログをまとめてみました。
ちなみにほとんどarchの記事を参考に構築しているので、archでも同じ感じで入ると思います。きっとmanjaroも入ると思います。(違ってたらごめんなさい。。)

podmanってなに?

podmanとはRedhat社が開発しているオープンソースのコンテナ管理ツールです。
RHEL/CentOSでは現在はdockerではなく、podmanの利用を推奨しています。どちらももちろん使えます。
dockerとは互換性があり、管理用のコマンドの多くは同じようなオプションで使えるようです。
互換性があるのはありがたいですね。コマンドに関してもpodman-dockerを入れたらdockerコマンドがそのまま使えてしまいます。とはいえ、dockerとpodmanはそもそも構造が異なるため、その差異は意識しておいた方がよさそうです。

dockerとpodmanの差異は、Redhatいわく、dockerのメインプロセスであるdockerdプロセスに問題が起こると全部のコンテナに影響がでてしまうから、管理プロセスをデーモン化(常駐プロセス)にするのは辞めようということのようです。
そのため、podmanにはdockerのような常駐プロセスはなく、コマンドラインからの支持を直接各コンテナに送っているようですが、コンテナ毎に管理プロセスはあるようなので、dockerdというコンテナ全体を一元管理するデーモン構成ではなく、各コンテナ毎に独立しましょうということとの理解で良いと思います。

EndeavourOSにpodmanをインストール

本体のインストール

podmanはEndeavourOS(archのリポジトリ)にあります。
なので、pacmanないし、yayのようなパッケージ管理コマンドでインストールできます。
yayやparuを使われている場合は、適宜読み替えてもらえば大丈夫です。

#podmanをpacmanコマンドでインストール
$ sodo pacman -S podman

#podmanのインストール確認
$ podman version
Client:       Podman Engine
Version:      4.1.0
API Version:  4.1.0
Go Version:   go1.18.1
Git Commit:   e4b03902052294d4f342a185bb54702ed5bed8b1
Built:        Sat May  7 03:18:30 2022
OS/Arch:      linux/amd64

# コンテナを動かすqemuを入れる
$ sudo pacman -S qemu
:: 3 個の選択肢が qemu にはあります:
:: リポジトリ extra
   1) qemu-base  2) qemu-desktop  3) qemu-full
数字を入力してください (デフォルト=1): 1      ←とりあえず標準で入れておく。
依存関係を解決しています...
衝突するパッケージがないか確認しています...

初期設定

まずはpodmanを動かすための初期設定を行っていきます。
ここでやるのは一般ユーザでpodmanを動かせるようにします。毎回rootユーザでpodmanを操作するのも辛いですし、そもそもrootで動かすとなると常にrootでログインってセキュリティ上よろしくないので、rootレスの設定を行っていきます。

# まずは一般ユーザをpodmanで動かせるように登録します。(これらはrootでやるのでsudoを使う)
$ sudo touch /etc/subuid /etc/subgid
# userをさっき作ったファイルに登録する。(viで直接編集でも大丈夫) usernameは使いたいユーザに読み替える
$ sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 username
$ cat /etc/subuid
username:100000:65536
$ cat /etc/subgid
username:100000:65536
# カーネル設定を確認(kernel.unprivileged_userns_clone が1であること)
$ sudo  sysctl kernel.unprivileged_userns_clone
kernel.unprivileged_userns_clone = 1
# 設定を反映させる
$ sudo podman system migrate

コンテナを動かす準備

コンテナを動かす準備として、仮想マシンを入れます。(2022年6月時点の標準構成だとFedora36が入ります)
仮想マシンを起動したところgvproxyが見つからないエラーが発生。
podman3.3から仮想マシンのポートフォワード用にgvproxyを使うようになったとのことなので、gvproxyをインストールします。AURには「gvisor-tap-vsock」というパッケージで存在するので、今回はAURのパッケージを使用することとしました。

# コンテナを動かす仮想マシンを初期化する
$ podman machine init
Downloading VM image: fedora-coreos-36.20220511.dev.0-qemu.x86_64.qcow2.xz: done
Extracting compressed file

Image resized.
Machine init complete
To start your machine run:

	podman machine start

# 仮想マシンの起動!だけど失敗。。
Starting machine "podman-machine-default"
Error: unable to start host networking: "could not find \"gvproxy\" 
in one of [/usr/local/libexec/podman /usr/local/lib/podman /usr/libexec/podman /usr/lib/podman]. 
 To resolve this error, set the helper_binaries_dir key in the `[engine]` section of containers.
conf to the directory containing your helper binaries."

ちょっと回り道(paruの導入)

paruとはAURヘルパーです。yayからフォークされて開発されているようです。ちなみにAURヘルパーはお好みでyayでもparuでもその他でもarch系Linuxを使うならマストアイテムですね!
paruはRust言語で書かれているため、Rustのコンパイラも一緒に入ります。
私の非力なPCではparuのコンパイルに10分くらいかかりました。。
また、Go言語のコンパイラも必要になるので、こっちはリポジトリからインストールしました。

# paruを取得する。AURからgitコマンドする
$ git clone https://aur.archlinux.org/paru.git
Cloning into 'paru'...
remote: Enumerating objects: 155, done.
remote: Counting objects: 100% (155/155), done.
remote: Compressing objects: 100% (108/108), done.
remote: Total 155 (delta 47), reused 155 (delta 47), pack-reused 0
Receiving objects: 100% (155/155), 46.54 KiB | 162.00 KiB/s, done.
Resolving deltas: 100% (47/47), done.

# paruのディレクトリに移動して
$ cd paru
# paruのビルド(ここでRustも一緒に入れる。sudoなくてもsudoが内部的に発行されるようす)
$ makepkg -si

# Go言語コンパイラのインストール
$ sudo pacman -S go

gVisor(gvproxy)の導入

さて、paruも入ったので、再度gVisorを入れてみます。ちなみにgVisorはGo言語で書かれているのでGoのコンパイラも一緒に入ります。

$ paru -S gvisor-tap-vsock
:: 依存関係を解決しています...
:: 衝突を確認しています...
:: 内部衝突を確認しています...

Aur (1) gvisor-tap-vsock-0.3.0-1

:: レビューを続行しますか? [Y/n]: Y

:: PKGBUILD をダウンロードしています...
 PKGBUILD は最新です
/home/qtaro/.cache/paru/clone/gvisor-tap-vsock/PKGBUILD
# Maintainer: Juanjo Gutiérrez <juanjo at gutierrezdequevedo dot com>
pkgname=gvisor-tap-vsock
pkgver=0.3.0
pkgrel=1
pkgdesc="A new network stack based on gVisor"
arch=('x86_64')
url="https://github.com/containers/gvisor-tap-vsock"
license=('Apache-2.0')
provides=('gvisor-tap-vsock')
source=($pkgname-$pkgver.tar.gz::https://github.com/containers/gvisor-tap-vsock>
sha256sums=('6ca454ae73fce3574fa2b615e6c923ee526064d0dc2bcf8dab3cca57e9678035')
makedepends=()

build() {
    cd "$pkgname-$pkgver"
    make
}

package() {
    cd "$pkgname-$pkgver"
    install -d -m 0755 "$pkgdir/usr/bin"
    install -d -m 0755 "$pkgdir/usr/lib/podman"
:: インストールを行いますか? [Y/n]: Y
開発情報を取得しています...
==> パッケージを作成: gvisor-tap-vsock 0.3.0-1 (2022年06月12日 15時03分47秒)
==> ソースを取得...
  -> ダウンロード gvisor-tap-vsock-0.3.0.tar.gz...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 3761k    0 3761k    0     0   507k      0 --:--:--  0:00:07 --:--:--  884k
==> source で sha256sums ファイルを検証...
    gvisor-tap-vsock-0.3.0.tar.gz ... 成功
==> パッケージを作成: gvisor-tap-vsock 0.3.0-1 (2022年06月12日 15時03分56秒)
==> ランタイムの依存関係を確認...
==> ビルドタイムの依存関係を確認...
==> ソースを取得...
  -> gvisor-tap-vsock-0.3.0.tar.gz を見つけました
==> source で sha256sums ファイルを検証...
    gvisor-tap-vsock-0.3.0.tar.gz ... 成功
==> 既存の $srcdir/ ディレクトリを削除...
==> ソースを展開...
  -> gvisor-tap-vsock-0.3.0.tar.gz を bsdtar で展開
==> ソースの準備ができました。
gvisor-tap-vsock-0.3.0-1: パッケージリストを解析しています...
==> パッケージを作成: gvisor-tap-vsock 0.3.0-1 (2022年06月12日 15時03分58秒)
==> ランタイムの依存関係を確認...
==> ビルドタイムの依存関係を確認...
==> 警告: 既存の $srcdir/ ツリーを使用
==> build() を開始...
go build -ldflags '-s -w' -o bin/gvproxy ./cmd/gvproxy
go build -ldflags '-s -w' -o bin/qemu-wrapper ./cmd/qemu-wrapper
GOOS=linux CGO_ENABLED=0 go build -ldflags '-s -w' -o bin/vm ./cmd/vm
==> fakeroot 環境を開始します...
==> package() を開始...
==> インストールを整理...
  -> libtool ファイルを削除...
  -> 不要なファイルを削除...
  -> スタティックライブラリファイルを削除しています...
  -> バイナリとライブラリから不要なシンボルを削除...
  -> man と info ページを圧縮...
==> パッケージの問題をチェック...
==> 警告: パッケージは $srcdir へのリファレンスを含んでいます
usr/lib/podman/gvproxy
usr/bin/vm
usr/bin/qemu-wrapper
==> パッケージを作成 "gvisor-tap-vsock"...
  -> .PKGINFO ファイルを生成...
  -> .BUILDINFO ファイルを生成...
  -> .MTREE ファイルを生成...
  -> パッケージの圧縮...
==> fakeroot 環境を終了。
==> 作成完了: gvisor-tap-vsock 0.3.0-1 (2022年06月12日 15時04分39秒)
==> 清掃...
[sudo] xxx のパスワード:
パッケージをロード...
依存関係を解決しています...
衝突するパッケージがないか確認しています...

パッケージ (1)    新しいバージョン  最終的な変化

gvisor-tap-vsock  0.3.0-1              15.42 MiB

合計インストール容量:  15.42 MiB

:: インストールを行いますか? [Y/n] 
(1/1) キーリングのキーを確認                       [----------------------] 100%
(1/1) パッケージの整合性をチェック                 [----------------------] 100%
(1/1) パッケージファイルのロード                   [----------------------] 100%
(1/1) ファイルの衝突をチェック                     [----------------------] 100%
:: パッケージの変更を処理しています...
(1/1) インストール gvisor-tap-vsock                [----------------------] 100%
:: トランザクション後のフックを実行...
(1/1) Arming ConditionNeedsUpdate...
$ 

仮想マシンの起動!あれ?

gvproxyも入れてサイド起動してみたら、あれ?ソケットに接続できない??
うーん、闇が深そうで嫌だなあ。。
(2022.06.19更新) 相変わらず理由はわかりませんが、一応コンテナは動いているようです。。

$ podman machine start
Starting machine "podman-machine-default"
Waiting for VM ...
Error: dial unix /run/user/1000/podman/podman-machine-default_ready.sock: connect: connection refused

コンテナの起動

コンテナのベースとなる仮想マシンの謎エラーは解決しませんが、コンテナ自体は動くようです。
なので、コンテナをかんたんに動かしたときのメモを書きます。
せっかくgvproxyも入れたので、コンテナ上のネットワークポートと、ホスト側のポートとポートフォワードできることも確認しときます。

# nginxのコンテナイメージをダウンロード
$ podman pull docker.io/library/nginx
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob db24d06d5af4 done  
Copying blob 42c077c10790 done  
Copying blob 62c70f376f6a done  
Copying blob 915cc9bd79c2 done  
Copying blob 75a963e94de0 done  
Copying blob 7b1fab684d70 done  
Copying config 0e901e6814 done  
Writing manifest to image destination
Storing signatures
0e901e68141fd02f237cf63eb842529f8a9500636a9419e3cf4fb986b8fe3d5d

# nginxのコンテナを起動。ちなみにコンテナ上のポート80番をホスト側の8888番にポートフォワード
$ podman run --rm -d --name nginx -p 8888:80 --network bridge nginx
bb244d431c55724968848f571258af4db7506702e6637ba6b5396db8ada38aef

# curlコマンドでnginxのtopページが表示できるか確認。
$ curl http://localhost:8888 |head -n 4
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   615  100   615    0     0  29266      0 --:--:-- --:--:-- --:--:-- 32368
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
$

おわりに

今回は、超お手軽というかコンテナの基本の一歩目をやってみました。
そのうちになれてきたら、nginx+PHP+MariaDBとかでWordPress動かすようなコンテナを作るとかやってみたいと思います。
dockerも企業では無料でなくなったり、そもそもRedhatは自分のところのpodmanを推奨したりと、コンテナ周りは常に動きがありますので、この記事もすぐに陳腐化するんだろうなともいますが、新しいものがでることは良いことですので、私も遅れないように情報収集しようと思います。

Arch系

Posted by Qtaro