Wie führe ich ein Shell-Skript auf dem Host aus dem Docker-Container aus?


88

Wie steuere ich den Host vom Docker-Container aus?

Wie kann man beispielsweise ein in das Host-Bash-Skript kopiertes Skript ausführen?


8
Wäre das nicht genau das Gegenteil von der Isolierung des Hosts vom Docker?
Marcus Müller

31
Ja. Aber es ist manchmal notwendig.
Alex Ushakov


Ich bin mir nicht sicher über "Control Host", aber ich war kürzlich bei einem Vortrag von Datenwissenschaftlern, die Docker verwenden, um Skripte auszuführen, um große Workloads (unter Verwendung von AWS-gemounteten GPUs) zu verarbeiten und das Ergebnis an den Host auszugeben. Ein sehr interessanter Anwendungsfall. Im Wesentlichen Skripte mit einer zuverlässigen Ausführungsumgebung dank Docker
KCD

@KCD Und warum bevorzugen sie die App-Containerisierung über Docker anstelle von Containern auf Systemebene (LXC)?
Alex Ushakov

Antworten:


30

Das hängt WIRKLICH davon ab, wozu Sie dieses Bash-Skript benötigen!

Wenn das Bash-Skript beispielsweise nur eine Ausgabe wiedergibt, können Sie dies einfach tun

docker run --rm -v $(pwd)/mybashscript.sh:/mybashscript.sh ubuntu bash /mybashscript.sh

Eine andere Möglichkeit besteht darin, dass das Bash-Skript Software installieren soll - beispielsweise das Skript zur Installation von Docker-Compose. du könntest so etwas tun

docker run --rm -v /usr/bin:/usr/bin --privileged -v $(pwd)/mybashscript.sh:/mybashscript.sh ubuntu bash /mybashscript.sh

An diesem Punkt müssen Sie jedoch genau wissen, was das Skript tut, um die spezifischen Berechtigungen, die es auf Ihrem Host benötigt, aus dem Container heraus zuzulassen.


1
Ich hatte die Idee, einen Container zu erstellen, der eine Verbindung zum Host herstellt und neue Container erstellt.
Alex Ushakov

1
Docker scheint Ihr relatives Reittier nicht zu mögen. Dies sollte funktionierendocker run --rm -v $(pwd)/mybashscript.sh:/work/mybashscript.sh ubuntu /work/mybashscript.sh
KCD

Danke für den Haken, ich habe den Beitrag repariert!
Paul Becotte

5
In der ersten Zeile wird ein neuer Ubuntu-Container gestartet und das Skript dort bereitgestellt, wo es gelesen werden kann. So kann der Container beispielsweise nicht auf das Host-Dateisystem zugreifen. In der zweiten Zeile werden die Hosts /usr/bindem Container ausgesetzt. In keinem Fall hat der Container vollen Zugriff auf das Hostsystem. Vielleicht irre ich mich, aber es scheint eine schlechte Antwort auf eine schlechte Frage zu sein.
Paul

3
Fair genug - die Frage war ziemlich vage. Bei der Frage wurde nicht nach "vollem Zugriff auf das Hostsystem" gefragt. Wie beschrieben, würde das Bash-Skript, wenn es nur eine Ausgabe wiedergeben soll, keinen Zugriff auf das Host-Dateisystem benötigen. In meinem zweiten Beispiel, in dem Docker-Compose installiert wurde, benötigen Sie lediglich den Zugriff auf das bin-Verzeichnis, in dem die Binärdatei gespeichert wird. Wie ich am Anfang sagte - um dies zu tun, müssten Sie sehr spezifische Vorstellungen darüber haben, was das Skript tut, um die richtigen Berechtigungen zuzulassen.
Paul Becotte

56

Die Lösung, die ich verwende, besteht darin, eine Verbindung zum Host herzustellen SSHund den Befehl wie folgt auszuführen:

ssh -l ${USERNAME} ${HOSTNAME} "${SCRIPT}"

AKTUALISIEREN

