[解決済み] dockerのユーザーファイル所有権を理解する:リンクされたボリュームのパーミッションを変更しない方法
質問
次のような簡単な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
. しかし、それは面倒なソリューションのように思えますが......。
ホストユーザーのホームディレクトリをマウントしないような解決策を考えなければならないかもしれません。
関連
-
centos7 インストール クリックハウスとセット ユーザー名 パスワード ケース 詳細
-
virtualboxが仮想マシンを開けない場合は?linuxがvirtualboxにアクセスできない時の解決策
-
deepinシステムのバージョン番号を見るには?deepinシステムのバージョン情報を見るコツ
-
[解決済み] CPAN.pmが@INCに見つからない(@INCには含まれています。/usr/local/lib/perl5 /usr/local/share/perl5。
-
[解決済み] mkdirのオプションが明確でない
-
[解決済み] Linuxで特定のポートで動作しているプロセスを停止させる方法は?
-
[解決済み] Dockerコンテナにユーザーを追加する方法は?
-
[解決済み] Docker共有ボリュームのパーミッションを管理する(最良の)方法は何ですか?
-
[解決済み】ビルド中にDockerfileでホストボリュームをDockerコンテナにマウントする方法
-
[解決済み】Docker Postgresのスクリプトでユーザー/データベースを作成する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vmware 16仮想マシンを開けない場合、ファイルをローカルにコピーする方法は?
-
deepin linuxでroot権限に切り替えるには?Deepinでrootに切り替えるためのヒント
-
Linux Mintシステムでプログラムをアンインストールするには? Linux で不要なアプリケーションをアンインストールするためのヒント
-
Linux MintのデスクトップでNoteをイタリックにすることは可能ですか?
-
LinuxでJenkinsプラグインのインストールが遅い場合の解決策
-
TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み] mkdirのオプションが明確でない
-
[解決済み] エラーです。Can't open display: (null)と表示されることがあります。
-
[解決済み] フォルダとそのサブフォルダ/ファイルのパーミッションを一括で変更する方法
-
[解決済み] Linuxで特定のポートで動作しているプロセスを停止させる方法は?