Docker 컨테이너의 파일 시스템 탐색


651

도커와 함께 컨테이너 내부에서 발생하는 일이나 그 안에 존재하는 파일을 이해해야한다는 것을 알았습니다. 한 가지 예는 docker index에서 이미지를 다운로드하는 것입니다. 이미지에 포함 된 단서가 없으므로 응용 프로그램을 시작할 수 없습니다.

이상적인 것은 이것들이나 그와 동등한 것으로 ssh 할 수 있다는 것입니다. 이것을 할 수있는 도구가 있습니까, 아니면 내가 이것을 할 수 있어야한다고 생각하는 docker에 대한 개념화가 잘못 되었습니까?


13
Docker의 최신 버전에서는 다음과 같은 것이 가능합니다 docker exec <container> bash. 따라서 컨테이너 내부에서 쉘을 열면됩니다.
— dashohoxha

7
컨테이너에서 bash를 실행하는 것은 bash가 컨테이너 내부에 설치된 경우에만 작동합니다.
— Christopher Thomas

7
마찬가지로 다음 docker exec <container> ls <dir path>과 같은 작업을 수행 할 수 있습니다 docker exec <container> cat <file path>. 그러나 bash의 경우 -it옵션을 추가하십시오 .
— 노암 마 노스


3
@ChristopherThomas, 정확히. 이 때문에 docker image save image_name > image.tar@ Gaurav24의 응답에 표시된 것처럼 이 작업을 수행하는 유일한 방법이 있음을 알았습니다.
— Jaime Hablutzel

답변:


736

UPDATE
가장 쉬운 방법 : 고정 표시기 간부를 사용하여

Docker 버전 1.3 이상은와 exec유사한 동작을 지원합니다 nsenter. 이 명령은 이미 실행중인 컨테이너에서 새 프로세스를 실행할 수 있습니다 (컨테이너에는 PID 1 프로세스가 이미 실행 중이어야 함). /bin/bash컨테이너 상태를 탐색하기 위해 실행할 수 있습니다 .

docker exec -t -i mycontainer /bin/bash

Docker 명령 행 설명서를 참조하십시오.

다른 방법 1
스냅 샷

컨테이너 파일 시스템을 다음과 같이 평가할 수 있습니다.

# find ID of your running container:
docker ps

# create image (snapshot) from container filesystem
docker commit 12345678904b5 mysnapshot

# explore this filesystem using bash (for example)
docker run -t -i mysnapshot /bin/bash

이런 식으로 정확한 시간에 실행중인 컨테이너의 파일 시스템을 평가할 수 있습니다. 컨테이너가 여전히 실행 중이며 향후 변경 사항이 포함되지 않습니다.

나중에 실행중인 컨테이너의 파일 시스템에는 영향을 미치지 않습니다.를 사용하여 스냅 샷을 삭제할 수 있습니다.

docker rmi mysnapshot

대체 방법 2
ssh

지속적인 액세스가 필요한 경우 컨테이너에 sshd를 설치하고 sshd 데몬을 실행할 수 있습니다.

 docker run -d -p 22 mysnapshot /usr/sbin/sshd -D

 # you need to find out which port to connect:
 docker ps

이렇게하면 ssh를 사용하여 앱을 실행할 수 있습니다 (원하는 것을 연결하고 실행하십시오).

업데이트 : 대체 방법 3
nsenter

사용 nsenter은 https://web.archive.org/web/20160305150559/http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/를 참조 하십시오.

짧은 버전은 다음과 같습니다. nsenter를 사용하면 해당 컨테이너가 SSH 또는 특수 목적 데몬을 실행하지 않더라도 기존 컨테이너로 쉘을 가져올 수 있습니다.


6
그러나 파일에 액세스해야하는 경우 "docker cp"명령을 사용하십시오. 사용법 : docker cp CONTAINER : PATH HOSTPATH ​​컨테이너 파일 시스템에서 호스트 경로로 파일 / 폴더를 복사하십시오. 경로는 파일 시스템의 루트를 기준으로합니다. #> docker cp 7bb0e258aefe : / etc / debian_version. #> docker cp blue_frog : / etc / hosts입니다.
— Amos Folarin