Da diese Antwort immer mehr Stimmen erhält, möchte ich daran erinnern (und wärmstens empfehlen), dass das Konto, das zum Aufrufen des Skripts verwendet wird, ein Konto ohne Berechtigungen sein sollte, das dieses Skript jedoch nur als sudo(das kann sein) ausführt aus sudoersDatei gemacht).


Als weitere Problemumgehung könnte der Container eine Reihe von Befehlen ausgeben und der Host könnte sie ausführen, nachdem der Container beendet wurde: eval $ (Docker-Lauf --rm -it Containername_zu_Ausgabeskript)
Parität3

Ich muss eine Befehlszeile auf dem Host in einem Docker-Container ausführen, aber wenn ich in den Container gehe, sshwird sie nicht gefunden. Haben Sie weitere Vorschläge?
Ron Rosenfeld

@ RonRosenfeld, welches Docker-Image verwenden Sie? Führen Sie im Fall von debian / ubuntu Folgendes aus : apt update && apt install openssh-client.
Mohammed Noureldin

Es wäre alles, was auf meinem Synology NAS installiert wurde. Wie kann ich sagen?
Ron Rosenfeld

@ RonRosenfeld, sorry ich verstehe nicht was du meinst
Mohammed Noureldin

47

Verwendete eine Named Pipe. Erstellen Sie auf dem Host-Betriebssystem ein Skript zum Schleifen und Lesen von Befehlen, und rufen Sie dann eval auf.

Lassen Sie den Docker-Container in die Named Pipe lesen.

Um auf das Rohr zugreifen zu können, müssen Sie es über ein Volume bereitstellen.

Dies ähnelt dem SSH-Mechanismus (oder einer ähnlichen Socket-basierten Methode), beschränkt Sie jedoch ordnungsgemäß auf das Host-Gerät, was wahrscheinlich besser ist. Außerdem müssen Sie keine Authentifizierungsinformationen weitergeben.

Meine einzige Warnung ist, vorsichtig zu sein, warum Sie dies tun. Es ist absolut etwas zu tun, wenn Sie eine Methode zum Selbst-Upgrade mit Benutzereingaben oder was auch immer erstellen möchten, aber wahrscheinlich keinen Befehl aufrufen möchten, um einige Konfigurationsdaten abzurufen, da der richtige Weg darin besteht, diese als Argumente zu übergeben / Volume in Docker. Seien Sie auch vorsichtig mit der Tatsache, dass Sie eine Bewertung vornehmen. Denken Sie also einfach über das Berechtigungsmodell nach.

Einige der anderen Antworten, z. B. das Ausführen eines Skripts unter einem Volume, funktionieren nicht generisch, da sie nicht auf die vollständigen Systemressourcen zugreifen können. Je nach Verwendung ist dies jedoch möglicherweise angemessener.


13
ACHTUNG: Dies ist die richtige / beste Antwort und es braucht etwas mehr Lob. Bei jeder anderen Antwort geht es darum, zu fragen, was Sie versuchen, und Ausnahmen für Dinge zu machen. Ich habe einen sehr spezifischen Anwendungsfall, bei dem ich dazu in der Lage sein muss, und dies ist imho die einzig gute Antwort. SSH oben würde eine Senkung der Sicherheits- / Firewall-Standards erfordern, und das Docker-Run-Zeug ist einfach falsch. Danke dafür. Ich gehe davon aus, dass dies nicht so viele positive Stimmen erhält, da es sich nicht um eine einfache Antwort zum Kopieren / Einfügen handelt, aber dies ist die Antwort. +100 Punkte von mir, wenn ich könnte
Farley

3
Für diejenigen, die nach weiteren Informationen suchen, können Sie das folgende Skript verwenden, das auf dem Host-Computer ausgeführt wird: unix.stackexchange.com/a/369465 Natürlich müssen Sie es mit 'nohup' ausführen und eine Art Supervisor-Wrapper erstellen um es am Leben zu erhalten (vielleicht einen Cron-Job verwenden: P)
Sucotronic

