Podman は、Linux でコンテナを開発、管理、実行するためのデーモンレスコンテナエンジンです。ルートレス(root以外の一般ユーザー)でコンテナを実行できるのが大きな魅力です。RHEL8 および CentOS8 では Docker コンテナエンジンは削除されサポート対象外になりました。そのため今後はこの Podman コンテナエンジンの利用が推奨されています。そこで今回は、CentOS8 へ Podman をインストールし、ルートレスでコンテナ起動するまでの手順をまとめてみました。
CentOS 8.1 (1911) 以上をインストール
ルートレスの Podman は、RHEL 8.1 で完全サポートされました。CentOS は、RHEL と機能的に互換性がありますので、ルートレスの Podman を使うには同等のバージョン CentOS 8.1 (1911) 以上をインストールする必要があります。
参考資料:RHEL 8.1: A minor release with major new container capabilities
CentOS 8.0 (1905) をインストールしている場合は、以下のコマンドで CentOS 8.1 (1911) 以上にアップデートしてください。
アップデートが終わったら一度再起動しておきましょう。
Podman のインストール
Podman をインストールします。
必須ではありませんが podman-docker をインストールすると docker コマンドを podman でエミュレートしてくれます。
ルートレス用のユーザーの作成
注意が必要なのは、Podman をインストールする前に作成した既存ユーザーは、そのままではルートレスPodman を実行できないことです。(実行するための設定は後ほどご紹介します)
ルートレス用のユーザーを作成する前に、ユーザーの名前空間を増やします。
---(以下を追加)---
user.max_user_namespaces=28633
上記の設定を反映します。
新規ユーザーを作成します。作成したユーザーは、ルートレスpodman を実行できるように自動で設定されます。
sudo passwd foo
作成したユーザーでログインしなおして、確認のため nginxコンテナを起動してみましょう。( su や su - でユーザーを切り替えるのはNGです。正しい環境変数が設定されません)
curlなどでコンテナ上の nginx に接続してデフォルトページ(のタグ)が表示されていればOKです。
(略)
<title>Welcome to nginx!</title>
以下のコマンドを実行すると、uid がユーザーの名前空間にどのようにを割り当てられるかが表示され、ルートレスが正しく動作していることを確認できます。
0 1001 1
1 165536 65536
かたずけ用コマンドです。要領は dockerコマンドとまったく同じですね。
podman rm $(podman ps -q -a) # 全コンテナ削除
podman rmi $(podman images -q) # 全コンテナイメージ削除
既存ユーザーでルートレスを実行するための設定
既存ユーザーで ルートレスPodman を実行するためには、手動で subuid と subgid を設定する必要があります。(自動で設定される場合もあるようです)
例として既存ユーザー bar の subuid と subgid の設定手順です。(設定値はご自分の環境に合わせて設定してください)
ユーザー foo には subuid が 100000 から 65536個 すなわち 100000〜165535 が割り当てられているため、既存ユーザー bar にはそれとかぶらないように 165536 から 65536個 の subuid を設定します。
sudo vi /etc/subuid
---(以下を追加)---
bar:165536:65536
subgid も同様に設定します。
sudo vi /etc/subgid
---(以下を追加)---
bar:165536:65536
以上で既存ユーザー bar でルートレスPodman を実行できるようになりました。
ルートレスに関する注意点や制限
ルートレスでコンテナを実行できるのは、セキュリティ的に大きなメリットがありますが、注意点や root 権限がないことによる制限があります。
ルートレスのコンテナイメージは /var/lib/containers/sigstore/ ではなく、ホームディレクトリの以下の場所に保存されます。
ルートレスのコンテナ環境の設定ファイルは /etc/containers/ ではなく、ホームディレクトリの以下場所に作成します。
root権限のない一般ユーザーは、ポート1024未満を公開することができないため、例えばですが ルートレスで実行したコンテナ上の Webサーバーをポート80 で公開することができません。
そのため、ポート1024未満でサービスを公開したい場合は、ポートフォワードなどでポートをマッピングする必要があります。(これには root 権限が必要です)
sudo firewall-cmd --add-port=80/tcp --permanent
sudo firewall-cmd --reload
上記以外にもルートレスには色々な制限があります。詳しくは公式ページをご確認ください。
参考資料:コンテナーの構築、実行、および管理(ルートレスに関する特別な考慮事項)| Red Hat Enterprise Linux 8
(おまけ)Kubernetes マニフェストの生成と再生
ルートレスとは関係ありませんが Podman は、Kubernetes マニフェストを生成したり再生することもできます。Kubernetes Pod の開発に便利な機能ですね。
(補足)Kubernetes(省略して「K8s」と表記することもあります)は、コンテナ化されたアプリケーションを管理するためによく使われるオープンソースのシステムです。コンテナベースのWebアプリケーションなどに今や必須のシステムになりました。
マニフェストの生成
マニフェストを生成するコンテナを実行します。
コンテナの ID または NAMES を確認します。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff089b05330e docker.io/library/nginx:latest nginx -g daemon o... About a minute ago Up About a minute ago 0.0.0.0:8080->80/tcp interesting_banach
コンテナの ID または NAMES を指定して Kubernetes マニフェストを生成します。
以下のコマンドで生成した Kubernetes マニフェストを使って Kubernetes Pod を作成することができます。
マニフェストの再生
マニフェストを生成したコンテナを削除します。
podman rm ff089b05330e
以下のコマンドで Kubernetes マニフェストを再生してコンテナを実行します。
マニフェストを生成した nginxコンテナが起動していることが確認できます。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
45f436568953 docker.io/library/nginx:latest /docker-entrypoin... 5 minutes ago Up 5 minutes ago 0.0.0.0:8080->80/tcp interestingbanach
おわりに
root 権限で実行されるコンテナは、ホストサーバに与える影響が大きく本番環境ではセキュリティの確保が大きな課題でした。ルートレスなコンテナは一部の制限はありますが、ホストサーバの root 権限を持たないためセキュリティの確保が容易になります。ぜひ積極的に活用したいですね。
コメント