programing

도커 - 이미지에서 호스트로 파일을 복사하려면 어떻게 해야 합니까?

testmans 2023. 10. 22. 19:44
반응형

도커 - 이미지에서 호스트로 파일을 복사하려면 어떻게 해야 합니까?

제 질문은 컨테이너에서 호스트로 파일을 복사하는 이 질문과 관련된 것입니다. 저는 종속성을 가져오고 소스에서 빌드 아티팩트를 컴파일하며 실행 파일을 실행하는 도커 파일이 있습니다.또한 빌드 아티팩트를 복사하고 싶습니다(제 경우에는.zip에 의해 제작된sbt dist'../target/'에서 하지만 이 질문은 항아리, 이진법 등에도 적용된다고 생각합니다.

docker cp이미지가 아닌 컨테이너에서 작동합니다. 파일을 꺼내려면 컨테이너를 시작해야 합니까?대본을 보고 달려봤는데요./bin/bash백그라운드에서 대화형 모드로 파일을 복사한 다음 컨테이너를 죽입니다. 하지만 이건 질긴 것 같군요.더 좋은 방법이 있습니까?

다른 한편으로, 나는 그것을 푸는 것을 피하고 싶습니다..tar실행 후 줄 세우기docker save $IMAGENAME한 개의 파일을 꺼내기 위해서입니다(그러나 그것은 지금 당장 가장 간단한 옵션으로 보입니다).

도커 볼륨을 사용합니다. 예:

docker run -v hostdir:out $IMAGENAME /bin/cp/../blah.zip /out

하지만 난 달려가고 있습니다.boot2dockerOSX에서 직접 Mac 호스트 파일 시스템에 쓰는 방법을 모릅니다(Boot2docker VM 내에 읽기-쓰기 볼륨이 마운트되어 있으므로 스크립트를 쉽게 공유하여 추출할 수 없음).blah.zip다른 사람들과 함께 찍은 사진에서생각은?

이미지에서 파일을 복사하려면 임시 컨테이너를 만들고 해당 컨테이너에서 파일을 복사한 다음 삭제합니다.

id=$(docker create image-name)
docker cp $id:path - > local-tar-file
docker rm -v $id

유감스럽게도 도커 이미지에서 직접 파일을 복사하는 방법은 없는 것 같습니다.먼저 컨테이너를 만든 다음 컨테이너에서 파일을 복사해야 합니다.

그러나 이미지에 다음과 같은 정보가 포함되어 있는 경우catcommand(많은 경우 가능), 한 번의 명령으로 수행할 수 있습니다.

docker run --rm --entrypoint cat yourimage  /path/to/file > path/to/destination

이미지에 포함되지 않는 경우cat, 단순히 용기를 만들고 사용합니다.docker cp이고르의 대답에 제시된 명령어.

docker cp $(docker create --name tc registry.example.com/ansible-base:latest):/home/ansible/.ssh/id_rsa ./hacked_ssh_key && docker rm tc

순수한 도커 기능을 기반으로 한 원라인 솔루션을 제공하고자 함(부시 필요 없음)

edit: 이 솔루션에서는 컨테이너를 실행할 필요도 없습니다.

edit2: @Jonathan Dumaine for --rm 덕분에 컨테이너가 제거될 수 있었습니다. 이전 명령으로 이미 제거된 무언가를 어딘가에서 복사하는 것이 비논리적으로 들렸기 때문에 시도하지 않았지만 시도해 보았고 작동했습니다.

edit3 : 확인한 코멘트 --rm이 예상대로 작동하지 않아 컨테이너가 절대 실행되지 않아 컨테이너를 제거하지 않아 생성된 컨테이너를 이후 삭제하는 기능을 추가하였습니다(--name tc= temporary- container).

편집 4: 이 오류가 나타났는데, 도커에 버그가 있는 것 같습니다. 왜냐하면 그것은 a-z에 있고 이것은 몇 달 전에 일어나지 않았기 때문입니다.

Error response from daemon: Invalid container name (t), only [a-zA-Z0-9][a-zA-Z0-9_.-] are allowed

훨씬 빠른 옵션은 실행 중인 컨테이너에서 마운트된 볼륨으로 파일을 복사하는 것입니다.

docker run -v $PWD:/opt/mount --rm --entrypoint cp image:version /data/libraries.tgz /opt/mount/libraries.tgz

리얼 0m0.446s

** VS **

docker run --rm --entrypoint cat image:version /data/libraries.tgz > libraries.tgz

리얼 0m9.014s

부모님 댓글에 고양이 사용법이 이미 나와 있습니다.타르도 비슷한 방식으로 사용할 수 있습니다.

docker run yourimage tar -c -C /my/directory subfolder | tar x

이 문제에 대한 또 다른 (짧은) 답변:

docker run -v $PWD:/opt/mount --rm -ti image:version bash -c "cp /source/file /opt/mount/"

업데이트 - @Elytscha Smith가 언급한 대로 이미지에 bash가 내장된 경우에만 작동합니다.

도커 당김을 이용한 첫 번째 당김 도커 이미지

docker pull <IMG>:<TAG>

그런 다음 docker create 명령을 사용하여 컨테이너를 만들고 컨테이너 id를 변수로 저장합니다.

img_id=$(docker create <IMG>:<TAG>)

자, 이제 실행해보세요.docker cp폴더 및 파일을 도커 컨테이너에서 호스트로 복사하는 명령

docker cp $img_id:/path/in/container /path/in/host

파일/폴더가 이동되면 도커름을 사용하여 컨테이너를 삭제합니다.

docker rm -v $img_id

질문 세부 정보에 대한 직접적인 답변은 아니지만 일반적으로 이미지를 풀면 이미지가 시스템에 저장되고 모든 파일도 마찬가지입니다.로컬 도커 설치의 스토리지 드라이버에 따라 이러한 파일은 일반적으로/var/lib/docker/overlay2(requires 루트 액세스).overlay2현재 가장 일반적인 스토리지 드라이버여야 하지만 경로가 다를 수 있습니다.

이미지와 연관된 레이어는 다음을 사용하여 찾을 수 있습니다.$ docker inspect image IMAGE_NAME:TAG, 찾아보다GraphDriver기여하다.
적어도 내 로컬 환경에서는 이미지와 연관된 모든 레이어를 빠르게 볼 수 있는 다음 기능도 수행합니다.
docker inspect image IMAGE_NAME:TAG | jq ".[0].GraphDriver.Data"

이 중 하나에diff디렉토리, 원하는 파일을 찾을 수 있습니다.
따라서 이론적으로는 임시 컨테이너를 만들 필요가 없습니다.물론 이 솔루션은 상당히 불편합니다.

업데이트 - tar 파일이 없는 더 나은 버전이 있습니다.

$id = & docker create image-name
docker cp ${id}:path .
docker rm -v $id

Igor Bukanov의 답변의 오래된 답변 PowerShell 변형:

$id = & docker create image-name
docker cp ${id}:path - > local-file.tar
docker rm -v $id

당신은 기본적으로 이미 최선의 해결책을 가지고 있었습니다.컨테이너에 파일을 복사하게 한 다음 작업이 완료되면 해당 파일을 제거합니다.

파일을 복사합니다./inside/container/사용자의 기계에/path/to/hostdir/.

docker run --rm -v /path/to/hostdir:/mnt/out "$IMAGENAME" /bin/cp -r /inside/container/ /mnt/out/

저는 맥OS에서 boot2docker를 사용하고 있습니다."docker cp"를 기반으로 한 스크립트는 휴대가 가능하다고 장담할 수 있습니다.모든 명령은 boot2docker 내부에서 릴레이되지만 바이너리 스트림은 Mac에서 실행되는 도커 명령줄 클라이언트로 다시 릴레이되기 때문입니다.따라서 도커 클라이언트의 쓰기 작업은 서버 내부에서 실행되고 실행 중인 클라이언트 인스턴스에 다시 기록됩니다!

제공하는 모든 도커 컨테이너와 도커 볼륨에 대한 백업 스크립트를 공유하고 있으며, boot2docker를 사용하여 리눅스 및 MacOS에서 백업 스크립트를 테스트하고 있습니다.플랫폼 간에 백업을 쉽게 교환할 수 있습니다.기본적으로 스크립트 안에서 다음 명령을 실행하고 있습니다.

docker run --name=bckp_for_volume --rm --volumes-from jenkins_jenkins_1 -v /Users/github/jenkins/backups:/backup busybox tar cf /backup/JenkinsBackup-2015-07-09-14-26-15.tar /jenkins

새 busybox 컨테이너를 실행하고 jenkins_1이라는 이름으로 jenkins 컨테이너의 볼륨을 마운트합니다.전체 볼륨은 파일 백업/JenkinsBackup-2015-07-09-14-26-15.tar에 기록됩니다.

백업 또는 복원 스크립트를 조정하지 않고 리눅스 컨테이너와 맥 컨테이너 간에 아카이브를 이미 이동했습니다.이것이 당신이 원하는 것이라면, 당신은 전체 스크립트를 여기서 찾을 수 있습니다: blacklabelops/jenkins.

호스트의 로컬 경로를 컨테이너의 경로에 바인딩한 다음cp스크립트 끝에 있는 해당 경로에 대한 원하는 파일입니다.

$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app \
  nginx:latest

그러면 나중에 복사할 필요가 없습니다.

언급URL : https://stackoverflow.com/questions/25292198/docker-how-can-i-copy-a-file-from-an-image-to-a-host

반응형