도커 컨테이너 초기화를 어떻게 디버깅 할 수 있습니까? Dockerfile에 추가 한

컨테이너가 완벽하게 빌드되었지만 제대로 시작되지 않더라도 컨테이너에 문제가 있습니다. 원인은 Dockerfile에 추가 한 해결 방법입니다 (자체 구성 / 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

분명히 거기에 약간의 오류가 있지만 실행 중에도 커가 수행하는 작업에 대한 자세한 정보를 얻을 수있는 방법이 궁금합니다. 예를 들어 다음과 같이 작동합니다.

$ docker run image ls
usr bin ...

그러나 이것은하지 않습니다 :

$ docker run image ls -l
$

로그에 아무것도 없으며 대화 형 쉘을 호출 할 수 없습니다. 나는 strace를 사용하여 무슨 일이 일어나고 있는지 알 수 있지만 더 좋은 방법이 있기를 바랐습니다.

도커를보다 자세하게 설정할 수있는 방법이 있습니까?

편집 : Andrew D 덕분에 위의 코드에 문제가 있음을 알았습니다 (그의 대답을 이해할 수 있도록 남겨 두었습니다). 이제 문제는 여전히 어떻게 ls -l이 ls 가 실패했는지 왜 실패했는지에 대해 어떻게 이런 식으로 디버깅하거나 내부를 얻을 수 있습니까 ?

편집 : 내 경우에는 아니지만 -D = true 더 많은 출력을 줄 수 있습니다 …



답변

Docker events명령이 도움이 될 수 있고 Docker logs 명령은 이미지 시작에 실패한 후에도 로그를 가져올 수 있습니다.

먼저 docker events백그라운드에서 시작 하여 무슨 일이 일어나고 있는지 확인하십시오.

docker events&

그런 다음 실패한 docker run ...명령을 실행하십시오 . 그런 다음 화면에 다음과 같은 내용이 표시됩니다.

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

그런 다음 이전 메시지 또는 시작 명령의 출력에서 ​​시작 16 진수 ID를 얻을 수 있습니다. 그런 다음 logs 명령과 함께 사용할 수 있습니다.

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

실패한 이미지 시작에서 일부 출력이 표시됩니다.

@alexkb가 의견에서 제안한 것처럼 : docker events&컨테이너가 AWS ECS 서비스와 같은 것으로 지속적으로 다시 시작되면 문제가 될 수 있습니다. 이 시나리오에서는의 컨테이너 16 진수 ID를 로그에서 가져 오는 것이 더 쉬울 수 있습니다 /var/log/ecs/ecs-agent.log.<DATE>. 그런 다음 docker를 사용하십시오 logs <hex id>.


답변

지금까지 내가 찾은 최고는 다음과 같습니다.

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

새 쉘에서 클라이언트를 시작하면됩니다. 오해는 클라이언트가 실제로 아무것도하지 않는다고 생각하는 것이 었습니다. 잘 데몬과 통신하고 있기 때문에 클라이언트 를 디버깅 하고 싶지 않고 데몬 자체를 (일반적으로) 디버그 하고 싶습니다 .


답변

필자의 경우 -a(STDOUT / STDERR에 첨부) 플래그로 충분했습니다.

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

시작 오류 (이 경우에는 로그 경로가 누락 됨 supervisord)가 표시되었습니다. 대부분의 컨테이너 시작 오류가 여기에 표시된다고 가정합니다.


답변

도커 출력을보다 완벽하게 만드는 방법에 대한 귀하의 질문에 대답 할 수는 없지만 .so 파일에서 문자열을 대체하는 내부 정규식은 약간 미친 것입니다. 문자열에는 할당 된 공간이 너무 많으며 다른 항목의 파일 오프셋을 변경하면 엘프 파일이 손상됩니다. 컨테이너 외부 에서 perl 명령 ( LD_LIBRARY_PATH 변경 전 ) 을 실행 한 후 .so 파일에서 objdump 또는 readelf를 실행 해보십시오 .

이 슬프게 필요한 핵에서 작동하는 이유 는 “tmp”와 “etc”가 동일한 문자열 길이이므로 오프셋 변경이 없기 때문입니다. / tmp를 사용하지 않으려면 / dkr 디렉토리 또는 이와 유사한 것을 고려하십시오.

이 방법을 사용해야하고 원하는 경로를 변경할 수없는 경우 라이브러리를 다시 빌드하고 소스에서 / etc / hosts의 기본 경로를 변경하십시오. 또는 수정 된 libnss_files.so이름을 바꾸면 도커 컨테이너를 시작할 때 사용하도록 libnss_altfiles.so변경 nsswitch.conf하고 사용하도록 변경 hosts: altfiles하십시오 (도 커가 마운트 된 nsswitch.conf를 바인딩하지 않으면 변경할 수 없습니다). 그러면 libnss_altfiles.so를 기본 시스템의 일반 라이브러리와 함께 사용할 수 있습니다. docker가 nsswitch.conf를 바인드 마운트하면 / lib-override 디렉토리에 재구성 된 libnss_files.so의 사본을 LD_LIBRARY_PATH로로드 할 수 있도록 남겨 두십시오.

결과적으로 suid / sgid 바이너리는 LD_LIBRARY_PATH 및 LD_PRELOAD를 무시하므로 해당 변수를 사용하면 일부 항목이 중단됩니다 (읽기 : 기본 / etc / hosts 사용으로 돌아 가기).


답변

때로는 docker 데몬을 실행하는 노드로 sshing 한 다음 다음을 수행하여 유용한 오류 메시지를 찾을 수 있습니다.

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

Mac OS의 ‘Docker Community Edition’에서 다음을 수행하여 docker vm에 연결할 수 있습니다.

$  screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty


답변