Durdurulmuş bir Docker kapsayıcısını farklı bir komutla nasıl başlatırsınız?


251

Durdurulan bir Docker kapsayıcısını varsayılan komut çöktüğü için farklı bir komutla başlatmak istiyorum - kapsayıcıyı başlatamıyorum ve sonra 'docker exec' kullanamıyorum.

Temelde kabın içeriğini inceleyebilmem için bir kabuk başlatmak istiyorum.

Neyse ki kapsayıcıyı -it seçeneği ile oluşturdum!

Yanıtlar:


380

Durdurulmuş kapsayıcı kimliğinizi bulma

docker ps -a

Durdurulmuş konteyneri uygulayın:

Bu komut, değiştirilmiş kapsayıcı durumunu yeni bir görüntüye kaydeder user/test_image

docker commit $CONTAINER_ID user/test_image

Farklı bir giriş noktasıyla başla / çalıştır:

docker run -ti --entrypoint=sh user/test_image

Giriş noktası argümanı açıklaması: https://docs.docker.com/engine/reference/run/#/entrypoint-default-command-to-execute-at-runtime

Not:

Yukarıdaki adımlar, aynı dosya sistemi durumuna sahip durdurulmuş bir kapsayıcı başlatmanız yeterlidir. Hızlı bir soruşturma için harika. Ancak ortam değişkenleri, ağ yapılandırması, ekli birimler ve diğer personel miras alınmaz, tüm bu bağımsız değişkenleri açıkça belirtmelisiniz.

Durdurulmuş bir kapsayıcı başlatma adımları buradan ödünç alındı: (son yorum) https://github.com/docker/docker/issues/18078


1
hayır, resimler salt okunur. Değiştirilmiş konteyner durumunu yeni bir görüntüye kaydeder test_image
Dmitriusan

4
Bu env, birimler, UID, hakkında neredeyse tüm yapılandırma özlüyor… Durdurulan konteyner ile ortak tek şey dosya sistemi (belki bazıları için yeterli)
Florian Klein

4
Bir şekilde aynı ortamı, ağ yapılandırmasını, ekli birimleri alabilseydim harika olurdu. inspectÇıkışı, sonraki çalıştırmada kullanılan bir yapılandırmaya dönüştürmek mümkün müdür ?
Otheus

2
@Webman, evet, ancak bir konteyneri durdurmadan önce monte edilen birimler için bu doğru değil. Bir dahaki sefere konteynere başladığınızda aynı hacimleri açıkça eklemeniz gerekecek
Dmitriusan

1
@ EmreTapcı, bence bunu Docker ideolojisine aykırı. Konteynırlar, sanal makinelerin aksine, tek kullanımlık bir koş-ve-at-at varlığı olmak üzere tasarlanmıştır. Aaa90210 yanıtını izlemeyi deneyebilirsiniz , ancak bu bir hack olacaktır.
Dmitriusan

126

Bu dosyayı düzenleyin (durdurulan kapsayıcınıza karşılık gelir):

vi /var/lib/docker/containers/923...4f6/config.json

"Yol" parametresini yeni komutunuzu gösterecek şekilde değiştirin, örneğin / bin / bash. "Args" parametresini, komuta argümanlar iletmek için de ayarlayabilirsiniz.

Liman hizmetini yeniden başlatın (bunun çalışan tüm kapsayıcıları durduracağını unutmayın):

service docker restart

Kapsayıcılarınızı listeleyin ve komutun değiştiğinden emin olun:

docker ps -a

Konteyneri başlatın ve takın, şimdi kabuğunuzda olmalısınız!

docker start -ai mad_brattain

Docker 1.7.1 kullanarak Fedora 22 üzerinde çalıştı.

NOT: Kabuğunuz etkileşimli değilse (örn. -İt seçeneğiyle orijinal kapsayıcı oluşturmadıysanız), bunun yerine komutu "/ bin / sleep 600" veya "/ bin / tail -f / dev / null" olarak değiştirebilirsiniz. kabuk almak için başka bir yol olarak "docker exec -it CONTID / bin / bash" yapmak için yeterli zaman vermek.

