Bagaimana cara menjalankan skrip shell pada host dari container docker?

95

Bagaimana cara mengontrol host dari kontainer buruh pelabuhan?

Misalnya, bagaimana cara mengeksekusi skrip yang disalin ke host bash?

Alex Ushakov
sumber
8
bukankah itu kebalikan dari mengisolasi host dari buruh pelabuhan?
Marcus Müller
31
Iya. Tapi terkadang perlu.
Alex Ushakov
kemungkinan duplikat dari Jalankan perintah host dari dalam kontainer buruh pelabuhan
Marcus Müller
Tidak yakin tentang "host kontrol" tetapi saya baru-baru ini mengikuti pembicaraan oleh para ilmuwan data yang menggunakan buruh pelabuhan untuk menjalankan skrip guna memproses beban kerja yang besar (menggunakan GPU yang dipasang di AWS) dan menampilkan hasilnya ke host. Kasus penggunaan yang sangat menarik. Pada dasarnya skrip dikemas dengan lingkungan eksekusi yang andal berkat buruh pelabuhan
KCD
@KCD Dan mengapa mereka lebih memilih kontainerisasi aplikasi melalui buruh pelabuhan daripada menggunakan wadah tingkat sistem (LXC)?
Alex Ushakov

Jawaban:

28

Itu BENAR-BENAR tergantung pada apa yang Anda butuhkan untuk skrip bash itu!

Misalnya, jika skrip bash hanya menggemakan beberapa output, Anda dapat melakukannya

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

Kemungkinan lainnya adalah Anda ingin skrip bash menginstal beberapa perangkat lunak - katakanlah skrip untuk menginstal docker-compose. Anda bisa melakukan sesuatu seperti

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

Tetapi pada titik ini Anda benar-benar harus mengetahui secara dekat apa yang dilakukan skrip untuk mengizinkan izin khusus yang diperlukan pada host Anda dari dalam penampung.

Paul Becotte
sumber
1
Saya punya ide untuk membuat container yang terhubung ke host dan membuat container baru.
Alex Ushakov
1
Docker sepertinya tidak menyukai tunggangan relatif Anda. Ini harus bekerjadocker run --rm -v $(pwd)/mybashscript.sh:/work/mybashscript.sh ubuntu /work/mybashscript.sh
KCD
5
Baris pertama memulai container ubuntu baru, dan memasang skrip di tempat yang dapat dibaca. Ini tidak mengizinkan akses penampung ke sistem file host, misalnya. Baris kedua memperlihatkan host /usr/binke penampung. Dalam kedua kasus tersebut, penampung tidak memiliki akses penuh ke sistem host. Mungkin saya salah, tapi sepertinya jawaban yang buruk untuk pertanyaan yang buruk.
Paul
3
Cukup adil- pertanyaannya cukup samar. Pertanyaannya tidak menanyakan "akses penuh ke sistem host". Seperti dijelaskan, jika skrip bash hanya dimaksudkan untuk menggemakan beberapa output, itu tidak akan MEMBUTUHKAN akses apa pun ke sistem file host. Untuk contoh kedua saya, yang menginstal docker-compose, satu-satunya izin yang Anda perlukan adalah akses ke direktori bin tempat biner disimpan. Seperti yang saya katakan di awal - untuk melakukan ini, Anda harus memiliki gagasan yang sangat spesifik tentang apa yang dilakukan skrip untuk memungkinkan izin yang tepat.
Paul Becotte
1
Mencoba ini, skrip dijalankan dalam penampung, bukan di host
All2Pie
60

Solusi yang saya gunakan adalah menyambung ke host SSHdan menjalankan perintah seperti ini:

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

MEMPERBARUI

Karena jawaban ini terus mendapatkan suara, saya ingin mengingatkan (dan sangat merekomendasikan), bahwa akun yang digunakan untuk memanggil skrip haruslah akun tanpa izin sama sekali, tetapi hanya menjalankan skrip itu sebagai sudo(itu bisa dilakukan dari sudoersfile).

