Docker konteynerinden ana bilgisayarda kabuk komut dosyası nasıl çalıştırılır?


94

Docker container'dan ana bilgisayarı nasıl kontrol edebilirim?

Örneğin, ana bash betiğine kopyalananlar nasıl çalıştırılır?


8
bu, ana bilgisayarı docker'dan ayırmanın tam tersi olmaz mıydı?
Marcus Müller

31
Evet. Ama bazen gerekli.
Alex Ushakov


"Kontrol ana bilgisayarı" ndan emin değilim, ancak son zamanlarda büyük iş yüklerini işlemek (AWS'ye bağlı GPU'ları kullanarak) ve sonucu ana bilgisayara göndermek için komut dosyalarını çalıştırmak için docker kullanan veri bilimciler tarafından yapılan bir konuşmadaydım. Çok ilginç bir kullanım durumu. Docker sayesinde güvenilir bir yürütme ortamıyla paketlenmiş komut dosyaları
KCD

@KCD Ve neden sistem düzeyinde kapsayıcılar (LXC) kullanmak yerine docker aracılığıyla uygulama kapsayıcıyı tercih ediyorlar?
Alex Ushakov

Yanıtlar:


28

Bu GERÇEKTEN o bash betiğinin ne yapmanız gerektiğine bağlı!

Örneğin, bash betiği yalnızca bazı çıktıları yansıtıyorsa,

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

Başka bir olasılık da, bash betiğinin bazı yazılımları yüklemesini istemenizdir - örneğin betik docker-compose'u kursun. gibi bir şey yapabilirsin

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

Ancak bu noktada, ana makinenizde ihtiyaç duyduğu belirli izinleri konteynerin içinden sağlamak için betiğin ne yaptığını gerçekten bilmek zorunda kalıyorsunuz.


1
Ana bilgisayara bağlanan ve yeni kapsayıcılar oluşturan bir kap yapma fikrim vardı.
Alex Ushakov

1
Docker, göreceli bağlantınızı beğenmiyor gibi görünüyor. Bu işe docker run --rm -v $(pwd)/mybashscript.sh:/work/mybashscript.sh ubuntu /work/mybashscript.sh
yaramalı

5
İlk satır yeni bir ubuntu konteyneri başlatır ve komut dosyasını okunabileceği yere bağlar. Örneğin, konteynerin ana bilgisayar dosya sistemine erişimine izin vermez. İkinci satır, ana makineyi /usr/binkonteynere gösterir. Her iki durumda da kapsayıcı, ana bilgisayar sistemine tam erişime sahip değildir. Belki yanılıyorum, ama kötü bir soruya kötü bir cevap gibi görünüyor.
Paul

3
Yeterince adil - soru oldukça belirsizdi. Soru, "ana bilgisayar sistemine tam erişim" istemiyordu. Açıklandığı gibi, bash betiği yalnızca bazı çıktıları yankılamak için tasarlandıysa, ana bilgisayar dosya sistemine erişim GEREKMEZ. Docker-compose'u kuran ikinci örneğim için, ihtiyacınız olan tek izin ikilinin depolandığı bin dizinine erişimdir. Başlangıçta söylediğim gibi - bunu yapmak için doğru izinlere izin vermek için betiğin ne yaptığı hakkında çok spesifik fikirlere sahip olmanız gerekir.
Paul Becotte

1
Bunu denedim, komut dosyası ana bilgisayarda değil konteynerde yürütülüyor
All2Pie

60

Kullandığım çözüm, ana bilgisayara bağlanmak SSHve şu şekilde komutu çalıştırmak:

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

GÜNCELLEME

Bu cevap oy almaya devam ettiği için, betiği çağırmak için kullanılan hesabın hiçbir izne sahip olmayan bir hesap olması gerektiğini hatırlatmak isterim (ve kesinlikle tavsiye ederim), ancak yalnızca bu komut dosyasını sudo( sudoersdosyadan yapılır ).


Başka bir geçici çözüm olarak, konteyner bir dizi komut üretebilir ve ana bilgisayar bunları konteynerden çıktıktan sonra çalıştırabilir: eval $ (docker run --rm -it container_name_to_output script)
parity3

