イメージの変更

仮想マシンイメージを取得すると、Image service にアップロードする前に、いくつか変更したいかもしれません。イメージを変更できる、いくつかの利用可能なツールを説明しています。

警告

実行中の仮想マシンに接続されているイメージを変更するために、これらのツールを使用しないでください。これらのツールは、動作していないイメージのみを変更するために設計されています。

guestfish

guestfish プログラムは、仮想マシンイメージ内のファイルを編集できる、 libguestfs プロジェクトのツールです。

注釈

guestfish は、イメージをローカルファイルシステムに直接マウントしません。代わりに、ファイルを表示、編集、削除するためのシェルインターフェースを提供します。 touch, chmod, rm など、多くの guestfish コマンドは、伝統的な bash コマンドに似ています。

guestfish 実行例

仮想マシンイメージが最初に作成された際に仮想ネットワークインターフェースカードに割り当てられた MAC アドレスの設定を削除するために、イメージの編集が必要な場合があります。次回起動時、MAC アドレスが異なるものになるからです。この例は、 /etc/udev/rules.d/70-persistent-net.rules ファイルを削除し、 /etc/sysconfig/network-scripts/ifcfg-eth0 ファイルの HWADDR 行を削除することにより、古い MAC アドレスへの参照を削除するために、 guestfish を使用する方法を示しています。

centos63_desktop.img という名前の CentOS qcow2 イメージがあると仮定します。以下のとおり、root としてイメージを読み書きモードでマウントします。

# guestfish --rw -a centos63_desktop.img

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for help on commands
'man' to read the manual
'quit' to quit the shell

><fs>

これにより guestfish セッションが始まります。

注釈

guestfish プロンプトは ><fs> のようになります。

何かしらの処理を実行する前に、まず guestfish プロンプトで run コマンドを実行する必要があります。これにより、すべてのファイル操作を実行するために使用する、仮想マシンが起動します。

><fs> run
  1. これで、 list-filesystems コマンドを使用して、イメージにあるファイルシステムを表示できます。

    ><fs> list-filesystems
    /dev/vda1: ext4
    /dev/vg_centosbase/lv_root: ext4
    /dev/vg_centosbase/lv_swap: swap
    
  2. 論理ボリュームをマウントする必要があります。

    ><fs> mount /dev/vg_centosbase/lv_root /
    
  3. 次に、ファイルを削除します。 rm guestfish コマンドを使用できます。これは、伝統的なシェルと同じ方法で動作します。

    ><fs> rm /etc/udev/rules.d/70-persistent-net.rules
    
  4. HWADDR 行を削除するために、 ifcfg-eth0 ファイルを編集したいです。 edit コマンドは、ファイルをホストにコピーし、エディターを実行し、ファイルを書き戻します。

    ><fs> edit /etc/sysconfig/network-scripts/ifcfg-eth0
    
  5. このイメージの起動時に 8021q カーネルを読み込むために、イメージを編集したい場合、/etc/sysconfig/modules/ ディレクトリに実行可能なスクリプトを作成する必要があります。 touch guestfish コマンドを使用して空のファイルを作成し、 edit コマンドを使用して編集できます。そして、 chmod コマンドを使用して実行可能にします。

    ><fs> touch /etc/sysconfig/modules/8021q.modules
    ><fs> edit /etc/sysconfig/modules/8021q.modules
    
  6. 以下の行をファイルに追加し、保存します。

    modprobe 8021q
    
  7. 続けて、実行可能にします。

    ><fs> chmod 0755 /etc/sysconfig/modules/8021q.modules
    
  8. これで完了したので、 exit コマンドを用いて終了できます。

    ><fs> exit
    

guestfish のさらなる利用

guestfish には、非常にさまざまな機能がありますが、このドキュメントの範囲を超えています。これらのツールを用いて実行できることは、 guestfs-recipes を参照することを推奨します。

guestmount

いくつかの種類の変更の場合、イメージのファイルシステムを直接マウントするほうが簡単かもしれません。libguestfs プロジェクトの guestmount プログラムにより実行できます。

  1. 例えば、 centos63_desktop.qcow2 イメージのルートパーティションを /mnt にマウントするために、以下のとおり実行します。

    # guestmount -a centos63_desktop.qcow2 -m /dev/vg_centosbase/lv_root --rw /mnt
    
  2. マウントポイントがゲストのどこであるか不明な場合、guestmount が使用するマウントポイントを自動的に決定するために、 -i (検査) フラグを使用できます。

    # guestmount -a centos63_desktop.qcow2 -i --rw /mnt
    
  3. マウントすると、rpm コマンドを使用してインストール済みパッケージを一覧表示するなどの操作を実行できます。

    # rpm -qa --dbpath /mnt/var/lib/rpm
    
  4. 完了したら、アンマウントします。

    # umount /mnt
    

