web-dev-qa-db-ja.com

Dockerコンテナーの起動後にスクリプトを自動的に実行する方法

複数のノードで構成されるelasticsearchクラスターを保護するために、Search Guardプラグインを使用しています。ここに私のDockerfileがあります:

#!/bin/sh
FROM docker.elastic.co/elasticsearch/elasticsearch:5.6.3

USER root

# Install search guard
RUN bin/elasticsearch-plugin install --batch com.floragunn:search-guard-5:5.6.3-16 \
    && chmod +x \
        plugins/search-guard-5/tools/hash.sh \
        plugins/search-guard-5/tools/sgadmin.sh \
        bin/init_sg.sh \
    && chown -R elasticsearch:elasticsearch /usr/share/elasticsearch

USER elasticsearch

SearchGuardを初期化する(内部ユーザーを作成して役割を割り当てる)。スクリプトを実行する必要がありますinit_sg.shコンテナの起動後。ここに問題があります:elasticsearchが実行されていない限り、スクリプトはセキュリティインデックスを初期化しません。

スクリプトの内容は次のとおりです。

sleep 10
plugins/search-guard-5/tools/sgadmin.sh -cd config/ -ts config/truststore.jks -ks config/kirk-keystore.jks -nhnv -icl

今、私はコンテナーの起動後にスクリプトを手動で実行するだけですが、それをKubernetesで実行しているためです。ポッドが強制終了または失敗し、何らかの理由で自動的に再作成される場合があります。この場合、プラグインはコンテナの起動後に自動的に初期化する必要があります!

これを達成するにはどうすればよいですか?ヘルプやヒントをいただければ幸いです。

6
PhiloJunkie

イメージ自体には、Dockerfileで指定されたエントリポイントENTRYPOINT ["/run/entrypoint.sh"]があります。独自のスクリプトで置き換えることができます。たとえば、新しいスクリプトを作成してマウントし、最初に/run/entrypoint.shを呼び出してから、Elasticsearchの開始を待ってからinit_sg.shを実行します。

4

これで問題が解決するかどうかはわかりませんが、確認する価値があります repo 's Dockerfile

Docker imageにコピーされたシンプルなrun.shファイルを作成し、DockerfileCMD ["run.sh"]と書きました。同様に、run.shに必要なものを定義し、CMD ["run.sh"]と記述します。あなたは以下のような別の例を見つけることができます

Dockerfile

FROM Java:8

RUN apt-get update && apt-get install stress-ng -y 
ADD target/restapp.jar /restapp.jar 
COPY dockerrun.sh /usr/local/bin/dockerrun.sh 
RUN chmod +x /usr/local/bin/dockerrun.sh 
CMD ["dockerrun.sh"]

dockerrun.sh

#!/bin/sh
Java -Dserver.port=8095 -jar /restapp.jar &
hostname="hostname: `hostname`"
Nohup stress-ng --vm 4 &
while true; do
  sleep 1000
done
4

私は正確な問題を解決しようとしていました。ここに私のために働いたアプローチがあります。

  1. ESのステータスをチェックする別のシェルスクリプトを作成し、ESの準備ができたときにのみSGの初期化を開始します。

シェルスクリプト

#!/bin/sh

echo ">>>>  Right before SG initialization <<<<"
# use while loop to check if elasticsearch is running 
while true
do
    netstat -uplnt | grep :9300 | grep LISTEN > /dev/null
    verifier=$?
    if [ 0 = $verifier ]
        then
            echo "Running search guard plugin initialization"
            /elasticsearch/plugins/search-guard-6/tools/sgadmin.sh -h 0.0.0.0 -cd plugins/search-guard-6/sgconfig -icl -key config/client.key -cert config/client.pem -cacert config/root-ca.pem -nhnv
            break
        else
            echo "ES is not running yet"
            sleep 5
    fi
done

Dockerfileにスクリプトをインストールする

スクリプトをコンテナーにインストールして、開始後にアクセスできるようにする必要があります。

COPY sginit.sh /
RUN chmod +x /sginit.sh

エントリポイントスクリプトの更新

ESイメージのエントリポイントスクリプトまたは実行スクリプトを編集する必要があります。 ESプロセスを開始する前に、バックグラウンドでsginit.shを開始します。

# Run sginit in background waiting for ES to start
/sginit.sh &

これにより、sginit.shがバックグラウンドで起動し、ESの起動後にのみSGを初期化します。

このsginit.shスクリプトをESの前にバックグラウンドで開始するのは、ESの開始をブロックしないためです。 ESの起動後に配置した場合も同じロジックが適用され、ESの起動をバックグラウンドに配置しない限り実行されません。

2
nafooesi

[〜#〜] cmd [〜#〜]をdockerファイルに入れて、コンテナの起動時にスクリプトを実行することをお勧めします

FROM debian
RUN apt-get update && apt-get install -y nano && apt-get clean
EXPOSE 8484
CMD ["/bin/bash", "/opt/your_app/init.sh"]

他の方法もありますが、これを使用する前に要件を確認してください。

    ENTRYPOINT "put your code here" && /bin/bash
    #exemple ENTRYPOINT service nginx start && service ssh start &&/bin/bash "use && to separate your code"
1
Sohan