web-dev-qa-db-fra.com

Comment puis-je exécuter le script automatiquement après le démarrage du conteneur Docker

J'utilise le plugin Search Guard pour sécuriser un cluster elasticsearch composé de plusieurs nœuds. Voici mon 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

Pour initialiser SearchGuard (créer des utilisateurs internes et attribuer des rôles). J'ai besoin d'exécuter le script init_sg.sh après le démarrage du conteneur. Voici le problème: à moins qu'elasticsearch ne soit en cours d'exécution, le script n'initialise aucun index de sécurité.

Le contenu du script est:

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

Maintenant, je viens d'exécuter le script manuellement après le démarrage du conteneur, mais puisque je l'exécute sur Kubernetes .. Les pods peuvent être tués ou échouer et être recréés automatiquement pour une raison quelconque. Dans ce cas, le plugin doit être initialisé automatiquement après le démarrage du conteneur!

Alors, comment y parvenir? Toute aide ou conseil serait vraiment apprécié.

6
PhiloJunkie

L'image elle-même a un point d'entrée ENTRYPOINT ["/run/entrypoint.sh"] spécifié dans le Dockerfile. Vous pouvez le remplacer par votre propre script. Par exemple, créez un nouveau script, montez-le et appelez d'abord /run/entrypoint.sh puis attendez le démarrage d'elasticsearch avant d'exécuter votre init_sg.sh.

4
Jonathan Lechner

Je ne sais pas si cela résoudra votre problème, mais cela vaut la peine de vérifier mon repo 's Dockerfile

J'ai créé un simple run.sh fichier copié dans l'image docker et dans le Dockerfile j'ai écrit CMD ["run.sh"]. De la même manière, définissez ce que vous voulez dans run.sh et écrire CMD ["run.sh"]. Vous pouvez trouver un autre exemple comme ci-dessous

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
Veerendra Kakumanu

J'essayais de résoudre le problème exact. Voici l'approche qui a fonctionné pour moi.

  1. Créez un script Shell distinct qui vérifie l'état ES et ne lancez l'initialisation de SG que lorsque ES est prêt:

Script Shell

#!/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

Installer le script dans Dockerfile

Vous devrez installer le script dans le conteneur afin qu'il soit accessible après son démarrage.

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

Mettre à jour le script du point d'entrée

Vous devrez modifier le script du point d'entrée ou exécuter le script de votre image ES. Pour qu'il démarre le sginit.sh en arrière-plan AVANT de démarrer le processus ES.

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

De cette façon, sginit.sh démarrera en arrière-plan et initialisera SG uniquement après le démarrage d'ES.

La raison pour laquelle ce script sginit.sh démarre avant ES en arrière-plan est pour ne pas empêcher ES de démarrer. La même logique s'applique si vous le mettez après le démarrage d'ES, il ne fonctionnera jamais à moins que vous ne mettiez le démarrage d'ES en arrière-plan.

2
nafooesi

Je suggérerais de mettre le CMD dans votre fichier docker pour exécuter le script au démarrage du conteneur

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

Il existe un autre moyen, mais avant d'utiliser ce regard sur votre besoin,

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