가상 디스크 수동 복제 / 재 작성


7

상당히 수동 방식으로 가상 디스크 이미지를 복제하려고합니다. 지금까지 나의 방법론의 개요는 다음과 같습니다 :

  1. 120GB HDD (하이퍼 바이저 및 HDD 크기는 중요하지 않습니다. 나머지는 물론 파티션 크기와 같이 완벽하고 일관성을 위해 포함됨)
  2. 가상 머신에 Ubuntu 12.04.3 설치
  3. 가상 컴퓨터 닫기
  4. 가상 컴퓨터와 연결된 가상 하드 디스크 탑재
  5. 디렉토리에 저장할 운영 체제 파일 및 데이터 추출
  6. 가상 하드 디스크 메타 데이터 저장
  7. 새 가상 디스크를 생성하고 파티션 및 부팅 정보를 (6)
  8. (5)에서 올바른 파티션으로 데이터 복원

문제

내 복제 된 VM은 부팅되지 않습니다. 그럽 (Grub)이 복사하는 것처럼 보입니다. 등장하다 내 루트 파티션 (우분투가 설치된 상태)을 확인합니다. 우분투가로드 될 것처럼, GRUB을 한번 부팅하고 자주색 화면을 볼 수 있습니다. 그런 다음 중지합니다. 그 후, 나는 Grub으로 부팅하고 OS를 선택한 다음 깜박이는 커맨드 라인 커서를 얻을 수 있습니다. 입력이 불가능합니다. 복제 프로세스에서 누락 된 부분이있는 것으로 의심됩니다 (자세한 내용은 아래 참조). 참고 : 저는 grub2를 사용하고 있습니다.

왜 이런 짓을하는?

계약상의 요구 사항의 일부로 버전 제어에 가상 디스크를 저장해야합니다. 거대한 바이너리 블롭 (가상 디스크)을 버전 관리에 사용하는 것이 복제본 (git) / 체크 아웃 (svn)뿐 아니라 diff에 대한 통증입니다. 여러 파일을 압축하는 것을 고려했지만 위의 (5)에서 추출한 OS / 데이터를 조작 할 수 있어야합니다. VCS 저장소에는 완전한 VM을 작성하는 데 필요한 모든 정보가 필요합니다.

세부 묘사

설명 된 것을 재현하는 자세한 지침 :

  1. VM 만들기 및 Ubuntu Live CD 부팅
  2. "Try Ubuntu"를 선택하십시오.
  3. 터미널 열기
  4. msdos 파티션 만들기 : sudo parted / dev / sda mklabel msdos
  5. 2GB 스왑 파일 만들기 : sudo parted / dev / sda mkpart 주 리눅스 스왑 2048s 4198399s
  6. 루트 파티션으로 나머지 드라이브를 사용하십시오. sudo parted / dev / sda mkpart 기본 ext4 4198400s 100 %
  7. 컴퓨터를 재부팅하고 "Install Ubuntu"를 선택하십시오.
  8. 고급 파티셔닝 옵션 선택
  9. 스왑 파티션을 두 번 클릭하고 스왑 파티션으로 사용하도록 선택합니다.
  10. 루트 파티션을 두 번 클릭하고 포맷을 선택하여 루트 (/)로 사용하십시오. 마운트 포인트

이제 다음을 수행하여 디스크를 복제하십시오.

# Set up some parameters
ORIG_DEV="/dev/nbd0"
ORIG_MNT=$(mktemp -d)
ORIG_IMG="orig.vdi" 
CLONE_DEV="/dev/nbd1"
CLONE_MNT=$(mktemp -d)
CLONE_IMG="clone.vdi"
qemu-img info $ORIG_IMG # save the "virtual size" output (in bytes) in the
                        # VIRT_SIZE variable in the next command
VIRT_SIZE="128849018880"

# Create the clone disk
qemu-img create -f vdi $CLONE_IMG $VIRT_SIZE

# Use qemu to make both disks accessible
modprobe nbd
qemu-nbd -c $ORIG_DEV $ORIG_IMG
qemu-nbd -c $CLONE_DEV $CLONE_IMG

# Set up the clone disk partition table and partitions
parted $CLONE_DEV mklabel msdos
parted $CLONE_DEV mkpart primary linux-swap 2048s 4198399s
parted $CLONE_DEV mkpart primary ext4 4198400s 100%

