第8章 コンテナーのコマンドライン参照

8.1. podman

podman コマンド (Pod Manager の略) を使用すると、Kubernetes、Docker ランタイム、またはその他のコンテナーランタイムを使用せずに、コンテナーをスタンドアロンエンティティーとして実行できます。それは、docker コマンドの代わりに機能できるツールです。同じコマンドライン構文を実装しながら、さらにコンテナーの管理機能を追加します。podman 機能は次のとおりです。

  • docker インターフェースに基づいている - podman 構文は docker コマンドに似ているため、docker に精通している場合には、podman への移行が簡単です。
  • コンテナーおよびイメージの管理 - 以下を行うために、Docker 互換と OCI 互換の両方のコンテナーイメージを、podman とともに使用できます。

    • コンテナーの実行、停止、および再起動
    • コンテナーイメージの作成および管理(プッシュ、コミット、設定、ビルドなど)
  • Pod の管理 - 個々のコンテナーを実行する以外に、podman は、Pod にグループ化された一連のコンテナーを実行できます。Pod は、Kubernetes が管理するコンテナーの最小単位です。
  • ランタイムなしでの動作 - ランタイム環境は、コンテナーと連携するため、podman では使用されません。

以下は、知っておくべき podman の実装機能です。

  • Podman、Buildah、および CRI-O のコンテナーエンジンはすべて、Docker の保存場所 (/var/lib/docker) をデフォルトで使用する代わりに、同じバックエンドストアディレクトリー /var/lib/containers を使用します。
  • Podman、Buildah、および CRI-O は、同じストレージディレクトリーを共有しているため、互いのコンテナーと対話することはできません。ただし、このツールはイメージを共有できます。また、この機能は、コンテナーを共有できます。
  • docker などの podman コマンドは、Dockerfile からコンテナーイメージを構築できます。
  • podman コマンドは、CRI-O サービスが利用できない場合に有益なトラブルシューティングツールです。
  • podman が対応していない dockerコマンドのオプションには、network、node、plugin (podman はプラグインをサポートしません)、rename (rm および create を使用して podman でコンテナーの名前を変更します)、secret、service、stack、swarm (podman は Docker Swarm をサポートしません) が含まれます。container および imageオプションは、podman で直接使用されるサブコマンドを実行するのに使用します。
  • プログラムで podman と対話するには、Podman のリモート API が、varlink と呼ばれる技術を使用して利用できます。これにより、podman は、(RHEL 8 Web コンソールや atomic コマンドなど) リモートツールからの API 要求をリッスンし、それに応答します。

8.1.1. podman コマンドの使用

docker コマンドを使用してコンテナーを操作するのに慣れている場合は、そのほとんどの機能とオプションが podman の機能とオプションに一致することが分かるでしょう。表 1 は、podman で使用できるコマンドの一覧です (podman -h を実行するとこの一覧を表示できます)。

表8.1 podman が対応するコマンド

podman コマンド

説明

podman コマンド

説明

attach

実行中のコンテナーに割り当てる

commit

変更したコンテナーから新規イメージを作成する

build

Dockerfile 命令を使用してイメージを構築する

create

コンテナーを作成するが、起動はしない

diff

コンテナーのファイルシステムの変更を検証する

exec

実行中のコンテナーでプロセスを実行する

export

コンテナーのファイルシステムの内容を tar アーカイブとしてエクスポートする

help, h

コマンド一覧、または特定のコマンドのヘルプを表示する

history

指定したイメージの履歴を表示する

images

ローカルストレージ内のイメージを一覧表示する

import

tarball をインポートして、ファイルシステムイメージを作成する

info

システム情報を表示する

inspect

コンテナーまたはイメージの設定を表示する

kill

1 つ以上の実行中のコンテナーに特定のシグナルを送信する

load

アーカイブからイメージを読み込む

login

コンテナーレジストリーにログインする

logout

コンテナレジストリーからログアウトする

logs

コンテナーのログを取得する

mount

作業中のコンテナーの root ファイルシステムをマウントする

pause

1 つ以上のコンテナー内の全プロセスを一時停止する

