docker-composeコンテナのマウント権限の問題
プロジェクトは、docker - composeの起動springbootアプリケーションに遭遇し、マウントされたログディレクトリは、問題を記述する権限を持っていない、その後、多くの情報をチェックし、最終的にいくつかの眉は、レコードを作る、その友人が少ないピットの〜を踏んで発生したことを願っています。
1. 問題の説明
プロジェクトのフレームワークはjhipsterを使って生成されています。さて、ログの記録を見るためには、生成されたログをマウントする必要があります。まず、システムが生成したすべてのログファイルをプロジェクトのlogsディレクトリに格納するためにlogback-spring.xmlの設定を変更します。コードは以下のとおりです。
次に、このディレクトリをlinuxの/temp/logs/bbb/ディレクトリにマウントします。以下は、app.ymlのコードです。
version: '2'
services:
aiops-app:
image: aiops
volumes:
- /temp/logs/bbb/:/home/jhipster/logs/
environment:
# - _JAVA_OPTIONS=-Xmx512m -Xms256m
- SPRING_PROFILES_ACTIVE=prod,swagger
- SPRING_DATASOURCE_URL=jdbc:mysql://test-mysql:3306/aiops?useUnicode=true&characterEncoding=utf8&useSSL=false
- JHIPSTER_SLEEP=10 # gives time for the database to boot before the application
ports:
- 9999:8080
ここで、logs ディレクトリを /temp/logs/bbb/ にマウントし、dockerFile ファイルを見ます。このファイルは、Java アプリケーションを docker イメージとしてパッケージするために使用します。
FROM openjdk:8-jre-alpine
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
JHIPSTER_SLEEP=0 \
JAVA_OPTS=""
# Add a jhipster user to run our application so that it doesn't need to run as root
RUN adduser -D -s /bin/sh jhipster
WORKDIR /home/jhipster
ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh
USER jhipster
ADD *.war app.war
ENTRYPOINT [". /entrypoint.sh"]
EXPOSE 8080
ここでは、ユーザ jhipster を作成し、作業ディレクトリ /home/jhipster を設定します。次に、起動コマンド entrypoint.sh をイメージにコピーし、entrypoint.sh を jhipster ユーザに割り当て、jhipster ユーザでアプリケーションを起動します。entrypoint .sh シェルスクリプトは、次のとおりです。
#! /bin/sh
echo "The application will start in ${JHIPSTER_SLEEP}s... " && sleep ${JHIPSTER_SLEEP}
exec java ${JAVA_OPTS} -Djava.security.egd=file:/dev/. /urandom -jar "${HOME}/app.war" "$@"
ここで${HOME}ディレクトリはlinuxのユーザディレクトリである/home/{username}を指し、現在のユーザはjhipsterなので、ここでのappディレクトリは実際には/home/jhipster/app.warです。${JHIPSTER_SLEEP }は上記の環境変数JHIPSTER_SLEEP=0で、 docker-compose -f appで起動後、app.warを実行します。 yml up -d コマンドで起動すると、図のようにエラーが報告されます。linuxでは、docker on windowはユーザーディレクトリc:gucciにしかマウントできないのに、なぜかtest downはエラーが報告されない。
2. エラー報告の理由と解決策
エラーの原因は、docker-composeの起動時に、コンテナとホストにディレクトリを作成し、ホストではdockerプロセスでディレクトリを作成するためです。しかし、コンテナ内のアプリケーションはjhipsterユーザーで実行されており、当然ながらlogsディレクトリへの書き込み権限がないため、エラーが報告されます。2つのロールは同期されるため、解決策は、ホストログのパーミッションをdockerユーザーのパーミッションに変更します。以下のコマンドで、ホストログのディレクトリのパーミッションを変更することができます。
chown -R 1000:1000 "/temp/logs/bbb/"
修正前と修正後を比較すると、このようになります。
修正後、デフォルトのbbbディレクトリのパーミッションがrootからjhipsterに変わったことがわかります。1000はdockerのユーザーIDで、デフォルトのdockerユーザーIDは1000です。修正後、dockerコンテナのディレクトリlogsロールもjhipsterになり、パーミッションを統一して、アプリケーションがjhipsterで動き、ログファイルのディレクトリパーミッションもjhipsterになって、当然このディレクトリへのログ書き込みができるようになっています。
この方法のメリットは、修正が容易なことですが、デメリットは、手作業が増えることで、複数のディレクトリが絡むと面倒なので、別の方法を紹介します。
3. root 権限でコマンドラインに入り、権限を変更した後、jhipster ユーザーでアプリケーションを起動します。
基本は、rootユーザでコンテナ内のlogsディレクトリのパーミッションをjhipsterに割り当て、jhipsterユーザでアプリケーションを起動します。ここでは、gosuコマンドがあり、以下の場所にあります。 https://github.com/tianon/gosu このコマンドは、"su" と "sudo" に代わる軽量なコマンドで、tty やシグナリングに関する問題の一部を解決するものです。まず、以下のように dockerFile ファイルを修正して sudo コマンドのサポートを追加する必要があります。
FROM openjdk:8-jre-alpine
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
JHIPSTER_SLEEP=0 \
JAVA_OPTS=""
# Add a jhipster user to run our application so that it doesn't need to run as root
RUN adduser -D -s /bin/sh jhipster
WORKDIR /home/jhipster
ADD *.war app.war
ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh
# Use the root user and download the sogu tool
USER root
ENV GOSU_VERSION 1.11
RUN set -eux; \
\
apk add --no-cache --virtual .gosu-deps \
dpkg \
gnupg \
\
\\
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
\
# verify the signature
export GNUPGHOME="$(mktemp -d)"; \
# for flaky keyservers, consider https://github.com/tianon/pgp-happy-eyeballs, ala https://github.com/docker-library/php/pull/666
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
command -v gpgconf && gpgconf --kill all || :; \
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
\
# clean up fetch dependencies
apk del --no-network .gosu-deps; \
\
chmod +x /usr/local/bin/gosu; \
# verify that the binary works
gosu --version; \
gosu nobody true
ENTRYPOINT [". /entrypoint.sh"]
EXPOSE 8080
以前の内容と比較して、rootに切り替えてgosuツールをダウンロードするコードが追加されています。具体的なダウンロードコマンドは、gosuのgithubにあります。 https://github.com/tianon/gosu/blob/master/INSTALL.md というのも、dockerFileの最初の文にあるように、javaアプリケーションのビルドはこれに基づいているからです。
その後、entrypoint.shに移動して権限を与え、以下のようにjhipsterでアプリを起動します。ここで、rootユーザに切り替えなければならない理由は、chownを使用するとエラーが報告されるからです。
#! /bin/sh
chown -R 1000:1000 "logs"
echo "The application will start in ${JHIPSTER_SLEEP}s... " && sleep ${JHIPSTER_SLEEP}
exec gosu jhipster java ${JAVA_OPTS} -Djava.security.egd=file:/dev/. /urandom -jar "app.war" "$@"
これで解決です。この方法では、イメージをパッケージ化するたびにgosuをダウンロードすることになり、少し遅くなりますが、パーミッションを変更する必要はありません。
要約すると、この記事で紹介されているのは https://www.cnblogs.com/jackluo/p/5783116.html が、gosuをダウンロードする部分がうまく動作しないため、一部変更しました。
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
ハートビート・エフェクトのためのHTML+CSS
-
HTML ホテル フォームによるフィルタリング
-
HTML+cssのボックスモデル例(円、半円など)「border-radius」使いやすい
-
HTMLテーブルのテーブル分割とマージ(colspan, rowspan)
-
ランダム・ネームドロッパーを実装するためのhtmlサンプルコード
-
Html階層型ボックスシャドウ効果サンプルコード
-
QQの一時的なダイアログボックスをポップアップし、友人を追加せずにオンラインで話す効果を達成する方法
-
sublime / vscodeショートカットHTMLコード生成の実装
-
HTMLページを縮小した後にスクロールバーを表示するサンプルコード
-
html のリストボックス、テキストフィールド、ファイルフィールドのコード例