Mohammed Noureldin
sumber
Sebagai solusi lain, container dapat mengeluarkan sekumpulan perintah dan host dapat menjalankannya setelah container keluar: eval $ (docker run --rm -it container_name_to_output script)
parity3
Saya perlu menjalankan baris perintah pada Host dari dalam wadah Docker, tetapi ketika saya masuk ke dalam wadah, sshtidak ditemukan. Apakah Anda punya saran lain?
Ron Rosenfeld
@RonRosenfeld, gambar Docker mana yang Anda gunakan? dalam kasus debian / ubuntu, menjalankan ini: apt update && apt install openssh-client.
Mohammed Noureldin
Itu akan menjadi apa pun yang diinstal pada NAS Synology saya. Bagaimana saya bisa tahu?
Ron Rosenfeld
@RonRosenfeld, maaf saya tidak mengerti apa yang Anda maksud
Mohammed Noureldin
52

Menggunakan pipa bernama. Pada os host, buat skrip untuk mengulang dan membaca perintah, lalu Anda memanggil eval untuk itu.

Minta kontainer buruh pelabuhan membaca pipa bernama itu.

Untuk dapat mengakses pipa, Anda perlu memasangnya melalui volume.

Ini mirip dengan mekanisme SSH (atau metode berbasis soket serupa), tetapi membatasi Anda dengan benar ke perangkat host, yang mungkin lebih baik. Selain itu, Anda tidak perlu memberikan informasi otentikasi.

Satu-satunya peringatan saya adalah berhati-hati tentang mengapa Anda melakukan ini. Ini benar-benar sesuatu yang harus dilakukan jika Anda ingin membuat metode untuk meningkatkan sendiri dengan input pengguna atau apa pun, tetapi Anda mungkin tidak ingin memanggil perintah untuk mendapatkan beberapa data konfigurasi, karena cara yang tepat adalah meneruskannya sebagai args / volume ke buruh pelabuhan. Juga berhati-hatilah tentang fakta bahwa Anda mengelak, jadi pikirkan saja model izinnya.

Beberapa dari. Jawaban lain seperti menjalankan skrip. Di bawah volume tidak akan berfungsi secara umum karena mereka tidak akan memiliki akses ke sumber daya sistem penuh, tetapi mungkin lebih tepat tergantung pada penggunaan Anda.

Bradford Medeiros
sumber
14
PERHATIAN: Ini adalah jawaban yang benar / terbaik, dan membutuhkan lebih banyak pujian. Setiap jawaban lain adalah mengutak-atik pertanyaan "apa yang Anda coba lakukan" dan membuat pengecualian untuk beberapa hal. Saya memiliki kasus penggunaan yang sangat spesifik yang mengharuskan saya untuk dapat melakukan ini, dan ini adalah satu-satunya jawaban yang bagus imho. SSH di atas akan membutuhkan penurunan standar keamanan / firewall, dan hal-hal yang dijalankan buruh pelabuhan benar-benar salah. Terima kasih untuk ini. Saya berasumsi ini tidak mendapatkan banyak suara positif karena ini bukan jawaban salin / tempel sederhana, tetapi inilah jawabannya. +100 poin dari saya jika saya bisa
Farley
3
Bagi mereka yang mencari informasi lebih lanjut, Anda dapat menggunakan skrip berikut yang berjalan di mesin host: unix.stackexchange.com/a/369465 Tentu saja, Anda harus menjalankannya dengan 'nohup' dan membuat semacam pembungkus pengawas untuk menjaganya tetap hidup (mungkin menggunakan pekerjaan cron: P)
sucotronic
7
Ini mungkin jawaban yang bagus. Namun, akan jauh lebih baik jika Anda memberikan lebih banyak detail dan penjelasan baris perintah lagi. Apakah mungkin untuk mengelaborasi?
Mohammed Noureldin
5
Suara positif, Ini berfungsi! Buat pipa bernama menggunakan 'mkfifo host_executor_queue' tempat volume dipasang. Kemudian untuk menambahkan konsumen yang menjalankan perintah yang dimasukkan ke dalam antrian sebagai shell host, gunakan 'tail -f host_executor_queue | SH &'. & Di akhir membuatnya berjalan di latar belakang. Terakhir untuk memasukkan perintah ke dalam antrian, gunakan 'echo touch foo> host_executor_queue' - tes ini membuat file temp foo di direktori home. Jika Anda ingin konsumen memulai pada startup sistem, letakkan '@reboot tail -f host_executor_queue | sh & 'di crontab. Cukup tambahkan jalur relatif ke host_executor_queue.
skybunk
1
Bisakah seseorang mengedit jawaban dengan kode contoh?
Lucas Pottersky
6

