ウェブサイト検索

Podmanを使用してコンテナの使い方を始める(Dockerデーモンは不要)


コンテナは、私たちがアプリケーションを開発、テスト、デプロイする方法を革命的に変えました。Dockerが最も有名なコンテナ化技術ですが、Podmanはバックグラウンドで動作するデーモンを必要としない魅力的な代替手段を提供します。Podmanは、Dockerと互換性がありながら、デーモンレスでルートレスな設計によって追加のセキュリティ利益を提供する無料でオープンソースのコンテナエンジンです。このチュートリアルでは、UbuntuにPodmanを設定し、基本的なコンテナ操作を始める方法を説明します。

このチュートリアルでは、あなたは学びます:

  • UbuntuにPodmanをインストールする方法
  • ルート特権なしでコンテナを実行する(ルートレスコンテナ)
  • コンテナとイメージを管理するための基本的なPodmanコマンド
  • コンテナ内でシンプルなウェブサーバーを実行する方法
  • Podmanを使用するためにDockerのエイリアスを設定する

Podmanとは何ですか、そしてなぜそれを使用するのですか?

Podman(ポッドマネージャー)は、デーモンを必要とせずにコンテナを実行および管理できるコンテナエンジンです。Dockerがroot権限で動作する集中管理のデーモンに依存しているのとは異なり、Podmanは通常のLinuxコマンドと同様のフォーク/エグゼックモデルで動作します。このアーキテクチャは、いくつかの利点を提供します:

  • ルートレス操作によるセキュリティの向上
  • 管理や心配するためのデーモンはありません
  • Docker互換のコマンドラインインターフェース
  • コンテナライフサイクルを管理するためのsystemdとのより良い統合

ルートレスとドッカーグループ
ルートレスのPodmanは、ユーザー名前空間を使用してコンテナプロセスを隔離し、コンテナが侵害された場合でも特権の昇格を防ぎます。Dockerグループのユーザーは、Dockerソケットがルートとして実行されているDockerデーモンへの無制限のアクセスを提供するため、ホスト上で実質的にルートに相当する権限を持っています。ユーザーをDockerグループに追加することは便利に思えますが、コンテナのブレイクアウトが完全なシステム侵害につながる可能性があるため、重大なセキュリティリスクを表しています。Podmanのルートレスアプローチは、この特権の昇格経路を排除することにより、根本的により安全なコンテナランタイムモデルを提供します。

Ubuntu に Podman をインストールする

まずは、UbuntuシステムにPodmanをインストールし、それが正しく動作するかどうか確認しましょう。

  1. パッケージリポジトリを更新してください: まず、パッケージリストが最新であることを確認してください。

    sudo apt update
  2. このコマンドは、最新の利用可能なバージョンを取得するためにパッケージインデックスを更新します。

  3. Podmanをインストールする: UbuntuのリポジトリからPodmanをインストールします

    sudo apt install -y podman
  4. -yフラグは、ユーザーの入力を必要とせずにインストールを自動的に確認します。

  5. インストールを確認する: Podmanが正しくインストールされたか確認してください

    podman --version
  6. このコマンドは、インストールされたPodmanのバージョンを表示し、成功したインストールを確認する必要があります。

  7. ルートレスモードの設定: ルートレスコンテナ操作のためにシステムを設定します

    podman system migrate
  8. このコマンドは、ルートレスコンテナ操作のために必要なユーザーネームスペースを設定します。すべての変更が有効になるためには、ログアウトして再度ログインする必要があるかもしれません。

PODMAN対DOCKER
Podmanは、通常のユーザーとしてコンテナをルート特権なしで実行するデーモンレスのコンテナエンジンを提供します。Dockerはバックグラウンドデーモンプロセスに依存していますが、より広範なエコシステムサポートと成熟したツールを持っています。両方の技術はOCI標準を実装しており、コンテナはほぼ互換性があります。Podmanのルートレスセキュリティモデルとポッドネイティブアーキテクチャは、企業環境でますます人気を高めています。

ルートレスコンテナの理解