Ich habe ein Diagramm erstellt, um einen Anwendungsfall zu veranschaulichen: imgur.com/a/9Wkxqu9
sucotronic

7
Dies könnte eine gute Antwort sein. Es wäre jedoch viel besser, wenn Sie mehr Details und weitere Erklärungen zur Befehlszeile geben würden. Ist es möglich, näher darauf einzugehen?
Mohammed Noureldin

5
Upvoted, das funktioniert! Erstellen Sie mit 'mkfifo host_executor_queue' eine Named Pipe, auf der das Volume bereitgestellt wird. Verwenden Sie dann 'tail -f host_executor_queue |, um einen Consumer hinzuzufügen, der Befehle ausführt, die als Host-Shell in die Warteschlange gestellt werden Sch &'. Das & am Ende lässt es im Hintergrund laufen. Um Befehle in die Warteschlange zu verschieben, verwenden Sie 'echo touch foo> host_executor_queue'. Bei diesem Test wird eine temporäre Datei foo im Ausgangsverzeichnis erstellt. Wenn der Consumer beim Systemstart gestartet werden soll, geben Sie '@reboot tail -f host_executor_queue | ein sh & 'in crontab. Fügen Sie einfach den relativen Pfad zu host_executor_queue hinzu.
Skybunk

7

Wenn Sie sich keine Sorgen um die Sicherheit machen und einfach einen Docker-Container auf dem Host aus einem anderen Docker-Container wie dem OP heraus starten möchten, können Sie den auf dem Host ausgeführten Docker-Server für den Docker-Container freigeben, indem Sie dessen Listen-Socket freigeben.

Bitte sehen Sie unter https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface nach, ob Ihre persönliche Risikotoleranz dies für diese bestimmte Anwendung zulässt.

Sie können dies tun, indem Sie Ihrem Startbefehl die folgenden Volume-Argumente hinzufügen

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

oder indem Sie /var/run/docker.sock in Ihrer Docker-Compose-Datei wie folgt freigeben:

version: '3'

services:
   ci:
      command: ...
      image: ...
      volumes
         - /var/run/docker.sock:/var/run/docker.sock

Wenn Sie den Docker-Startbefehl in Ihrem Docker-Container ausführen, sieht der Docker-Server, der auf Ihrem Host ausgeführt wird, die Anforderung und stellt den Geschwistercontainer bereit.

Bildnachweis: http://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/


1
Beachten Sie, dass Docker im Container installiert sein muss, andernfalls müssen Sie auch ein Volume für die Docker-Binärdatei bereitstellen (z /usr/bin/docker:/usr/bin/docker. B. ).
Gerry

1
Bitte seien Sie vorsichtig, wenn Sie den Docker-Sockel in Ihren Container einbauen.
DatGuyKaj

@DatGuyKaj danke, ich habe meine Antwort bearbeitet, um die von Ihrer Ressource beschriebenen Probleme widerzuspiegeln.
Matt Bucci

2

Schreiben Sie einen einfachen Python-Server, der einen Port überwacht (z. B. 8080), binden Sie den Port -p 8080: 8080 an den Container, senden Sie eine HTTP-Anfrage an localhost: 8080, um den Python-Server aufzufordern, Shell-Skripte mit Popen auszuführen, einen Curl auszuführen oder Schreiben von Code, um eine HTTP-Anfrage zu erstellen 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()

1

Ich habe einen einfachen Ansatz.

Schritt 1: Mounten Sie /var/run/docker.sock:/var/run/docker.sock (damit Sie Docker-Befehle in Ihrem Container ausführen können)

Schritt 2: Führen Sie dies unten in Ihrem Container aus. Der Schlüsselteil hier ist ( --network host, da dies aus dem Hostkontext ausgeführt wird)

Docker run -i --rm --network host -v /opt/test.sh:/test.sh alpine: 3.7 sh /test.sh

test.sh sollte einige Befehle enthalten (ifconfig, netstat usw.), die Sie benötigen. Jetzt können Sie die Host-Kontextausgabe erhalten.