Bir Docker konteynerinin içinden Host üzerinde bir komut satırı çalıştırmam gerekiyor, ancak konteynere girdiğimde sshbulunamadı. Başka bir öneriniz var mı?
Ron Rosenfeld

@RonRosenfeld, hangi Docker görüntüsünü kullanıyorsunuz? debian durumunda / ubuntu, bu çalıştırın: apt update && apt install openssh-client.
Muhammed Nureldin

Synology NAS'ıma yüklenmiş olan şey bu olacaktır. Nasıl söyleyebilirim?
Ron Rosenfeld

@RonRosenfeld, üzgünüm ne demek istediğini anlamıyorum
Mohammed Noureldin

52

Adlandırılmış bir kanal kullandı. Ana bilgisayar işletim sisteminde, komutları döngülemek ve okumak için bir komut dosyası oluşturun ve ardından bunun üzerine eval çağırın.

Docker kapsayıcısının bu adlandırılmış boruya okumasını sağlayın.

Boruya erişebilmek için, bir birim aracılığıyla monte etmeniz gerekir.

Bu, SSH mekanizmasına (veya benzer bir soket tabanlı yönteme) benzer, ancak sizi uygun şekilde ana cihazla sınırlar, ki bu muhtemelen daha iyidir. Ayrıca kimlik doğrulama bilgilerinin etrafından dolaşmanız gerekmez.

Tek uyarım, bunu neden yaptığın konusunda dikkatli olmak. Kullanıcı girdisi veya her neyse, kendi kendine yükseltme yapmak için bir yöntem oluşturmak istiyorsanız, bu tamamen yapmanız gereken bir şeydir, ancak muhtemelen bazı yapılandırma verilerini almak için bir komut çağırmak istemezsiniz, çünkü doğru yol bunu bağımsız değişken olarak iletmek olacaktır / docker içine hacim. Ayrıca değerlendirmekte olduğunuz gerçeği konusunda da dikkatli olun, bu yüzden sadece izin modelini bir düşünün.

Betiğin bir birim altında çalıştırılması gibi diğer yanıtlardan bazıları, tüm sistem kaynaklarına erişemeyecekleri için genel olarak çalışmayacaktır, ancak kullanımınıza bağlı olarak daha uygun olabilir.


14
DİKKAT: Bu doğru / en iyi cevap ve biraz daha övgüye ihtiyacı var. Diğer her yanıt, "ne yapmaya çalıştığını" sormakla ve bazı şeyler için istisnalar yapmakla uğraşıyor. Bunu yapabilmemi gerektiren çok özel bir kullanım durumum var ve bu tek iyi cevap imho. Yukarıdaki SSH, güvenlik / güvenlik duvarı standartlarının düşürülmesini gerektirir ve docker çalıştırma işleri tamamen yanlıştır. Bunun için teşekkürler. Bunun pek çok olumlu oy almayacağını varsayıyorum çünkü basit bir kopyala / yapıştır yanıtı değil, ama cevap bu. Mümkünse benden +100 puan
Farley

3
Daha fazla bilgi arayanlar için, ana makinede çalışan aşağıdaki komut dosyasını kullanabilirsiniz: unix.stackexchange.com/a/369465 Elbette, onu 'nohup' ile çalıştırmanız ve bir tür gözetmen sarmalayıcı oluşturmanız gerekecek onu canlı tutmak için (belki bir cron işi kullanın: P)
sucotronic

7
Bu iyi bir cevap olabilir. Ancak, daha fazla ayrıntı ve biraz daha komut satırı açıklaması verirseniz çok daha iyi olur. Detaylandırmak mümkün mü?
Mohammed Nureldin

5
Olumlu oy verildi, Bu işe yarıyor! Birimin takılı olduğu 'mkfifo host_executor_queue' kullanarak adlandırılmış bir kanal oluşturun. Ardından, sıraya konağın kabuğu olarak yerleştirilen komutları çalıştıran bir tüketici eklemek için 'tail -f host_executor_queue | sh & '. Sonunda & işareti, arka planda çalışmasını sağlar. Son olarak, komutları kuyruğa göndermek için 'echo touch foo> host_executor_queue' kullanın - bu test, ana dizinde geçici bir foo dosyası oluşturur. Tüketicinin sistem başlangıcında başlamasını istiyorsanız, '@reboot tail -f host_executor_queue | sh & 'crontab içinde. Sadece host_executor_queue için göreli yol ekleyin.
skybunk