Podmanの主な利点の一つは、ルートなしのコンテナをネイティブにサポートしていることであり、これにより通常の権限のないユーザーとしてコンテナを実行することができます。これにより、コンテナがホストシステムやお互いから分離されることでセキュリティが向上します。

  1. ユーザー名前空間設定を確認してください: ユーザー名前空間が正しく設定されていることを確認してください

    cat /proc/sys/user/max_user_namespaces

    出力はゼロ以外の数字である必要があります。もしゼロの場合は、以下のようにユーザー名前空間を有効にする必要があります:

    sudo sysctl user.max_user_namespaces=15000

    この変更を永続的にするには、/etc/sysctl.conf に次の行を追加してください:

    user.max_user_namespaces=15000
  2. subuidおよびsubgidマッピングの設定: これらのマッピングは、ルートレスコンテナにとって重要です

    sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $(whoami)
  3. このコマンドは、コンテナ化されたプロセスに使用されるあなたのユーザーアカウントに対して、一連の従属性UIDおよびGIDを割り当てます。

    PODMAN ユーザー名前空間警告
    サブ UID およびサブ GID マッピングを適切に設定することは、Podman における安全なルートレスコンテナ操作に不可欠です。これらのマッピングがないと、非ルートユーザーとしてコンテナを実行しようとしたときに、権限エラーが発生する可能性があります。

  4. 設定を確認する: ユーザーに必要なマッピングがあることを確認してください

    grep $(whoami) /etc/subuid /etc/subgid

    あなたのユーザーに割り当てられたUID/GID範囲を示すエントリが両方のファイルに表示されるはずです。

基本的なPodmanコマンド

では、コンテナとイメージを管理するための基本的なPodmanコマンドをいくつか探ってみましょう。Dockerに慣れているなら、大部分のコマンドが同じであることに気付くでしょう。

  1. 最初のコンテナイメージをプルする: 簡単なウェブサーバーイメージをダウンロードする

    podman pull docker.io/nginxinc/nginx-unprivileged:latest
  2. このコマンドは、Docker Hubからnginx-unprivilegedイメージをダウンロードします。ルートレスモードで実行しているため、特権なしのバージョンを使用しています。

  3. 利用可能な画像のリスト: ローカルで利用可能な画像を確認する

    podman images
  4. これにより、あなたのシステムにダウンロードされたすべてのコンテナイメージが表示されます。

  5. コンテナを実行する: ウェブサーバーコンテナを開始する

    podman run --name my-nginx -p 8080:8080 -d docker.io/nginxinc/nginx-unprivileged:latest

    このコマンド:

    • –name my-nginx: コンテナに親しみやすい名前を付けます
    • -p 8080:8080: コンテナのポート8080をホストのポート8080にマッピングします
    • -d: コンテナをデタッチモード(バックグラウンド)で実行します
  6. 実行中のコンテナのリスト: 現在実行中のコンテナを確認する

    podman ps

    これにより、すべての実行中のコンテナが表示されます。停止しているコンテナも含めてすべてのコンテナを表示するには、次のコマンドを使用します:

    podman ps -a
  7. コンテナログを確認する: コンテナからの出力を表示します

    podman logs my-nginx
  8. これはコンテナによって生成されたログを表示し、トラブルシューティングに役立ちます。

  9. ウェブサーバーにアクセスする: ウェブサーバーが動作していることを確認してください

    curl http://localhost:8080

    これはデフォルトのNginxウェルカムページのHTMLを返すべきで、あなたのコンテナが正しく動作していることを確認します。

  10. コンテナを停止する: 実行中のコンテナを優雅に停止する

    podman stop my-nginx
  11. これはコンテナにSIGTERM信号を送信し、適切にシャットダウンできるようにします。

  12. 停止したコンテナを開始する: 既存のコンテナを再起動する

    podman start my-nginx
  13. これは、以前に作成された停止したコンテナを再起動します。

  14. コンテナを削除: 使用が終わったコンテナを削除します

    podman stop my-nginx
    podman rm my-nginx
  15. コンテナを削除する前に、-f(強制)フラグを使用しない限り、コンテナを停止しなければなりません。

  16. 画像を削除する: スペースを空けるために画像を削除します

    podman rmi docker.io/nginxinc/nginx-unprivileged:latest
  17. これは指定された画像をローカルストレージから削除します。-f フラグを使用して強制的に削除しない限り、コンテナによって使用されている画像は削除できません。

PodmanのためのDockerエイリアスを作成する