2
In der offiziellen Docker-Dokumentation zum Netzwerk mithilfe des Host-Netzwerks heißt es: "Auf alle anderen Arten, wie z. B. Speicher, Prozessnamespace und Benutzernamensraum, ist der Prozess jedoch vom Host isoliert." Check out - docs.docker.com/network/network-tutorial-host
Peter Mutisya

1

Meine Faulheit führte mich dazu, die einfachste Lösung zu finden, die hier nicht als Antwort veröffentlicht wurde.

Es basiert auf dem großartigen Artikel von luc juggery .

Alles, was Sie tun müssen, um eine vollständige Shell für Ihren Linux-Host aus Ihrem Docker-Container heraus zu erhalten, ist:

docker run --privileged --pid=host -it alpine:3.8 \
nsenter -t 1 -m -u -n -i sh

Erläuterung:

--privileged: Erteilt dem Container zusätzliche Berechtigungen. Dadurch kann der Container auf die Geräte des Hosts (/ dev) zugreifen.

--pid = host: Ermöglicht den Containern die Verwendung des Prozessbaums des Docker-Hosts (der VM, auf der der Docker-Dämon ausgeführt wird). nsenter-Dienstprogramm: Ermöglicht die Ausführung eines Prozesses in vorhandenen Namespaces (den Bausteinen, die Container isolieren).

Mit nsenter (-t 1 -m -u -n -i sh) kann der Prozess sh im gleichen Isolationskontext wie der Prozess mit PID 1 ausgeführt werden. Der gesamte Befehl stellt dann eine interaktive sh-Shell in der VM bereit

Dieses Setup hat erhebliche Auswirkungen auf die Sicherheit und sollte mit Vorsicht (falls vorhanden) verwendet werden.


1

Diese Antwort ist nur eine detailliertere Version der Lösung von Bradford Medeiros , die sich auch für mich als die beste Antwort herausstellte. Der Verdienst geht also an ihn.

In seiner Antwort erklärt er, was zu tun ist ( Named Pipes ), aber nicht genau, wie es zu tun ist.

Ich muss zugeben, dass ich zum Zeitpunkt des Lesens seiner Lösung nicht wusste, was Pfeifen heißen. Ich hatte Mühe, es zu implementieren (obwohl es eigentlich ganz einfach ist), aber es gelang mir, und ich helfe gerne, indem ich erkläre, wie ich es gemacht habe. In meiner Antwort geht es also nur darum, die Befehle zu beschreiben, die Sie ausführen müssen, damit es funktioniert, aber auch hier geht ihm die Ehre zu.

TEIL 1 - Testen des Named-Pipe-Konzepts ohne Docker

Wählen Sie auf dem Haupthost den Ordner aus, in dem Sie beispielsweise Ihre Named-Pipe-Datei und beispielsweise /path/to/pipe/einen Pipe-Namen ablegen möchten mypipe, und führen Sie dann Folgendes aus:

mkfifo /path/to/pipe/mypipe

Die Pipe wird erstellt. Art

ls -l /path/to/pipe/mypipe 

Überprüfen Sie, ob die Zugriffsrechte mit "p" beginnen, z

prw-r--r-- 1 root root 0 mypipe

Führen Sie jetzt aus:

tail -f /path/to/pipe/mypipe

Das Terminal wartet nun darauf, dass Daten in diese Pipe gesendet werden

Öffnen Sie nun ein weiteres Terminalfenster.

Und dann laufen:

echo "hello world" > /path/to/pipe/mypipe

Überprüfen Sie das erste Terminal (das mit tail -f), es sollte "Hallo Welt" anzeigen.

TEIL 2 - Führen Sie Befehle durch die Pipe

Führen Sie auf dem Host-Container tail -fdiesen Befehl aus, der ihn nur als Befehle ausführt , anstatt nur das auszugeben, was als Eingabe gesendet wird:

eval "$(cat /path/to/pipe/mypipe)"

