Liman işçisi konteyneri başlatma işleminde nasıl hata ayıklayabilirim?


93

Bir konteyner ile ilgili bir sorunum vardı, mükemmel bir şekilde inşa edilmesine rağmen düzgün bir şekilde başlamıyor. Bunun nedeni Dockerfile'a eklediğim bir geçici çözümdür (kendinden yapılandırılmış / etc / hosts yönlendirmesine sahip olmak için)

RUN mkdir -p -- /lib-override /etc-override && cp /lib/libnss_files.so.2 /lib-override
ADD hosts.template /etc-override/hosts
RUN perl -pi -e 's:/etc/hosts:/etc-override/hosts:g' /lib-override/libnss_files.so.2
ENV LD_LIBRARY_PATH /lib-override

Belli ki orada bazı hatalar var, ama acaba docker'ın ne yaptığı hakkında daha fazla bilgi edinebilirim. örneğin, bu çalışır:

$ docker run image ls
usr bin ...

Ama bu değil:

$ docker run image ls -l
$

Kayıtlarda hiçbir şey yok ve etkileşimli bir kabuk da diyemiyorum. Neler olduğunu görmek için strace'ı kullanabilirim ama daha iyi bir yol olacağını umuyordum.

Liman işini daha ayrıntılı bir şekilde ayarlayabilmemin bir yolu var mı?

EDIT : Andrew D sayesinde. Şimdi yukarıdaki kodda neyin yanlış olduğunu biliyorum (cevabını anlamak için bıraktım). Şimdi mesele hala böyle bir şeyi nasıl hata ayıklayabilirim ya da neden- ls-l'nin neden başarısız olmadığına dair içsel bilgi alabilirim .

EDIT : -D = true, benim durumumda olmasa da, daha fazla çıktı verebilir ...


Lütfen cevaplardan birini "kabul edildi" olarak işaretlemeye gayret gösterin, teşekkürler!
Brian,

Yanıtlar:


95

Docker eventskomutu yardımcı olabilir ve Docker günlükleri komutu, görüntünün başlayamamasından sonra bile günlükleri alabilir.

İlk docker eventsönce neler olup bittiğini görmek için arka planda başlayın .

docker events&

Ardından başarısız docker run ...komutunuzu çalıştırın . Sonra ekranda aşağıdaki gibi bir şey görmelisiniz:

2015-12-22T15:13:05.503402713+02:00 xxxxxxxacd8ca86df9eac5fd5466884c0b42a06293ccff0b5101b5987f5da07d: (from xxx/xxx:latest) die

Daha sonra, başlangıç ​​onaltılı kimliğini önceki mesajdan veya run komutunun çıktısından alabilirsiniz. Daha sonra logs komutuyla kullanabilirsiniz:

docker logs <copy the instance id from docker events messages on screen>

Şimdi başarısız görüntü başlangıcından bir miktar çıktı görmelisiniz.

@Alexkb'nin bir yorumda önerdiği gibi: kabınız docker events&sürekli AWS ECS servisi gibi bir şeyden tekrar başlatılıyorsa, sıkıntılı olabilir. Bu senaryoda, konteyner onaltılı kimliğini günlüklerin dışına çıkarmak daha kolay olabilir /var/log/ecs/ecs-agent.log.<DATE>. O zaman liman işçisi kullanın logs <hex id>.


Çok yararlı! Liman işçisi için yeni ve çalışan portainer'ı almaya çalışıyordu. Bu hata ayıklama adımlarıyla çözüldü. Medium.com'da aynı problemi olan birini buldum: medium.com/@jameson_37151/…
Jameson

"Kapsayıcı bulunamadı"!
demirli kirpi

Garip. Sadece emin olmak için @dementedhedgehog " (from xxx/xxx:latest) die" ile biten günlük iletisinden onaltılık kimliği kopyalamayı denediniz mi?
Peter Lamberg,