DockerからPodmanに移行する場合や、Dockerコマンドを期待するスクリプトを使用する必要がある場合は、Podmanを使用するためのエイリアスを設定できます。

  1. エイリアスを一時的に作成する: 現在のセッションのためにエイリアスを設定してください

    alias docker=podman
  2. これにより、一時的なエイリアスが作成され、現在のターミナルセッションでのみ利用可能になります。

  3. エイリアスを永続化する: エイリアスをシェルの設定に追加します

    echo "alias docker=podman" >> ~/.bashrc

    これにより、エイリアスがあなたの.bashrcファイルに追加され、新しいBashセッションに対して恒久的になります。

    Zsh ユーザー向け:

    echo "alias docker=podman" >> ~/.zshrc

    エイリアスを追加した後、シェルの設定を再読み込みしてください:

    source ~/.bashrc  # or source ~/.zshrc for Zsh users
  4. エイリアスをテストする: Dockerコマンドが現在Podmanを使用していることを確認します

    docker --version
  5. これによりPodmanのバージョンが表示され、エイリアスが正しく機能していることが確認されるはずです。

より実用的なウェブアプリケーションを運営する

Podmanでボリュームの動作を理解するために、カスタムHTMLファイルを使用してシンプルなウェブアプリケーションコンテナを作成しましょう。

  1. シンプルなHTMLファイルを作成する: まず、ディレクトリとHTMLファイルを作成しましょう。

    mkdir -p ~/podman-demo/html
    echo "<html><body><h1>Hello from Podman\!</h1><p>This is my custom container running with Podman.</p></body></html>" > ~/podman-demo/html/index.html
  2. これにより、ディレクトリ構造と私たちのコンテナから提供するシンプルなHTMLファイルが作成されます。

  3. ボリュームマウントでコンテナを実行する: あなたのHTMLディレクトリをコンテナにマウントします

    podman run --name custom-nginx -p 8080:8080 -v ~/podman-demo/html:/usr/share/nginx/html:Z -d docker.io/nginxinc/nginx-unprivileged:latest

    このコマンド:

    • -v ~/podman-demo/html:/usr/share/nginx/html:Z: あなたのローカルディレクトリをコンテナにマウントします
    • Zサフィックスは、SELinuxがシステムで有効になっている場合に正しいSELinuxラベル付けを保証します。
  4. カスタムページを確認する: HTMLが正しく表示されているか確認してください

    curl http://localhost:8080
  5. あなたが作成したカスタムHTMLコンテンツを見るべきです。

  6. その場で変更する: HTMLを修正し、即座に更新を確認する

    echo "<html><body><h1>Updated Content\!</h1><p>I've updated this without restarting the container.</p></body></html>" > ~/podman-demo/html/index.html
    curl http://localhost:8080

    ディレクトリをボリュームとしてマウントしたため、ホスト上のファイルへの変更はコンテナに即座に反映されます。

資格のない画像名の取り扱い

新しいバージョンのPodmanでは、短いイメージ名を使用すると、次のようなエラーが発生することがあります:

  1. 資格のない検索レジストリを設定する: より短いコマンドを好む場合は、Podmanを特定のレジストリを検索するように設定できます。

    sudo mkdir -p /etc/containers
    sudo sh -c 'echo "[registries.search] registries = [\"docker.io\", \"quay.io\"]" > /etc/containers/registries.conf'

    この設定では、Podmanは未資格画像名を使用した際に自動的にdocker.ioとquay.ioを検索します。

    検索レジストリを構成した後、短いイメージ名を使用できるようになりました:

    podman pull nginxinc/nginx-unprivileged:latest
    podman run --name my-nginx -p 8080:8080 -d nginxinc/nginx-unprivileged:latest
  2. これは、Dockerから移行する場合や、修飾されていないイメージ名を使用している既存のスクリプトで作業している場合に特に役立ちます。

  3. 設定を確認する: あなたのレジストリ設定が動作していることを確認してください

    podman info | grep -A 10 registries

    これにより、追加した検索レジストリを含む構成されたレジストリが表示されます。

コンテナリソースの管理

Podmanは、コンテナが使用できるリソースを制限および制御することを可能にし、これは本番環境にとって重要です。

  1. メモリ制限付きでコンテナを実行する: コンテナが使用できるメモリの量を制限します

    podman run --name limited-nginx -p 8081:8080 --memory 128m -d docker.io/nginxinc/nginx-unprivileged:latest
  2. これにより、コンテナは128MBのRAMを超えて使用できなくなります。

  3. CPU制限を設定したコンテナを実行する: CPU使用率を制限する

    podman run --name cpu-limited-nginx -p 8082:8080 --cpus 0.5 -d docker.io/nginxinc/nginx-unprivileged:latest
  4. これにより、コンテナはCPUコアの半分以上を使用することが制限されます。

  5. リソース制約を確認する: 制限が設定されていることを確認してください

    podman inspect limited-nginx
  6. このコマンドは、リソース制限を含むコンテナのホスト構成を表示します。

PodmanをSystemdと統合する