Versuchen Sie dann vom anderen Terminal aus Folgendes auszuführen:

echo "ls -l" > /path/to/pipe/mypipe

Gehen Sie zurück zum ersten Terminal und Sie sollten das Ergebnis des ls -lBefehls sehen.

TEIL 3 - Lass es für immer zuhören

Möglicherweise haben Sie bemerkt, dass im vorherigen Teil direkt nach der ls -lAnzeige der Ausgabe nicht mehr auf Befehle gewartet wird.

eval "$(cat /path/to/pipe/mypipe)"Führen Sie stattdessen Folgendes aus:

while true; do eval "$(cat /path/to/pipe/mypipe)"; done

(Das kannst du nicht sagen)

Jetzt können Sie eine unbegrenzte Anzahl von Befehlen nacheinander senden. Alle Befehle werden ausgeführt, nicht nur der erste.

TEIL 4 - Damit es auch beim Neustart funktioniert

Die einzige Einschränkung ist, dass die "while" -Schleife nicht mehr funktioniert, wenn der Host neu gestartet werden muss.

Um den Neustart zu handhaben, habe ich Folgendes getan:

Fügen Sie das while true; do eval "$(cat /path/to/pipe/mypipe)"; donein eine Datei execpipe.shmit #!/bin/bashHeader ein

Vergiss chmod +xes nicht

Fügen Sie es crontab hinzu, indem Sie es ausführen

crontab -e

Und dann hinzufügen

@reboot /path/to/execpipe.sh

Testen Sie es an diesem Punkt: Starten Sie Ihren Server neu und geben Sie nach dem Sichern einige Befehle in die Pipe ein und prüfen Sie, ob sie ausgeführt werden. Natürlich können Sie die Ausgabe von Befehlen ls -lnicht sehen, touch somefilees hilft also nicht, aber es hilft.

Eine weitere Option besteht darin, das Skript so zu ändern, dass die Ausgabe in eine Datei eingefügt wird, z.

while true; do eval "$(cat /path/to/pipe/mypipe)" &> /somepath/output.txt; done

Jetzt können Sie ausführen ls -lund die Ausgabe (sowohl stdout als auch stderr mit &>in bash) sollte in output.txt sein.

TEIL 5 - Lass es mit Docker funktionieren

Wenn Sie Docker Compose und Dockerfile wie ich verwenden, habe ich Folgendes getan:

Angenommen, Sie möchten den übergeordneten Ordner von mypipe wie /hostpipein Ihrem Container bereitstellen

Füge das hinzu:

VOLUME /hostpipe

in Ihrer Docker-Datei, um einen Mount-Punkt zu erstellen

Dann füge folgendes hinzu:

volumes:
   - /path/to/pipe:/hostpipe

Erstellen Sie in Ihrem Docker eine Compose-Datei, um / path / to / pipe als / hostpipe zu mounten

Starten Sie Ihre Docker-Container neu.

TEIL 6 - Testen

In Ihren Docker-Container ausführen:

docker exec -it <container> bash

Gehen Sie in den Mount-Ordner und überprüfen Sie, ob Sie die Pipe sehen können:

cd /hostpipe && ls -l

Versuchen Sie nun, einen Befehl aus dem Container heraus auszuführen:

echo "touch this_file_was_created_on_main_host_from_a_container.txt" > /hostpipe/mypipe

Und es sollte funktionieren!

