kvm自动给虚拟机分配IP
kvm生成一台新机器后,并不能自动分配新的ip。本文介绍了基于php语言,结合libvirt一系列的工具,实现通过命令行对虚拟机进行克隆和自动ip分配的方案。
前置条件
克隆来源的domain里边的文件已经被删除:/etc/udev/rules.d/70-persistent-net.rules。
实现流程
实现代码
<?php $opts = getopt('d:', [ 'ip:', 'old:', 'new:', ]); if (empty($opts)) { help(); } define('IMG_DIR', '/data/vm-images/'); function help() { echo << Usage: php clone.php --ip [ip] --old [domain] --new [domain] ip 创建的domain的ip,选填 old 从哪个domain复制,默认为standard new 新domain的名称,必填 HELP; exit(1); } $ip = ''; if (isset($opts['ip'])) { $ip = $opts['ip']; } $old = 'standard'; if (isset($opts['old'])) { $old = $opts['old']; } if (!isset($opts['new'])) { help(); } $new = $opts['new']; $file = IMG_DIR.$new.'.img'; echo '克隆镜像'.PHP_EOL; $cmd = sprintf('virt-clone -o %s -n %s -f %s', $old, $new, $file); echo $cmd.PHP_EOL; system($cmd, $status); if ($status === 0) { echo '镜像克隆成功'.PHP_EOL; } if (!$ip) { exit; } $cmd = sprintf('cat /etc/libvirt/qemu/%s.xml |grep -E "(uuid|<mac address)"', $new); exec($cmd, $lines, $status); if ($status !== 0) { die('获取配置失败'); } $uuid = ''; $mac = ''; foreach($lines as $line) { if (preg_match('#uuid>([^<]+)<#', $line, $ms)) { $uuid = $ms[1]; } elseif (preg_match('#address\=\'([^\']+)\'#', $line, $ms)) { $mac = $ms[1]; } } var_dump($uuid, $mac); unset($lines); echo "获取网卡配置".PHP_EOL; $domFile = '/etc/sysconfig/network-scripts/ifcfg-eth0'; $cmd = sprintf('virt-cat -d %s %s', $new, $domFile); echo $cmd.PHP_EOL; exec($cmd, $lines, $status); if ($status !== 0) { die('获取网卡配置失败'); } foreach($lines as &$line) { list($key, $value) = explode('=', $line); switch($key) { case 'HWADDR': $line = $key.'='.$mac; break; case 'IPADDR': $line = $key.'='.$ip; break; case 'UUID': $line = $key.'='.$uuid; break; } } $ethFile = __DIR__.'/tmp/'.$new.'/ifcfg-eth0'; if (!is_dir(dirname($ethFile))) { mkdir(dirname($ethFile), 0755, true); } file_put_contents($ethFile, implode("\n", $lines)); unset($lines); echo "替换网卡文件".PHP_EOL; $cmd = sprintf('virt-copy-in -d %s %s %s', $new, $ethFile, dirname($domFile)); echo $cmd.PHP_EOL; system($cmd, $status); if ($status !==0) { die("写入网卡文件失败"); } echo "写入网卡文件成功".PHP_EOL; echo "克隆成功!".PHP_EOL;