virt-* ツール

libguestfs プロジェクトは、他にも以下のような有用なツールを作成しています。

  • virt-edit は、イメージ内のファイルを編集できます。

  • virt-df は、イメージ内の空き容量を表示できます。

  • virt-resize は、イメージの容量を変更できます。

  • virt-sysprep は、イメージを配布する準備ができます (例えば、SSH ホスト鍵の削除、MAC アドレス情報の削除、ユーザーアカウントの削除)。

  • virt-sparsify は、イメージをスパース化できます。

  • virt-p2v は、物理マシンを KVM で動作するイメージに変換できます。

  • virt-v2v は、Xen や VMware のイメージを KVM のイメージに変換できます。

イメージ内の単一ファイルの編集

この例は、 virt-edit を使用して、ファイルを編集する方法を示します。このコマンドは、 -a フラグの引数としてファイル名を、 -d フラグの引数としてドメイン名を利用できます。以下の例は、これを使用して、現在動作中の libvirt ドメイン名 instance-000000e1 のインスタンスにある /etc/shadow ファイルを編集する方法について示します。

# virsh shutdown instance-000000e1
# virt-edit -d instance-000000e1 /etc/shadow
# virsh start instance-000000e1

イメージのリサイズ

これは、イメージの容量を変更するために、 virt-resize を使用する方法の簡単な例です。容量を 50 GB に変更したい、qcow2 形式の 16 GB Windows イメージがあると仮定します。

  1. まず、 virt-filesystems を使ってパーティションを識別します。

    # virt-filesystems --long --parts --blkdevs -h -a /data/images/win2012.qcow2
    Name       Type       MBR  Size  Parent
    /dev/sda1  partition  07   350M  /dev/sda
    /dev/sda2  partition  07   16G   /dev/sda
    /dev/sda   device     -    16G   -
    
  2. この場合、容量を変更したいパーティションは /dev/sda2 です。新しい qcow2 イメージを作成し、容量を変更して元の内容を新しいイメージをコピーするために virt-resize コマンドを使用します。

    # qemu-img create -f qcow2 /data/images/win2012-50gb.qcow2 50G
    # virt-resize --expand /dev/sda2 /data/images/win2012.qcow2 \
      /data/images/win2012-50gb.qcow2
    Examining /data/images/win2012.qcow2 ...
    **********
    
    Summary of changes:
    
    /dev/sda1: This partition will be left alone.
    
    /dev/sda2: This partition will be resized from 15.7G to 49.7G.  The
        filesystem ntfs on /dev/sda2 will be expanded using the
        'ntfsresize' method.
    
    **********
    Setting up initial partition table on /data/images/win2012-50gb.qcow2 ...
    Copying /dev/sda1 ...
     100% [                                                                 ] 00:00
    Copying /dev/sda2 ...
     100% [                                                                 ] 00:00
    Expanding /dev/sda2 using the 'ntfsresize' method ...
    
    Resize operation completed with no errors. Before deleting the old
    disk, carefully check that the resized disk boots and works correctly.
    

lopp デバイス、kpartx、ネットワークブロックデバイス

libguestfs にアクセスできない場合、loop デバイス、kpartx、ネットワークブロックデバイスを使用して、イメージのファイルシステムをホストに直接マウントできます。

警告

このセクションに記載されたツールを用いて、信頼されないゲストイメージをマウントすることは、セキュリティーリスクがあります。それらにアクセスする場合、必ず guestfish や guestmount などの libguestfs ツール群を使用してください。詳細は Daniel Berrangé 氏の A reminder why you should never mount guest disk images on the host OS を参照してください。

raw イメージのマウント (LVM なし)

パーティション管理に LVM を使用していない raw 形式の仮想マシンイメージがある場合、losetup コマンドを使用して未使用の loop デバイスを見つけます。

# losetup -f
/dev/loop0

この例では、/dev/loop0 が空いています。loop デバイスを raw イメージに関連付けます。

# losetup /dev/loop0 fedora17.img

イメージがパーティションを一つだけ持つ場合、loop デバイスを直接マウントできます。

# mount /dev/loop0 /mnt

