Dockerボリューム権限管理の詳細な説明

Dockerボリューム権限管理の詳細な説明

ボリュームデータボリュームは Docker の重要な概念です。データ ボリュームは、1 つ以上のコンテナーで使用できる特別なディレクトリであり、コンテナー アプリケーションのストレージに貴重な機能を提供します。

  • 永続データはコンテナのライフサイクルから切り離されており、コンテナが削除された後もデータ ボリューム内のコンテンツを保持できます。 Docker 1.9 以降に導入された名前付きボリュームを使用すると、データ ボリュームのライフ サイクルをより便利に管理できます。データ ボリュームは個別に作成および削除できます。
  • データボリュームはコンテナ間でデータを共有するために使用できます
  • さまざまなタイプのデータストレージ実装をサポートできます

Docker はデフォルトでホスト上のローカル ファイル ボリュームをサポートし、ホストのディレクトリをコンテナーにマウントできます。コンテナ階層化ファイルシステムによってパフォーマンスが低下することはないため、ローカル ファイル ボリュームは、MySQL データベース ファイルの保存など、高パフォーマンスのデータ アクセスを必要とするシナリオに非常に適しています。同時に、Docker はボリューム プラグインを通じてさまざまな種類のデータ ボリュームをサポートしており、さまざまなアプリケーション負荷のストレージ要件をより柔軟に解決できます。たとえば、Alibaba Cloud Container Service は、クラウド ディスク ベースのブロック ストレージと OSSFS および NAS/NFS ベースの共有ファイル ストレージを備えたコンテナーを提供できます。

ただし、Docker ボリュームの権限の管理は非常にわかりにくいことがよくあります。この記事では、Docker データ ボリュームの権限管理における一般的な問題と解決策を例を挙げて紹介します。

Jenkinsからローカルデータボリュームをマウントする際のエラーについて

同僚が最近、コンテナ内で Jenkins を実行する際に問題に遭遇しました。再現手順は次のとおりです。

注意: Windows/Mac を使用している場合は Boot2docker 仮想マシンにログインする必要がありますが、Linux の場合は必要ありません。

docker-machine ssh デフォルト

Jenkinsの公式イメージを起動してログを確認する

docker run -d -p 8080:8080 -p 50000:50000 --name ジェンキンス ジェンキンス
docker ログ ジェンキンス

「jenkins」コンテナのログを見ると、すべてが正常であることが分かります。

ただし、Jenkins 構成データを永続化するために、ホストの現在のディレクトリにあるデータ フォルダーをコンテナー内のディレクトリ "/var/jenkins_home" にマウントすると、問題が発生します。

docker rm -f ジェンキンス
docker run -d -p 8080:8080 -p 50000:50000 -v $(pwd)/data:/var/jenkins_home --name jenkins jenkins
docker ログ ジェンキンス

エラーログは次のとおりです

touch: '/var/jenkins_home/copy_reference_file.log' にアクセスできません: 権限が拒否されました
/var/jenkins_home/copy_reference_file.log に書き込めません。ボリュームの権限が間違っていますか?

何が起こっているのか?

前の起動方法で「/var/jenkins_home」ディレクトリの権限を確認し、Jenkinsコンテナの現在のユーザーを確認しましょう。現在のユーザーは「jenkins」であり、「/var/jenkins_home」ディレクトリはjenkinsユーザーが所有しています。

docker@default:~$ docker run -ti --rm --entrypoint="/bin/bash" jenkins -c "whoami && id"
ジェンキンス
uid=1000(jenkins) gid=1000(jenkins) グループ=1000(jenkins)

docker@default:~$ docker run -ti --rm --entrypoint="/bin/bash" jenkins -c "ls -la /var/jenkins_home"
合計 20
drwxr-xr-x 2 jenkins jenkins 4096 6月 5日 08:39 .
drwxr-xr-x 28 root root 4096 5月24日 16:43 ..
-rw-r--r-- 1 jenkins jenkins 220 2014年11月12日 .bash_logout
-rw-r--r-- 1 jenkins jenkins 3515 2014年11月12日 .bashrc
-rw-r--r-- 1 ジェンキンス ジェンキンス 675 2014年11月12日 .profile

ローカルデータボリュームをマッピングする場合、/var/jenkins_homeディレクトリの所有者はrootユーザーになります。

docker run -ti --rm -v $(pwd)/data:/var/jenkins_home --entrypoint="/bin/bash" jenkins -c "ls -la /var/jenkins_home"
合計 4
drwxr-sr-x 2 ルートスタッフ 40 6月 5日 08:32 .
drwxr-xr-x 28 root root 4096 5月24日 16:43 ..

