仮想ディスクの手動クローン/再作成


7

かなり手動で仮想ディスクイメージのクローンを作成しようとしています。これまでの私の方法論の概要は次のとおりです。

  1. VirtualBoxで120GBのHDDを使用して仮想マシンを作成します(ハイパーバイザーとHDDのサイズは関係ありません。ほとんどの場合、パーティションサイズなどの残りの質問との完全性と一貫性のために含まれます)
  2. Ubuntu 12.04.3を仮想マシンにインストールします
  3. 仮想マシンを閉じる
  4. 仮想マシンに関連付けられた仮想ハー​​ドディスクをマウントする
  5. オペレーティングシステムファイルとデータを抽出してディレクトリに保存する
  6. 仮想ハードディスクのメタデータを保存する
  7. 新しい仮想ディスクを作成し、(6)からパーティションとブート情報を復元します
  8. (5)から正しいパーティションにデータを復元します

問題

複製したVMが完全に起動しません。GRUBはコピーするようだ、と表示されます(Ubuntuがそれにインストールされている)私のルートパーティションを確認します。Ubuntuが読み込まれそうになっているように、Grubを一度通過すると紫色の画面が表示されます。その後、停止します。その後、Grubを起動してOSを選択すると、コマンドラインカーソルが点滅します。入力できません。クローン作成プロセスで不足しているものがあると思われます(詳細については以下を参照)。注:私はレガシーではなくgrub2を使用しています。

なぜあなたはこれをやっている?

契約上の要件の一部として、仮想ディスクをバージョン管理に保存する必要があります。バージョン管理で巨大なバイナリBLOB(仮想ディスク)を使用することは、主にclone(git)/ checkout(svn)だけでなく、diffにとっても苦痛です。複数のファイルに圧縮することを検討しましたが、上記の(5)で抽出したOS /データを操作できる必要があります。VCSリポジトリには、完全なVMを構築するために必要なすべての情報が必要です。

詳細

説明した内容を再現するための詳細な手順:

  1. VMを作成し、Ubuntu Live CDを起動します
  2. 「Ubuntuを試す」を選択します
  3. ターミナルを開く
  4. msdosパーティションを作成します:sudo parted / dev / sda mklabel msdos
  5. 2GBのスワップファイルを作成します。sudoparted / dev / sda mkpart primary linux-swap 2048s 4198399s
  6. ルートパーティションに残りのドライブを使用します。sudo parted / dev / sda mkpart primary ext4 4198400s 100%
  7. マシンを再起動し、「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)。ディスクが空のスペースでいっぱいになると、ホストファイルシステム上でディスクが拡張し始めました(ハァッ!)。ddこれが起こっていることに気付いたときに停止し、ディスクイメージを圧縮しました。まだ3GBを超えていました。(gzip / bzipを使用したことはありません。今晩から始めます。ddワイプを最後まで実行させようとしますが、それが機能しても時間のかからないソリューションを好むでしょう) 。
  4. e2image。私の他の質問:e2image restore file system metadataをご覧ください。私はこれを解決していません。詳細セクションで提供する、パーティションの作成、フォーマット、ブートセクターコピーなどの手順は、ルートパーティションをコピーするに、e2imageによって作成されたものと非常に似たサイズのイメージファイルを生成することに注意してください。
  5. 別の仮想マシンを起動して、この仮想マシンにchrootしてgrub-installを実行します。実際にこれを行ったことはありませんが、誰かが提案した場合に備えて、ここに含めました。ユーザーの場合、スクリプトを実行できるように仮想マシンの再結合が必要です。これにより、関連するセットアッププロセスが排除されます。
  6. Grubの代わりにextlinuxをインストールします。成功していませんが、この演習では、ブートローダーがパーティションからRAMディスクを正常にロードしているが、この時点でスタックしていることを示しています(と思います!)。

ここまで来てくれたら、ありがとう!調査の方法についての提案は、詳細ではありませんが、大歓迎です。前もって感謝します。


完全性のために+1。私はさらに助けたいと思います
カナダルーク

