Çalışan bir kapta kabuk oturumu başlatmak mümkün mü (ssh olmadan)


341

Ben safça çalışan bir kapsayıcıda bir bash kabuk çalıştırmak için bekliyordum:

docker run "id of running container" /bin/bash

mümkün değil gibi görünüyor, hatayı alıyorum:

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

Yani, bash kabuğunu çalışan bir kapta çalıştırmak istersem (ör. Teşhis amaçlı)

SSH sunucusu çalıştırmak ve ssh üzerinden oturum açmak zorunda mıyım?


1
docker run CONTAINER1.0
kolypto


1
sadecedocker attach container_name
maxbellec

1
Günümüzde ikinci cevabın kabul edilenden çok daha iyi olduğu görülüyor - kabul edilen cevabı değiştirmeyi yeniden düşünebilir misiniz?
jsbueno

Yanıtlar:


285

EDIT: Artık kullanabilirsiniz docker exec -it "id of running container" bash( doc )

Daha önce, bu sorunun cevabı şuydu:

Gerçekten gerekir ve bir hata ayıklama ortamında iseniz, bunu yapabilirsiniz: sudo lxc-attach -n <ID> Kimliğin tam ( docker ps -notrunc) olması gerektiğini unutmayın .

Ancak, buna karşı şiddetle tavsiye ederim.

uyarı: -notrunckullanımdan kaldırıldı, --no-truncyakında değiştirilecek .


1
neden ona karşı öneriyorsun?
Max L.

7
Buna karşı öneriyorum çünkü 1) çok yeni bir çekirdek gerektiriyor, 2) Docker'ın dışında bir şeyler yapıyorsunuz, bu yüzden onu takip edemeyeceksiniz (günlükler, ekler, vb.). Ayrıca, docker şu anda lxc'yi kullanabilir, ancak sonsuza kadar yapacağının garantisi yoktur.
13'te 21

1
0.7.6 sürümüne güncellemeyi deneyin. Docker şu anda hala lxc kullanıyor ve lxc-attachgayet iyi çalışıyor. Sadece iki kat kontrol ettim ve benim için çalışıyor. (3.8'den önce çekirdekle çalışmadığını unutmayın).
14'te

2
0,9'dan itibaren liman işçisi varsayılan olarak LXC ile çalışmaz. docker -d -e lxc
Docker

2
Max L., kullanım durumunuz veri hacimleriyle çözülebilir . Test edilmemiş örnek: 1) kapsayıcıyı veri hacminde nginx günlükleriyle çalıştırın docker run -v /var/log/nginx -name somename imagename command:; 2) veri hacminin içeriğini görüntülemek için bir kap çalıştırın: docker run -volumes-from somename -i -t busybox /bin/sh.
ciastek

615

Docker 1.3 ile yeni bir komut var docker exec. Bu, çalışan bir liman işçisine girmenizi sağlar:

docker exec -it "id of running container" bash

2
Bu benim için harika çalıştı. Docker çalıştırmak için çok yararlı bir ek.
oraserrata

Çalışan bir kapsayıcı yürütürken değişiklik yaptıysam ve değişiklikleri çevrimiçi olarak yansıtmak istersem ne olur? en iyi uygulamalar nelerdir?
mediaroot

Çok kullanışlı. Teşekkür ederim
luongnv89

docker psçalışan örneklerin kimliğini almak için kullanın
muon

Not: Kapsayıcıda bash olmayabilir (»exec:" bash ": yürütülebilir dosya bulunamadı«). docker inspect <image>Hangi kabuğun kullanılabilir olduğunu görmek için kullanın . docker exec -it <container id> /bin/shBunun yerine koş .
pixelbrackets

14

Sadece yap

docker attach container_name

Durdurmadan kaptan kopmakta için, yorum belirtildiği gibi, yazın Ctrlpardından Ctrlq.