1
birisi yanıtı örnek kodla düzenleyebilir mi?
Lucas Pottersky

6

Güvenlik konusunda endişelenmiyorsanız ve sadece OP gibi başka bir docker konteynerinden ana bilgisayarda bir docker konteyner başlatmak istiyorsanız, ana bilgisayarda çalışan docker sunucusunu, dinleme soketini paylaşarak docker konteyneriyle paylaşabilirsiniz.

Lütfen https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface adresine bakın ve kişisel risk toleransınızın bu özel uygulama için buna izin verip vermediğini görün.

Bunu, başlatma komutunuza aşağıdaki birim değiştirgelerini ekleyerek yapabilirsiniz.

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

veya docker compose dosyanız içinde /var/run/docker.sock'u şu şekilde paylaşarak:

version: '3'

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

Docker kapsayıcınızda docker start komutunu çalıştırdığınızda, ana makinenizde çalışan docker sunucusu isteği görür ve kardeş kapsayıcıyı sağlar.

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


1
Docker'ın konteynerde kurulu olması gerektiğini göz önünde bulundurun, aksi takdirde docker binary için bir birim bağlamanız gerekecektir (örn. /usr/bin/docker:/usr/bin/docker).
Gerry


@DatGuyKaj teşekkürler, kaynağınız tarafından ana hatlarıyla belirtilen sorunları yansıtmak için cevabımı düzenledim.
Matt Bucci

Bu, bir konteynerde değil, ana bilgisayarda bir komut dosyası çalıştırmakla ilgili soruya cevap vermiyor
Brandon

5

Bu cevap, Bradford Medeiros'un çözümünün sadece daha detaylı bir versiyonudur ve benim için de en iyi cevap olduğu ortaya çıktı, bu yüzden kredi ona gidiyor.

Cevabında, NE yapılması gerektiğini ( adlandırılmış borular ) açıklıyor, ancak tam olarak NASIL yapılacağını değil.

Çözümünü okuduğumda boruların ne olduğunu bilmediğimi itiraf etmeliyim. Bu yüzden onu uygulamak için mücadele ettim (aslında gerçekten basit olsa da), ama başardım, bu yüzden nasıl yaptığımı açıklayarak yardımcı olmaktan mutluluk duyuyorum. Bu yüzden cevabımın amacı, onu çalıştırmak için çalıştırmanız gereken komutları detaylandırmak, ama yine, kredi ona gidiyor.

BÖLÜM 1 - Adlandırılmış boru konseptinin docker olmadan test edilmesi

Ana ana bilgisayarda, örneğin adlandırılmış kanal dosyanızı yerleştirmek istediğiniz klasörü /path/to/pipe/ve örneğin bir kanal adını seçin mypipeve ardından şunu çalıştırın:

mkfifo /path/to/pipe/mypipe

Boru oluşturuldu. Tür

ls -l /path/to/pipe/mypipe 

Ve erişim haklarının "p" ile başlamasını kontrol edin, örneğin

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

Şimdi çalıştırın:

tail -f /path/to/pipe/mypipe

Terminal şimdi verilerin bu boruya gönderilmesini bekliyor

Şimdi başka bir terminal penceresi açın.

Ve sonra çalıştırın:

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

İlk terminali (olanı tail -f) kontrol edin, "merhaba dünya" yazmalıdır

BÖLÜM 2 - Komutları borudan geçirin

Ana bilgisayar kapsayıcısında, tail -fyalnızca girdi olarak gönderilen her şeyi çıktı olarak çalıştırmak yerine, onu komut olarak yürütecek şu komutu çalıştırın:

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

Ardından, diğer terminalden şunu çalıştırmayı deneyin:

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

İlk terminale geri dönün ve ls -lkomutun sonucunu görmelisiniz .

BÖLÜM 3 - Sonsuza dek dinlemesini sağlayın

Önceki bölümde, ls -lçıktı görüntülendikten hemen sonra komutları dinlemeyi bıraktığını fark etmiş olabilirsiniz .

Bunun yerine şunu eval "$(cat /path/to/pipe/mypipe)"çalıştırın:

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

(bunu yapamazsın)