4
옵션 4는 맨 위로 이동하여 이름을 변경해야합니다 Option 1.
— automorphic

5
@JanusTroelsen 쉘이 없다면 설치할 수 있습니다 – 예를 들어 alpine linux를위한 dockerfile (실제로 쉘이 없습니다) : RUN apk update && apk add bash(size : ~ 4MB)
— Kamil Kiełczewski

2
내 경험상 Docker exec의 제한 사항은 명령을 실행중인 컨테이너 또는 진입 점으로 추가해야한다는 것입니다. 따라서 중지 된 컨테이너는이 방법의 범위를 벗어납니다.
— Webwoman

1
윈도우의 리눅스 쉘을 사용하려면docker exec -t -i mycontainer /bin/sh
— Jason Masters

266

업데이트 : 탐험 중!

이 명령을 사용 하면 실행중인 도커 컨테이너 를 탐색 할 수 있습니다 .

docker exec -it name-of-container bash

docker-compose에서 이에 해당하는 내용은 다음과 같습니다.

docker-compose exec web bash

(이 경우 web은 서비스 이름이며 기본적으로 tty가 있습니다.)

당신이 안으로 들어가면 :

ls -lsa

또는 다음과 같은 다른 bash 명령 :

cd ..

이 명령을 사용 하면 도커 이미지 를 탐색 할 수 있습니다 .

docker run --rm -it --entrypoint=/bin/bash name-of-image

일단 안으로 :

ls -lsa

또는 다음과 같은 다른 bash 명령 :

cd ..

-it대화 형 및 tty 의 약자.


이 명령을 사용 하면 실행중인 도커 컨테이너 또는 이미지 를 검사 할 수 있습니다 .

docker inspect name-of-container-or-image

이 작업을 수행하고 싶 bash거나sh 있습니다. json return에서 entrypoint 또는 cmd를 찾으십시오.

docker exec documentation 참조

docker-compose exec 문서를 참조하십시오

docker inspect documentation 참조


1
이것은 매우 유용합니다, 감사합니다! 도커 이미지 파일 구조에 포함 된 파일을 응용 프로그램으로 드래그 앤 드롭해야하지만 GUI 형식으로 열지 않으면 불가능합니다. 어떻게 해결할 수 있습니까?
— Arkya Chatterjee

2
이것은 bash가 설치된 컨테이너에서만 작동한다는 것이 분명합니다.
— 소프트웨어 엔지니어

2
Windows 컨테이너 / Powershell에서이 작업을 수행하는 방법을 찾는 사람은 다음 명령을 사용하십시오. docker exec -ti <name> powershell( source )
— ssell

1
@ssell 내 컨테이너 / 이미지에는 어떤 이유로 든 powershell이 ​​없었으므로 제대로 docker exec -ti <name> cmd작동했습니다. 그리고 나와 같은 다른 초보자의 경우 컨테이너 인스턴스 이름 docker ps(070494393ca5와 같은 이름)을 사용자가 할당 한 읽기 쉬운 이름 대신 사용하십시오.
— Simon_Weaver


162

컨테이너가 멈췄거나 쉘이없는 경우 (예 : 설치 안내서에hello-world 언급 되거나alpine traefik ) 파일 시스템을 탐색하는 유일한 방법 일 수 있습니다.

컨테이너의 파일 시스템을 tar 파일로 보관할 수 있습니다 :

docker export adoring_kowalevski > contents.tar

또는 파일을 나열하십시오.

docker export adoring_kowalevski | tar t

이미지에 따라 시간과 디스크 공간이 걸릴 수 있습니다.


12
표준 UNIX 도구가 설치되지 않은 컨테이너의 내용을 나열하고 싶었습니다. export위 예제 의 변형이 그 자리를 hit습니다 :docker export adoring_kowalevski | tar tf -
— berto

3
경고 : 경고 : 많은 양 의 데이터 (> GB)를 내보내고 시간이 오래 걸릴 수 있습니다.
— 빈스 Bowdren

