bestsource

데이터 전용 볼륨을 한 호스트에서 다른 호스트로 포팅하는 방법은 무엇입니까?

bestsource 2023. 8. 17. 21:35
반응형

데이터 전용 볼륨을 한 호스트에서 다른 호스트로 포팅하는 방법은 무엇입니까?

볼륨 작업에 대한 도커 문서에서 설명한 대로 데이터 전용 컨테이너라는 개념이 있습니다. 이 컨테이너는 데이터 전용 컨테이너가 실제로 실행 중인지 여부에 관계없이 여러 개의 다른 컨테이너에 마운트할 수 있는 볼륨을 제공합니다.

기본적으로, 이것은 멋지게 들립니다.하지만 한 가지 이해가 안 되는 것이 있습니다.

이러한 볼륨(설명서에 나와 있듯이 이동성을 위해 호스트의 폴더에 명시적으로 매핑되지 않음)은 Docker가 호스트의 일부 내부 폴더에서 생성하고 관리합니다./var/docker/volumes/…).

이러한 볼륨을 사용하는 경우 호스트 간에 마이그레이션해야 합니다. 볼륨을 어떻게 이식합니까?FAICS에는 고유한 ID가 있습니다. 볼륨과 해당 데이터 전용 컨테이너를 새 호스트에 복사할 수 있습니까?복사할 파일을 확인하려면 어떻게 해야 합니까?아니면 Docker에 내장된 지원 중 아직 발견하지 못한 것이 있습니까?

공식 답변은 "데이터 볼륨 백업, 복원 또는 마이그레이션" 섹션에서 확인할 수 있습니다.

백업:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm 때 합니다.
  • --volumes-from DATADATA 컨테이너에서 공유하는 볼륨에 연결
  • -v $(pwd):/backup; 파일을 bind에 다음과 같이 .
  • busybox 이미지 - 유지관리에 . - - 속한에리적합지보은단순한▁-▁a적합관에리.
  • tar cvf /backup/backup.tar /data 디렉토리/data 파일에 되지 않은 .

복원:

# create a new data container
$ sudo docker create -v /data --name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

도커 문서의 공식 답변과 여기에 있는 상위 답변을 확장하면 다음 기능을 사용할 수 있습니다..bashrc또는.zshrc:

# backup files from a docker volume into /tmp/backup.tar.gz
function docker-volume-backup-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -czvf /backup/backup.tar.gz "${@:2}"
}

# restore files from /tmp/backup.tar.gz into a docker volume
function docker-volume-restore-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -xzvf /backup/backup.tar.gz "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie ls -lh "${@:2}"
}

# backup files from a docker volume into /tmp/backup.tar
function docker-volume-backup() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -cvf /backup/backup.tar "${@:2}"
}

# restore files from /tmp/backup.tar into a docker volume
function docker-volume-restore() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -xvf /backup/backup.tar "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox ls -lh "${@:2}"
}

은 백은다저니다에 됩니다./tmp저장된 백업 파일을 도커 호스트 간에 이동할 수 있습니다.

두 쌍의 백업/복원 별칭도 있습니다.압축과 데비안을 사용하는 것: jessie와 압축이 없지만 비지박스가 있는 것.백업할 파일이 크면 압축을 사용하는 것이 좋습니다.

볼륨을 tar로 내보내고 다른 시스템으로 전송할 수 있습니다.그리고 두 번째 기계에서 타르로 데이터를 가져옵니다.이는 볼륨의 구현 세부 정보에 의존하지 않습니다.

# you can list shared directories of the data container
docker inspect <data container> | grep "/vfs/dir/"

# you can export data container directory to tgz
docker run --cidfile=id.tmp --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgz

# clean up: remove exited container used for export and temporary file
docker rm `cat id.tmp` && rm -f id.tmp

유사한 사용 사례에 대해 도커-볼륨-스냅샷 명령을 방금 작성했습니다.이 명령은 tomasop의 답변을 기반으로 합니다.

명령으로,

  1. 스냅샷 생성
docker-volume-snapshot create <volume-name> snapshot.tar
  1. snapshot.tar를 다른 호스트로 이동합니다.
  2. 스냅샷 복원