1
e2imageの男性は、-rパラメータではなくに言及しています-Q。作成者のTheodore 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. 120GB HDDを使用してVirtualBoxで仮想マシンを作成します
  2. Ubuntu 12.04.3を仮想マシンにインストールします
  3. 仮想マシンを閉じる
  4. 仮想マシンのクローンを作成し、オリジナルを脇に置きます
  5. オリジナルまたは最初のクローンの仮想ハードディスクをマウントします(例:/ media / virtual)
  6. cd / media / virtual
  7. git --git-dir = / somewhere / else / virtual.git --work-tree =。初期化
  8. git --git-dir = / somewhere / else / virtual.git --work-tree =。追加 。
  9. git --git-dir = / somewhere / else / virtual.git --work-tree =。commit -m "初期インポート"
  10. ...その他のgitタスク...

常に--git-dir = / somewhere / else / virtual.git --work-tree =を追加したくない場合、それを取り除く方法を説明するStackoverflowに関する質問があります: 追跡したいファイルの外に.gitフォルダを保存できますか?

正確にあなたが求めたものではありませんが、あなたの問題の説明は、あなたがそれを行う正確な方法よりもあなたの仕事を成し遂げることにより興味を持っているという印象を私に与えます。


この答えを書いているとき、クローンについて言及するのを忘れていました。今これを追加しました。
マーカスN.

ご回答ありがとうございます。応答の遅れをおaび申し上げます。私は間違っているかもしれませんが、これが私の問題を完全に解決するとは思いません。VHD自体ではなく、バージョン管理でOS /データファイルのみを保存します(間違えた場合は修正してください)。OSとデータだけでなくバージョン管理必要であるため、VHDを再構築しようとしました。基本的なパーティション情報とブートセクターを含む「シェル」としては、管理可能なサイズですが、ext4メタデータおよび(または)OSファイルがその上にあると、大きすぎます。いずれにせよ、賢いアイデアのために+1、ありがとう。
mkingston

はい、そうです...ファイルのみを保存します。たぶん私はあなたを誤解したかもしれませんが、仮想ディスク全体をblobとして扱うことを避けるためにあなたがそれが欲しいと思いました。
マーカスN.

通信エラーは私自身のものです。VCSリポジトリ内で、機能するOVAを作成するためにすべての情報を利用できる必要があります。理想的には、これにはOS /データのコピー(個々のファイルとして)、非常に小さな「シェル」VHD、およびVHDとOS /データを動作中のVMに再結合するスクリプトが含まれます。私の質問には、この要件を推測するための関連情報が含まれていると思いますが、それよりも明確ではありません。これを反映するために質問を更新します。賢いアイデアと質問に答えるためにあなたが注いだ努力をありがとう、私は本当に感謝しています。
mkingston

あなたの答えが私の問題を解決したからではなく、あなたがその半分を受け取ることになったので、あなたの賢明な思考とあなたの提案に感謝したので、私はあなたに賞金を授与しました。
mkingston

3

たぶん、あなたはすでにこれを試したことがあるかもしれませんが、そうではないかもしれません。しかし、「複製されたVM」内のLive CDからGrub2を再インストールしようとしましたか?ホストコンピューターからGrub2をインストールしているように聞こえました。

  • 起動しない複製されたVMがあるポイントに到達したら
  • UbuntuインストールディスクなどのLive CDをVMにマウントする
  • VMを起動し、F12を押してLive CDから起動します
  • コマンドライン(VM内)からgrubを再インストールします

プロセスを自動化する場合は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にあり、カスタマイズされたLive CD起動スクリプトを追加することに関する Stack Exchangeの質問/回答がaskubuntu.comにあります。


私はそれがうまくいくと絶対に期待しています。しかし、スクリプトを使用してソリューションを実行できる必要があります(下のポイント5を参照What else have you tried?)。ユーザーがリポジトリをマシン(git cloneまたはsvn checkout)に転送すると、構成ファイルから非常に簡単にvmを構築できます。これをスクリプト化することは可能だと思いますが、おそらく私の現在の努力をさらに追求するよりも多くの作業が必要になるでしょう。あなたがそれが間違っていると思うなら、私は知りたいです。いずれにせよあなたの貢献に感謝します。
mkingston

