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パスワードとログインエラーの問題について簡単に説明します

推薦する

Reactは無限ループスクロール情報を実装する

この記事では、無限ループスクロールを実現するためのReactの具体的なコードを参考までに紹介します。...

MySQL スライディングオーダー問題の原理と解決の例分析

この記事では、例を使用して、MySQL スライディング順序問題の原理と解決方法を説明します。ご参考ま...

div の特定の実装は自動的に折り返されず、HTML で折り返されないよう強制されます。

1. 改行なしを実現するには<nobr>タグを使用するコードをコピーコードは次のとおりで...

MySQL 5.7.31 64 ビット無料インストール版チュートリアル図

1. ダウンロードダウンロードアドレス: https://dev.mysql.com/get/Dow...

アニメーションの再生と一時停止を制御するための CSS のヒント (非常に実用的)

今日は、CSS を使用してアニメーションの再生と一時停止を制御する非常に簡単なトリックを紹介します。...

VMware Workstation 14 Pro のインストールとアクティベーションのグラフィック チュートリアル

この記事では、VMware Workstation 14 Proのインストールとアクティベーションに...

MySQL からエクスポートされた scv ファイル内の文字化けやジャンプ行の問題をすばやく解決します

仕事上の理由により、完全なオンライン化(​​つまり、すべてのデータがオンラインで完了し、インポートや...

DockerでLinuxシェルコマンドを実行する方法

Docker でシェル コマンドを実行するには、コマンドの前に sh -c を追加する必要があります...

CSS スタイルを HTML 外部スタイルシートにインポートする方法

リンクインスタイルとは、すべてのスタイルを 1 つ以上の外部スタイルシート ファイルに配置することで...

Linux で top コマンドを使用する際のヒント

まず、top のいくつかのフィールドの意味を紹介します。 VIRT:仮想メモリ使用量1. プロセスが...

Ubuntuはポート22を開きます

シナリオssh 経由で Ubuntu サーバーに接続するには、xshell ツールを使用する必要があ...

Linux で Bash 環境変数を設定する方法

Shell は C 言語で書かれたプログラムであり、ユーザーが Linux を使用するための橋渡しと...

MySQL 5.7.21 解凍版インストール Navicat データベース操作ツールインストール

MySQL解凍版とNavicatデータベース操作ツールのインストールは、以下のとおりです。 1. M...

SQL ファジー クエリ レポート: ORA-00909: パラメータの数が無効です。解決策

あいまいクエリにOracleデータベースを使用する場合、コンソール エラーは次の図に表示されます。理...

MySQL の 2 種類の一時テーブルの使用方法の詳細な説明

外部一時テーブルCREATE TEMPORARY TABLE によって作成された一時テーブルは、外部...