私はしばらくの間 Docker をいじっていましたが、永続的なデータを扱うときに同じ問題が見つかり続けています。
Dockerfile
私は自分のものを創り、ボリュームを公開するまたは使用--volumes-from
するコンテナ内にホストフォルダをマウントする。
ホスト上の共有ボリュームにはどのような権限を適用すればよいですか?
2つの選択肢が考えられます:
これまで、すべてのユーザーに読み取り/書き込みアクセス権を付与したので、Docker コンテナからフォルダーに書き込むことができます。
ホストからコンテナにユーザーをマップして、より細かい権限を割り当てることができます。ただし、これが可能かどうかはわかりませんし、それについてはあまり知りません。これまでのところ、私ができることは、コンテナを some user: として実行することだけです
docker run -i -t -user="myuser" postgres
が、このユーザーの UID はホストのものと異なるためmyuser
、権限は機能しません。また、ユーザーをマッピングするとセキュリティ上のリスクが生じるかどうかもわかりません。
他に選択肢はありますか?
皆さんはこの問題にどのように対処していますか?
ベストアンサー1
2016-03-02更新: Docker 1.9.0以降、Dockerは名前付きボリュームどれのデータのみのコンテナを置き換える以下の回答とリンクされたブログ投稿は、Docker 内でデータをどのように考えるかという意味で依然として価値がありますが、以下に説明するパターンを実装するには、データ コンテナーではなく名前付きボリュームを使用することを検討してください。
これを解決する標準的な方法は、データのみのコンテナこのアプローチでは、ボリューム データへのすべてのアクセスは、-volumes-from
データ コンテナーを使用するコンテナーを介して行われるため、ホストの uid/gid は関係ありません。
たとえば、ドキュメントに記載されている使用例の 1 つは、データ ボリュームのバックアップです。これを行うには、 を介してバックアップを実行する別のコンテナーが使用されtar
、-volumes-from
ボリュームをマウントするために も使用されます。したがって、理解すべき重要なポイントは、適切な権限でホスト上のデータにアクセスする方法を考えるのではなく、別のコンテナーを介して必要な操作 (バックアップ、ブラウジングなど) を実行する方法を考えることです。コンテナー自体は一貫した uid/gid を使用する必要がありますが、ホスト上の何かにマップする必要はないため、移植性は維持されます。
これは私にとっても比較的新しいことですが、特定のユースケースがある場合は、遠慮なくコメントしてください。回答を詳しく述べたいと思います。
更新: コメントで指定されたユースケースでは、some/graphite
Graphite を実行するためのイメージと、データ コンテナーとしてのイメージがある可能性がありますsome/graphitedata
。したがって、ポートなどを無視すると、Dockerfile
イメージはsome/graphitedata
次のようになります。
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
RUN mkdir -p /data/graphite \
&& chown -R graphite:graphite /data/graphite
VOLUME /data/graphite
USER graphite
CMD ["echo", "Data container for graphite"]
データ コンテナーをビルドして作成します。
docker build -t some/graphitedata Dockerfile
docker run --name graphitedata some/graphitedata
Dockerfilesome/graphite
も同じ uid/gid を取得する必要があるため、次のようになります。
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
# ... graphite installation ...
VOLUME /data/graphite
USER graphite
CMD ["/bin/graphite"]
そして、次のように実行されます。
docker run --volumes-from=graphitedata some/graphite
さて、これで、Graphite コンテナーと、適切なユーザー/グループに関連付けられたデータのみのコンテナーが作成されました (コンテナーをデータ コンテナーにも再利用してsome/graphite
、実行時にエントリポイント/コマンドをオーバーライドすることもできますが、個別のイメージとして持つ方がわかりやすいと思います)。
ここで、データ フォルダー内の何かを編集したいとします。ボリュームをホストにバインド マウントしてそこで編集するのではなく、その作業を行う新しいコンテナーを作成します。これを と呼びますsome/graphitetools
。また、イメージと同じように、適切なユーザー/グループも作成しますsome/graphite
。
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
&& useradd -r -g graphite graphite
VOLUME /data/graphite
USER graphite
CMD ["/bin/bash"]
some/graphite
Dockerfile から継承するか、Dockerfile 内で継承することでこれを DRY にすることができますsome/graphitedata
。また、新しいイメージを作成する代わりに、既存のイメージの 1 つを再利用することもできます (必要に応じてエントリポイント/cmd をオーバーライドします)。
ここで、以下を実行するだけです:
docker run -ti --rm --volumes-from=graphitedata some/graphitetools
そして、vi /data/graphite/whatever.txt
すべてのコンテナに一致する uid/gid を持つ同じ graphite ユーザーが存在するため、これは完璧に機能します。
/data/graphite
ホストからマウントすることはないので、ホストの uid/gid がgraphite
およびgraphitetools
コンテナー内で定義された uid/gid にどのようにマップされるかを気にする必要はありません。これらのコンテナーはどのホストにもデプロイでき、引き続き完全に動作します。
これのすばらしい点は、graphitetools
あらゆる種類の便利なユーティリティとスクリプトが用意されており、ポータブルな方法で展開できるようになったことです。
更新2:この回答を書いた後、私はより完全なブログ投稿このアプローチについて。お役に立てれば幸いです。
更新 3 : この回答を修正し、詳細を追加しました。以前は所有権と権限について誤った仮定が含まれていました。所有権は通常、ボリュームの作成時、つまりデータ コンテナーで割り当てられます。ボリュームが作成されるのはそのときだからです。このブログただし、これは必須ではありません。データ コンテナーを「参照/ハンドル」として使用し、エントリポイントで chown を介して別のコンテナーに所有権/権限を設定し、正しいユーザーとしてコマンドを実行するために gosu で終了することができます。このアプローチに興味のある方は、コメントしてください。このアプローチを使用したサンプルへのリンクを提供できます。