Jika Anda tidak khawatir tentang keamanan dan Anda hanya ingin memulai kontainer pekerja galangan pada host dari dalam kontainer pekerja galangan lain seperti OP, Anda dapat berbagi server pekerja galangan yang berjalan pada tuan rumah dengan kontainer pekerja galangan dengan membagikan soket pendengarnya.

Silakan lihat https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface dan lihat apakah toleransi risiko pribadi Anda memungkinkan hal ini untuk aplikasi khusus ini.

Anda dapat melakukan ini dengan menambahkan argumen volume berikut ke perintah mulai Anda

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

atau dengan membagikan /var/run/docker.sock dalam file pembuatan buruh pelabuhan Anda seperti ini:

version: '3'

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

Saat Anda menjalankan perintah docker start dalam container docker Anda, server docker yang berjalan di host Anda akan melihat permintaan dan menyediakan container saudara.

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

Matt Bucci
sumber
1
Pertimbangkan bahwa buruh pelabuhan harus dipasang di kontainer, jika tidak, Anda juga perlu memasang volume untuk biner buruh pelabuhan (misalnya /usr/bin/docker:/usr/bin/docker).
Gerry
1
Harap berhati-hati saat memasang soket buruh pelabuhan di penampung Anda, ini bisa menjadi masalah keamanan yang serius: docs.docker.com/engine/security/security/…
DatGuyKaj
@DatGuyKaj terima kasih, saya telah mengedit jawaban saya untuk mencerminkan masalah yang diuraikan oleh sumber daya Anda.
Matt Bucci
Ini tidak menjawab pertanyaan, yaitu tentang menjalankan skrip pada host, bukan dalam wadah
Brandon
5

Jawaban ini hanyalah versi yang lebih rinci dari solusi Bradford Medeiros , yang bagi saya juga merupakan jawaban terbaik, jadi pujian diberikan kepadanya.

Dalam jawabannya, dia menjelaskan APA yang harus dilakukan ( dinamai pipa ) tetapi tidak persis BAGAIMANA melakukannya.

Saya harus mengakui bahwa saya tidak tahu apa yang dinamai pipa pada saat saya membaca solusinya. Jadi saya berjuang untuk menerapkannya (meskipun sebenarnya sangat sederhana), tetapi saya berhasil, jadi saya dengan senang hati membantu dengan menjelaskan bagaimana saya melakukannya. Jadi inti dari jawaban saya hanyalah merinci perintah yang perlu Anda jalankan untuk membuatnya berfungsi, tetapi sekali lagi, kredit diberikan kepadanya.

BAGIAN 1 - Menguji konsep pipa bernama tanpa buruh pelabuhan

Di host utama, pilih folder tempat Anda ingin meletakkan file pipa bernama Anda, misalnya /path/to/pipe/dan nama pipa, misalnya mypipe, lalu jalankan:

mkfifo /path/to/pipe/mypipe

Pipa dibuat. Tipe

ls -l /path/to/pipe/mypipe 

Dan periksa hak akses dimulai dengan "p", seperti

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

Sekarang jalankan:

tail -f /path/to/pipe/mypipe

Terminal sekarang menunggu data untuk dikirim ke pipa ini

Sekarang buka jendela terminal lain.

Dan kemudian jalankan:

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

Periksa terminal pertama (yang dengan tail -f), itu harus menampilkan "hello world"

BAGIAN 2 - Jalankan perintah melalui pipa

Pada penampung host, alih-alih berjalan tail -fyang hanya mengeluarkan apa pun yang dikirim sebagai masukan, jalankan perintah ini yang akan menjalankannya sebagai perintah:

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

Kemudian, dari terminal lain, coba jalankan:

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

Kembali ke terminal pertama dan Anda akan melihat hasil dari ls -lperintah tersebut.

BAGIAN 3 - Buatlah mendengarkan selamanya

Anda mungkin telah memperhatikan bahwa di bagian sebelumnya, tepat setelah ls -loutput ditampilkan, ia berhenti mendengarkan perintah.

Alih-alih eval "$(cat /path/to/pipe/mypipe)", jalankan:

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

(Anda tidak dapat melakukannya)