Artık birbiri ardına sınırsız sayıda komut gönderebilirsiniz, sadece birincisi değil, hepsi çalıştırılacaktır.

BÖLÜM 4 - Yeniden başlatma gerçekleştiğinde bile çalışmasını sağlayın

Tek uyarı, ana bilgisayarın yeniden başlatılması gerekirse, "while" döngüsü çalışmayı durduracaktır.

Yeniden başlatmayı işlemek için işte yaptığım şey:

Put while true; do eval "$(cat /path/to/pipe/mypipe)"; doneadlı bir dosyada execpipe.shile #!/bin/bashbaşlığındaki

Unutma chmod +xo

Çalıştırarak crontab'e ekleyin

crontab -e

Ve sonra ekliyor

@reboot /path/to/execpipe.sh

Bu noktada test edin: sunucunuzu yeniden başlatın ve yedeklendiğinde, bazı komutları boruya yansıtın ve çalıştırılıp çalıştırılmadıklarını kontrol edin. Tabii ki, komutların çıktısını göremezsiniz, bu yüzden ls -lyardımcı touch somefileolmayacak , ancak yardımcı olacaktır.

Diğer bir seçenek, çıktıyı bir dosyaya koymak için komut dosyasını değiştirmektir, örneğin:

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

Artık çalıştırabilirsiniz ls -lve çıktı (hem stdout hem de stderr &>bash içinde kullanılır ) output.txt içinde olmalıdır.

BÖLÜM 5 - Docker ile çalışmasını sağlayın

Hem docker compose hem de dockerfile'ı benim yaptığım gibi kullanıyorsanız, işte yaptığım şey:

Mypipe'ın üst klasörünü /hostpipekonteynerinizdeki gibi bağlamak istediğinizi varsayalım

Bunu ekle:

VOLUME /hostpipe

bir bağlama noktası oluşturmak için dockerfile'ınızda

Sonra şunu ekleyin:

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

docker'ınızda / yol / için / borulu / hostpipe olarak bağlamak için dosya oluşturun

Docker konteynerlerinizi yeniden başlatın.

BÖLÜM 6 - Test

Docker konteynerinize yürütün:

docker exec -it <container> bash

Montaj klasörüne gidin ve boruyu görebildiğinizi kontrol edin:

cd /hostpipe && ls -l

Şimdi konteynerin içinden bir komut çalıştırmayı deneyin:

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

Ve işe yaramalı!

UYARI: Bir OSX (Mac OS) ana makineniz ve bir Linux kapsayıcınız varsa, çalışmaz (açıklama burada https://stackoverflow.com/a/43474708/10018801 ve burada https://github.com/docker sorun) / for-mac / issues / 483 ) çünkü boru uygulaması aynı değildir, bu nedenle Linux'tan boruya yazdıklarınız yalnızca Linux tarafından okunabilir ve Mac OS'den boruya yazdıklarınız yalnızca bir Mac OS (bu cümle çok doğru olmayabilir, ancak platformlar arası bir sorunun olduğunu unutmayın).

Örneğin, Mac OS bilgisayarımdan DEV'de docker kurulumumu çalıştırdığımda, yukarıda açıklandığı gibi adlandırılmış kanal çalışmıyor. Ancak hazırlık ve üretimde Linux ana bilgisayarım ve Linux kapsayıcılarım var ve mükemmel çalışıyor.

BÖLÜM 7 - Node.JS kapsayıcısından örnek

Düğüm js kapsayıcımdan ana ana bilgisayara bir komut göndermek ve çıktıyı almak için şu şekilde:

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);

Bu güzel çalışıyor. Güvenlik ne olacak? Bunu, çalışan bir kapsayıcı içinden docker kapsayıcılarını başlatmak / durdurmak için kullanmak istiyorum? Docker komutlarını çalıştırma dışında herhangi bir ayrıcalığa sahip olmayan bir dockeruser mı yapmalıyım?
Kristof van Woensel

4

Bir bağlantı noktasında dinleyen basit bir sunucu python sunucusu yazın (örneğin 8080), kap ile -p 8080: 8080 bağlantı noktasını bağlayın, python sunucusundan popen ile kabuk komut dosyalarını çalıştırmasını istemek için localhost: 8080'e bir HTTP isteği gönderin, bir curl çalıştırın veya HTTP isteği yapmak için kod yazma 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()