5
@berto는 엄청난 일이 아니지만 f -명령 끝에 at 가 필요하지는 않습니다 . tar는 기본적으로 표준 입력에서 읽습니다. 간단하게 docker export adoring_kowalevski | tar t작동합니다.
— Shaun Bouckaert

단순할수록 좋습니다. 대단해, 팁 주셔서 감사합니다! 🙌🏽
— berto

1
@ShaunBouckaert의 기본값 tar f은 구성에 따라 다릅니다. 한 부분은 TAPE환경 변수입니다. 다른 것은 빌드의 일부로 제어됩니다. 결과적으로 stdin 을 읽 거나 stdout을 쓰지 않는다고 가정해야 하지만 항상 명시 적으로 명시해야합니다.
— roaima

42

컨테이너의 파일 시스템은 docker의 데이터 폴더에 있으며 일반적으로 / var / lib / docker에 있습니다. 실행중인 컨테이너 파일 시스템을 시작하고 검사하려면 다음을 수행하십시오.

hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash

그리고 현재 작업 디렉토리는 컨테이너의 루트입니다.


3
여기에는 마운트 된 볼륨이 포함되지 않습니다.
— hwjp

34

컨테이너 생성 전 :

컨테이너 안에 장착 된 이미지의 구조를 탐색하려면 다음을 수행하십시오.

sudo docker image save image_name > image.tar
tar -xvf image.tar

이것은 이미지의 모든 레이어와 json 파일에 존재하는 구성의 가시성을 제공합니다.

컨테이너 생성 후 :

이를 위해 위의 답변이 이미 많이 있습니다. 이 작업을 선호하는 방법은 다음과 같습니다.

docker exec -t -i container /bin/bash


여기서 컨테이너 내에서 bash를 실행하면 이미지와 동일한 아키텍처를 가진 시스템에서 bash를 실행하는 경우에만 작동한다는 점을 언급해야합니다. PC에서 raspberry pi의 이미지 파일 시스템을 들여다 보려고하면 bash 트릭이 작동하지 않습니다.
— Maxim Kulkin 2016 년

@MaximKulkin 정말요? 컨테이너가 Linux이면 bash를 사용할 수있는 경우 호스트가 무엇이든 중요하지 않습니다. 아마도 당신은 Windows 컨테이너를 생각하고 있습니까?
— Thorbjørn Ravn Andersen

26

컨테이너가 실제로 시작될 때 가장 혐오스러운 답변이 효과가 있지만 실행할 수 없을 때 컨테이너에서 파일을 복사하려는 경우 예를 들어 이전에 저를 저장했습니다.

docker cp <container-name>:<path/inside/container> <path/on/host/>

docker cp ( link ) 덕분에 파일 시스템의 다른 부분처럼 컨테이너에서 직접 복사 할 수 있습니다. 예를 들어, 컨테이너 내부의 모든 파일을 복구합니다.

mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/

재귀 적으로 복사하도록 지정할 필요는 없습니다.


6
왜 +1이 더 이상 없습니까! 확실히 가장 좋은 방법
— Nicholas DiPiazza

tar를 통해 내보내는 것보다 훨씬 간단합니다. 심볼릭 링크를 통해 파일을 얻으려면 -L을 사용해야했습니다. 컨테이너를 실행할 필요가 없습니다!
— MKaama

17

에 우분투 14.04 실행 도커 1.3.1 , 나는 다음과 같은 디렉토리에있는 호스트 시스템의 컨테이너 루트 파일 시스템을 발견 :

/var/lib/docker/devicemapper/mnt/<container id>/rootfs/

전체 도커 버전 정보 :

Client version: 1.3.1
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 4e9bbfa
OS/Arch (client): linux/amd64
Server version: 1.3.1
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 4e9bbfa

매력처럼 작동합니다 : name = <name> dockerId = $ (docker inspect -f {{.Id}} $ name) / var / lib / docker / devicemapper / mnt / $ dockerId / rootfs /
— Florent