Sekarang Anda dapat mengirim perintah dalam jumlah tak terbatas satu demi satu, semuanya akan dieksekusi, bukan hanya yang pertama.

BAGIAN 4 - Jadikan bekerja bahkan saat reboot terjadi

Satu-satunya peringatan adalah jika host harus reboot, loop "while" akan berhenti bekerja.

Untuk menangani reboot, inilah yang telah saya lakukan:

Letakkan while true; do eval "$(cat /path/to/pipe/mypipe)"; donedalam file yang disebut execpipe.shdengan #!/bin/bashsundulan

Jangan lupa untuk chmod +xitu

Tambahkan ke crontab dengan menjalankan

crontab -e

Dan kemudian menambahkan

@reboot /path/to/execpipe.sh

Pada titik ini, ujilah: reboot server Anda, dan ketika sudah kembali, gema beberapa perintah ke dalam pipa dan periksa apakah sudah dijalankan. Tentu saja, Anda tidak dapat melihat keluaran dari perintah, jadi ls -ltidak akan membantu, tetapi touch somefileakan membantu.

Pilihan lainnya adalah memodifikasi skrip untuk meletakkan output dalam sebuah file, seperti:

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

Sekarang Anda dapat menjalankan ls -ldan output (baik stdout dan stderr yang digunakan &>di bash) harus dalam output.txt.

BAGIAN 5 - Buatlah bekerja dengan buruh pelabuhan

Jika Anda menggunakan docker compose dan dockerfile seperti yang saya lakukan, inilah yang telah saya lakukan:

Anggaplah Anda ingin memasang folder induk mypipe seperti /hostpipedi penampung Anda

Tambahkan ini:

VOLUME /hostpipe

di file dok Anda untuk membuat titik pemasangan

Kemudian tambahkan ini:

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

di file penulisan buruh pelabuhan Anda untuk memasang / path / ke / pipa sebagai / hostpipe

Mulai ulang kontainer buruh pelabuhan Anda.

BAGIAN 6 - Pengujian

Jalankan ke kontainer buruh pelabuhan Anda:

docker exec -it <container> bash

Masuk ke folder mount dan periksa apakah Anda dapat melihat pipa:

cd /hostpipe && ls -l

Sekarang coba jalankan perintah dari dalam penampung:

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

Dan itu harus berhasil!

PERINGATAN: Jika Anda memiliki host OSX (Mac OS) dan wadah Linux, itu tidak akan berfungsi (penjelasan di sini https://stackoverflow.com/a/43474708/10018801 dan masalah di sini https://github.com/docker / for-mac / issues / 483 ) karena implementasi pipa tidak sama, jadi apa yang Anda tulis ke dalam pipa dari Linux hanya dapat dibaca oleh Linux dan apa yang Anda tulis ke pipa dari Mac OS hanya dapat dibaca oleh Mac OS (kalimat ini mungkin tidak terlalu akurat, tetapi perlu diketahui bahwa ada masalah lintas platform).

Misalnya, ketika saya menjalankan pengaturan buruh pelabuhan di DEV dari komputer Mac OS saya, pipa bernama seperti yang dijelaskan di atas tidak berfungsi. Tetapi dalam pementasan dan produksi, saya memiliki host Linux dan wadah Linux, dan berfungsi dengan sempurna.

BAGIAN 7 - Contoh dari wadah Node.JS

Berikut adalah cara saya mengirim perintah dari node js container saya ke host utama dan mengambil hasilnya:

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);
Vincent
sumber
Ini bekerja dengan baik. Bagaimana dengan keamanan? Saya ingin menggunakan ini untuk memulai / menghentikan kontainer buruh pelabuhan dari dalam kontainer yang sedang berjalan? Apakah saya hanya membuat buruh pelabuhan tanpa hak apapun kecuali untuk menjalankan perintah buruh pelabuhan?
Kristof van Woensel
4

Tulis server python server sederhana yang mendengarkan di port (katakanlah 8080), ikat port -p 8080: 8080 dengan kontainer, buat permintaan HTTP ke localhost: 8080 untuk meminta server python menjalankan skrip shell dengan popen, jalankan curl atau menulis kode untuk membuat permintaan 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()
Frank Chang
sumber
IMO ini adalah jawaban terbaik. Menjalankan perintah sewenang-wenang di mesin host HARUS dilakukan melalui beberapa jenis API (misalnya REST). Ini adalah satu-satunya cara agar keamanan dapat ditegakkan dan proses yang berjalan dapat dikontrol dengan benar (mis. Kill, penanganan stdin, stdout, exit-code, dan sebagainya). Jika tentunya akan cantik jika API ini bisa berjalan di dalam Docker, tapi secara pribadi saya tidak keberatan untuk menjalankannya di host secara langsung.
barney765
2