IMO bu en iyi cevaptır. Ana makinede rastgele komutların çalıştırılması bir tür API (örneğin REST) ​​aracılığıyla YAPILMALIDIR. Bu, güvenliğin uygulanabilmesinin ve çalışan süreçlerin düzgün bir şekilde kontrol edilebilmesinin tek yoludur (örn. Öldürme, stdin, stdout, çıkış kodu vb.). Elbette bu API'nin Docker içinde çalışabilmesi güzel olurdu, ancak şahsen onu doğrudan ana bilgisayarda çalıştırmayı umursamıyorum.
barney765

2

Tembelliğim, burada cevap olarak yayınlanmayan en kolay çözümü bulmamı sağladı.

Bu dayanmaktadır harika bir yazı ile luc juggery .

Docker konteynerinizin içinden linux sunucunuza tam bir kabuk kazandırmak için yapmanız gereken tek şey:

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

Açıklama:

--privileged: kapsayıcıya ek izinler verir, kapsayıcının ana bilgisayarın (/ dev) cihazlarına erişmesine izin verir

--pid = host: kapsayıcıların Docker ana bilgisayarının (Docker arka plan programının çalıştığı VM) işlem ağacını kullanmasına izin verir nsenter yardımcı programı: mevcut ad alanlarında (kapsayıcılara yalıtım sağlayan yapı taşları) bir işlem çalıştırmaya izin verir

nsenter (-t 1 -m -u -n -i sh), sh işleminin PID 1 ile işlemle aynı yalıtım bağlamında çalıştırılmasına izin verir. Tüm komut daha sonra sanal makinede etkileşimli bir sh kabuğu sağlayacaktır.

Bu kurulumun büyük güvenlik etkileri vardır ve (varsa) dikkatli kullanılmalıdır.


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

3
Bu cevap OP'nin sorusunu çözebilirken, nasıl çalıştığını ve sorunu neden çözdüğünü açıklamanız önerilir. Bu, yeni geliştiricilerin neler olup bittiğini ve bu ve benzeri sorunları nasıl düzelteceklerini anlamalarına yardımcı olur. Katkıda bulunduğunuz için teşekkürler!
Caleb Kleveter

1

Basit bir yaklaşımım var.

Adım 1: Mount /var/run/docker.sock:/var/run/docker.sock (Böylece konteynerinizin içinde docker komutlarını çalıştırabileceksiniz)

Adım 2: Bunu aşağıda kabınızın içinde gerçekleştirin. Buradaki anahtar kısım (- ağ ana bilgisayarı, çünkü bu, ana bilgisayar bağlamından yürütülecektir)

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

test.sh, ihtiyacınız olan bazı komutları (ifconfig, netstat vb.) içermelidir. Artık ana bilgisayar bağlam çıktısını alabileceksiniz.


2
Docker ana bilgisayar ağını kullanarak ağ oluşturma hakkındaki resmi belgelerine göre, "Ancak, depolama, işlem ad alanı ve kullanıcı ad alanı gibi diğer tüm şekillerde, işlem ana bilgisayardan izole edilmiştir." Göz
Peter Mutisya

0

Marcus'un hatırlattığı gibi, docker temelde süreç izolasyonudur. Docker 1.8'den başlayarak, dosyaları ana bilgisayar ve konteyner arasında her iki yönde de kopyalayabilirsiniz, bkz.docker cp

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

Bir dosya kopyalandıktan sonra onu yerel olarak çalıştırabilirsiniz


1
Bunu biliyorum. Bu betiği docker konteynerinden başka bir deyişle nasıl çalıştırabilirim?
Alex Ushakov


2
@AlexUshakov: Olmaz. Bunu yapmak, docker'ın birçok avantajını ortadan kaldırır. Yapma. Denemeyin. Ne yapmanız gerektiğini yeniden düşünün.
Marcus Müller

Vlad's trick forumlarına
user2915097

1
Her zaman, ana bilgisayarda, konteynırınızdaki bir değişkenin değerini alabilir myvalue=$(docker run -it ubuntu echo $PATH)ve bunu bir komut dosyası kabuğunda düzenli olarak test edebilirsiniz (tabii ki, $ PATH dışında bir şey kullanacaksınız, sadece bir örnek), belirli bir değerdir, komut dosyanızı başlatırsınız
user2915097