docker-volume-snapshot restore snapshot.tar <volume-name>

여기에 IBM의 최신 툴을 추가하겠습니다. 이 툴은 실제로 한 컨테이너 호스트에서 다른 컨테이너 호스트로 볼륨 마이그레이션을 위해 만들어졌습니다.이것은 현재 진행 중인 프로젝트입니다.따라서 나중에 추가 기능이 있는 다른 버전을 찾을 수 있습니다.

Cargo는 최소한의 다운타임으로 컨테이너의 데이터와 함께 한 호스트에서 다른 호스트로 컨테이너를 마이그레이션하기 위해 개발되었습니다.Cargo는 Union 파일 시스템의 데이터 연합 기능을 사용하여 소스 및 대상 호스트에 걸쳐 통합된 데이터 뷰(주로 루트 파일 시스템)를 생성합니다.따라서 소스 루트 파일 시스템의 데이터가 온디맨드(COW(Copy-on-Write) 파티션을 사용하여) 또는 백그라운드(rsync)에서 느리게 대상 호스트로 복사될 때 Cargo는 대상 호스트에서 거의 즉시(밀리초 이내) 컨테이너를 시작할 수 있습니다.

중요한 점은 다음과 같습니다.

  • 서버가 마이그레이션 프로세스를 처리합니다.

프로젝트 링크는 다음과 같습니다.

https://github.com/nadgowdas/cargo

시스템이 서로 다른 VPC에 있거나 로컬 시스템에서/로 복사하려는 경우(나의 경우처럼) 내가 만든 dvsync를 사용할 수 있습니다.그것은 기본적으로 ngrok과 결합되어 있습니다.rsyncSSH를 통해 2개의 작은 이미지(둘 다 ~ 25MB)로 패키지화됩니다.먼시작다니합저를 시작합니다.dvsync-server에서 (할 경우 "" " " " " " (" " " " " " " " " " ")가 합니다.NGROK_AUTHTOKENngrok 대시보드에서 얻을 수 있음):

$ docker run --rm -e NGROK_AUTHTOKEN="$NGROK_AUTHTOKEN" \
  --mount source=MY_VOLUME,target=/data,readonly \
  quay.io/suda/dvsync-server

은 면러시수다있니습할을 할 수 있습니다.dvsync-client에서 "" " " " 를 합니다."합니다.DVSYNC_TOKEN서버에 표시됨:

docker run -e DVSYNC_TOKEN="$DVSYNC_TOKEN" \
  --mount source=MY_TARGET_VOLUME,target=/data \
  quay.io/suda/dvsync-client 

복사가 완료되면 클라이언트가 종료됩니다.이것은 도커 CLI, 컴포지트, 스웜, 쿠버네티스와도 작동합니다.

시스템 간에 SSH 연결을 설정할 수 있는 경우를 대비하여 다음과 같이 한 줄로 설명합니다.

docker run --rm -v <SOURCE_DATA_VOLUME_NAME>:/from alpine ash -c "cd /from ; tar -cf - . " | ssh <TARGET_HOST> 'docker run --rm -i -v <TARGET_DATA_VOLUME_NAME>:/to alpine ash -c "cd /to ; tar -xpvf - " '

크레딧은 Guido Diepen의 게시물로 갑니다.

저는 언급할 평판이 없기 때문에 여기에 답변을 추가합니다.위의 모든 답변이 저에게 도움이 되었지만, 저와 같은 다른 사람들도 문서의 내용을 복사하려고 할 것이라고 생각합니다.backup.tar줄을 지어.named docker volume협력자의 컴퓨터에서. 또는 도커 볼륨 설명서에서 이 문제에 대해 구체적으로 설명하지 않았습니다.

파일을 에 복사하려는 이유는 무엇입니까?

이것은 다음과 같은 시나리오에서 도움이 될 수 있습니다.named docker volume기존 내부에서 지정되었습니다.docker-compose.yml일부 컨테이너에서 사용할 파일입니다.