ps

コンテナーの一覧を表示する

port

コンテナーのポートマッピングまたは特定のマッピングを一覧表示する

pull

レジストリーからイメージを取得する

push

指定した宛先にイメージをプッシュする

restart

1 つ以上のコンテナーを再起動する

rm

ホストから 1 つ以上のコンテナーを削除する。実行している場合は、-f を追加する

rmi

ローカルストレージから 1 つ以上のイメージを削除する

run

新しいコンテナーでコマンドを実行する

save

イメージをアーカイブに保存する

search

イメージのレジストリーを検索する

start

1 つ以上のコンテナーを起動する

stats

1 つ以上のコンテナーの CPU、メモリー、ネットワーク I/O、ブロック I/O、および PID の割合を表示する

stop

1 つ以上のコンテナーを停止する

tag

ローカルイメージに名前を追加する

top

コンテナーの実行中のプロセスを表示する

umount, unmount

作業コンテナーのルートファイルシステムをアンマウントする

unpause

1 つ以上のコンテナーでプロセスの一時停止を解除する

version

podman のバージョン情報を表示する

wait

1 つ以上のコンテナーをブロックする

  

8.1.2. 基本的な podman コマンドの試行

podman は、docker コマンドの機能と構文を反映しています。このオプションを使用してコンテナーと連携する例は、「Working with Docker Formatted Container Images」 を参照してください。ほとんどの場合は、dockerpodman に置き換えます。以下は、podman の使用例です。

8.1.3. ローカルシステムにコンテナーイメージを取得 (プル)

# podman pull registry.redhat.io/ubi8/ubi
Trying to pull registry.redhat...Getting image source signatures
Copying blob sha256:d1fe25896eb5cbcee...
Writing manifest to image destination
Storing signatures
fd1ba0b398a82d56900bb798c...

8.1.4. ローカルコンテナーイメージの一覧表示

# podman images
REPOSITORY                    TAG      IMAGE ID       CREATED       SIZE
registry.redhat.io/ubi8/ubi   latest   de9c26f23799   5 weeks ago   80.1MB
registry.redhat.io/ubi8/ubi   latest   fd1ba0b398a8   5 weeks ago   211MB

8.1.5. コンテナーイメージの検証