0

Boru konseptini kullanabilirsiniz, ancak ana makinede bir docker konteynerinden bir komut dosyası yürütme hedefini gerçekleştirmek için ana bilgisayar ve fswatch üzerindeki bir dosyayı kullanabilirsiniz . Öyle (Kendi sorumluluğunuzdadır kullanın):

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

Bu örnekte, kapsayıcı içinde komutları / dev / command_pipe'a gönderin, örneğin:

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

Ana bilgisayarda, ağın oluşturulup oluşturulmadığını kontrol edebilirsiniz:

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

-7

User2915097'nin yanıtını genişletmek için :

İzolasyon fikri, bir uygulamanın / işlemin / kapsayıcının (bu açınız ne olursa olsun) ana sisteme neler yapabileceğini çok açık bir şekilde kısıtlayabilmektir. Bu nedenle, bir dosyayı kopyalayıp çalıştırabilmek gerçekten tüm konsepti bozacaktır.

Evet. Ama bazen gerekli.

Hayır. Durum bu değil veya Docker doğru kullanım değil. Yapmanız gereken şey, yapmak istediğiniz şey için net bir arayüz bildirmek (örneğin, bir ana bilgisayar yapılandırmasını güncellemek) ve tam olarak bunu yapmak için minimum bir istemci / sunucu yazmaktır . Ancak genel olarak bu pek arzu edilen bir durum gibi görünmüyor. Çoğu durumda, yaklaşımınızı yeniden düşünmeli ve bu ihtiyacı ortadan kaldırmalısınız. Docker, temelde her şey bazı protokoller kullanılarak erişilebilen bir hizmet olduğunda ortaya çıktı. Ana bilgisayarda keyfi şeyler yürütme haklarını alan bir Docker kapsayıcısının herhangi bir uygun kullanım durumunu düşünemiyorum.


Kullanım durumum var: Dockerized hizmetim var A( github'da src). Gelen Arepo ben 'git çekme' komutundan sonra yeni liman işçisi görüntü oluşturmak ve bunları çalıştırmak (ve tabii ki eski kabını kaldırın) doğru kanca oluşturur. Sonraki: github, ana sunucuya basıldıktan sonra rastgele uç nokta bağlantısına POST isteği oluşturmaya izin veren web kancalarına sahiptir. Bu yüzden, bu uç nokta olacak ve sadece HOST makinesindeki repo A'da 'git pull' çalıştıracak olan dockerized hizmet B'yi yaratmayacağım (önemli: 'git pull' komutu HOST ortamında çalıştırılmalıdır - B ortamında değil B'nin içinde yeni A konteyneri çalıştıramaz ...)
Kamil Kiełczewski

1
Sorun: HOST içinde linux, git ve docker dışında hiçbir şeye sahip olmak istemiyorum. Ve dockerizet hizmeti A ve hizmet B'ye sahip olmak istiyorum (ki bu aslında biri git itme komutunu master üzerinde yaptıktan sonra repo A'da git çekme işlemini yürüten git-push işleyicisidir). O halde git otomatik dağıtımı sorunlu bir kullanım örneğidir
Kamil Kiełczewski

@ KamilKiełczewski Ben de aynısını yapmaya çalışıyorum, bir çözüm buldunuz mu?
user871784

1
"Hayır, durum bu değil" demek dar görüşlüdür ve dünyadaki her kullanım durumunu bildiğinizi varsayar. Kullanım örneğimiz testler yürütüyor. Ortamı doğru bir şekilde test etmek için konteynerlerde çalıştırmaları gerekir, ancak testlerin doğası göz önüne alındığında, ana bilgisayarda komut dosyaları yürütmeleri gerekir.
Senica Gonzalez

1
Sadece neden -7 cevabını bıraktığımı merak edenler için: a) yanılabilir olmakta sorun yok. Ben hatalıydım. Bunun burada belgelenmesi sorun değil. b) Yorumlar aslında değer katmaktadır; cevabın silinmesi onları da silecektir. c) Yine de dikkate alınması akıllıca olabilecek bir bakış açısına katkıda bulunur (mecbur değilseniz izolasyonunuzu kırmayın. Bazen buna mecbur kalırsınız).
Marcus Müller
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.