# Format the clone disk partitions and clone the UUIDs
mkswap $CLONE_DEVp1 -U $(blkid $ORIG_DEVp1 -s UUID -o value)
mkfs.ext4 $CLONE_DEVp2 -U $(blkid $ORIG_DEVp2 -s UUID -o value)

# Mount both disks and copy root from the original to the clone
mount $CLONE_DEVp2 $CLONE_MNT
mount $ORIG_DEVp2 $ORIG_MNT
find $ORIG_MNT -maxdepth 1 -mindepth 1 | xargs -I{} cp -ar {} $CLONE_MNT
umount $ORIG_MNT
umount $CLONE_MNT

# Copy the boot sector and partition table from the original
dd if=$ORIG_DEV of=$CLONE_DEV bs=$((2048*512)) count=1

# Disconnect the disks
qemu-nbd -d $CLONE_DEV
qemu-nbd -d $ORIG_DEV

그 외에 또 무슨 짓을 한거야?

  1. grub-install --root-directory = / path / to / clone / device / boot / / dev / clone_device. 이것은 올바른 장치에 Grub을 설치했지만 호스트의 장치 세부 사항으로 설치합니다. VM이 부팅되지 않습니다.
  2. 복제 디스크에 chroot 한 다음, grub-install을 실행하십시오. 64 비트 호스트를 사용하여 32 비트 게스트를 복제 할 수 있어야하기 때문에 문제가 발생했습니다. 이것은 조사 할 수있는 희망적인 길일 것 같지만, 나는 이것을 달성하는 방법에 관해서 붙어 있습니다.
  3. 가상 디스크를 마운트하고 모든 파일을 데이터 파티션 밖으로 이동합니다. mv, 데이터와 스왑 파티션을 제로화 ( dd if=/dev/zero of=/dev/nbd0p2 )를 선택하고 가상 디스크를 압축합니다 ( VBoxManage modifyhd clone.vdi --compress ). 디스크가 빈 공간 (hah!)으로 채워지면서 호스트 파일 시스템에서 디스크가 확장되기 시작했습니다. 나는 멈췄다. dd 이런 일이 발생했다는 것을 깨달았을 때 디스크 이미지가 압축되었습니다. 3GB가 넘었습니다. (gzip / bzip을 사용하지 않았지만, 오늘 저녁에 시도해 볼 것입니다. dd 닦아내 기가 완료되도록 시도 할 것입니다.하지만 작동하는 경우에도 더 적은 시간이 소요되는 솔루션을 선호합니다) .
  4. e2 이미지. 내 다른 질문보기 : e2image는 파일 시스템 메타 데이터를 복원합니다. . 나는 이것을 해결하지 못했다. 내가 제공하는 단계는 세부 묘사 섹션 작성, 포맷 및 부트 섹터 복사를 포함하여 전에 루트 파티션을 복사하고 e2image로 만든 것과 비슷한 크기의 이미지 파일을 생성합니다.
  5. grub-install을 실행하기 위해 다른 VM으로 부팅하여이 VM에 chroot합니다. 나는 실제로이 일을하지 않았지만 누군가가 제안 할 경우를 대비하여 여기에 포함시켰다. 필자에게는 스크립트 작성이 가능한 가상 머신의 재조합이 필요합니다. 관련된 설치 프로세스가 배제됩니다.
  6. Grub 대신 extlinux를 설치하십시오. 실패한 동안,이 연습은 부트 로더가 내 파티션에서 램 디스크를 성공적으로로드하고 있지만 (이 시점에서 멈추는) 것으로 나타났습니다.

당신이 여기까지왔다면 이미 감사드립니다! 조사 방법에 대한 어떠한 제안도, 그러나 자세히 알려지지 않을 것입니다. 미리 감사드립니다.


완전을 위해 +1; 나는 더 도움이 되었으면 좋겠다.
Canadian Luke

1
e2image man은 -r 매개 변수보다는 -Q. 제작자에게 연락을 시도 할 수 있습니다. 테오도르 Ts'o , 누가 분명히 당신을 도울 수 있습니다.
harrymc