NOT2: Docker'ın yeni sürümlerinde config.v2.json bulunur; burada Giriş Noktası'nı veya Cmd'yi değiştirmeniz gerekir (teşekkürler user60561).


44
gözlerim. gözlerim. Umarım bu bir yerde Docker bu düzgün işlemek için bir özellik isteği olduğunu.
gertvdijk

2
@AlexeyStrakh "/ usr / bin / sleep 600" çalıştırmayı deneyebilir ve sonra bir kabuk almak için "docker exec -it / bin / bash" yapabilirsiniz. Her ne kadar bu Path değişkenine parametreleri koymak emin değilim. Aksi takdirde, bir exec gerçekleştirmeniz için yeterince uzun süre hayatta kalacak başka bir komut bulmaya çalışın veya Dmitriusan'ın cevabını görün.
aaa90210

3
sorunun tek doğru cevabı budur: diğer tüm önermeler "neredeyse aynı" bir konteynır çalıştırıyorlar, ama hacimleri, env, UID'leri unutuyorlar…
Florian Klein

3
Benim durumumda / usr / bin / sleep mevcut değildi. Ben kullanarak başarılı olmuş..."Path":"tail","Args":["-f","/dev/null"]...
nevrome

4
Docker'ın daha yeni sürümleri var config.v2.json, ya Entrypointda değiştirmeniz gerekiyor Cmd.
user60561

20

Giriş noktası komut dosyanızın üstüne bir kontrol ekleyin

Docker'ın bunu gerçekten yeni bir özellik olarak uygulaması gerekiyor, ancak burada, hata ayıklamayı zorlaştırabilen, başarı veya başarısızlıktan sonra sona eren bir Giriş Noktasına sahip olduğunuz durumlar için başka bir geçici çözüm seçeneği var.

Henüz bir Entrypoint betiğiniz yoksa, kapsayıcı için ihtiyacınız olan komutları çalıştıran bir komut dosyası oluşturun. Ardından, bu dosyanın en üstüne şu satırları ekleyin entrypoint.sh:

# Run once, hold otherwise
if [ -f "already_ran" ]; then
    echo "Already ran the Entrypoint once. Holding indefinitely for debugging."
    cat
fi
touch already_ran

# Do your main things down here

catBağlantıyı sürdürdüğünden emin olmak için bir TTY sağlamanız gerekebilir. Ben benim gibi Entrypoint komut dosyası ile konteyner çalıştırıyorum:

docker run -t --entrypoint entrypoint.sh image_name

Bu, komut dosyasının bir kez çalışmasına neden olarak, zaten çalıştığını belirten bir dosya oluşturur (kapsayıcının sanal dosya sisteminde). Daha sonra hata ayıklama gerçekleştirmek için kapsayıcıyı yeniden başlatabilirsiniz:

docker start container_name

Kapsayıcıyı yeniden already_ranbaşlattığınızda, dosya bulunarak Entrypoint komut dosyasının durmasına neden olur cat(bu yalnızca hiç gelmeyecek olan girdiyi sonsuza kadar bekler, ancak kapsayıcıyı canlı tutar). Daha sonra bir hata ayıklama bashoturumu yürütebilirsiniz :

docker exec -i container_name bash

Kapsayıcı çalışırken, bu şekilde hata ayıklamanız gerekirse already_ran, entrypoint.shkomut dosyasını yeniden çalıştırmak için el ile yürütebilirsiniz .


3
Ek olarak, giriş noktasını /bin/shbunun yerine çalıştırabilirsiniz cat- o zaman her zaman yeniden başlayabilirsiniz. Çözümünüz sallanıyor!
Danny Dulai

4

Benim sorunum:

  • İle bir konteyner başlattım docker run <IMAGE_NAME>
  • Ve sonra bu kaba bazı dosyalar ekledik
  • Sonra kabı kapattım ve yukarıdaki komutla tekrar başlatmayı denedim.
  • Ama yeni dosyaları kontrol ettiğimde kayıplar
  • koştuğumda docker ps -aiki kap görebiliyordum.
  • Bu, her docker run <IMAGE_NAME>komut çalıştırışımda yeni görüntü yaratıldığı anlamına gelir