WARNUNG: Wenn Sie einen OSX-Host (Mac OS) und einen Linux-Container haben, funktioniert dies nicht (Erklärung hier https://stackoverflow.com/a/43474708/10018801 und Problem hier https://github.com/docker / for-mac / issue / 483 ), da die Pipe-Implementierung nicht identisch ist. Was Sie also unter Linux in die Pipe schreiben, kann nur von Linux gelesen werden, und was Sie unter Mac OS in die Pipe schreiben, kann nur von a gelesen werden Mac OS (dieser Satz ist möglicherweise nicht sehr genau, aber beachten Sie, dass ein plattformübergreifendes Problem vorliegt).

Wenn ich beispielsweise mein Docker-Setup in DEV von meinem Mac OS-Computer aus ausführe, funktioniert die oben erläuterte Named Pipe nicht. Aber in Staging und Produktion habe ich Linux-Host und Linux-Container, und es funktioniert perfekt.

TEIL 7 - Beispiel aus dem Node.JS-Container

So sende ich einen Befehl von meinem js-Container des Knotens an den Haupthost und rufe die Ausgabe ab:

const pipePath = "/hostpipe/mypipe"
const outputPath = "/hostpipe/output.txt"
const commandToRun = "pwd && ls-l"

console.log("delete previous output")
if (fs.existsSync(outputPath)) fs.unlinkSync(outputPath)

console.log("writing to pipe...")
const wstream = fs.createWriteStream(pipePath)
wstream.write(commandToRun)
wstream.close()

console.log("waiting for output.txt...") //there are better ways to do that than setInterval
let timeout = 10000 //stop waiting after 10 seconds (something might be wrong)
const timeoutStart = Date.now()
const myLoop = setInterval(function () {
    if (Date.now() - timeoutStart > timeout) {
        clearInterval(myLoop);
        console.log("timed out")
    } else {
        //if output.txt exists, read it
        if (fs.existsSync(outputPath)) {
            clearInterval(myLoop);
            const data = fs.readFileSync(outputPath).toString()
            if (fs.existsSync(outputPath)) fs.unlinkSync(outputPath) //delete the output file
            console.log(data) //log the output of the command
        }
    }
}, 300);

0

Wie Marcus erinnert, ist Docker im Grunde genommen Prozessisolation. Ab Docker 1.8 können Sie Dateien in beide Richtungen zwischen Host und Container kopieren (siehe Dokument von)docker cp

https://docs.docker.com/reference/commandline/cp/

Sobald eine Datei kopiert wurde, können Sie sie lokal ausführen


1
Ich weiß es. Wie kann man dieses Skript mit anderen Worten im Docker-Container ausführen?
Alex Ushakov


2
@ AlexUshakov: auf keinen Fall. Dies würde viele der Vorteile von Docker zunichte machen. Tu es nicht. Versuch es nicht. Überdenken Sie, was Sie tun müssen.
Marcus Müller


1
Sie können auf dem Host jederzeit den Wert einer Variablen in Ihrem Container abrufen myvalue=$(docker run -it ubuntu echo $PATH)und ihn regelmäßig in einer Skript-Shell testen (natürlich verwenden Sie etwas anderes als $ PATH, dies ist nur ein Beispiel), wenn dies der Fall ist
Ist ein

0
docker run --detach-keys="ctrl-p" -it -v /:/mnt/rootdir --name testing busybox
# chroot /mnt/rootdir
# 

2
Während diese Antwort möglicherweise die Frage des OP löst, wird empfohlen, dass Sie erklären, wie es funktioniert und warum es das Problem löst. Dies hilft neuen Entwicklern zu verstehen, was los ist und wie dieses und ähnliche Probleme selbst behoben werden können. Vielen Dank für Ihren Beitrag!
Caleb Kleveter

0

Sie können das Pipe-Konzept verwenden, aber eine Datei auf dem Host und fswatch verwenden , um das Ziel zu erreichen, ein Skript aus einem Docker-Container auf dem Host-Computer auszuführen. So (Verwendung auf eigenes Risiko):

#! /bin/bash

touch .command_pipe
chmod +x .command_pipe

# Use fswatch to execute a command on the host machine and log result
fswatch -o --event Updated .command_pipe | \
            xargs -n1 -I "{}"  .command_pipe >> .command_pipe_log  &

 docker run -it --rm  \
   --name alpine  \
   -w /home/test \
   -v $PWD/.command_pipe:/dev/command_pipe \
   alpine:3.7 sh

rm -rf .command_pipe
kill %1

In diesem Beispiel senden Sie im Container Befehle wie folgt an / dev / command_pipe:

/home/test # echo 'docker network create test2.network.com' > /dev/command_pipe

Auf dem Host können Sie überprüfen, ob das Netzwerk erstellt wurde:

$ docker network ls | grep test2
8e029ec83afe        test2.network.com                            bridge              local

-8

So erweitern Sie die Antwort von user2915097 :

Die Idee der Isolation besteht darin, in der Lage zu sein, die Auswirkungen einer Anwendung / eines Prozesses / eines Containers (unabhängig von Ihrem Blickwinkel) auf das Hostsystem sehr deutlich einzuschränken. Das Kopieren und Ausführen einer Datei würde also das gesamte Konzept brechen.

Ja. Aber es ist manchmal notwendig.

Nein, das ist nicht der Fall, oder Docker ist nicht das Richtige. Was Sie tun sollten, ist eine klare Schnittstelle für das zu deklarieren, was Sie tun möchten (z. B. eine Host-Konfiguration aktualisieren), und einen minimalen Client / Server zu schreiben, um genau das zu tun , und nichts weiter. Im Allgemeinen scheint dies jedoch nicht sehr wünschenswert zu sein. In vielen Fällen sollten Sie einfach Ihren Ansatz überdenken und diese Notwendigkeit beseitigen. Docker entstand, als im Grunde alles ein Dienst war, der mit einem Protokoll erreichbar war. Ich kann mir keinen richtigen Verwendungszweck für einen Docker-Container vorstellen, der die Rechte erhält, beliebige Dinge auf dem Host auszuführen.


Ich habe Anwendungsfall: Ich habe Docker-Service A(src auf Github). Im ARepo erstelle ich richtige Hooks, die nach dem Befehl 'git pull' ein neues Docker-Image erstellen und ausführen (und natürlich den alten Container entfernen). Weiter: Github verfügt über Web-Hooks, mit denen POST-Anforderungen an beliebige Endpunktverbindungen nach dem Push-on-Master erstellt werden können. Ich werde also keinen Docker-Dienst B erstellen, der dieser Endpunkt ist und der nur 'git pull' in Repo A auf der HOST-Maschine ausführt (wichtig: Der Befehl 'git pull' muss in der HOST-Umgebung ausgeführt werden - nicht in der B-Umgebung, weil B. kann keinen neuen Container A in B laufen lassen ...)
Kamil Kiełczewski

1
Das Problem: Ich möchte nichts in HOST haben, außer Linux, Git und Docker. Und ich möchte Dockerizet-Service A und Service B haben (das ist in der Tat ein Git-Push-Handler, der Git-Pull auf Repo A ausführt, nachdem jemand Git-Push auf Master gemacht hat). Die automatische Bereitstellung von Git ist also ein problematischer Anwendungsfall
Kamil Kiełczewski,

@ KamilKiełczewski Ich versuche genau das Gleiche zu tun, hast du eine Lösung gefunden?
user871784

1
Zu sagen: "Nein, das ist nicht der Fall" ist engstirnig und setzt voraus, dass Sie jeden Anwendungsfall auf der Welt kennen. Unser Anwendungsfall sind Tests. Sie müssen in Containern ausgeführt werden, um die Umgebung korrekt zu testen. Angesichts der Art der Tests müssen sie jedoch auch Skripts auf dem Host ausführen.
Senica Gonzalez

1
Nur für diejenigen, die sich fragen, warum ich eine -7-Antwort offen lasse: a) Es ist in Ordnung, fehlbar zu sein. Ich lag falsch. Es ist in Ordnung, dass dies hier dokumentiert ist. b) Die Kommentare tragen tatsächlich zum Wert bei; Durch Löschen der Antwort werden diese ebenfalls gelöscht. c) Es trägt immer noch zu einer Sichtweise bei, die möglicherweise zu berücksichtigen ist (brechen Sie Ihre Isolation nicht, wenn Sie dies nicht müssen. Manchmal müssen Sie dies jedoch tun).
Marcus Müller
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.