Podmanの利点の一つは、Quadletsを使用してsystemdを通じて管理できることであり、これによりコンテナをシステムサービスとして扱うことが可能になります。

  1. 適切なQuadletファイルを作成する: コンテナユニットファイルを設定する

    mkdir -p ~/.config/containers/systemd
    cat > ~/.config/containers/systemd/my-nginx.container << EOF
    [Container]
    Image=docker.io/nginxinc/nginx-unprivileged:latest
    PublishPort=8081:8080
    HostName=nginx-web
    
    [Service]
    Restart=always
    TimeoutStartSec=900
    
    [Install]
    WantedBy=default.target
    EOF
  2. ホスト上でポート8080を使用しているかもしれない他のサービスとの潜在的な競合を避けるために、ポート8081を使用していることに注意してください。コンテナ内部のポートは8080のままですが、外部からはポート8081でアクセスできます。

  3. Podmanのsystemdソケットアクティベーションを有効にする: これはユーザーのsystemdサービスに必要です

    systemctl --user enable --now podman.socket

    これにより、Podmanソケットが有効化されます。これはsystemdがPodmanコンテナを管理するために必要です。ソケットが有効であることを確認する出力が表示されるはずです:

    Created symlink /home/username/.config/systemd/user/sockets.target.wants/podman.socket → /usr/lib/systemd/user/podman.socket.
  4. systemdを再読み込み: 新しいユニットファイルをsystemdに認識させること

    systemctl --user daemon-reload
  5. これにより、新しいサービスを含むようにsystemd設定が再読み込みされます。

  6. サービスを開始する: コンテナ化されたサービスを実行します

    systemctl --user start my-nginx

    サービスを参照する際の推奨方法であるため、.service サフィックスなしの基本名を使用していることに注意してください。

    コンテナが実行中であることを確認するには、以下を使用できます:

    systemctl --user status my-nginx
  7. 出力に「アクティブ(実行中)」とNginxプロセスが表示されるはずです。

  8. ユーザーサービスのためのリ lingeringを有効にする: ログアウト後もサービスを実行できるようにする

    loginctl enable-linger $(whoami)
  9. これにより、ユーザーサービスはブート時に起動し、ログアウトした後も動作し続けることができます。この手順がなければ、ユーザーサービスはログインしている間だけ動作します。

  10. ブート時にサービスを実行するように設定する: サービスの永続性を構成する
    Quadletサービスの場合、標準のsystemctl enableコマンドではなく、シンボリックリンクを使用する必要があります:

    mkdir -p ~/.config/systemd/user/default.target.wants/
    ln -sf ~/.config/containers/systemd/my-nginx.container ~/.config/systemd/user/default.target.wants/my-nginx.service

    これは、systemctl enable が通常作成するシンボリックリンクを手動で作成します。このアプローチは、Quadlet サービスが動的に生成されるため、必要です。

    リンクを作成した後、systemdの設定を再読み込みします:

    systemctl --user daemon-reload

    サービスが正しくリンクされているかどうかを確認できます:

    ls -la ~/.config/systemd/user/default.target.wants/
  11. Quadletファイル構造の理解: 主要なセクションを学ぶ
    Quadletファイルにはこれらの主要セクションが含まれています:

    • [ユニット]: 標準のsystemdユニットメタデータ
    • [コンテナ]: Podman特有のコンテナ設定
    • [サービス]: サービスの動作設定
    • [インストール]: Systemdのインストール情報

    より多くのオプションは、man podman-systemd.unitを実行することで見つけることができます。

  12. システム全体のサービスの作成: すべてのユーザーのために実行されるべきサービス
    ユーザーセッションに tied されていないシステムサービスとして実行されるべきコンテナ:

    sudo mkdir -p /etc/containers/systemd
    sudo nano /etc/containers/systemd/global-nginx.container

    上記と同じ形式を使用し、その後次のことで有効にします:

    sudo systemctl daemon-reload
    sudo systemctl enable --now global-nginx

Podmanを使用したカスタムコンテナイメージの構築

