GNU/Linux >> Linux の 問題 >  >> Linux

コンテナ内でのPodmanの使用方法

上流のコンテナ技術に取り組んでいる人々に最もよく聞かれるトピックの1つは、コンテナ内でPodmanを実行することです。これらのほとんどは、歴史的にDocker in Docker(DIND)に関連していましたが、今では、Podman in Podman(PINP)またはPodman in Docker(PIND)も実行したいと考えています。

しかし、Podmanは、ルートフルとルートレスの複数の方法で実行できます。根っからのPodmanと根のないPodmanのさまざまな組み合わせを実行したいと思う人が出てきます:

  • ルートフルポッドマンのルートフルポッドマン
  • ルートフルポッドマンのルートレスポッドマン
  • ルートレスポッドマンのルートフルポッドマン
  • ルートレスポッドマンのルートレスポッドマン

あなたは写真を手に入れます。

このブログでは、特権の説明から始めて、各組み合わせについて説明します。ここでは、パート1のPINPシナリオから始めます。シリーズのパート2では、同様の根拠について説明しますが、Kubernetesのコンテキスト内で行います。全体像については、必ず両方の記事をお読みください。

コンテナエンジンには特権が必要です

コンテナ内でPodmanのようなコンテナエンジンを実行するには、最初に理解する必要があるのは、かなりの量の特権が必要であるということです。

  • コンテナには複数のUIDが必要です。ほとんどのコンテナイメージが機能するには、複数のUIDが必要です。たとえば、ほとんどのファイルがrootによって所有されているが、一部はapacheユーザー(UID =60)によって所有されているイメージがあるとします。
  • コンテナエンジンはファイルシステムをマウントし、システムコールのクローンを使用してユーザーの名前空間を作成します。

注:Podmanの新しいバージョンが必要になる場合があります。このブログの例は、Podman3.2で実行されました。

テスト画像

このブログの例では、quay.io/podman/stableを使用します コンテナ内でPodmanを実行するための最良の方法を見つけるというアイデアで作成された画像。 Dockerfileとcontainers.confからこのイメージを構築する方法を調べることができます github.comリポジトリの画像。

# stable/Dockerfile
#
# Build a Podman container image from the latest
# stable version of Podman on the Fedoras Updates System.
# https://bodhi.fedoraproject.org/updates/?search=podman
# This image can be used to create a secured container
# that runs safely with privileges within the container.
#
FROM registry.fedoraproject.org/fedora:latest

# Don't include container-selinux and remove
# directories used by yum that are just taking
# up space.
RUN dnf -y update; yum -y reinstall shadow-utils; \
yum -y install podman fuse-overlayfs --exclude container-selinux; \
rm -rf /var/cache /var/log/dnf* /var/log/yum.*

RUN useradd podman; \
echo podman:10000:5000 > /etc/subuid; \
echo podman:10000:5000 > /etc/subgid;

VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers

ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf

RUN chown podman:podman -R /home/podman

# chmod containers.conf and adjust storage.conf to enable Fuse storage.
RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock

ENV _CONTAINERS_USERNS_CONFIGURED=""

Dockerfileを調べてみましょう。

FROM registry.fedoraproject.org/fedora:latest

# Don't include container-selinux and remove
# directories used by yum that are just taking
# up space.
RUN dnf -y update; yum -y reinstall shadow-utils; \
yum -y install podman fuse-overlayfs --exclude container-selinux; \
rm -rf /var/cache /var/log/dnf* /var/log/yum.*

最初にfedoraを最新にプルし、次に最新のパッケージに更新します。 shadow-utilsを再インストールすることに注意してください 、shadow-utilsに既知の問題があるため filecapsがあるFedoraイメージにインストールします newsubuidで およびnewsubgid 設定されていません。 shadow-utilsを再インストールします 問題を修正します。次に、Podmanとfuse-overlayfsをインストールします 。 container-selinuxはインストールしません コンテナ内では必要ないためです。

RUN useradd podman; \
echo podman:10000:5000 > /etc/subuid; \
echo podman:10000:5000 > /etc/subgid;

次に、ユーザーpodmanを作成します /etc/subuidを設定します および/etc/subgid 5000のUIDを使用するファイル。これは、コンテナ内にユーザー名前空間を設定するために使用されます。 5000は任意の数であり、小さすぎる可能性があります。ルートレスユーザーに割り当てられた65kよりも小さいため、この数を選択しました。コンテナをrootとしてのみ実行している場合は、65kの方が適切な数値でした。

VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers

このイメージでルートフルコンテナとルートレスコンテナを実行できるため、2つのボリュームを作成します。 RootfullPodmanは/var/lib/containersを使用します コンテナストレージとルートレスの使用/home/podman/.local/share/containers 。オーバーレイオーバーレイオーバーレイはカーネルによって拒否されることが多いため、これにより、コンテナ内で使用される非オーバーレイボリュームが作成されます。

ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf

