Làm thế nào tôi có thể gỡ lỗi khởi tạo container docker?


93

Tôi đã có một vấn đề với một container, mặc dù nó được xây dựng hoàn hảo nhưng nó không khởi động đúng cách. Nguyên nhân là do một cách giải quyết mà tôi đã thêm vào Dockerfile (để có định tuyến tự cấu hình / etc / hosts)

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

Rõ ràng có một số lỗi trong đó, nhưng tôi tự hỏi làm thế nào tôi có thể biết thêm thông tin về những gì docker đang làm trong khi chạy. ví dụ, điều này hoạt động:

$ docker run image ls
usr bin ...

Nhưng điều này không:

$ docker run image ls -l
$

Không có gì trong nhật ký và tôi cũng không thể gọi một vỏ tương tác. Tôi có thể sử dụng strace để xem những gì đang xảy ra nhưng tôi đã hy vọng có một cách tốt hơn.

Có cách nào để tôi có thể thiết lập docker dài dòng hơn không?

EDIT : Cảm ơn Andrew D. Bây giờ tôi biết có gì sai với đoạn mã trên (tôi đã để nó để câu trả lời của anh ấy có thể hiểu được). Bây giờ vấn đề vẫn là làm thế nào tôi có thể gỡ lỗi một cái gì đó như thế này hoặc nhận được một số nội bộ tại sao ls -l thất bại tại sao ls không.

EDIT : -D = true có thể cho đầu ra nhiều hơn, mặc dù không phải trong trường hợp của tôi ...


Hãy cố gắng đánh dấu một trong những câu trả lời là "được chấp nhận", cảm ơn!
Brian đứng đầu

Câu trả lời:


95

eventsLệnh Docker có thể giúp và lệnh Nhật ký Docker có thể tìm nạp nhật ký ngay cả khi hình ảnh không bắt đầu.

Đầu tiên bắt đầu docker eventstrong nền để xem những gì đang xảy ra.

docker events&

Sau đó chạy docker run ...lệnh thất bại của bạn . Sau đó, bạn sẽ thấy một cái gì đó như sau trên màn hình:

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

Sau đó, bạn có thể lấy id hex khởi động từ tin nhắn trước hoặc đầu ra của lệnh chạy. Sau đó, bạn có thể sử dụng nó với lệnh log:

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

Bây giờ bạn sẽ thấy một số đầu ra từ khởi động hình ảnh thất bại.

Như @alexkb đã đề xuất trong một nhận xét: docker events&có thể gây rắc rối nếu container của bạn liên tục được khởi động lại từ một cái gì đó như dịch vụ AWS ECS. Trong kịch bản này, có thể dễ dàng lấy id hex container ra khỏi nhật ký /var/log/ecs/ecs-agent.log.<DATE>. Sau đó sử dụng docker logs <hex id>.


Rất hữu ích! Mới sử dụng docker và đang cố gắng chạy portainer. Giải quyết nó với các bước gỡ lỗi. Tìm thấy ai đó trên Medium.com có ​​cùng một vấn đề: Medium.com/@jameson_37151/ Kẻ
Jameson

Tôi nhận được "không tìm thấy container"!?
con nhím mất trí

Lạ thật. Để chắc chắn, @dementedhedgehog bạn đã thử sao chép hex-id từ thông điệp tường trình kết thúc bằng " (from xxx/xxx:latest) die"?
Peter Lamberg

1
Cảm ơn bạn rất nhiều câu trả lời này, nó là một cứu tinh. Điều duy nhất cần thêm là docker events&có thể gây rắc rối nếu container của bạn liên tục được khởi động lại từ một cái gì đó như dịch vụ AWS ECS. Vì vậy, trong kịch bản này, có thể dễ dàng lấy id hex container ra khỏi nhật ký /var/log/ecs/ecs-agent.log.<DATE>. Sau đó sử dụng docker logs <hex id>như được đề xuất bởi câu trả lời này để xem tại sao mọi thứ không khởi động.
alexkb