Kemalasan saya membuat saya menemukan solusi termudah yang tidak dipublikasikan sebagai jawaban di sini.

Ini didasarkan pada artikel bagus oleh luc juggery .

Yang perlu Anda lakukan untuk mendapatkan shell penuh ke host linux Anda dari dalam container docker Anda adalah:

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

Penjelasan:

--privileged: memberikan izin tambahan ke container, ini memungkinkan container mendapatkan akses ke perangkat host (/ dev)

--pid = host: memungkinkan wadah untuk menggunakan pohon proses dari host Docker (VM tempat daemon Docker berjalan) utilitas nsenter: memungkinkan untuk menjalankan proses di ruang nama yang ada (blok bangunan yang menyediakan isolasi ke wadah)

nsenter (-t 1 -m -u -n -i sh) memungkinkan untuk menjalankan proses sh dalam konteks isolasi yang sama seperti proses dengan PID 1. Seluruh perintah kemudian akan menyediakan shell sh interaktif di VM

Pengaturan ini memiliki implikasi keamanan yang besar dan harus digunakan dengan hati-hati (jika ada).

Shmulik ahituv
sumber
1
docker run --detach-keys="ctrl-p" -it -v /:/mnt/rootdir --name testing busybox
# chroot /mnt/rootdir
# 
Zibri
sumber
3
Meskipun jawaban ini mungkin menyelesaikan pertanyaan OP, disarankan agar Anda menjelaskan cara kerjanya dan mengapa ini menyelesaikan masalah. Ini membantu pengembang baru memahami apa yang sedang terjadi dan cara memperbaikinya sendiri serta masalah serupa. Terima kasih telah berkontribusi!
Caleb Kleveter
1

Saya memiliki pendekatan sederhana.

Langkah 1: Pasang /var/run/docker.sock:/var/run/docker.sock (Jadi Anda akan dapat menjalankan perintah buruh pelabuhan di dalam wadah Anda)

Langkah 2: Jalankan ini di bawah di dalam wadah Anda. Bagian kuncinya di sini adalah ( --network host karena ini akan dijalankan dari konteks host)

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

test.sh harus berisi beberapa perintah (ifconfig, netstat dll ...) apapun yang Anda butuhkan. Sekarang Anda akan bisa mendapatkan keluaran konteks host.

Bala
sumber
2
Menurut dokumentasi resmi buruh pelabuhan pada jaringan yang menggunakan jaringan host, "Namun, dalam semua cara lain, seperti penyimpanan, ruang nama proses, dan ruang nama pengguna, proses tersebut diisolasi dari host." Lihat - docs.docker.com/network/network-tutorial-host
Peter Mutisya
0

Seperti yang diingatkan Marcus, buruh pelabuhan pada dasarnya adalah proses isolasi. Dimulai dengan buruh pelabuhan 1.8, Anda dapat menyalin file dua arah antara host dan wadah, lihat dokumendocker cp

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

Setelah file disalin, Anda dapat menjalankannya secara lokal

pengguna2915097
sumber
1
Saya tahu itu. Bagaimana cara menjalankan skrip ini dari, dengan kata lain, di dalam container docker?
Alex Ushakov
1
duplikat stackoverflow.com/questions/31720935/… ?
pengguna2915097
2
@AlexUshakov: tidak mungkin. Melakukan itu akan merusak banyak keuntungan buruh pelabuhan. Jangan lakukan itu. Jangan mencobanya. Pertimbangkan kembali apa yang perlu Anda lakukan.
Marcus Müller
Lihat juga forum
pengguna2915097
1
Anda selalu dapat, pada host, mendapatkan nilai dari beberapa variabel dalam wadah Anda, seperti myvalue=$(docker run -it ubuntu echo $PATH)dan mengujinya secara teratur di shell skrip (tentu saja, Anda akan menggunakan sesuatu selain $ PATH, hanya sekedar contoh), ketika itu adalah beberapa nilai tertentu, Anda meluncurkan skrip Anda
pengguna2915097
0

