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

사용 nsenterhttps://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.