1
Çok teşekkürler bu cevap, bu bir hayat kurtarıcı. Eklemek için tek şey, docker events&eğer konteyneriniz sürekli olarak AWS ECS servisi gibi bir şeyden tekrar başlatılıyorsa, sorun olabilir. Bu nedenle, bu senaryoda, konteyner onaltılı kimliğini günlüklerden çıkarmak daha kolay olabilir /var/log/ecs/ecs-agent.log.<DATE>. Ardından docker logs <hex id>, neden önyükleme yapmadığını görmek için bu cevabın önerdiği şekilde kullanın .
alexkb

1
@alexkb Teşekkürler! Önerinizi cevabın sonuna ekledim, böylece başkaları daha kolay bulabilir.
Peter Lamberg,

18

Şu ana kadar öğrendiğim en iyi şey:

#stop the current demon and start it in debug modus
sudo service docker stop
dockerd -D # --debug

Sadece istemciyi yeni bir kabuktan başlat. Yanlış anlama, müşterinin aslında herhangi bir şey yaptığını düşünmekti ... peki sadece daemon ile iletişim kuruyor, bu yüzden istemciyi, ama daemon'un kendisini (normalde) hata ayıklamak istemiyorsunuz .


13

Benim durumumda, -a(STDOUT / STDERR 'e ekle) bayrağı yeterliydi:

user@machine:~$ docker start -a server_name
Error: The directory named as part of the path /log/log_path/app.log does not exist.
For help, use /usr/bin/supervisord -h

Başlangıç ​​hatasını gösterdi (bizim durumumuzda, kullanılan bir eksik günlük yolu supervisord). Çoğu konteyner başlatma hatasının burada da ortaya çıkacağını varsayıyorum.


3

Liman çıkışını daha eksiksiz hale getirme konusundaki sorunuza cevap veremem, ancak yerinde bir dizinin yerine. diğer girişlerin dosya ofsetlerini değiştirirseniz, elf dosyası bozulur. Perl komutunu ( LD_LIBRARY_PATH değişikliğinden önce ) çalıştırdıktan sonra .so dosyanızda objdump veya readelf komutunu çalıştırmayı deneyin - doların artık bozuk olduğunu gösterir.

Ne yazık ki gerekli olan kesmede çalışmasının nedeni, "tmp" ve "etc" nin aynı dizi uzunluğudur, bu nedenle ofset değişmez. / Tmp kullanmamayı tercih ediyorsanız / dkr dizinini veya benzerini göz önünde bulundurun.

Bu yaklaşımı benimsemeniz gerekiyorsa ve istediğiniz yollar değiştirilemezse, kitaplığı yeniden oluşturun ve kaynaktaki / etc / hosts dosyasının varsayılan yolunu değiştirin. Ya da daha iyisi, tadilatınızı oluştururken docker konteynerinizi başlatırken kullanmak üzere değiştirmek ve kullanmak libnss_files.sogibi bir şeyi yeniden adlandırın (docker, nsswitch.conf da bağlanmışsa, değiştiremezsiniz). Bu, temel sistemdeki normal kütüphanelerinize paralel olarak libnss_altfiles.so dosyasına sahip olmanızı sağlar. Liman işçisi nsswitch.conf dosyasını bağlarsa, yeniden yarattığınız libnss_files.so kopyasını / lib-override dizininizde LD_LIBRARY_PATH tarafından yüklenmeye hazır halde bırakın.libnss_altfiles.sonsswitch.confhosts: altfiles

Heads up olarak, suid / sgid ikili dosyaları LD_LIBRARY_PATH ve LD_PRELOAD'ı görmezden gelir, bu yüzden eğer bu değişkenleri kullanırsanız bazı şeyler bozulur (okuma: varsayılan / etc / hosts kodunu kullanmaya geri dönün).


Harika bir fikir için çok teşekkürler ... Çok hızlıydım ve şimdi olanları görüyorum.
Stat'ı

0

Bazen, liman işçisi arka planını çalıştıran düğüme girip ardından aşağıdakileri yaparak yararlı hata mesajlarını bulabilirsiniz:

$ tail -f /var/log/containers/* /var/log/docker.log 2>&1

Mac OS'de 'Docker Community edition' bölümünde, aşağıdakileri yaparak docker vm'ye bağlanabilirsiniz:

$  screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
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.