Çözüm: İlk olarak çalıştırdığınız kapta çalışmak için şu adımları izleyin

  • docker ps konteynerinizin konteyner almak için
  • docker container start <CONTAINER_ID> mevcut kapsayıcıyı başlatmak için
  • Sonra kaldığınız yerden devam edebilirsiniz. Örneğindocker exec -it <CONTAINER_ID> /bin/bash
  • Daha sonra yeni bir görüntü oluşturmaya karar verebilirsiniz.

Bu soruya cevap vermiyor. OP kapsayıcıyı nasıl yeniden başlatacağını bilmek istiyor ama kullanılanlardan farklı argümanlarladocker run <containerID>
CodeBlooded

2

@ Dmitriusan'ın cevabını aldım ve bir takma ad haline getirdim:

takma ad docker-run-prev-container = 'prev_container_id = "$ (docker ps -aq | head -n1)" && docker taahhüt "$ prev_container_id" "prev_container / $ prev_container_id" && docker run -it --entrypoint = bash "prev_container / $ '"prev_container_id

Bunu ~/.bashrctakma adlar dosyanıza ekleyin ve sizi docker-run-prev-containerönceki kapsayıcıdaki bir kabuğa bırakacak olan yepyeni bir takma adınız olur.

Hata ayıklama başarısız oldu docker builds.


2

Bu tam olarak istediğiniz şey değildir, ancak docker exportistediğiniz tek şey dosyaları incelemekse durdurulan bir kapta kullanabilirsiniz .

mkdir $TARGET_DIR
docker export $CONTAINER_ID | tar -x -C $TARGET_DIR

1

Kapsayıcıdan çıkılıp çıkılmadığı, yalnızca kodunuzun çöktüğü ve kapta neler olup bittiğini görmeniz gerektiği belirtilmedi. Eğer çıkmazsa, işte başka bir potansiyel çözüm.

Kapsayıcı kimliğini şununla al: docker ps

docker exec -it 665b4a1e17b6 /bin/sh

Giriş noktası sorunlu bir şeye ayarlanırsa, Dmitriusan'ın cevabında önerildiği gibi geçersiz kılınabilir. Ayrıca, ile çalışan herhangi bir konteynere ekleyebileceğiniz de not edilmelidir docker attach. Pek çok çözüm farklı çözümler. Sadece görüntüyü taahhüt etme gereğini görmüyorum. Gereksiz görünüyor.

Docker yürütme dokümanları - https://docs.docker.com/engine/reference/commandline/exec/

Docker eki için dokümanlar - https://docs.docker.com/engine/reference/commandline/attach/


-12

Aslında bu cevapların her ikisine de katılmıyorum. Kapta ne olduğunu görmek istiyorsanız, bir kabuk almak için bu komutu çalıştırabilirsiniz. Giriş noktasını hiç veya herhangi bir yapılandırmada değiştirmeye gerek yoktur.

docker run -it <image_name> bash

12
Bu işlem çalışmaz bir kap değil, bir kap hakkında sorduğu için çalışmaz.
Peter Vrabel

Sanırım hakkın ama bunu yapmak için bir neden göremiyorum. Günlükleri stdout'a yönlendirebilir ve docker logs <container_id> --followihtiyacınız olanı verebilirsiniz. Başka bir alternatif yukarıdaki komutu kullanmak ve ardından dockerfile'da aynı komutla o görüntüde çökme hizmetini başlatmak ve oradan hata ayıklamaktır.
deadbabykitten

4
Run komutu bir görüntüden yeni bir kap oluşturur. Durdurulmuş bir kapsayıcı başlatmıyor.
Waleed Abdulla

2
Ummm, .. liman işçisinin amacı her görüntünün aynı şekilde döndürülebilmesi değil mi? Bu tartışmanızı reddeder. Durdurulmuş bir kapsayıcı başlatması GEREKMEZ. Herhangi bir konteyner tamamen aynıdır, bu yüzden hangisini başlattığı veya durdurduğu önemli değildir. Sadece içeriği incelemeye çalýţýyor. Bunu yapmanın en kolay yolu, komutun komutunu veya boru çıkışını günlüklere basmak ve çalıştırmaktır. Bazen basit problemler için en karmaşık çözümleri buluyorsunuz.
deadbabykitten

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.