@CanadianLuke 감사합니다, 나도 그래! @harrymc, 나는 사용을 고려하지 않았다. e2image -r 왜냐하면 내 경험에 의하면 Windows는 스파 스 파일을 저장하는 데 아주 능숙하지 않기 때문에 개발자가 Windows를 사용하려면 저장소의 체크 아웃에 많은 공간이 필요합니다. 그러나 Windows에서 스파 스 파일을 사용하여 앞서 언급 한 "경험"은 매우 제한되어 있으므로 거의 추적하지 못했으며 추가 조사가 필요합니다. 제안에 대해 대단히 감사 드리며, 나는 그것에 대해 살펴보고 그것이 어떻게 진행되는지 알려줄 것입니다.
mkingston

답변:


4

가상 디스크의 내용을 추출하고 다시 만들 필요가 없어 보이는 대체 제안이 있습니다.

git을 사용하는 경우, 마운트 된 가상 디스크에서 직접 작업하고 .git 디렉토리를 다른 위치에 둘 수 있습니다. 가상 디스크의 루트 파티션의 루트 디렉토리에 .gitignore (있을 경우)가 있어야 할 필요가 있습니다.

편집하다:
복제의 경우 초기 설치 후 VirtualBox의 일반적인 메커니즘을 사용할 수 있습니다. 특정 버전을 복원해야 할 때마다 원본에서 다른 복제본을 만든 다음 마운트하여 git checkout을 수행하십시오.
grub 버전이 다르지 않은 한, 모두 당신이해야 할 일입니다. grub 버전이 다른 경우 12.04.3.iso에서 VM을 부팅하고 grub-install을 수행해야합니다.

이렇게하면 대체 워크 플로가 (새로운 4 단계 추가, 5 단계 수정) :

  1. VirtualBox 120GB HDD로 가상 머신 생성
  2. 가상 머신에 Ubuntu 12.04.3 설치
  3. 가상 컴퓨터 닫기
  4. 가상 머신을 복제하고 원본을 옆으로 두십시오.
  5. 원본 또는 첫 번째 복제본의 가상 하드 디스크 탑재 (예 : / media / virtual)
  6. cd / media / virtual
  7. git --git-dir = / 어딘 / else / virtual.git --work-tree =. 초기화
  8. git --git-dir = / 어딘 / else / virtual.git --work-tree =. 추가.
  9. git --git-dir = / 어딘 / else / virtual.git --work-tree =. commit -m "초기 가져 오기"
  10. ... 다른 git 작업 ...

항상 추가하고 싶지 않으면 --git-dir = / 어딘지 / else / virtual.git --work-tree =. , 그것을 제거하는 방법을 설명하는 Stackoverflow에 대한 질문이 있습니다. .git 폴더를 추적하려는 파일 외부에 저장할 수 있습니까?

당신이 요구 한 것과 정확히 일치하지는 않지만 문제 설명은 정확한 방식보다 일을 끝내는 것에 더 관심이 있다는 인상을줍니다.


이 대답을 쓸 때 복제에 대해 언급하는 것을 잊었습니다. 나는 이것을 지금 추가했다.
Markus N.

답변 주셔서 감사합니다. 응답 지연에 대해 사과드립니다. 나는 틀릴 수도 있지만 이것이 내 문제를 해결할 것이라고는 생각하지 않는다. VHD 자체가 아니라 버전 제어에 OS / 데이터 파일 만 저장합니다 (실수 한 경우 수정하십시오). 버전 관리에 있어야하기 때문에 VHD를 재구성하려고했습니다. OS 및 데이터 . 기본 파티션 정보와 부트 섹터를 포함하는 "셸"로서, 관리할만한 크기이지만 일단 ext4 메타 데이터와 OS 파일이 있으면 너무 큽니다. 어쨌든 영리한 아이디어를 얻으려면 +1, 다시 한 번 감사드립니다.
mkingston

예, 맞습니다 ... 파일 만 저장합니다. 어쩌면 내가 너를 잘못 이해 했겠지만, 나는 그게 가상 디스크 전체를 blob로 취급하는 것을 피하기 위해 원하는 것이라고 생각했다.
Markus N.