# podman inspect registry.redhat.io/ubi8/ubi | less
[
    {
        "Id": "4bbd153adf8487a8a5114af0d6...",
        "Digest": "sha256:9999e735605c73f...",
        "RepoTags": [
            "registry.access.redhat.com/ubi8/ubi:latest"
        ],
        "RepoDigests": [
            "registry.access.redhat.com/ubi8/ubi/rhel@sha256:9999e7356...

8.1.6. コンテナーイメージの実行

コンテナーでシェルを開くコンテナーを実行します。

# podman run -it registry.redhat.io/ubi8/ubi /bin/bash
[root@8414218c04f9 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 13:48 pts/0    00:00:00 /bin/bash
root        21     1  0 13:49 pts/0    00:00:00 ps -ef
[root@8414218c04f9 /]# exit
#

8.1.7. 実行中または終了したコンテナーを一覧表示

# podman ps -a
CONTAINER ID   IMAGE                                             COMMAND
   CREATED AT                      STATUS                  PORTS NAMES
440becd26893   registry.redhat.io/ubi8/ubi-minimal:latest  /bin/bash
   2018-05-10 09:02:52 -0400 EDT   Exited (0) About an hour ago  happy_hodgkin
8414218c04f9   registry.redhat.io/ubi8/ubi:latest          /bin/bash
   2018-05-10 09:48:07 -0400 EDT   Exited (0) 14 minutes ago     nostalgic_boyd

8.1.8. コンテナーまたはイメージの削除

コンテナー ID を使用して、コンテナーを削除します。

# podman rm 440becd26893

イメージ ID または名前を使用して、コンテナーイメージを削除します (-f を使用して強制します)。

# podman rmi registry.redhat.io/ubi8/ubi
# podman rmi de9c26f23799
# podman rmi -f registry.redhat.io/ubi8/ubi:latest

8.1.9. Kube pod yaml ファイルの生成

podman generate コマンドを使用して、コンテナーまはは Pod から Kubernetes Pod yaml ファイルを作成します。

  1. デーモンプロセス (この例では mariadb) として実行するコンテナー化されたサービスを開始します。

    # podman run -d -e MYSQL_USER=user -e MYSQL_PASSWORD=pass \
         -e MYSQL_DATABASE=db -p 3306:3306 --name mymariadb rhscl/mariadb-102-rhel7
  2. コンテナー名または ID を取得します。

    # podman ps
    CONTAINER ID  IMAGE
        COMMAND               CREATED         STATUS
             PORTS                   NAMES
    e421a3424ab0  registry.access.redhat.com/rhscl/mariadb-102-rhel7:latest
        container-entrypo...  19 seconds ago  Up 16 seconds ago
             0.0.0.0:3306->3306/tcp  mymariadb
  3. コンテナー名または ID を使用して Kubernetes yaml 出力を生成し、これをファイルに転送します。

    # podman generate kube mymariadb > mymariadbkube.yaml
    # less mymariadbkube.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: "2019-10-31T13:19:41Z"
      labels:
        app: mymariadb
      name: mymariadb
    spec:
      containers:
      - command:
    ...
     - name: MYSQL_VERSION
          value: "10.2"
        - name: CONTAINER_SCRIPTS_PATH
          value: /usr/share/container-scripts/mysql
        - name: MYSQL_PREFIX
          value: /opt/rh/rh-mariadb102/root/usr
        - name: ENABLED_COLLECTIONS
          value: rh-mariadb102
        - name: DESCRIPTION
          value: MariaDB is a multi-user, multi-threaded SQL database server. The container
            image provides a containerized packaging of the MariaDB mysqld daemon and
            client application. The mysqld server daemon accepts connections from clients
            and provides access to content from MariaDB databases on behalf of the clients.
     - name: STI_SCRIPTS_PATH
          value: /usr/libexec/s2i
        - name: PROMPT_COMMAND
          value: . /usr/share/container-scripts/mysql/scl_enable
        - name: MYSQL_USER
          value: user
        - name: MYSQL_PASSWORD
          value: pass
    ...

    podman generate コマンドは、コンテナーに接続されている論理ボリュームマネージャー (LVM) の論理ボリュームまたは物理ボリュームを反映しません。

  4. yaml ファイルを使用して、Kubernetes または OpenShift 環境で Pod を作成できます。

    # kubectl create -f mymariadbkube.yaml

8.1.10. systemd ユニットファイルの生成

Podman により、systemd はコンテナープロセスを制御および管理できます。podman generate systemd コマンドを使用して、非 root (ルートレス) ユーザーとして既存のコンテナーの systemd ユニットファイルを生成できます。

  1. コンテナーを作成します (例: myfedora)。

    # podman create -d --name myfedora fedora:latest top
    54502f309f3092d32b4c496ef3d099b270b2af7b5464e7cb4887bc16a4d38597
  2. コンテナー名または ID を使用して systemd ユニットファイルを生成し、それを ~/.config/systemd/user/container-myfedora.service ファイルに送ります。

    # podman generate systemd --name myfedora > ~/.config/systemd/user/container-myfedora.service
    container-myfedora.service
    autogenerated by Podman 1.6.2
    Tue Nov 19 15:49:15 CET 2019
    
    [Unit]
    Description=Podman container-myfedora.service
    Documentation=man:podman-generate-systemd(1)
    
    [Service]
    Restart=on-failure
    ExecStart=/usr/bin/podman start myfedora
    ExecStop=/usr/bin/podman stop -t 10 myfedora
    KillMode=none
    Type=forking
    PIDFile=/run/user/1000/overlay-containers/54502f309f3092d32b4c496ef3d099b270b2af7b5464e7cb4887bc16a4d38597/userdata/conmon.pid
    
    [Install]
    WantedBy=multi-user.target
  3. これで、コンテナーの状態を開始して確認できます。

    # systemctl --user start container-myfedora.service
    # systemctl --user status container-myfedora.service
  4. コンテナーを停止できます。

    # systemctl --user stop container-myfedora.service

詳細は、「Running containers with Podman and shareable systemd services」を参照してください。

8.1.11. コンテナーの SELinux ポリシーの作成

コンテナーの SELinux ポリシーを生成するには、UDICA ツールを使用します。詳細は「udica の SELinux ポリシージェネレーターの概要」を参照してください。

8.1.12. MPI での podman の使用

Podman を Open MPI (Message Passing Interface) と共に使用して、HPC (High Performance Computing) 環境でコンテナーを実行できます。

この例では、Open MPI から取得した ring.c プログラムに基づいています。この例では、値はリングのような方法ですべてのプロセスによって渡されます。メッセージがランク 0 に渡されるたびに、値はデクリメントされます。各プロセスが 0 メッセージを受信すると、次のプロセスに渡して終了します。0 を最初に渡すと、すべてのプロセスが 0 メッセージを取得し、通常通りに終了できます。

手順

  1. Open MPI をインストールします。

    $ sudo yum install openmpi
  2. 環境モジュールをアクティベートするには、以下を入力します。

    $ . /etc/profile.d/modules.sh
  3. mpi/openmpi-x86_64 モジュールを読み込みます。

    $ module load mpi/openmpi-x86_64

    必要に応じて、mpi/openmpi-x86_64 モジュールを自動的に読み込むには、以下の行を .bashrc ファイルに追加します。

    $ echo "module load mpi/openmpi-x86_64" >> .bashrc
  4. mpirunpodman を組み合わせるには、以下の定義でコンテナーを作成します。

    $ cat Containerfile
    FROM registry.access.redhat.com/ubi8/ubi
    
    RUN yum -y install openmpi-devel wget && \
        yum clean all
    
    RUN wget https://raw.githubusercontent.com/open-mpi/ompi/master/test/simple/ring.c && \
        /usr/lib64/openmpi/bin/mpicc ring.c -o /home/ring && \
        rm -f ring.c
  5. コンテナーをビルドします。

    $ podman build --tag=mpi-ring .
  6. コンテナーを起動します。CPU が 4 つあるシステムでは、このコマンドはコンテナーを 4 つ起動します。

    $ mpirun \
       --mca orte_tmpdir_base /tmp/podman-mpirun \
       podman run --env-host \
         -v /tmp/podman-mpirun:/tmp/podman-mpirun \
         --userns=keep-id \
         --net=host --pid=host --ipc=host \
         mpi-ring /home/ring
    Rank 2 has cleared MPI_Init
    Rank 2 has completed ring
    Rank 2 has completed MPI_Barrier
    Rank 3 has cleared MPI_Init
    Rank 3 has completed ring
    Rank 3 has completed MPI_Barrier
    Rank 1 has cleared MPI_Init
    Rank 1 has completed ring
    Rank 1 has completed MPI_Barrier
    Rank 0 has cleared MPI_Init
    Rank 0 has completed ring
    Rank 0 has completed MPI_Barrier

    これにより、mpirun は 4 つの Podman コンテナーを開始し、各コンテナーは ring バイナリーのインスタンスを実行します。4 つプロセスはすべて、MPI を介して相互に通信しています。

    以下の mpirun オプションは、コンテナーの起動に使用されます。

    • --mca orte_tmpdir_base /tmp/podman-mpirun 行は、Open MPI に対し、/tmp ではなく、その一時ファイルをすべて /tmp/podman-mpirun に作成するように指示します。複数のノードを使用する場合、このディレクトリーは他のノードで名前が異なります。そのためには、完全な /tmp ディレクトリーを、より複雑なコンテナーにマウントする必要があります。

    mpirun コマンドは、podman コマンドを起動するコマンドを指定します。以下の podman オプションは、コンテナーを起動するのに使用されます。

    • run コマンドはコンテナーを実行します。
    • --env-host オプションは、ホストからコンテナーにすべての環境変数をコピーします。
    • -v /tmp/podman-mpirun:/tmp/podman-mpirun は、Podman に対し、Open MPI がコンテナーで利用可能な一時ディレクトリーおよびファイルを作成するディレクトリーをマウントするように指示します。
    • --userns=keep-id 行を使用すると、コンテナー内外のユーザー ID マッピングが保証されます。
    • --net=host --pid=host --ipc=host 行は、同じネットワーク、PID、および IPC 名前空間を設定します。
    • mpi-ring はコンテナーの名前です。
    • /home/ring は、コンテナー内の MPI プログラムです。

詳細は、Adwell Reber の記事「Podman in HPC environments」を参照してください。

8.1.13. コンテナーチェックポイントの作成および復元

CRIU (Checkpoint/Restore In Userspace) は、実行中のコンテナーまたは個々のアプリケーションでチェックポイントを設定して、その状態をディスクに保存するソフトウェアです。保存されたデータを使用して、再起動後にチェックポイントが設定されたのと同じ時点でコンテナーを復元できます。

8.1.13.1. コンテナーチェックポイントのローカルでの作成および復元

この例は、リクエストの後にインクリメントされる 1 つの整数を返す Python ベースの Web サーバーに基づいています。

手順

  1. Python ベースのサーバーを作成します。

    # cat counter.py
    #!/usr/bin/python3
    
    import http.server
    
    counter = 0
    
    class handler(http.server.BaseHTTPRequestHandler):
        def do_GET(s):
            global counter
               s.send_response(200)
               s.send_header('Content-type', 'text/html')
               s.end_headers()
               s.wfile.write(b'%d\n' % counter)
               counter += 1
    
    
    server = http.server.HTTPServer(('', 8088), handler)
    server.serve_forever()
  2. 以下の定義でコンテナーを作成します。

    # cat Containerfile
    FROM registry.access.redhat.com/ubi8/ubi
    
    COPY counter.py /home/counter.py
    
    RUN useradd -ms /bin/bash counter
    
    RUN yum -y install python3 && chmod 755 /home/counter.py
    
    USER counter
    ENTRYPOINT /home/counter.py

    コンテナーは Universal Base Image (UBI 8) をベースとしており、Python ベースのサーバーを使用します。

  3. コンテナーをビルドします。

    # podman build . --tag counter

    counter.py ファイルおよび Containerfile ファイルは、コンテナービルドプロセス (podman build) の入力です。ビルドされたイメージはローカルに保存され、タグ counter でタグ付けされます。

  4. root でコンテナーを起動します。

    # podman run --name criu-test --detach counter
  5. 実行中のコンテナーの一覧を表示するには、次のコマンドを実行します。

    # podman ps
    CONTAINER ID  IMAGE  COMMAND  CREATED   STATUS  PORTS NAMES
    e4f82fd84d48  localhost/counter:latest  5 seconds ago  Up 4 seconds ago  criu-test
  6. コンテナーの IP アドレスを表示します。

    # podman inspect criu-test --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.247
  7. 要求をコンテナーに送信します。

    # curl 10.88.0.247:8080
    0
    # curl 10.88.0.247:8080
    1
  8. コンテナーのチェックポイントを作成します。

    # podman container checkpoint criu-test
  9. システムを再起動します。
  10. コンテナーをリストアします。

    # podman container restore --keep criu-test
  11. 要求をコンテナーに送信します。

    # curl 10.88.0.247:8080
    2
    # curl 10.88.0.247:8080
    3
    # curl 10.88.0.247:8080
    4

    結果は 0 で再度開始することはありませんが、以前の値が継続されます。

これにより、再起動後に完全なコンテナーの状態を簡単に保存できます。

詳細は、Adrian Reberによる記事「Adding checkpoint/restore support to Podman」を参照してください。

8.1.13.2. コンテナー復元を使用した起動時間の短縮

コンテナーマイグレーションを使用して、初期化に特定の時間を必要とするコンテナーの起動時間を短縮できます。チェックポイントを使用すると、同じホストまたは別のホストでコンテナーを複数回復元できます。この例は、「コンテナーチェックポイントのローカルでの作成および復元」セクションに基づいています。

手順

  1. コンテナーのチェックポイントを作成し、チェックポイントイメージを tar.gz ファイルにエクスポートします。

    # podman container checkpoint criu-test --export /tmp/chkpt.tar.gz
  2. tar.gz ファイルからコンテナーを復元します。

    # podman container restore --import /tmp/chkpt.tar.gz --name counter1
    # podman container restore --import /tmp/chkpt.tar.gz --name counter2
    # podman container restore --import /tmp/chkpt.tar.gz --name counter3

    --name (-n) オプションは、エクスポートしたチェックポイントから復元されるコンテナーの新しい名前を指定します。

  3. 各コンテナーの ID と名前を表示します。

    # podman ps -a --format "{{.ID}} {{.Names}}"
    a8b2e50d463c counter3
    faabc5c27362 counter2
    2ce648af11e5 counter1
  4. 各コンテナーの IP アドレスを表示します。

    #️ podman inspect counter1 --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.248
    
    #️ podman inspect counter2 --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.249
    
    #️ podman inspect counter3 --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.250
  5. 各コンテナーに要求を送信します。

    #️ curl 10.88.0.248:8080
    4
    #️ curl 10.88.0.249:8080
    4
    #️ curl 10.88.0.250:8080
    4

    異なるコンテナーを使用して同じチェックポイントから復元するため、すべてのケースで結果は 4 であることに注意してください。

この方法では、最初にチェックポイントされたコンテナーのステートフルレプリカを迅速に起動できます。

詳細は、「Container migration with Podman on RHEL」を参照してください。

8.1.13.3. システム間のコンテナーの移行

この手順は、コンテナーで実行しているアプリケーションの状態を失うことなく、実行中のコンテナーをあるシステムから別のシステムに移行する方法を示しています。この例は、counter とタグ付けされた 「コンテナーのチェックポイントの作成および復元のコンテナー」セクションに基づいています。

前提条件

以下の手順は、コンテナーがレジストリーにプッシュされている場合には不要です。Podman は、ローカルで利用できない場合にコンテナーをレジストリーから自動的にダウンロードするためです。この例ではレジストリーを使用していません。以前に構築およびタグ付けされたコンテナーをローカルにエクスポートし (「コンテナーチェックポイントのローカルでの作成および復元」セクションを参照)、この移行の宛先システムにコンテナーをインポートする必要があります。

  • 以前にビルドしたコンテナーをエクスポートします。

    # podman save --output counter.tar counter
  • エクスポートしたコンテナーイメージを移行先システム (other_host) にコピーします。

    # scp counter.tar other_host:
  • エクスポートしたコンテナーを移行先システムにインポートします。

    # ssh other_host podman load --input counter.tar

このコンテナーマイグレーションの移行先システムには、ローカルコンテナーストレージに保存されているものと同じコンテナーイメージがあります。

手順

  1. root でコンテナーを起動します。

    # podman run --name criu-test --detach counter
  2. コンテナーの IP アドレスを表示します。

    # podman inspect criu-test --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.247
  3. 要求をコンテナーに送信します。

    # curl 10.88.0.247:8080
    0
    # curl 10.88.0.247:8080
    1
  4. コンテナーのチェックポイントを作成し、チェックポイントイメージを tar.gz ファイルにエクスポートします。

    # podman container checkpoint criu-test --export /tmp/chkpt.tar.gz
  5. チェックポイントアーカイブを移行先ホストにコピーします。

    # scp /tmp/chkpt.tar.gz other_host:/tmp/
  6. 移行先ホスト (other_host) のチェックポイントを復元します。

    # podman container restore --import /tmp/chkpt.tar.gz
  7. 宛先ホスト (other_host) のコンテナーに要求を送信します。

    # curl 10.88.0.247:8080
    2

これにより、状態を失うことなく、あるシステムから別のシステムへステートフルコンテナーが移行されました。

詳細は、「Container migration with Podman on RHEL」を参照してください。


このページには機械翻訳が使用されている場合があります (詳細はこちら)。