イメージが複数のパーティションを持つ場合、パーティションを別々のデバイス (/dev/mapper/loop0p1) として認識させるために kpartx を使用します。そして、ルートファイルシステムに対応するパーティションをマウントします。

# kpartx -av /dev/loop0

イメージがいわゆる 3 パーティション (/boot、/、swap) を持つ場合、パーティションごとに 1 つの新しいデバイスにすべきです。

$ ls -l /dev/mapper/loop0p*
brw-rw---- 1 root disk 43, 49 2012-03-05 15:32 /dev/mapper/loop0p1
brw-rw---- 1 root disk 43, 50 2012-03-05 15:32 /dev/mapper/loop0p2
brw-rw---- 1 root disk 43, 51 2012-03-05 15:32 /dev/mapper/loop0p3

root として、2番目のパーティションをマウントします。

# mkdir /mnt/image
# mount /dev/mapper/loop0p2 /mnt/image

完了後、クリーンアップします。

# umount /mnt/image
# rmdir /mnt/image
# kpartx -d /dev/loop0
# losetup -d /dev/loop0

raw イメージのマウント (LVM あり)

LVM を用いてパーティションを管理している場合、パーティションをホストに公開するために、前の例にあるとおりコマンド losetupkpartx を使用します。

# losetup -f
/dev/loop0
# losetup /dev/loop0 rhel62.img
# kpartx -av /dev/loop0

次に、LVM ボリュームグループを識別するために、vgscan コマンドを使用する必要があります。また、ボリュームをデバイスとして公開するために vgchange コマンドを実行します。

# vgscan
Reading all physical volumes. This may take a while...
Found volume group "vg_rhel62x8664" using metadata type lvm2
# vgchange -ay
2 logical volume(s) in volume group "vg_rhel62x8664" now active
# mount /dev/vg_rhel62x8664/lv_root /mnt

完了後、クリーンアップします。

# umount /mnt
# vgchange -an vg_rhel62x8664
# kpartx -d /dev/loop0
# losetup -d /dev/loop0

qcow2 イメージのマウント (LVM なし)

qcow2 イメージをマウントするために、 nbd (ネットワークブロックデバイス) カーネルモジュールを読み込む必要があります。この例は、今回の目的に十分である、16 個のブロックデバイスをサポートします。root として、以下のとおり実行します。

# modprobe nbd max_part=16

1 番目のブロックデバイス (/dev/nbd0) が現在未使用であると仮定して、 qemu-nbd コマンドと partprobe コマンドを使用して、ディスクパーティションを利用できます。root として以下のとおり実行します。

# qemu-nbd -c /dev/nbd0 image.qcow2
# partprobe /dev/nbd0

イメージがいわゆる 3 パーティション (/boot、/、swap) を持つ場合、パーティションごとに 1 つの新しいデバイスにすべきです。

$ ls -l /dev/nbd0*
brw-rw---- 1 root disk 43, 48 2012-03-05 15:32 /dev/nbd0
brw-rw---- 1 root disk 43, 49 2012-03-05 15:32 /dev/nbd0p1
brw-rw---- 1 root disk 43, 50 2012-03-05 15:32 /dev/nbd0p2
brw-rw---- 1 root disk 43, 51 2012-03-05 15:32 /dev/nbd0p3

注釈

If the network block device you selected was already in use, the initial qemu-nbd command will fail silently, and the /dev/nbd0p{1,2,3} device files will not be created.

イメージのパーティションが LVM で管理されていない場合、直接マウントできます。

# mkdir /mnt/image
# mount /dev/nbd0p2 /mnt/image

完了後、クリーンアップします。

# umount /mnt/image
# rmdir /mnt/image
# qemu-nbd -d /dev/nbd0

qcow2 イメージのマウント (LVM あり)

イメージのパーティションが LVM で管理されている場合、 qemu-nbdpartprobe を実行後、マウントできるデバイスとして LVM パーティションを認識するために、 vgscanvgchange -ay を使用する必要があります。

# modprobe nbd max_part=16
# qemu-nbd -c /dev/nbd0 image.qcow2
# partprobe /dev/nbd0
# vgscan
Reading all physical volumes. This may take a while...
Found volume group "vg_rhel62x8664" using metadata type lvm2
# vgchange -ay
2 logical volume(s) in volume group "vg_rhel62x8664" now active
# mount /dev/vg_rhel62x8664/lv_root /mnt

完了後、クリーンアップします。

# umount /mnt
# vgchange -an vg_rhel62x8664
# qemu-nbd -d /dev/nbd0