통신 오류는 저의 것입니다. VCS 저장소 내에서 작동 가능한 OVA를 만들려면 모든 정보가 필요합니다. 이상적으로는 OS / 데이터의 복사본 (개별 파일), 매우 작은 "셸"VHD 및 VHD 및 OS / 데이터를 작동중인 VM으로 재결합하는 스크립트가 포함됩니다. 제 질문에는이 요구 사항을 추론 할 수있는 관련 정보가 포함되어 있다고 생각합니다. 그러나 그것이 될 수있는 것보다 덜 명확합니다. 이를 반영하기 위해 질문을 업데이트 할 것입니다. 영리한 생각과 질문에 대한 답변을 위해 다시 한 번 감사드립니다. 정말 감사드립니다.
mkingston

현상금이 내 문제를 해결했기 때문에 현상금을 수여하지 않았지만 (어쨌든 답을주지 못했습니다!) 어쨌든 반을 받고, 당신의 영리한 생각과 제안에 감사드립니다. .
mkingston

3

어쩌면 당신은 이미 이것을 시도해 보았을 것입니다. 하지만 "중복 된 VM"내에 Live CD에서 Grub2를 다시 설치해 보셨습니까? 내가 읽은 모든 것은 호스트 시스템에서 Grub2를 설치하는 것과 같습니다.

  • 부팅되지 않는 복제 된 VM이있는 지점에 도달하면
  • Ubuntu와 같은 라이브 CD 탑재 VM에 디스크 설치
  • VM을 부팅하고 F12 키를 눌러 Live CD에서 부팅합니다.
  • 명령 줄에서 grub을 다시 설치하십시오 (VM 내부).

사용할 수있는 프로세스를 자동화하고 싶다면 VBoxManage 시작시 Grub2를 다시 설치하는 스크립트를 실행하는 사용자 정의 Ubuntu Live CD를 마운트합니다.

VBoxManage storageattach "io" --storagectl "IDE Controller" \
--port 1 --device 0 --type dvddrive --medium debian-6.0.2.1-i386-CD-1.iso

예제 소스

잘만되면 너무 오래되어서는 안된다. Live CD 사용자 정의를위한 help.ubuntu.com에 대한 안내서 , 스택 교환 askubuntu.com의 질문 / 답변에 사용자 정의 된 라이브 CD에 시작 스크립트 추가


나는 그것이 작동 할 것이라고 절대적으로 기대한다. 하지만 스크립트로 솔루션을 실행할 수 있어야합니다 (아래의 5 절 참조). What else have you tried? ), 그래서 사용자가 자신의 컴퓨터 (git clone 또는 svn checkout)로 저장소를 전송할 때 그들은 구성 파일에서 VM을 매우 쉽게 빌드 할 수 있습니다. 나는 이것을 대본 작성하는 것이 가능할 것이라고 생각하지만, 나의 현재 노력 중 일부를 추구하는 것보다 더 많은 일이 필요할 것이다. 그게 잘못되었다고 생각한다면 나는 알고 싶어. 어떠한 경우에도 귀하의 기여에 대해 대단히 감사드립니다.
mkingston

나는 당신이 "다른 VM"을 의미하는 것을 오해 했음에 틀림 없습니다. 생각이 떠오르는 점은 VBoxManage 명령을 사용하여 Live CD를 마운트하고 시작시 Grub2를 다시 설치하기 위해 스크립트를 실행하는 사용자 정의 라이브 CD를 만듭니다. 명백한 도전은 여기에 사용자 정의 Live CD이지만, 사용자 정의 Live CD를 매우 쉽게 만들 수있는 온라인 자습서와 도구가 몇 가지 있습니다. 이전에는 OpenSUSE Live CD를 만들 수있는 온라인 도구가 있었으며 원하는 패키지를 선택하고 시작 스크립트를 업로드 할 수있었습니다.
Drew Chapin

시간이되면 오늘 나중에 살펴보고 사용자 지정 Live CD를 만드는 방법에 대해 제안합니다.
Drew Chapin

귀하의 업데이트 및 의견을 보았고 아직 조치를 취할 시간이 없었 음을 언급하고자합니다. 가능한 한 빨리 독서 / 실험을 해보겠습니다. 고마워.
mkingston

불행하게도 저는 오늘까지이 일로 돌아갈 수 없었습니다. 결과적으로 실제로 라이브 CD에서 grub을 성공적으로 설치할 수는 없습니다. 필자는 파일 시스템 메타 데이터에 문제가 있다고 생각합니다. 어쨌든 당신의 제안에 감사드립니다.
mkingston