3
우분투 16.10 및 도커 1.12.1에서는 불행히도 더 이상 그렇지 않습니다 ( devicemapper디렉토리 없음 ). 파일은 아래에 /var/lib/docker/overlay/<a sha256 apparently/<upper or merged>/...있습니다. 파일에 액세스하는 것이 얼마나 휴대용 / 안전한지 잘 모르겠습니다
— WoJ

1
1.10부터 Docker는 이전에 계층 및 컨테이너 식별자 모두에서와 같이 무작위로 생성 된 UUID를 사용하지 않는 새로운 컨텐츠 주소 지정 가능 스토리지 모델을 도입했습니다. 새 모델에서는 레이어 ID의 보안 콘텐츠 해시로 대체됩니다. 따라서이 방법은 더 이상 작동하지 않습니다.
— Artem Dolobanko

이것은 휴대용이 아니며 스토리지 드라이버 의 선택에 크게 의존 합니다 . 솔루션이 direct-lvm예를 들어 작동하는지 확실하지 않습니다 .
— rustyx

14

사용해보십시오

docker exec -it <container-name> /bin/bash

bash가 구현되지 않았을 수 있습니다. 당신이 사용할 수있는

docker exec -it <container-name> sh

12

나는 aufs / devicemapper에 독립적 인 또 다른 더러운 트릭을 사용합니다.

컨테이너가 실행중인 명령을보고 예를 들어 docker ps 아파치이거나 java다음과 같이하면됩니다.

sudo -s
cd /proc/$(pgrep java)/root/

용기 안에 들어 있습니다.

기본적으로 /proc/<PID>/root/컨테이너가 프로세스를 실행하는 한 루트 CD를 폴더에 넣을 수 있습니다 . 심볼릭 링크는 해당 모드를 사용하는 것이 의미가 없습니다.


이 방법에 대한 추가 정보는 여기 : superuser.com/a/1288058/195840
— Eduardo Lucio

12

컨테이너가 실제 Linux 시스템이 아닌 경우를 제외하고 가장 많이 투표 된 답변이 좋습니다.

많은 컨테이너 (특히 이동 기반 컨테이너)에는 표준 바이너리 (아니오 /bin/bash또는 /bin/sh)가 없습니다 . 이 경우 실제 컨테이너 파일에 직접 액세스해야합니다.

매력처럼 작동합니다.

name=<name>
dockerId=$(docker inspect -f {{.Id}} $name)
mountId=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$dockerId/mount-id)
cd /var/lib/docker/aufs/mnt/$mountId

참고 : 루트로 실행해야합니다.


더 이상 작동하지 않습니다. devicemapper 폴더가 없습니다.
— 0xcaff

답변이 오래된 사람들이 정리하면 좋을 것입니다.
— Matthew Purdon

2
새로운 도커 스토리지 구조와 일치하도록 명령을 업데이트했습니다.
— Florent

10

내 경우에는를 제외하고 컨테이너에서 쉘이 지원되지 않았습니다 sh. 그래서 이것은 매력처럼 작동했습니다.

docker exec -it <container-name> sh


5

이미지에 대한 bash 세션이 시작됩니다.

도커 실행 --rm -it --entrypoint = / bin / bash


1
이 기본 엔트리 포인트가 실행되지 않을 때 유용합니다
— parsethis

4

나에게 이것은 잘 작동합니다 ( / var / lib / docker / 디렉토리를 지적한 마지막 주석 덕분에 ).

chroot /var/lib/docker/containers/2465790aa2c4*/root/

여기서 2465790aa2c4 는 실행중인 컨테이너의 짧은 ID ( docker ps 로 표시됨 )와 별표입니다.


4

Docker의 최신 버전에서는 docker exec [container_name]컨테이너 내부에서 셸을 실행하는 Docker를 실행할 수 있습니다.

컨테이너의 모든 파일 목록을 얻으려면 실행하십시오. docker exec [container_name] ls


1
나는 이것을 시도했지만 작동하지 않았다. 위의 Khalil Gharbaoui의 제안은 효과가있었습니다.
— Nick