2つのcontainers.confを事前設定しました コンテナが各モードでより簡単に実行できるようにするためのファイル。

イメージは、デフォルトでfuse-overlayfsで実行するように設定されています。場合によっては、カーネルのオーバーレイファイルシステムをルートフルモードで実行でき、すぐにルートレスモードで実行できるようになります。ただし、現時点では、コンテナー内のコンテナーストレージとしてfuse-overlayfsを使用しています。他の人はVFSストレージドライバーを使用していますが、これはそれほど効率的ではありません。

--特権フラグ

コンテナ内でPodmanを実行する最も簡単な方法は、--privilegedを使用することです。 フラグ。

--privilegedを使用したrootfulPodmanのRootfulPodman

# podman run --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8-minimal" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
Trying to pull registry.access.redhat.com/ubi8:latest...
Getting image source signatures
Copying blob sha256:a591faa84ab05242a17131e396a336da172b0e1ec66d921c9f130b7c4c24586d
Copying blob sha256:76b9354adec626b01ffb0faae4a217cebd616661fd90c4b54ba4415f53392fb8
Copying config sha256:dc080723f596f2407300cca2c19a17accad89edcf39f7b8b33e6472dd41e30f1
Writing manifest to image destination
Storing signatures
hello

時間を節約するために、多くの実験を行うため、ホスト./mycontainersにディレクトリを作成しました。 、使用するコンテナにボリュームマウントし、毎回イメージをプルする必要はありません。

# podman run --privileged -v ./mycontainers:/var/lib/containers quay.io/podman/stable podman run ubi8 echo hello
hello

--privilegedを使用したrootfulPodmanのRootlessPodman

quay.io/podman/stable 画像はpodmanで設定されています ルートレスコンテナの実行に使用できるユーザー。

# podman run --user podman --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
...
hello

この場合、コンテナ内で実行されているPodmanは、ユーザー podmanとして実行されていることに注意してください。 。これは、コンテナ化されたPodmanがユーザー名前空間を使用して、特権コンテナ内に制限されたコンテナを作成するためです。

--privilegedを使用してDockerでrootlessPodmanを実行する

ルートフルPodmanと同様に、Docker内で--privilegedを使用してルートレスPodmanを実行することもできます。 オプション。

# docker run --privileged quay.io/podman/stable podman run ubi8 echo hello

Dockerを使用したルートレスポッドマン

# docker run --user podman --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
...
hello

これをより安全に行うことができますか?

外側のコンテナを実行したにもかかわらず、--privileged 上記では、内部コンテナはロックダウンモードで実行されています。コンテナ内で実行されているルートレスのPodmanは実際にロックダウンされており、エスケープするのは非常に困難です。それを考えると、私は--privilegedを使用するのが好きではありません 国旗。セキュリティの観点から、もっとうまくやれると思います。

--privilegedフラグなしで実行

--privilegedを削除する方法を見てみましょう セキュリティを強化するためのフラグ。

--privilegedのないrootfulPodmanのRootfulPodman

# podman run --cap-add=sys_admin,mknod --device=/dev/fuse --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello

--privilegedを排除できます ルートフルポッドマンからフラグを立てますが、コンテナ内のルートフルポッドマンを機能させるには、いくつかのセキュリティ機能を無効にする必要があります。

  1. 機能:--cap-add=sys_admin,mknod 2つのLinux機能を追加する必要があります。
    1. CAP_SYS_ADMIN コンテナ内でrootとして実行されているPodmanが、必要なファイルシステムをマウントするために必要です。
    2. CAP_MKNOD コンテナ内でrootとして実行されているPodmanが、/devにデバイスを作成するために必要です。 。 (Dockerはデフォルトでこれを許可していることに注意してください。)
  2. デバイス:--device /dev/fuse フラグは、コンテナ内でfuse-overlayfsを使用する必要があります。このオプションは、ホスト上のPodmanに/dev/fuseを追加するように指示します コンテナ化されたPodmanが使用できるようにコンテナに追加します。
  3. SELinuxを無効にする:--security-opt label=disable オプションは、ホストのPodmanにコンテナのSElinux分離を無効にするように指示します。 SELinuxでは、コンテナ化されたプロセスが、コンテナ内で実行するために必要なすべてのファイルシステムをマウントすることはできません。

--privilegedを使用しないDockerのRootfulPodman