3

우분투 탑재 지점에 대해별로 생각하지 못했던 것 같습니다. VM을 여러 개의 파티션으로 분리하는 것을 고려 했습니까?

아래 링크에서

http://www.easy-ubuntu-linux.com/ubuntu-installation-606-12.html

기본 설치는 SWAP의 경우 4G, + 1G, / tmp의 경우 + 2G이며 / usr, / var, / home, / opt에 대해 별도의 파티션을 만들 수 있습니다

처음에는 각자 1G로 만들어야합니다. 필요한 경우 가상 박스로 동적으로 확장 할 수 있습니다.

참고:

http://www.ubuntugeek.com/linux-or-ubuntu-directory-structure.html

그런 다음 SVC 범위, 사용자 파일 또는 로그 또는 OS 만 확인할 수 있습니까? 당신은 버전에서 훨씬 적은 고통을 가질 수 있습니다.

대부분의 경우 /, / usr 및 / opt를 설치 후 읽기 전용 및 변경 불가능으로 설정하여 전체 버전의 두통을 줄일 수 있습니다.

한 가지 사실은 계약 상태에 따라 가상 디스크를 저장해야한다는 것을 상기시켜주는 것입니다. 가상 디스크의 추출 데이터를 저장하는 것이 계약과 일치하지 않는 것 같습니다. 그러나 여러 가상 디스크를 저장하는 것은 일치합니다. 그래서 마운트 지점을 만든 다음 그 중 일부만 읽기 전용으로 만드는 것이 좋습니다 (그 중 한 버전 만 있습니다).

마운트 지점의 파일 액세스 날짜를 끌 수 있는지 확인하는 것을 잊지 마십시오. (매우 높은 보안 설정으로는 컴퓨터 포렌식을 해제 할 수 없습니다)

액세스 날짜가 켜지면 실제로 액세스 날짜가 디스크에 기록됩니다. 따라서 2 일에 액세스하는 가상 디스크 / 마운트 지점은 아무 것도 기록되지 않더라도 실제로 1 일에 가상 디스크 / 마운트 지점과 다른 버전입니다.

참조 (액세스 시간 없음) :

https://askubuntu.com/questions/59179/how-do-i-make-noatime-mounts-default


이 시나리오에서는 여러 개의 파티션이있는 하나의 가상 디스크보다 여러 개의 가상 디스크를 제안하려고합니다. 그렇지 않으면 VCS의 관점에서 분리 할 수 ​​없습니다.
Markus N.

이 자체로는 체크 아웃하는 동안 대용량 파일의 전송 문제를 해결할 수 없습니다. 그러나 여러 파티션을 포함하는 여러 VHD를 사용하면됩니다. 이것은 릴리스 요구 사항에 조금 의존적 일 수 있습니다 (아직 명확하지 않습니다). 감사합니다. +1하여 의견을 보내주십시오.
mkingston

0

한 가지 더 생각해 보면, 실제로 살펴볼 것입니다. /etc/fstab. 파티션은 어떻게 정의되어 있습니까? 그들이 그들에 의해 정의 된 경우 UUID,이 정보가 복제 프로세스로 복제되지 않을 가능성이 있습니다. 그것들을 다음과 같은 장치 이름으로 정의 할 수 있습니다. /dev/sda0 예를 들면.

한 가지 다른 점, 왜 자식을 돌리지 말아야 하는가? 안에서부터 가상 머신 자체? 당신의 저장소를 가지고있는 호스트에 디렉토리가 있다고 생각할 수 있습니다. 그런 다음 가상 컴퓨터는이 디렉터리를 탑재하고 실행할 수 있습니다. git 가상 머신 자체에서.


귀하의 제안에 감사드립니다. 필자는 실제로 UUID를 복제하고 fstab이 장치 이름 대신이 이름을 참조하는지 확인했습니다. 불행히도 VHD 자체는 VCS 저장소에 있어야합니다. VM 내부에서 git을 실행하면 저장소에있는 큰 바이너리 파일의 clone / checkout / diff에서 발생하는 문제를 완화하지 못하는 답을 오해하지 않는 한.
mkingston
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.