5
Teşekkürler!! Yardımcı oldu. Ve asıl soru bağlamında, bir şey eklemek istiyorum. Kapsayıcımızda hata ayıkladıktan sonra ve yerine docker attach container_namekullanın . command kapsayıcıyı durdurur ve burada kapsayıcıyı ayırır ve ayırır ve çalışır durumda tutarctrl pctrl qexitexitctrlpctrl q
phoenix

10

İşler değiştiğinden, şu anda çalışan bir konteynere erişmenin önerilen yolu kullanıyor nsenter.

Bu github deposu hakkında daha fazla bilgi bulabilirsiniz . Ancak genel olarak nsenter'ı şu şekilde kullanabilirsiniz:

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

veya sarmalayıcıyı kullanabilirsiniz docker-enter:

docker-enter <container_name_or_ID>

Konu hakkında güzel bir açıklama Jérôme Petazzoni'nin blog girişinde bulunabilir: Docker kaplarınızda neden sshd'yi çalıştırmanıza gerek yok?


ne yazık ki, env değişkenleri bu yaklaşım kullanılarak bertaraf edilir (eğer link ile oluşturulan değişkenleri kontrol etmek isterseniz). Yapmanızı öneririm source /proc/*/environ.
Tomas Tomecek

8

Koşamayacağın ilk şey

docker run "existing container" command

Çünkü bu komut bir kap değil , bir görüntü beklemektedir ve yine de yeni bir kapın ortaya çıkmasına neden olacaktır (bu yüzden bakmak istediğiniz kap değil)

Docker ile farklı bir şekilde düşünmek için kendimizi zorlamamız gerektiğine katılıyorum (böylece konteynere giriş yapmanıza gerek kalmayacak şekilde yollar bulmalısınız), ancak yine de yararlı buluyorum ve bu şekilde çalışıyorum etrafında.

Komutlarımı DEAMON modunda amir aracılığıyla çalıştırıyorum.

Sonra ne diyorum yürütmek docker_loop.sh İçerik hemen hemen budur:

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

Yaptığı şey, konteynere "eklemenize" supervisorctlve günlükleri durdurmak / başlatmak / yeniden başlatmak ve kontrol etmek için arayüzle sunulmanıza izin vermesidir . Bu yeterli Ctrl+Dolmazsa, normal bir sistemmiş gibi etrafınıza bir göz atmanızı sağlayacak bir kabuğa düşebilirsiniz.

LÜTFEN AYRICA HESABINIZA GEÇİN, bu sistemin kabı bir kabı olmayan kadar güvenli olmadığından, kabınızı sabitlemek için gerekli tüm adımları uygulayın.


5

Bu çekme isteğine göz atın: https://github.com/docker/docker/pull/7409

Hangi önümüzdeki docker exec <container_id> <command>yardımcı programı uygular . Bu mevcut olduğunda, örneğin çalışan bir konteyner içinde ssh servisini başlatmak ve durdurmak mümkün olmalıdır.

Bunu nsinityapmak için: "nsinit, çalışan bir kabın ad alanının içindeki bir kabuğa erişmek için kullanışlı bir yol sağlar" , ancak yayınlanması zor görünüyor. https://gist.github.com/ubergarm/ed42ebbea293350c30a6


docker execDocker 1.3'e indi, bu yüzden çalışan bir kapta yeni bir kabuk oturumu oluşturmak ve katılmak mümkün
foz


1

Aslında kabın içinde bir kabuk bulundurmanın bir yolu var.

/root/run.shSüreci, süreç yöneticisini (süpervizör) veya her neyse başlattığınızı varsayın .

/root/runme.shBazı gnu-ekran hileleriyle yaratın :

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

Artık, sekmelerinizde sekmelerde ve sekme 1'de etkileşimli bir kabuk docker attachvar.

Başka bir öneri, bu ekran hilesi de dahil olmak üzere gerekli tüm araçlarla üretim görüntüsünün üstünde bir "geliştirme paketi" görüntüsü oluşturmaktır.


1

işte benim çözümüm

DOckerfile'ın bir parçası:

...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

"initd.sh" nin bir parçası

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

görüntü oluşturulduktan sonra exec ve attach kullanarak iki seçeneğiniz vardır:

  1. exec (kullandığım) ile çalıştırın:

docker run --name $ CONTAINER_NAME -dt $ IMAGE_NAME

sonra

docker exec -it $ CONTAINER_NAME / bin / bash

ve kullan

Sökmek için CTRL + D

  1. ekleme ile çalıştırın:

docker run --name $ CONTAINER_NAME -düzenleme IMAGE_NAME

sonra

liman işçisi $ CONTAINER_NAME ekliyor

ve kullan

Sökmek için CTRL + P ve CTRL + Q

seçenekler arasındaki fark -i parametresindedir


1

İki yol var.

Ekli

$ sudo docker attach 665b4a1e17b6 #by ID

Exec ile

$ sudo docker exec - -t 665b4a1e17b6 #by ID


0

Kapsayıcı çalıştırılırken ad atamak yararlıdır. Container_id yönergesine ihtiyacınız yok.

docker run --name container_name yourimage docker exec -it container_name bash


0

ilk olarak, istenen kabın kapsayıcı kimliğini

docker ps

böyle bir şey alacaksınız:

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                          PORTS                    NAMES
3ac548b6b315        frontend_react-web     "npm run start"     48 seconds ago      Up 47 seconds                   0.0.0.0:3000->3000/tcp   frontend_react-web_1

şimdi bu kapsayıcı kimliğini kopyalayın ve aşağıdaki komutu çalıştırın:

docker exec -it container_id sh

docker exec -it 3ac548b6b315 sh


-2

Belki de konteynır geliştirirken sanal makineler açısından kendim gibi yanıltmıştınız. Benim tavsiyem: Yapmamaya çalışın.

Konteynerler diğer tüm süreçler gibidir. Aslında, hata ayıklama amacıyla onlara "iliştirmek" isteyebilirsiniz (/ proc // env veya strace -p'yi düşünün), ancak bu çok özel bir durumdur.

Normalde işlemi sadece "çalıştırırsınız", bu nedenle yapılandırmayı değiştirmek veya günlükleri okumak istiyorsanız, yeni bir kapsayıcı oluşturun ve dizinleri paylaşarak, stdout'a yazarak günlükleri bunun dışında yazdığınızdan emin olun (böylece docker günlükleri çalışır) ya da böyle bir şey.

Hata ayıklama amacıyla, bir kabuk başlatmak, sonra kodunuzu başlatmak, ardından kabuğu sağlam bırakmak için CTRL-p + CTRL-q tuşlarına basmak isteyebilirsiniz. Bu şekilde aşağıdakileri kullanarak yeniden bağlayabilirsiniz:

docker attach <container_id>

Kapsayıcıda hata ayıklamak istiyorsanız, yapmasını beklemediğiniz bir şey yapıyorsa, hata ayıklamayı deneyin: /server/596994/how-can-i-debug-a-docker-container -initialization


Bu tamamen yanlış. Uygulamanızın çalıştığı LXC ad alanını inceleyebilmek "çok özel bir durum" değil, herhangi bir geliştirici için ortak / günlük bir etkinliktir.
sleepycal

@sleepycal "herhangi bir geliştirici" biraz önyargılı geliyor. Her halükarda süreçlerin iç gözlemini kullanıyorum, böylece aynı şey kaplar için de geçerli. Hata ayıklamanın ardındaki fikir budur. İşleme bir hata ayıklayıcı eklersiniz (bir klibi olabilir). Kapsayıcıya "giriş yaptığınızı" düşünmek hala bana yanıltıcı geliyor.
estani

-4

Hayır, bu mümkün değil. Gerekirse supervisordbir ssh sunucusu almak gibi bir şey kullanın . Yine de, kesinlikle ihtiyacı sorgularım.

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.