「別のVM」の意味を誤解していたに違いありません。ただし、思い浮かぶのは、VBoxManageコマンドを使用してLive CDをマウントし、起動時にGrub2を再インストールするスクリプトを実行するカスタムLive CDを作成することです。ここでの明らかな課題は、カスタムLive CDですが、カスタムLive CDを非常に簡単に作成できるチュートリアルとツールがオンラインでいくつかあります。以前は、OpenSUSE Live CDを作成して、必要なパッケージを選択し、起動スクリプトをアップロードできるオンラインツールがありました。
ドリューチャピン

時間に余裕があれば、今日は後で見て、カスタムLive CDの作成方法を提案します。
ドリューチャピン

あなたのアップデートとコメントを見ただけで、まだ何もする時間がないことを伝えたいだけです。できるだけ早く、読書/実験を行います。ありがとう。
mkingston

残念ながら、今日までこれを実際に回避することはできませんでした。実のところ、ライブCDからgrubを正常にインストールすることはできません。ファイルシステムメタデータの一部に問題があると思います。とにかくあなたの提案をありがとう。
mkingston

3

Ubuntuのマウントポイントについてあまり知らなかったようですね。VMを複数のパーティションに分割することを検討しましたか?

以下のリンクから:

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

基本インストールは4G、SWAPの+ 1G、/ tmpの+ 2Gのみで、/ usr、/ var、/ home、/ optに個別のパーティションを作成できます。

最初からそれぞれ1Gを作成するだけで、必要に応じて仮想ボックスで動的に拡張できます

参照:

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

その後、SVCスコープを決定できます。ユーザーファイルまたはログまたはOSのみですか?そのため、バージョンの痛みがはるかに少なくなります。

ほとんどの場合、セットアップ後に/、/ usr、および/ optを読み取り専用にして変更できないようにするだけで、バージョン全体の頭痛の種を減らすことができます。

ただし、1つのことは、仮想ディスクを格納する必要がある契約状態であるため、仮想ディスクからの抽出データの格納が契約と一致しないことを思い出してください。しかし、複数の仮想ディスクの一致を保存します。そのため、マウントポイントを作成し、それらの一部を読み取り専用にすることをお勧めします(したがって、それらのバージョンは1つしかありません)。

さらに注意してください。マウントポイントのファイルアクセス日付をオフにできるかどうかを忘れずに確認してください。(いくつかの非常に高いセキュリティ設定では、それをオフにすることはできません、コンピューターフォレンジック)

アクセス日がオンになっている場合、アクセス日は実際にディスクに書き込まれるためです。そのため、2日目にアクセスする仮想ディスク/マウントポイントは、何も書かれていなくても、実際には1日目の仮想ディスク/マウントポイントとは異なるバージョンです。

参照(アクセス時間なし):

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


このシナリオでは、複数のパーティションを持つ1つの仮想ディスクよりも、複数の仮想ディスクを推奨します。そうしないと、VCSのビューからそれらを分離できません。
マーカスN.

これだけでは、チェックアウト中の大きなファイルの転送の問題を解決しません。ただし、異なるパーティションを含む複数のVHDを使用すると可能性があります。これは私のリリース要件に少し依存しているかもしれません(まだ明確ではありません)。ありがとう、そしてあなたの提案のために+1。
mkingston

0

もう1つ考えて、実際に調べます/etc/fstab。パーティションはどのように定義されていますか?それらがで定義されているUUID場合、おそらくこの情報が複製プロセスで複製されない可能性があります。/dev/sda0たとえば、デバイス名で定義することができます。

もう1つのポイントは、仮想マシン自体の内部から gitを実行しない理由です。私はあなたのリポジトリを持つホスト上にディレクトリを持つことを考えることができます。その後、仮想マシンはこのディレクトリをマウントgitして、仮想マシン自体で実行できます。


提案ありがとう。実際にUUIDを複製し、fstabがデバイス名ではなくこれらを参照することを確認しました。残念ながら、VM内からgitを実行して答えを誤解しない限り、VHD自体はVCSリポジトリ内にある必要があります。これは、リポジトリ内の大きなバイナリファイルのclone / checkout / diffから生じる問題を軽減しません。
mkingston
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.