의 내용 복사backup.tar의 상태가.named docker volume

  1. 호스트 시스템에서 수락된 응답 또는 도커 볼륨 설명서의 단계에 따라backup.tar파일을 저장하고 일부 리포지토리에 밀어넣습니다.

  2. 당기다.backup.tar저장소에서 공동작업자의 컴퓨터로 이동합니다.

  3. 공동작업자의 컴퓨터에서 임시 컨테이너와 명명된 도커 볼륨을 생성합니다.

docker run -v named_docker_volume:/dbdata --name temp_db_container ubuntu /bin/bash

  • --name temp_db_container다음 컨테이너를 만듭니다.temp_db_container

  • ubuntu /bin/bash사용ubuntu빌드할 이미지temp_db_container을 시작으로/bin/bash

  • -v named_docker_volume:/dbdata마운트 더/dbdata의 폴더.temp_db_container라고 불리는 도커 볼륨으로named_docker_volume이 특별한 이름의 볼륨을 사용합니다.named_docker_volume당사에 지정된 볼륨 이름과 일치합니다.docker-compose.ymljava.

  1. the collaborator's machine에서 공작업컴다음내의 합니다.backup.tar이름이 지정된 도커 볼륨으로.

docker run --rm --volumes-from temp_db_container -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

  • --volumes-from temp_db_container:temp_db_container컨너의이테/dbdata가 폴가매습니다에 매핑되었습니다.named_docker_volume볼륨을 설정합니다. 그서저장모파일에 ./dbdata 폴는즉복니다됩으로 됩니다.named_docker_volume 볼륨 도커 볼륨
  • -v $(pwd):/backup컴퓨터의 를 로컬컴작디를리토에 ./backup는 위폴더치한 안에 .temp_db_container
  • ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1" 더▁the를 언타라.backup.tar되지 않은 하여 되지파내정일내저다니장합부에리여하분류않은용로을▁the▁inside에 보관합니다./dbdata폴더를 누릅니다.
  1. 컨테이너 temp_db_container

docker rm temp_db_container

허용된 답변에서 조정되었지만 bash 파이프라인에서 사용할 수 있다는 점에서 더 많은 유연성을 제공합니다.

#!/bin/bash