これにより、「jenkins」ユーザーのプロセスが「/var/jenkins_home」ディレクトリにアクセスすると、アクセス許可が拒否される問題が発生する理由が説明されます。

ホストマシン上のデータボリュームディレクトリを再度確認してみましょう。現在のパスの下にある「data」ディレクトリの所有者は「root」です。これは、このディレクトリがDockerプロセスによってデフォルトで作成されるためです。

docker@default:~$ ls -laデータ
合計 0
drwxr-sr-x 2 ルートスタッフ 40 6月 5 08:32 ./
drwxr-sr-x 5 docker スタッフ 160 6月 5日 08:32 ../

問題を発見した後の対応する解決策も非常に簡単です。現在のディレクトリの所有者を uid 1000 に割り当ててから、「jenkins」コンテナを起動すると、すべて正常になります。

sudo chown -R 1000データ
docker ジェンキンスを起動する

このとき、ブラウザを使用して「http://192.168.99.100:8080/」にアクセスし、Jenkins Web インターフェースを表示します。注: アクセスできない場合は、docker-machine ip コマンドを使用して現在の Docker ホストの IP アドレスを取得する必要がある場合があります。

再びコンテナに入り、「/var/jenkins_home」ディレクトリの権限を確認すると、その所有者は「jenkins」になっています。

docker@default:~$ docker exec jenkins ls -la /var/jenkins_home
合計 24
drwxr-sr-x 11 jenkins スタッフ 340 6月 5日 09:00 .
drwxr-xr-x 28 root root 4096 5月24日 16:43 ..
drwxr-sr-x 3 jenkins スタッフ 60 6月 5 08:59 .java
-rw-r--r-- 1 jenkins スタッフ 289 6月 5日 08:59 copy_reference_file.log
...

興味深いのは、ホスト上で確認できる「data」ディレクトリの所有者が「docker」であることです。これは、「boot2docker」ホスト上の「docker」ユーザーの uid も「1000」であるためです。

docker@default:~$ ls -laデータ
合計 20
drwxr-sr-x 2 docker スタッフ 40 6月 5日 11:55 ./
drwxr-sr-x 6 docker スタッフ 180 6月 5日 11:55 ../
...

この時点で、コンテナのローカル データ ボリューム内のファイル/ディレクトリの権限は、uid/gid が Docker コンテナとホスト内の異なるユーザー名/グループ名にマップされる可能性があることを除いて、ホスト上の権限と一致していることが既にわかっています。

上記では、ホスト マシンで chown コマンドを実行するときに、特定のユーザー名ではなく uid を使用するという一般的なトリックを使用して、正しい所有者を設定できるようにしました。

問題は解決したが、考えることはまだ終わっていない。ローカル データ ボリュームを使用する場合、Jenkins コンテナーはホスト ディレクトリのアクセス許可の正確性に依存するため、自動展開に余分な作業が追加されます。 Jenkins コンテナにデータ ボリュームの正しいアクセス許可を自動的に設定させる方法はありますか?この問題は、非ルート モードで実行される多くのアプリケーションにも当てはまります。

非ルートアプリケーションのローカルデータボリュームを正しくマウントする

万能の stackoverflow.com には、関連する多くの議論が掲載されています。最も有益な質問と回答の 1 つは次のとおりです。

http://stackoverflow.com/questions/23544282/docker 共有ボリュームの権限を管理する最良の方法は何ですか?

基本的な考え方は 2 つあります。

1 つは、データ コンテナー方式を使用してコンテナー間でデータ ボリュームを共有することです。これにより、ホスト マシン上のデータ ボリュームのアクセス許可の問題を解決する必要がなくなります。 Docker はバージョン 1.9 以降、純粋なデータ コンテナーを置き換える名前付きボリュームを提供しているため、この問題を実際に解決する必要があります。

もう 1 つのアイデアは、コンテナを root ユーザーとして起動し、コンテナ起動スクリプトで「chown」コマンドを使用してデータ ボリューム ファイルのアクセス許可を変更してから、非 root ユーザーに切り替えてプログラムを実行することです。

この問題を解決するために、2 番目のアイデアを参考にしましょう。

以下は、Jenkins イメージに基づく Dockerfile です。「root」ユーザーに切り替えて、イメージに「gosu」コマンドと新しいエントリ ポイント「/entrypoint.sh」を追加します。

jenkins:latestより
ユーザー ルート
GOSU_SHA=5ec5d23079e94aea5f7ed92ee8a1a34bbf64c2d4053dadf383992908a2f9dc8a を実行してください \
 && curl -sSL -o /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.9/gosu-$(dpkg --print-architecture)" \
 && chmod +x /usr/local/bin/gosu \
 && echo "$GOSU_SHA /usr/local/bin/gosu" | sha256sum -c - 