그것은 나를 위해 일했다. 이미지 이름 대신 컨테이너 ID를 사용해 볼 수도 있습니다
— Diwann

4

docker aufs 드라이버의 경우 :

스크립트는 컨테이너 루트 디렉토리를 찾습니다 (docker 1.7.1 및 1.10.3 테스트)

if [ -z "$1" ] ; then
 echo 'docker-find-root $container_id_or_name '
 exit 1
fi
CID=$(docker inspect   --format {{.Id}} $1)
if [ -n "$CID" ] ; then
    if [ -f  /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id ] ; then
        F1=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id)
       d1=/var/lib/docker/aufs/mnt/$F1
    fi
    if [ ! -d "$d1" ] ; then
        d1=/var/lib/docker/aufs/diff/$CID
    fi
    echo $d1
fi

4

기존 답변 중 컨테이너가 종료되었거나 다시 시작할 수 없으며 / 또는 쉘이 설치되지 않은 컨테이너 (예 : 무분별한 컨테이너)의 경우를 다루지 않습니다. Docker 호스트에 루트 액세스 권한이있는 한 작동합니다.

실제 수동 검사를 위해서는 먼저 레이어 ID를 찾으십시오.

docker inspect my-container | jq '.[0].GraphDriver.Data'

출력에서 다음과 같이 보일 것입니다

"MergedDir": "/var/lib/docker/overlay2/03e8df748fab9526594cfdd0b6cf9f4b5160197e98fe580df0d36f19830308d9/merged"

컨테이너 파일 시스템의 현재 보이는 상태를 찾으려면이 폴더 (루트로)를 탐색하십시오.


3

이 답변은 컨테이너가 실행 중이 아니더라도 도커 볼륨 파일 시스템을 탐색하려는 사람들과 같은 사람들에게 도움이 될 것입니다.

실행중인 도커 컨테이너를 나열하십시오.

docker ps

=> 컨테이너 ID "4c721f1985bd"

로컬 물리적 시스템에서 도커 볼륨 마운트 지점을 확인하십시오 ( https://docs.docker.com/engine/tutorials/dockervolumes/ ).

docker inspect -f {{.Mounts}} 4c721f1985bd

=> [{/ tmp / container-garren / tmp true rprivate}]

이것은 로컬 물리적 시스템 디렉토리 / tmp / container-garren이 / tmp 도커 볼륨 대상에 매핑되었음을 나타냅니다.

로컬 물리적 시스템 디렉토리 (/ tmp / container-garren)를 아는 것은 도커 컨테이너가 실행 중인지 여부에 관계없이 파일 시스템을 탐색 할 수 있음을 의미합니다. 이것은 컨테이너가 실행되지 않은 후에도 지속되지 않아야 할 잔여 데이터가 있음을 파악하는 데 중요했습니다.


1
이것은 컨테이너 내부에 볼륨으로 마운트 된 로컬 디렉토리 만 찾지 만 컨테이너의 전체 파일 시스템에 대한 액세스는 허용하지 않습니다.
— Bojan Komazec

3

또 다른 트릭은 원자 도구 를 사용하여 다음과 같은 작업을 수행하는 것입니다.

mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt

Docker 이미지는 검사하기 위해 / path / to / mnt 에 마운트됩니다 .


그러나 이것이 작동하려면 특별히 컨테이너를 만들어야합니다. 어쩌면 당신은 이것을 경고로 추가해야합니다. 대부분의 사람들이 그것을 솔루션으로 팀 / 회사에 팔지
— 못할

3

리눅스 전용

내가 사용하는 가장 간단한 방법은 proc dir을 사용하는 것인데, 도커 컨테이너 파일을 검사하려면 컨테이너가 실행 중이어야합니다.

  1. 컨테이너의 프로세스 ID (PID)를 찾아 변수에 저장

    PID = $ (docker inspect -f '{{.State.Pid}}'컨테이너-이름-여기)

  2. 컨테이너 프로세스가 실행 중인지 확인하고 변수 이름을 사용하여 컨테이너 폴더로 이동하십시오.

    cd / proc / $ PID / root

이 긴 명령을 사용하여 PID 번호를 찾지 않고 디렉토리를 통과하려면

cd /proc/$(docker inspect -f '{{.State.Pid}}' your-container-name-here)/root

팁 :

컨테이너 내부에 들어간 후에는 서비스 중지 또는 포트 번호 변경과 같은 모든 작업이 컨테이너의 실제 프로세스에 영향을 미칩니다.

그것이 도움이되기를 바랍니다.

노트 :

이 방법은 컨테이너가 여전히 실행중인 경우에만 작동합니다. 그렇지 않으면 컨테이너가 중지되거나 제거 된 경우 디렉토리가 더 이상 존재하지 않습니다.


2

컨테이너 내부에서 일어나는 일을 이해하는 가장 좋은 방법은 다음과 같습니다.

  1. 노출 -p 8000

    docker run -it -p 8000:8000 image
    
  2. 그 안에 서버를 시작

    python -m SimpleHTTPServer
    

2

이미 실행중인 컨테이너의 경우 다음을 수행 할 수 있습니다.

dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])