if [ $# != 2 ]; then
    echo Usage "$0": volume /path/of/the/dir/in/volume/to/backup
    exit 1
fi

if [ -t 1 ]; then
    echo The output of the cmd is binary data "(tar)", \
         and it should be redirected instead of printed to terminal
    exit 1
fi

volume="$1"
path="$2"

exec docker run --rm --mount type=volume,src="$volume",dst=/mnt/volume/ alpine tar cf - . -C /mnt/volume/"$path"

볼륨을 주기적으로 증분 백업하려면 다음 스크립트를 사용할 수 있습니다.

#!/bin/bash

if [ $# != 3 ]; then
    echo Usage "$0": volume /path/of/the/dir/in/volume/to/backup /path/to/put/backup
    exit 1
fi

volume="$1"
volume_path="$2"
path="$3"

if [[ "$path" =~ ^.*/$ ]]; then
    echo "The 3rd argument shouldn't end in '/', otherwise rsync would not behave as expected"
    exit 1
fi

container_name="docker-backup-rsync-service-$RANDOM"
docker run --rm --name="$container_name" -d -p 8738:873 \
    --mount type=volume,src="$volume",dst=/mnt/volume/ \
    nobodyxu/rsyncd

echo -e '\nStarting syncing...'

rsync --info=progress2,stats,symsafe -aHAX --delete \
    "rsync://localhost:8738/root/mnt/volume/$volume_path/"  "$path"
exit_status=$?

echo -e '\nStopping the rsyncd docker...'
docker stop -t 1 "$container_name"

exit $exit_status

를 활용합니다.rsync볼륨과 호스트 dir 간에 dir를 직접 동기화하는 의 서버 및 클라이언트 기능.

다음을 사용한 답변에 만족하지 못했습니다.tar저는 그 문제를 제 손으로 처리하기로 결정했습니다.데이터를 자주 동기화하고 크기가 클 것이기 때문에 특별히 사용하고자 했습니다.rsync.사용.tar매번 모든 데이터를 전송하는 것은 시간과 전송의 낭비일 뿐입니다.

두 원격 도커 컨테이너 간의 통신 문제를 해결하는 데 며칠이 걸린 후, 저는 마침내 다음을 사용하는 솔루션을 얻었습니다.socat.

  • 두 개의 도커 컨테이너(하나는 소스에, 다른 하나는 대상에, 각각 하나는 소스 볼륨과 대상 볼륨)를 마운트합니다.
  • 려달을 rsync --deamon에서 를 스트리밍 중 에서.
  • 려달을 docker exec source_container socat - TCP:localhost그리고 실행docker exec desintation_container socat TCP-LISTEN:rsync -그리고 둘 다 stdin과 stdout을 연결합니다.소원socat합니다.rsync --daemon /에서하고, 하나는 stdout/stdin/stddin입니다.socat에 귀 기울입니다.:rsync포트(포트 873) 및 stdin/stdout으로 리디렉션합니다.그런 다음 이들을 서로 연결하여 기본적으로 한 컨테이너 포트에서 다른 컨테이너 포트로 데이터를 파이프로 연결합니다.
  • 됩니다.rsynclocalhost:rsync""를통한효인연결적과▁""연결를"를 통한 socat파이프"를 연결합니다.rsync --daemon.

기본적으로 다음과 같이 작동합니다.

log "Running both destination and source containers"
src_did=$(
    env DOCKER_HOST=$src_docker_host docker run --rm -d -i -v \
    "$src_volume":/data:ro -w /data alpine_with_rsync_and_socat\
    sleep infinity
)
dst_did=$(
    env DOCKER_HOST=$dst_docker_host docker run --rm -d -i -v \
    "$dst_volume":/data:rw -w /data alpine_with_rsync_and_socat \
    sleep infinity
)

log "Running rsyncd on destination container"
    env DOCKER_HOST=$dst_docker_host docker exec "$dst_did" sh -c "
        cat <<EOF > /etc/rsyncd.conf &&
uid = root
gid = root
use chroot = no
max connections = 1
numeric ids = yes
reverse lookup = no
[data]
path = /data/
read only = no
EOF
        rsync --daemon
    "

log "Setup rsync socat forwarding between containers"
{
    coproc { env DOCKER_HOST=$dst_docker_host docker exec -i "$dst_did" \
       socat -T 10 - TCP:localhost:rsync,forever; }
    env DOCKER_HOST=$src_docker_host docker exec -i "$src_did" \
       socat -T 10 TCP-LISTEN:rsync,forever,reuseaddr - <&"${COPROC[0]}" >&"${COPROC[1]}"
} &

log "Running rsync on source that will connect to destination"
env DOCKER_HOST=$src_docker docker exec -e RSYNC_PASSWORD="$g_password" -w /data "$src_did" \
    rsync -aivxsAHSX --progress /data/ rsync://root@localhost/data

이 접근 방식의 또 다른 장점은 데이터를 로컬에 저장하지 않고도 두 원격 호스트 간에 데이터를 복사할 수 있다는 것입니다.는 또한 이 아이디어를 중심으로 작성한 대본을 공유합니다.이 스크립트를 사용하면 두 개의 원격 호스트에서 볼륨을 복사하는 작업이 단순해집니다.,docker-rsync-volumes --delete -f ssh://user@productionserver grafana_data -t ssh://user@backupserver grafana_data_backup.

이 SSH는 한 서버에서 다른 서버로 볼륨을 복사합니다.

docker run --rm -v $VOLUME:/$VOLUME alpine tar -czv --to-stdout -C /$VOLUME . | ssh $REMOTEHOST "docker run --rm -i -v $VOLUME:/$VOLUME alpine tar xzf - -C /$VOLUME"

필터와 일치하는 두 개 이상의 볼륨을 복사하려는 경우.

REMOTEHOST=root@123.123.123.123

Volumes=($(docker volume ls --filter "name=mailcow*" --format="{{.Name}}"))

for VOLUME in ${Volumes[@]}; do
   docker run --rm -v $VOLUME:/$VOLUME alpine tar -czv --to-stdout -C /$VOLUME . | ssh $REMOTEHOST "docker run --rm -i -v $VOLUME:/$VOLUME alpine tar xzf - -C /$VOLUME"
done

언급URL : https://stackoverflow.com/questions/21597463/how-to-port-data-only-volumes-from-one-host-to-another

반응형