PodmanはDockerfileを使用してコンテナイメージを構築できるため、カスタムコンテナを簡単に作成できます。

  1. Dockerfileを作成する: カスタムコンテナイメージを定義します。

    mkdir -p ~/podman-build
    cd ~/podman-build
    cat > Dockerfile << EOF
    FROM docker.io/nginxinc/nginx-unprivileged:latest
    COPY index.html /usr/share/nginx/html/index.html
    EXPOSE 8080
    CMD ["nginx", "-g", "daemon off;"]
    EOF
    echo "<html><body><h1>Custom Podman Image</h1><p>This content is baked into the image.</p></body></html>" > index.html
    
  2. これは、nginx-unprivilegedベースイメージにカスタムindex.htmlを追加するDockerfileを作成します。

  3. 画像を作成する: カスタム画像を作成してください

    podman build -t custom-nginx:1.0 .
  4. これは、現在のディレクトリにあるDockerfileを使用して、1.0のタグを持つcustom-nginxという名前のイメージを構築します。

  5. カスタムイメージからコンテナを実行する: 新しいイメージをテストする

    podman run --name my-custom-nginx -p 8090:8080 -d custom-nginx:1.0
  6. これにより、カスタムイメージを使用してコンテナが起動します。

  7. カスタムコンテンツを確認する: あなたのカスタムHTMLが配信されていることを確認してください

    curl http://localhost:8090

    あなたの画像に組み込まれたカスタムHTMLコンテンツを見るべきです。

結論

あなたは今、Podmanの基本を学びました。これには、インストール、コンテナの実行、イメージの管理、独自のカスタムコンテナの作成が含まれます。Podmanは、ほとんどのDockerコマンドやワークフローと完全に互換性のある、安全なデーモンレスのDockerの代替手段を提供します。

Podmanを使用すると、ルート権限を持つデーモンのセキュリティ懸念なしにコンテナ化を楽しむことができます。ルートレスの運用は、追加の分離とセキュリティの層を提供し、開発環境と本番環境の両方にとって優れた選択肢となります。

コンテナ化の旅を続ける中で、次のようなより高度なトピックを探求したくなるかもしれません。

  • ポッドマンポッド(リソースを共有するコンテナのグループ)
  • コンテナネットワークと高度なネットワーキング機能
  • マルチコンテナアプリケーションのためのPodman Composeの使用
  • Podman Kubernetes YAMLジェネレーターを介したKubernetesとの統合

Dockerの知識の大部分は直接Podmanに移行できるため、二つの間でスイッチしたり、並行して使用したりするのが簡単であることを思い出してください。新しいPodmanのスキルを持っていることで、無料のオープンソースツールを使用して、安全にアプリケーションをコンテナ化する準備が整っています。

一般的な問題のトラブルシューティング

  • 無資格の画像名エラー

    Error: short-name "nginxinc/nginx-unprivileged:latest" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"
    • 常に完全修飾されたイメージ名を使用してください(例:docker.io/nginx:latest)
    • あるいは、/etc/containers/registries.conf で検索レジストリを設定します。
  • クワドレットサービスの有効化に失敗しました

    Failed to enable unit: Unit /run/user/1000/systemd/generator/my-nginx.service is transient or generated
    • Quadletサービスには、systemctl enableの代わりにシンボリックリンクを使用してください。
    • mkdir -p ~/.config/systemd/user/default.target.wants/
      ln -sf ~/.config/containers/systemd/my-nginx.container ~/.config/systemd/user/default.target.wants/my-nginx.service
      systemctl --user daemon-reload
  • ポートバインディングエラー

    Error: rootlessport listen tcp 0.0.0.0:8080: bind: address already in use
    • ポートを使用しているものを特定するために lsof を使用します: sudo lsof -i :8080
    • コンテナ設定のホストポートマッピングを変更してください
    • ポートを使用しているプロセスを適切に終了または停止してください
  • ルートレスモードにおける許可の問題

    • ユーザーネームスペースが有効になっていることを確認してください: sysctl user.max_user_namespaces
    • subuid/subgidマッピングを確認する: grep $ (whoami) /etc/subuid /etc/subgid
    • コンテナファイルのファイル権限を確認してください
  • コンテナ開始失敗

    • 詳細なログを確認してください: podman logs コンテナ名
    • コンテナを検査する: podman inspect container_name
    • journalctl --user -xeu service_name.serviceを使用してsystemdサービスを確認してください
    • コンテナを開始する前にイメージを事前取得します: podman pull image_name
  • 最小限の作業例
    複雑な設定に苦労している場合は、最小限の作業例から始めてください:

    cat > ~/.config/containers/systemd/basic-nginx.container << EOF
    [Container]
    Image=docker.io/nginxinc/nginx-unprivileged:latest
    PublishPort=8081:8080
    
    [Install]
    WantedBy=default.target
    EOF

    それから再読み込みして、より簡単なサービスを試してください:

    systemctl --user daemon-reload
    systemctl --user start basic-nginx

関連記事: