ルートレスポッドマンコンテナは、ユーザーが追加の権限を必要とせずに、ホームディレクトリ内のほぼすべてのコンテナを実行できるようにする非常に優れた機能です。
このブログで説明したように、ルートレスコンテナはユーザー名前空間を利用します。
ユーザー名前空間やSELinuxなどの他のコンテナーセキュリティレイヤーにより、コンテナー内でコンテンツを共有することがより困難になる場合があります。システムディレクトリをコンテナに共有したいが、パーミッションエラーで失敗する多くのユーザーを見てきました。これらのディレクトリは通常、グループアクセスを介して共有されます。これにより、ユーザーはディレクトリ内のコンテンツを読み書きできます。
[次のこともお勧めします:Podmanを使用したルートレスコンテナ]
たとえば、ユーザーはディレクトリ / mnt / Engineering
を持っている場合があります。 root
が所有するシステム上 およびグループeng code> 、および権限が770に設定されています。
例を見てみましょう。
engcode>を追加します グループ:
# groupadd eng
共有ディレクトリを作成します:
# mkdir /var/lib/mycontainers/
ディレクトリのグループアクセスを変更します:
# chown root:eng /var/lib/mycontainers/
グループがディレクトリに書き込めるように権限を変更します:
# chmod 770 /mnt/engineering
コンテナがディレクトリを使用できるように、ディレクトリのSELinuxタイプを変更します。
# chcon -t container_file_t /mnt/engineering
次に、ディレクトリの権限を見てみましょう:
# ls -lZ /mnt/engineering/ -d
drwxrwx---. 2 root eng unconfined_u:object_r:user_tmp_t:s0 40 Feb 9 07:24 /mnt/engineering/
これで、ユーザーを engcode>に追加できます。 グループ:
$ grep eng /etc/group
Eng:x:14905:dwalsh
システムにログインし、ユーザーが engcode>にいることを確認します グループ:
$ id
uid=3267(dwalsh) gid=3267(dwalsh) groups=3267(dwalsh),10(wheel),14905(eng) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
ユーザーがディレクトリ内のコンテンツを読み書きできることを確認してください:
$ touch /mnt/engineering/test
$ ls -l /mnt/engineering/
total 0
-rw-------. 1 dwalsh dwalsh 0 Feb 9 07:36 test
このボリュームを使用してコンテナーを実行しますが、コンテナーは許可を拒否されます:
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 ls /mnt/engineering/
ls: cannot open directory '/mnt/engineering/': Permission denied
ラベルを正しく設定してSELinuxがブロックされていないことがわかっているので、どうなりましたか?
ユーザー名前空間
問題はユーザーの名前空間です。
$ podman run --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 id
uid=3267(dwalsh) gid=3267(dwalsh) groups=3267(dwalsh)
-userns =keep-id
に注意してください フラグは、コンテナ内のUIDがrootではなく、ユーザーの通常のUIDであることを確認するために使用されます。 id
を実行すると上記に注意してください コンテナの外でコマンドを実行すると、私のグループには engcode>が含まれます グループですが、コンテナが実行されると、
eng
グループは表示されません。セキュリティの観点から、これは良いことです。コンテナプロセスがエスケープされた場合、グループアクセス権を持つディレクトリにアクセスできなくなるからです。ユーザーがアクセスを許可したい場合、問題があります。
問題は、これらのディレクトリへのコンテナへのアクセスを許可することが難しいことです。 engcode>の作成 コンテナ内のグループが
engcode>と一致しません ユーザー名前空間が実際のグループUIDをオフセットするため、ホスト上のグループ。
幸いなことに、OCIランタイム crun
これらの追加グループをコンテナにリークするための特別な機能をサポートします。この機能は、 podman run
でカバーされています マニュアルページ:
man podman run
...
Note: if the user only has access rights via a group, accessing the de‐
vice from inside a rootless container will fail. The crun(1) runtime
offers a workaround for this by adding the option --annotation
run.oci.keep_original_groups=1.
さらに、 crun
で説明されています マニュアルページ:
man crun
…
run.oci.keep_original_groups=1
If the annotation run.oci.keep_original_groups is present, then crun
will skip the setgroups syscall that is used to either set the addi‐
tional groups specified in the OCI configuration, or to reset the list
of additional groups if none is specified.
その注釈を設定すると、以下に示すように、ルートレスのPodmanがボリュームにアクセスできるようになります。
$ podman run -ti --annotation run.oci.keep_original_groups=1 --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 ls /mnt/engineering/
-rw-------. 1 dwalsh dwalsh 0 Feb 9 12:36 test
OCI仕様には現在、これをOCIランタイムに通知する方法がないため、注釈を使用します。仕様に追加することをお勧めします。現時点では、 crun
以外のOCIランタイムはありません。 runc
を含むこれを処理できます 。おそらく将来的に、この機能はOCIに追加される予定です。
containers.conf
ユーザーがすべてのコンテナーでユーザーグループを共有するようにしたい場合は、このアノテーションを containers.conf
に追加できます。 ホームディレクトリにあります。
$ cat ~/.config/containers/containers.conf
[containers]
annotations=["run.oci.keep_original_groups=1",]
これで、デフォルトのPodmanでもボリュームにコンテンツを作成でき、コンテナー外のユーザープロセスは正しいコンテンツを見ることができます。
$ podman run -ti --userns=keep-id -v /mnt/engineering/:/mnt/engineering ubi8 touch /mnt/engineering/test2
$ ls -l /mnt/engineering/
total 0
-rw-------. 1 dwalsh dwalsh 0 Feb 9 07:36 test
-rw-r--r--. 1 dwalsh dwalsh 0 Feb 9 13:36 test2
[コンテナを使い始めますか?この無料コースをチェックしてください。コンテナ化されたアプリケーションのデプロイ:技術的な概要。 ]
結論
ボリュームマウントを介したホストからコンテナへのコンテンツの共有は、コンテナのさまざまなセキュリティ機能によってブロックされる場合があります。幸いなことに、Podmanと crun
特定のコンテナがこのコンテンツとcontainers.conf
を共有できるようにする高度な機能があります ユーザーがシステムをすべてのコンテナーにセットアップして、これらのボリュームにアクセスできるようにします。