1. ホーム
  2. linux

[解決済み] dockerのユーザーファイル所有権を理解する:リンクされたボリュームのパーミッションを変更しない方法

2023-05-18 21:23:29

質問

次のような簡単なDockerfileを考えてみてください。

FROM debian:testing
RUN  adduser --disabled-password --gecos '' docker
RUN  adduser --disabled-password --gecos '' bob 

を、何もない作業ディレクトリで実行します。dockerイメージをビルドします。

docker build -t test .

を実行し、コンテナ上でbashスクリプトを実行し、作業ディレクトリをbobのホームディレクトリの新しいサブディレクトリにリンクします。

docker run --rm -it -v $(pwd):/home/bob/subdir test 

のコンテンツは誰のものですか? subdir の内容は誰のものですか?コンテナ上で、実行します。

cd /home/bob/subdir
ls -l

ad we see:

-rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile

すげええええええええええええええええええええええええええ docker が中身を所有しています! コンテナの外のホストマシンに戻ると、元のユーザーがまだ Dockerfile . の所有権を修正してみましょう。 bob のホームディレクトリの所有権を修正してみましょう。コンテナ上で、実行します。

chown -R bob:bob /home/bob
ls -l 

と表示されます。

-rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile

しかし、ちょっと待ってください!コンテナの外側で、今度は ls -l

-rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile

私たちはもはや自分たちのファイルを所有していません。 恐ろしいニュースだ!


上記の例でユーザーを1人しか追加していなければ、すべてがもっとスムーズに進んだことでしょう。 何らかの理由で、Docker は、ユーザーが所有する任意のホーム ディレクトリを 最初 が所有するホームディレクトリを作成します (たとえ、そのユーザーが以前のイメージで宣言されていたとしても)。 同様に、この が最初に のユーザーは、私のホームユーザーと同じ所有者権限に対応するものです。

質問1 これは正しいのでしょうか? 私は上記の実験に基づいて推測しているだけなのですが、どなたかこれに関するドキュメントを紹介していただけませんか?

質問2 : おそらくこれは、カーネル上で両者が同じ数値を持っているからで、もし私がホームユーザがidでないシステムでテストした場合 1000 でないシステムでテストした場合、パーミッションはすべてのケースで変更されるのではないでしょうか?

質問3 : 本当の問題は、もちろん、「これをどうすればいいのか」です。 もし bob としてログインしている場合 bob としてログインしている場合、その人はコンテナを bob としてコンテナを実行し、彼のホストアカウントでファイルパーミッションが変更されないようにする必要があります。 現状では、彼は実際にはコンテナをユーザー docker としてコンテナを実行する必要があります。

私はあなたが尋ねるのを聞いています なぜこんな奇妙な Dockerfile があるのですか? . 私も時々不思議に思います。私は、異なるユーザのログインを許可するウェブアプリ(RStudio-server)用のコンテナを書いていて、それは単に有効なユーザ名として、Linuxマシンからのユーザ名と認証情報を使用します。 このため、複数のユーザーを作成したいという、おそらく変わった動機が生じました。 私は、実行時にのみユーザーを作成することでこれを回避することができ、すべてがうまくいっています。 しかし、私はベースイメージを使用しており、そのイメージには単一の docker ユーザーを追加したベースイメージを使用しており、(ベストプラクティスに従って) root として実行せずに対話的に使用することができます。 これは、そのユーザーが 最初の ユーザーとなり、すべてを所有することになるため、他のユーザーとしてログオンしようとすると失敗します (書き込み権限がないため、アプリを開始できません)。 スタートアップ スクリプトを実行させる chown を最初に実行させると、この問題は解決されますが、リンクされたボリュームのパーミッションが変更されてしまいます (明らかに、ボリュームをリンクしている場合のみ問題です)。

どのように解決するのですか?

これは正しいのでしょうか?私は上記の実験に基づいて推測しているだけなのですが、どなたかこれに関するドキュメントを紹介していただけませんか?

おそらくこれは、両者がカーネル上で同じ数値を持っているからで、もし私がホームユーザーが id 1000 でないシステムでテストしたら、すべてのケースでパーミッションが変更されるのではないでしょうか?

を読んでみてください。 info coreutils 'chown invocation' を読んでみてください。ファイルのパーミッションや所有権がどのように機能するかについて、より良いアイデアを与えてくれるかもしれません。

基本的に、あなたのマシン上の各ファイルは、そのパーミッションと所有権を定義する一連のビットを付加しています。あなたが chown を実行するときは、これらのビットを設定するだけです。

あなたが chown を、ユーザ名やグループ名を使って特定のユーザやグループに送ることができます。 chown/etc/passwd でユーザー名と /etc/group で、名前を ID に対応付けようとします。もしユーザ名/グループ名がこれらのファイルに存在しない場合は chown は失敗します。

root@dc3070f25a13:/test# touch test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 root root    0 Oct 22 18:15 test
root@dc3070f25a13:/test# chown test:test test
chown: invalid user: 'test:test'

しかし chown は、あなたのマシンにその ID を持つユーザー/グループが存在するかどうかに関わらず、(もちろん、いくつかの正の上限整数の範囲内で)好きなものに ID を使用してファイルを作成することができます。

root@dc3070f25a13:/test# chown 5000:5000 test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 5000 5000    0 Oct 22 18:15 test

UID と GID ビットはファイル自体に設定されるため、これらのファイルを docker コンテナ内にマウントすると、ファイルはホスト上と同じオーナー/グループ UID を持ちますが、マップされるのは /etc/passwd にマップされ、ルート (UID 0) が所有していない限り、おそらく別のユーザーとなります。

bob が所定のホストマシンで bob としてログインしている場合、彼は bob としてコンテナを実行でき、彼のホストアカウントでファイルのパーミッションが変更されることはないはずです。現状では、自分のアカウントが変更されるのを避けるために、実際にはユーザー docker としてコンテナを実行する必要があります。

現在のセットアップでは、UID > ユーザー名を /etc/passwd の UIDs > usernames がコンテナ内の UIDs > usernames と一致する必要があるようです。 /etc/passwd というように、ホストでログインしているユーザと同じユーザでマウントされたユーザディレクトリを操作したい場合。

特定のユーザ ID を持つユーザを作成するには useradd -u xxxx . しかし、それは面倒なソリューションのように思えますが......。

ホストユーザーのホームディレクトリをマウントしないような解決策を考えなければならないかもしれません。