Comment contrôler l'hôte de conteneur docker?
Par exemple, comment exécuter copié dans le script hôte bash?
Cela dépend VRAIMENT de ce que vous avez besoin de ce script bash!
Par exemple, si le script bash fait juste écho à une sortie, vous pouvez simplement faire
docker run --rm -v $(pwd)/mybashscript.sh:/mybashscript.sh ubuntu bash /mybashscript.sh
Une autre possibilité est que vous souhaitiez que le script bash installe un logiciel, par exemple le script pour installer docker-compose. vous pourriez faire quelque chose comme
docker run --rm -v /usr/bin:/usr/bin --privileged -v $(pwd)/mybashscript.sh:/mybashscript.sh ubuntu bash /mybashscript.sh
Mais à ce stade, vous devez vraiment savoir intimement ce que fait le script pour autoriser les autorisations spécifiques dont il a besoin sur votre hôte à partir du conteneur.
Je sais que c'est une vieille question, mais la solution idéale est peut-être de se connecter à l'hôte via SSH
et d'exécuter la commande comme suit:
ssh -l ${USERNAME} ${HOSTNAME} "${SCRIPT}"
Comme cette réponse ne cesse de générer des votes, je souhaite ajouter une note indiquant que le compte utilisé pour invoquer le script doit être un compte sans autorisation, mais uniquement exécuter ce script en tant que Sudo (cela peut être effectué à partir du fichier sudoers
).
Utilisé un canal nommé . Sur l'hôte hôte, créez un script pour lire et lire les commandes, puis appelez eval à cet effet.
Demandez au conteneur de menu fixe de se lire sur le tuyau nommé.
Pour pouvoir accéder au tuyau, vous devez le monter via un volume.
Ceci est similaire au mécanisme SSH (ou à une méthode similaire basée sur un socket), mais vous limite correctement au périphérique hôte, ce qui est probablement meilleur. De plus, vous n'avez pas besoin de transmettre des informations d'authentification.
Mon seul avertissement est d'être prudent sur la raison pour laquelle vous faites cela. C'est tout à fait quelque chose à faire si vous voulez créer une méthode d'auto-mise à niveau avec une entrée utilisateur ou autre, mais vous ne voudrez probablement pas appeler une commande pour obtenir des données de configuration, car le moyen approprié serait de passer cela en argument./volume en docker. Faites également attention au fait que vous êtes en train d’évaluer, alors pensez au modèle d’autorisation.
Certaines des autres réponses telles que l'exécution d'un script sous un volume ne fonctionneront pas de manière générique car ils n'auront pas accès à l'ensemble des ressources système, mais cela pourrait être plus approprié en fonction de votre utilisation.
Comme le rappelle Marcus, le menu fixe est essentiellement un processus d’isolation. À partir de docker 1.8, vous pouvez copier des fichiers dans les deux sens entre l'hôte et le conteneur, voir la doc de docker cp
https://docs.docker.com/reference/commandline/cp/
Une fois qu'un fichier est copié, vous pouvez l'exécuter localement
Si vous souhaitez simplement démarrer un conteneur Docker sur l'hôte à partir d'un autre conteneur Docker tel que l'OP, vous pouvez partager le serveur Docker qui s'exécute sur l'hôte avec le conteneur Docker en partageant son socket d'écoute.
Vous pouvez le faire en ajoutant les arguments de volume suivants à votre commande de démarrage
docker run -v /var/run/docker.sock:/var/run/docker.sock ...
ou en partageant /var/run/docker.sock dans votre fichier de docker, composez le fichier comme ceci:
version: '3'
services:
ci:
command: ...
image: ...
volumes
- /var/run/docker.sock:/var/run/docker.sock
Lorsque vous exécutez la commande docker start dans votre conteneur docker, le serveur docker exécuté sur votre hôte voit la demande et met en service le conteneur frère.
crédit: http://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/
docker run --detach-keys="ctrl-p" -it -v /:/mnt/rootdir --name testing busybox
# chroot /mnt/rootdir
#
J'ai une approche simple.
Étape 1: Montez /var/run/docker.sock:/var/run/docker.sock (vous pourrez donc exécuter des commandes de menu dans votre conteneur)
Étape 2: Exécutez la procédure ci-dessous dans votre conteneur. La partie clé ici est ( --Hôte réseau car cela sera exécuté à partir du contexte hôte)
docker run -i --rm --network Host -v /opt/test.sh:/test.sh Alpine: 3.7 sh /test.sh
test.sh devrait contenir les quelques commandes (ifconfig, netstat, etc.), quoi que vous ayez besoin de ... .. Maintenant, vous pourrez obtenir la sortie du contexte de l'hôte.
Écrivez un serveur python de serveur simple à l'écoute sur un port (disons 8080), liez le port -p 8080: 8080 au conteneur, envoyez une requête HTTP à localhost: 8080 pour demander au serveur python de lancer des scripts écrire du code pour créer une requête HTTP curl -d '{"foo": "bar"}' localhost: 8080
#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
import subprocess
import json
PORT_NUMBER = 8080
# This class will handles any incoming request from
# the browser
class myHandler(BaseHTTPRequestHandler):
def do_POST(self):
content_len = int(self.headers.getheader('content-length'))
post_body = self.rfile.read(content_len)
self.send_response(200)
self.end_headers()
data = json.loads(post_body)
// Use the post data
cmd = "your Shell cmd"
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, Shell=True)
p_status = p.wait()
(output, err) = p.communicate()
print "Command output : ", output
print "Command exit status/return code : ", p_status
self.wfile.write(cmd + "\n")
return
try:
# Create a web server and define the handler to manage the
# incoming request
server = HTTPServer(('', PORT_NUMBER), myHandler)
print 'Started httpserver on port ' , PORT_NUMBER
# Wait forever for incoming http requests
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down the web server'
server.socket.close()