1
@alexkb Cảm ơn! Tôi đã thêm đề xuất của bạn vào cuối câu trả lời để người khác có thể tìm thấy nó dễ dàng hơn.
Peter Lamberg

18

Vâng, điều tốt nhất tôi đã tìm ra cho đến nay là:

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

Chỉ cần bắt đầu máy khách từ một vỏ mới. Quan niệm sai lầm là nghĩ rằng khách hàng thực sự làm bất cứ điều gì cả ... vâng, đó chỉ là giao tiếp với daemon, vì vậy bạn không muốn gỡ lỗi máy khách mà là chính daemon (bình thường).


13

Trong trường hợp của tôi, -acờ (đính kèm STDOUT / STDERR) là đủ:

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

Nó cho thấy lỗi khởi động (trong trường hợp của chúng tôi, một đường dẫn nhật ký bị thiếu được sử dụng bởi supervisord). Tôi cho rằng hầu hết các lỗi khởi động container cũng sẽ xuất hiện ở đây.


3

Tôi không thể trả lời câu hỏi của bạn về cách làm cho đầu ra docker hoàn chỉnh hơn nhưng tôi có thể nói với bạn rằng regex tại chỗ thay thế một chuỗi trong tệp .so là một chút điên rồ: chuỗi chỉ có rất nhiều không gian được phân bổ cho nó và nếu bạn thay đổi tập tin offset của các mục khác, tập tin elf sẽ bị hỏng. Hãy thử chạy objdump hoặc readelf trên tệp .so của bạn sau khi chạy lệnh perl ( trước khi thay đổi LD_LIBRARY_PATH ) bên ngoài một container - đô la để donut nó hiện bị hỏng.

Lý do nó hoạt động trong vụ hack cần thiết đáng buồn này là vì "tmp" và "vv" có cùng độ dài chuỗi nên không có sự thay đổi nào. Xem xét thư mục / dkr hoặc tương tự nếu bạn không muốn sử dụng / tmp.

Nếu bạn PHẢI thực hiện phương pháp này và các đường dẫn mong muốn của bạn không thể thay đổi, hãy xây dựng lại thư viện và thay đổi đường dẫn mặc định cho / etc / hosts trong nguồn. Hoặc tốt hơn, khi xây dựng sửa đổi của bạn đổi libnss_files.sotên nó thành một cái gì đó giống như libnss_altfiles.sovà thay đổi nsswitch.confđể sử dụng hosts: altfileskhi bắt đầu bộ chứa docker của bạn (trừ khi docker đã gắn kết nsswitch.conf, thì bạn không thể thay đổi nó). Điều này sẽ cho phép bạn có libnss_altfiles.so song song với các thư viện bình thường của bạn trong hệ thống cơ sở. Nếu docker không gắn kết nsswitch.conf, hãy để lại một bản sao libnss_files.so được xây dựng lại trong thư mục / lib-override của bạn đã sẵn sàng để được tải bởi LD_LIBRARY_PATH.

Khi đề phòng, các nhị phân suid / sgid bỏ qua LD_LIBRARY_PATH và LD_PRELOAD, vì vậy một số nội dung sẽ bị hỏng (đọc: quay lại sử dụng mặc định / etc / hosts) nếu bạn sử dụng các biến đó.


Cảm ơn rất nhiều vì cái nhìn sâu sắc tuyệt vời ... Tôi đã quá nhanh và xem bây giờ chuyện gì đang xảy ra. Tôi vẫn không biết tại sao việc lấy chỉ số cần giải quyết máy chủ (ls -l) trong khi danh sách tệp đơn giản (ls), không ...
estani

0

Đôi khi, bạn có thể tìm thấy các thông báo lỗi hữu ích bằng cách sshing vào nút chạy trình nền docker và sau đó thực hiện:

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

Trên 'Phiên bản cộng đồng Docker' trên Mac OS, bạn có thể kết nối với docker vm bằng cách thực hiện:

$  screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.