コピー entrypoint.sh /entrypoint.sh
エントリポイント ["/entrypoint.sh"]

注: gosu は、公式の Docker イメージによく登場する小さなツールです。これは、「su」コマンドと「sudo」コマンドの軽量な代替品であり、tty とシグナル配信に関するいくつかの問題を解決します。

新しいエントリ ポイント「entrypoint.sh」の内容は次のとおりです。「JENKINS_HOME」ディレクトリの所有権を「jenkins」に設定し、「gosu」コマンドを使用して「jenkins」ユーザーに切り替えて「jenkins」アプリケーションを実行します。

#!/bin/bash
セット-e
chown -R 1000 "$JENKINS_HOME"
gosu jenkins /bin/tini -- /usr/local/bin/jenkins.sh を実行します

https://github.com/denverdino/docker-jenkins から関連コードを直接取得し、独自の Jenkins イメージを構築できます。実行コマンドは次のとおりです。

git クローン https://github.com/AliyunContainerService/docker-jenkins
jenkins のディレクトリに移動します。
denverdino/jenkins を実行します。

次に、新しいイメージに基づいてJenkinsコンテナを起動します。

docker rm -f ジェンキンス
docker run -d -p 8080:8080 -p 50000:50000 -v $(pwd)/data:/var/jenkins_home --name jenkins denverdino/jenkins

要約する

この記事では、Docker データ ボリュームの基本的な概念について説明します。非ルート プロセスがローカル データ ボリュームにアクセスするときに発生するアクセス許可の問題に対する解決策を提供しました。今後も Docker データ ボリュームで発生するその他の問題についてまとめていく予定です。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Docker 学習に関する簡単な説明: Docker データ量 (ボリューム)
  • Dockerデータ管理の名前付きボリュームの詳細な説明
  • Docker におけるコンテナデータボリュームとデータ管理の詳細な説明
  • Dockerfile命令VOLUMEの簡単な紹介
  • Docker ボリュームの使用の詳細と例

<<:  JavaScript で H5 ゴールド コイン関数を実装する (サンプル コード)

>>:  忘れられたMySQLパスワードとログインエラーの問題について簡単に説明します

推薦する

JavaScript カウントダウン プロンプト ボックス

この記事の例では、カウントダウンプロンプトボックスを実装するためのJavaScriptの具体的なコー...

JavaScript における var と let の違い

目次1. スコープはさまざまな方法で表現されます2. 変動昇進と非昇進の違い3. 一時的なデッドゾー...

MySQL への接続時に発生する 1449 および 1045 例外の解決方法

MySQL への接続時に発生する 1449 および 1045 例外の解決方法 mysql 1449:...

AWS無料サーバーアプリケーションとネットワークプロキシ設定チュートリアルの詳細な説明

目次予防必要条件AWSアカウントを申請する仮想マシンの申請と有効化仮想マシンを申請するセキュリティグ...

固定テーブル幅テーブルレイアウト: 固定

テーブルを画面全体(残りの空白領域)に表示するために、幅属性は 100% と定義されることが多く、セ...

CSS で TikTok テキスト揺れエフェクトを実装する例

日々の開発において、フロントエンドの学生はアニメーションやデザインについてよく議論します。デザイナー...

ネイティブjsは9マスグリッドのドラッグアンドドロップを実現します

ネイティブJSを使用して9つの正方形のグリッドを記述し、9つのグリッドの位置をドラッグして変更する効...

Ubuntu 18.04で国内ソースを変更する方法の例

Ubuntu はソースが中国からなのでダウンロード速度が比較的遅いです。CentOS と異なり、yu...

Vueはツリーテーブルを実装する

この記事では、ツリーテーブルを実装するためのVueの具体的なコードを例として紹介します。具体的な内容...

Linux で FastDFS ファイル サーバーを構築するための実装手順

目次1. ソフトウェアパッケージ2. gccをインストールする3. libfastcommonをイン...

js キャンバスは角丸画像を実現します

この記事では、角を丸くするためのjsキャンバスの具体的なコードを参考までに紹介します。具体的な内容は...

IISとAPACHEはHTTPSへのHTTPリダイレクトを実装しています

7 のMicrosoft の公式 Web サイトから HTTP Rewrite モジュールをダウンロ...

Vue3+スクリプト設定+ts+Vite+Volarプロジェクト

目次Viteを使用してvue + tsプロジェクトを作成するVue 3の3つの構文オプションAPIコ...