デフォルトでは、コンテナ内のプロセスは root ユーザー権限で実行され、この root ユーザーはホスト マシンの root ユーザーと同じユーザーです。恐ろしいことに聞こえますが、これはコンテナ内のプロセスに適切な機会が与えられると、ホスト マシン上のすべてを制御できることを意味するからです。この記事では、ユーザー名、グループ名、ユーザー ID (uid)、グループ ID (gid) がコンテナー内のプロセスとホスト システム間でどのようにマッピングされるかを理解します。これはシステムのセキュリティにとって非常に重要です。注: この記事のデモ環境は Ubuntu 16.04 です (下の画像はインターネットから引用したものです)。 まずuidとgidを理解しましょう Linux カーネルは uid と gid を管理し、カーネルレベルのシステム コールを使用して、要求に権限を付与するかどうかを決定します。たとえば、プロセスがファイルに書き込もうとすると、カーネルは作成プロセスの uid と gid をチェックして、ファイルを変更するのに十分な権限があるかどうかを判断します。カーネルはユーザー名とグループ名ではなく、uid と gid を使用することに注意してください。 簡潔にするために、この記事の残りの部分では uid のみを例として使用します。システムは、基本的に gid を uid と同じように扱います。 多くの学生は、Docker コンテナを単に軽量の仮想マシンとして理解しています。これにより、コンテナ技術の理解の難しさが軽減されますが、多くの誤解を招く可能性もあります。実際、仮想マシン技術とは異なり、同じホスト上で実行されるすべてのコンテナは同じカーネル (ホストのカーネル) を共有します。コンテナ化によってもたらされる大きな価値は、これらすべての独立したコンテナ (実際にはプロセス) がカーネルを共有できることです。つまり、Docker ホスト上で数百または数千のコンテナが実行されている場合でも、カーネルによって制御される uid と gid のセットは 1 つだけになります。したがって、同じ uid は、ホストとコンテナ内の同じユーザーを表します (異なる場所に異なるユーザー名が表示される場合でも)。 ユーザー名を表示するための通常の Linux ツール (id などのコマンドなど) はカーネルの一部ではないため、同じ uid が異なるコンテナーで異なるユーザー名として表示される場合があることに注意してください。ただし、異なるコンテナーであっても、同じ uid に対して異なる権限を持つことはできません。 Linux ユーザー名前空間テクノロジーをすでに知っている場合は、「Linux 名前空間: ユーザー」を参照してください。これまでのところ、Docker はデフォルトでユーザー名前空間を有効にしていないことに注意してください。これは、この記事で説明されているケースでもあります。次の記事では、ユーザー名前空間を有効にするために Docker を設定する方法を紹介します。 コンテナ内のデフォルト ユーザーは root です。 関連する設定が行われていない場合、コンテナ内のプロセスはデフォルトで root ユーザー権限で開始されます。次のデモでは、ubuntu イメージを使用して sleep プログラムを実行します。 $ docker run -d --name sleepme ubuntu スリープ無限 上記のコマンドでは sudo が使用されていないことに注意してください。ホスト マシン上の著者のログイン ユーザーは nick で、uid は 1000 です。 ホスト内のスリープ プロセスの情報を表示します。 $ ps aux | grep スリープ スリープ プロセスの有効なユーザー名は root です。つまり、スリープ プロセスには root 権限があります。 次にコンテナに入り、状況が以前と同じであることを確認します。スリープ プロセスにもルート権限があります。 では、コンテナ内の root ユーザーはホスト上の root ユーザーと同じですか? 答えは「はい、同じ UID に対応します」です。理由は前に説明しました。システム全体が同じカーネルを共有し、カーネルは uid と gid のセットを 1 つだけ管理します。 実際、上記の結論はデータ量を通じて簡単に検証できます。ホスト マシン上に、root ユーザーだけが読み書きできるファイルを作成します。 次に、それをコンテナにマウントします。 $ docker run --rm -it -w=/testv -v $(pwd)/testv:/testv ubuntu コンテナ内でファイルを読み書きできます。 コンテナ内のプロセスのユーザー ID は、Dockerfile の USER コマンドまたは docker run コマンドの --user パラメータを使用して指定できます。これら 2 つの状況を別々に検討してみましょう。 Dockerfile でユーザー ID を指定する Dockerfile にユーザー appuser を追加し、USER コマンドを使用して、プログラムをこのユーザーとして実行するように指定できます。Dockerfile の内容は次のとおりです。 Ubuntuから useradd -r -u 1000 -g appuserを実行します ユーザー appuser ENTRYPOINT ["sleep", "infinity"] test という名前のイメージにコンパイルします。 docker build -t テストを実行します。 テストイメージを使用してコンテナを起動します。 $ docker run -d --name sleepme テスト ホスト内のスリープ プロセスの情報を表示します。 今回表示される有効なユーザーは nick です。これは、ホスト マシンで、uid 1000 を持つユーザーの名前が nick であるためです。次にコンテナに入り、確認してみましょう。 $ docker exec -it sleepme bash コンテナ内の現在のユーザーは、設定した appuser です。コンテナ内の /etc/passwd ファイルを確認すると、appuser の uid が 1000 であることがわかります。これは、ホスト マシンのユーザー nick の uid と同じです。 ユーザー nick だけが読み書きできる別のファイルを作成しましょう。 また、それをデータ ボリュームとしてコンテナーにマウントします。 $ docker run -d --name sleepme -w=/testv -v $(pwd)/testv:/testv テスト コンテナでは、testfile の所有者は appuser になり、もちろん appuser にはファイルの読み取りと書き込みの権限があります。 ここで一体何が起こったのでしょうか?これは何を示しているのでしょうか? まず、ホスト システムには、uid 1000 のユーザー ニックネームが存在します。次に、コンテナ内のプログラムは appuser として実行されます。これは、Dockerfile プログラムで USER appuser コマンドを使用して指定されます。 実際、システム カーネルによって管理される uid 1000 は 1 つだけです。ホスト マシンではユーザー nick と見なされ、コンテナーではユーザー appuser と見なされます。 コマンドライン引数からユーザーIDをカスタマイズする docker run コマンドの --user パラメータを使用して、コンテナ内のプロセスのユーザー ID を指定することもできます。たとえば、次のコマンドを実行します。 $ docker run -d --user 1000 --name sleepme ubuntu スリープ無限 コマンドラインでパラメータ --user 1000 を指定したので、スリープ プロセスの実効ユーザーは nick として表示されます。コンテナに入って見てみましょう: $ docker exec -it sleepme bash 何が起こっているのか?ユーザー名が「名前がありません!」と表示される! /etc/passwd ファイルを確認すると、確かに uid 1000 のユーザーは存在しません。ユーザー名がなくても、ユーザー ID の権限にはまったく影響しません。ニックネームを持つユーザーだけが読み書きできるファイルの読み書きは引き続き可能で、ユーザー情報はユーザー名ではなく uid に置き換えられます。 コンテナの作成時に docker run --user で指定されたユーザー ID は、Dockerfile で指定された値を上書きすることに注意してください。 $ docker run -d テスト スリープ プロセス情報を表示します。 $ docker run --user 0 -d テスト スリープ プロセス情報を再度確認します。 --urser 0 パラメータを指定するプロセスは、有効なユーザーが root であることを示しており、コマンドラインパラメータ --user 0 が Dockerfile 内の USER コマンドの設定をオーバーライドすることを示しています。 要約する この記事の例から、コンテナ内で実行されているプロセスにもホスト リソースへのアクセス権があることがわかります (Docker はデフォルトでユーザーを分離しません)。もちろん、一般的にコンテナ テクノロジでは、コンテナ内のプロセスの可視リソースがコンテナ内でブロックされます。ただし、データ ボリューム内のファイルに対する操作で示したように、コンテナー内のプロセスがホスト マシンのリソースにアクセスする機会を得ると、その権限はホスト マシン上のユーザーの権限と同じになることがわかります。したがって、より安全な方法は、デフォルトのルート ユーザーを使用するのではなく、コンテナー内のプロセスに適切な権限を持つユーザーを指定することです。もちろん、Linux のユーザー名前空間テクノロジーを使用してユーザーを分離するという、より良い解決策があります。次の記事では、ユーザー名前空間のサポートを有効にするために Docker を構成する方法を紹介します。 参照: Docker コンテナでの uid と gid の動作を理解する 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 |
<<: MySQLの日付文字列タイムスタンプ変換の詳細な説明
>>: redhat7 に yum 経由で mysql5.7.17 をインストールするチュートリアル
この記事では、グラフィック認証コードログインを実装するためのVueの具体的なコードを参考までに紹介し...
この記事では、例を使用して MySQL インデックスの原理と使用方法を説明します。ご参考までに、詳細...
目次1. 準備2. MySQL暗号化関数方式2.1 MySQL 暗号化2.2 MYSQL 復号化3....
以下のように表示されます。 CSSコードコンテンツをクリップボードにコピー分割{境界線: 2px 固...
この記事では、例を使用して、MySQL のさまざまな一般的な結合テーブルクエリについて説明します。ご...
レンダリングBlog Gardenでよく使われるスタイル /*タイトル h1 h2 h3 スタイル*...
1. js は hasOwnProperty が不正に占有されることから保護しません。オブジェクトに...
この記事では、MySQL 8.0.15 winx64のインストールと設定方法を参考までに紹介します。...
1. JDKをインストールする1. 古いバージョンまたはシステム独自のJDKをアンインストールする...
編集者:この記事では、インタラクティブデザインがブランドコミュニケーションチェーン全体で果たすべき役...
jsはクリックとドロップの特殊効果を実現します。まずは効果画像を見てみましょうさっそく始めましょう。...
HTMLタグのリストマークタイプ名前または意味効果述べるファイルのタグ付け<HTML> ...
序文:私の知る限り、現在 CSS で制御できるのは、タグをホバーしたときにそのタグの下の兄弟タグとサ...
モバイル アプリを開発する場合、Web サイトが特定の高さまでスクロールしたときにコンテンツの一部を...
イギリスBFC: ブロック書式設定コンテキストBFCレイアウトルール内箱は縦方向に次々に配置されます...