Anda dapat menggunakan konsep pipa, tetapi gunakan file pada host dan fswatch untuk mencapai tujuan menjalankan skrip pada mesin host dari kontainer buruh pelabuhan. Seperti itu (Gunakan dengan risiko Anda sendiri):

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

Dalam contoh ini, di dalam wadah, kirim perintah ke / dev / command_pipe, seperti ini:

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

Di host, Anda dapat memeriksa apakah jaringan telah dibuat:

$ docker network ls | grep test2
8e029ec83afe        test2.network.com                            bridge              local
Fábio Silva
sumber
-7

Untuk memperluas user2915097 ini respon :

Ide isolasi adalah untuk dapat membatasi apa yang dapat dilakukan oleh aplikasi / proses / wadah (apapun sudut pandang Anda) terhadap sistem host dengan sangat jelas. Karenanya, dapat menyalin dan mengeksekusi file benar-benar akan merusak keseluruhan konsep.

Iya. Tapi terkadang perlu.

Tidak. Bukan itu masalahnya, atau Docker bukanlah hal yang tepat untuk digunakan. Apa yang harus Anda lakukan adalah mendeklarasikan antarmuka yang jelas untuk apa yang ingin Anda lakukan (misalnya memperbarui konfigurasi host), dan menulis klien / server minimal untuk melakukan hal itu dan tidak lebih. Secara umum, bagaimanapun, ini tampaknya tidak terlalu diinginkan. Dalam banyak kasus, Anda cukup memikirkan kembali pendekatan Anda dan menghapus kebutuhan itu. Docker muncul ketika pada dasarnya semuanya adalah layanan yang dapat dijangkau menggunakan beberapa protokol. Saya tidak dapat memikirkan kasus penggunaan yang tepat dari container Docker yang mendapatkan hak untuk mengeksekusi barang sewenang-wenang di host.

Marcus Müller
sumber
Saya memiliki kasus penggunaan: Saya memiliki layanan dockerized A(src di github). Dalam Arepo saya membuat hook yang tepat yang setelah perintah 'git pull' membuat image buruh pelabuhan baru dan menjalankannya (dan menghapus container lama tentunya). Berikutnya: github memiliki web-hooks yang memungkinkan pembuatan permintaan POST ke tautan titik akhir arbitrer setelah push on master. Jadi saya tidak akan membuat layanan dockerized B yang akan menjadi titik akhir itu dan yang hanya akan menjalankan 'git pull' di repo A di mesin HOST (penting: perintah 'git pull' harus dijalankan di lingkungan HOST - bukan di lingkungan B karena B tidak dapat menjalankan wadah baru A di dalam B ...)
Kamil Kiełczewski
1
Masalahnya: Saya tidak ingin ada apa pun di HOST kecuali linux, git, dan buruh pelabuhan. Dan saya ingin memiliki layanan dockerizet A dan layanan B (yang sebenarnya adalah git-push handler yang menjalankan git pull pada repo A setelah seseorang membuat git push pada master). Jadi git auto-deploy adalah kasus penggunaan yang bermasalah
Kamil Kiełczewski
@ KamilKiełczewski Saya mencoba melakukan hal yang sama, apakah Anda sudah menemukan solusinya?
pengguna871784
1
Mengatakan, "Tidak, bukan itu masalahnya" adalah berpikiran sempit dan mengasumsikan Anda tahu setiap kasus penggunaan di dunia. Kasus penggunaan kami menjalankan pengujian. Mereka perlu dijalankan di container untuk menguji lingkungan dengan benar, tetapi mengingat sifat pengujian, mereka juga perlu mengeksekusi skrip pada host.
Senica Gonzalez
1
Hanya untuk mereka yang bertanya-tanya mengapa saya meninggalkan jawaban -7: a) tidak apa-apa untuk membuat kesalahan. Saya salah. Tidak apa-apa ini didokumentasikan di sini. b) Komentar benar-benar memberikan nilai; menghapus jawaban akan menghapusnya juga. c) Ini masih memberikan kontribusi sudut pandang yang mungkin bijaksana untuk dipertimbangkan (jangan putus isolasi Anda jika Anda tidak perlu. Kadang-kadang Anda harus melakukannya).
Marcus Müller