# docker run --cap-add=sys_admin --cap-add mknod --device=/dev/fuse --security-opt seccomp=unconfined --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello
  1. 注Dockerはコンマ区切りの--cap-addをサポートしていません コマンドなので、 sys_adminを追加する必要がありました およびmknod 個別に
  2. まだ必要な--device /dev/fuse 、コンテナのデフォルトは/dev/fuseであるため
  3. Dockerは常にroot:rootが所有する組み込みボリュームを作成するため、ストレージに使用できるように、Podman用にコンテナーにマウントするボリュームを作成する必要があります。
  4. いつものように、SELinux分離を無効にする必要があります
  5. seccompも無効にする必要があります 、Dockerのseccompは少し厳しいため Podmanよりもポリシー。 --seccomp=/usr/share/containers/seccomp.jsonを使用すると、Podmanセキュリティポリシーを使用できます。
# docker run --cap-add=sys_admin --cap-add mknod --device=/dev/fuse --security-opt seccomp=/usr/share/containers/seccomp.json --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello

--privilegedのないrootfulPodmanのRootlessPodman

nonを実行します -ユーザー名前空間を使用する非rootユーザーを使用するPodmanを内部に持つ特権コンテナ。

# podman run --user podman --security-opt label=disable --security-opt unmask=ALL --device /dev/fuse -ti quay.io/podman/stable podman run -ti docker.io/busybox echo hello
hello
  1. 以前の根強いケースのroofulとは異なり、危険なセキュリティ機能を追加する必要がないことに注意してください sys_admin およびmknod
  2. この場合、私は--user podmanで実行しています。 、これにより、コンテナ内のPodmanがユーザー名前空間内で自動的に実行されます
  3. マウントをブロックするため、SELinuxを引き続き無効にします
  4. まだ--device /dev/fuseが必要です コンテナ内でfuse-overlayfsを使用するには

Podman-ホストからPodmanソケットがリークされたルートフルPodmanでリモート

# podman run -v /run:/run --security-opt label=disable quay.io/podman/stable podman --remote run busybox echo hi
hi

この場合、/runがリークしています。 ホストからコンテナへのディレクトリ。これにより、podman --remoteが可能になります ホストのPodmanソケットと通信し、ホストOSでコンテナを起動します。これは多くの場合、Docker In Docker、特にDockerビルドを実行する方法です。この方法でPodmanビルドを実行し、以前にシステムにプルされたイメージを利用することもできます。

ただし、これは非常に安全ではないことに注意してください。コンテナ内のプロセスは、ホストマシンを完全に引き継ぐことができます。

  1. SELinuxは、コンテナプロセスが/runでリークされたソケットを使用するのをブロックするため、SELinux分離を無効にする必要があります。 。
  2. podman --remote Podmanにリモートモードで動作するように指示するフラグが追加されました。 podman-remoteをインストールすることもできます。 実行可能ファイルをコンテナに入れて使用します。

[コンテナを使い始めますか?この無料コースをチェックしてください。コンテナ化されたアプリケーションのデプロイ:技術的な概要。 ]

Podman-ホストからPodmanソケットがリークされたDockerでリモート

# docker run -v /run:/run --security-opt label=disable quay.io/podman/stable podman --remote run busybox echo hi
hi

同じ例がDockerコンテナでも機能します。

この例は、Podmanソケットがコンテナーにリークされた状態で、完全にロックダウンされたコンテナー(SELinuxが無効になっている場合を除く)を示しています。 SELinuxは、必要に応じてこのアクセスをブロックします。

# /bin/podman run --security-opt=label=disable -v /run/podman:/run/podman quay.io/podman/stable podman --remote run alpine echo hi
hi

コンテナ化されたルートフルポッドマンを備えたルートレスポッドマン

$ podman run --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
..
hello

ルートレスポッドマンを実行しているルートレスポッドマン

$ podman run --security-opt label=disable --user podman --device /dev/fuse quay.io/podman/stable podman run alpine echo hello

最終的な考え

これで、ルートフルモードとルートレスモードの両方を使用して、PodmanオプションでPodmanのコンテキストを取得できます。さまざまな組み合わせで。また、--privilegedを取り巻く必要な特権と考慮事項についてもよく理解できます。 フラグ。

このシリーズのパート2では、PodmanとKubernetesの使用について説明します。この記事は同様の領域をカバーしていますが、Kubernetesのコンテキスト内にあります。

[システム管理者のスキルをテストしたいですか?今日、スキル評価を受けてください。 ]


Linux
  1. Nginxを使用してリダイレクトする方法

  2. OpenSUSELeap15.3でPodmanをインストールして使用する方法

  3. プロセスが lxc/Docker 内で実行されているかどうかを判断する方法は?

  1. LinuxでBusyBoxを使用する方法

  2. Linuxでcronを使用する方法

  3. docker コンテナ内で cron ジョブを実行する方法

  1. LinuxでSuコマンドを使用する方法

  2. テクノロジープレビュー:コンテナー内でコンテナーを実行する

  3. Kubernetes内でPodmanを使用する方法