cd /var/lib/docker/btrfs/subvolumes/$dockerId

해당 디렉토리로 들어가려면 루트 여야합니다. 루트가 아닌 경우 명령을 실행하기 전에 'sudo su'를 시도하십시오.

편집 : v1.3 이후에는 Jiri의 답변을 참조하십시오.


4
쉘을 시작하는 다른 suid 프로그램을 시작하는 suid 프로그램을 실행할 이유가 거의 없기 때문에 "sudo su"보다는 "sudo -i"에 대해 부분적으로 강합니다. 중간 사람을 잘라내십시오. :)
— dannysauer

당신의 대답은 매우 좋으며, 길만이 아닙니다. 피어스 봇의 경로를 사용해야합니다.
— Florent

2

Docker v19.03을 사용하는 경우 다음 단계를 수행하십시오.

# find ID of your running container:

  docker ps

# create image (snapshot) from container filesystem

  docker commit 12345678904b5 mysnapshot

# explore this filesystem 

  docker run -t -i mysnapshot /bin/sh

1

AUFS 스토리지 드라이버를 사용하는 경우 내 docker-layer 스크립트를 사용하여 컨테이너의 파일 시스템 루트 (mnt) 및 readwrite 레이어를 찾을 수 있습니다.

# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt      : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f

2018-03-28 편집 :
docker-layer가 docker-backup 으로 대체되었습니다.


1

docker exec명령은 여러 경우에 도움이 될 수 있습니다 실행중인 컨테이너에서 명령을 실행합니다.

사용법 : docker exec [옵션] 컨테이너 명령 [ARG ...]

실행중인 컨테이너에서 명령을 실행하십시오.

옵션 :
  -d, --detach 분리 모드 : 백그라운드에서 명령 실행
      --detach-keys string 분리를위한 키 시퀀스를 재정의합니다.
                             컨테이너
  -e, --env list 환경 변수 설정
  -i, --interactive 연결되어 있지 않아도 STDIN을 열어 둡니다
      --privileged 명령에 확장 권한을 부여합니다
  -t, --tty 의사 TTY 할당
  -u, --user string 사용자 이름 또는 UID (형식 :
                             [:])
  -w, --workdir string 컨테이너 내의 작업 디렉토리

예를 들면 다음과 같습니다.

1) bash에서 실행중인 컨테이너 파일 시스템에 액세스 :

docker exec -it containerId bash 

2) 필요한 권한을 가질 수 있도록 루트로 실행중인 컨테이너 파일 시스템에 대한 bash 액세스 :

docker exec -it -u root containerId bash  

이것은 컨테이너에서 루트로 일부 처리를 수행 할 수있는 경우 특히 유용합니다.

3) 특정 작업 디렉토리로 bash에서 실행중인 컨테이너 파일 시스템에 액세스 :

docker exec -it -w /var/lib containerId bash 

0

다음과 같이 컨테이너 내부에서 bash를 실행할 수 있습니다. $ docker run -it ubuntu /bin/bash

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.