The following tools will help you to create KVM VMS or domains using CentOS Cloud images. Those images can be downloaded from http://cloud.centos.org/centos/7/images. Those images are ready to use with cloud-init scripts. cloud-init basically requires two files in a CD ISO image you have to insert during the VM creation with virt-install. Basically this post we will resize and manage cloud-init in KVM for Centos QCOW2 images using a /bin/bash script. We’ll start creating user-data and meta-data files and put them into a CD ISO image like this.
#!/bin/bash cat > ./user-data << _EOF_ #cloud-config # Hostname management preserve_hostname: False hostname: server_a fqdn: server_a.example.com # Remove cloud-init when finished with it runcmd: - [ yum, -y, remove, cloud-init ] - echo "GATEWAY=192.168.1.1" >> /etc/sysconfig/network - echo "nameserver 8.8.8.8" >> /etc/resolv.conf - echo "domain example.com" >> /etc/resolv.conf - /etc/init.d/network restart - ifdown eth0 - ifup eth0 # Configure where output will go output: all: ">> /var/log/cloud-init.log" users: - name: centos chpasswd: list: | centos: reverse expire: False # configure interaction with ssh server ssh_svcname: ssh ssh_deletekeys: True ssh_genkeytypes: ['rsa', 'ecdsa'] # Install my public ssh key to the first user-defined user configured # in cloud.cfg in the template (which is centos for CentOS cloud images) ssh_authorized_keys: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCetM2yjjUNYO8pm4IJxj8KzOWJirdOYu/VNZvhQ95hcgvi6VtgDhwFrCsPRqCzOD8+XSfI2evkvNCsj8LOpB8K3VUJxsqNzcKuv5l2157rl6+XksyH8bLHUxA2XG1zPIYeFs+2cwbNvENnKRzl7ZgEeCRYKbS+OcAOmk0+rGBx7rHTSg+MfkLtX3VgfNdUxx+ZKeAMqDkSuKSTlOZJDjIbAW0pCffp mau@nuage.lab _EOF_ # Manging metadata cloud-init now cat > meta-data << _EOF_ instance-id: server_a local-hostname: server_a _EOF_ genisoimage -output cidata.iso -volid cidata -joliet -r user-data meta-data # this script is part of the post: "Resize and manage cloud-init in KVM for Centos QCOW2 images"
Then, finally you can just add that iso as a CD image into your virt-install command and wait for a couple of minutes.
Now, if you want to add a little more and create a more advanced script with arguments, we can also add the resize QCOW2 images into the process.
Check this example where I am using a simple linux bridge called bridge0 linked to enp0s3 interface in this case.
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-bridge0 DEVICE="bridge0" ONBOOT="yes" TYPE=Bridge BOOTPROTO=static IPADDR=192.168.1.5 NETMASK=255.255.255.0
the wired interface:
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-enp0s3 BOOTPROTO="static" DEVICE="enp0s3" NM_CONTROLLED="no" ONBOOT="yes" BRIDGE=bridge0
I’ll create domains using a fixed IP address and resizing the boot disk. The script that I am showing it’s based on Giovanni’s Post: Create a Linux Lab on KVM Using Cloud Images.
I am highlighting some lines over the script that you may change to fit what you have. Be aware I am using virt-install and virt-resize. be sure to install them in advance.
virt-resize and qemu-img can take a long time in processing depending on the size of the disk.
Check on the cloud-init details. I am using metadata to change the IP address. Also, you would change the ssh public key. Also, I am setting centos’s password to reverse if you want to check this out thru console. Don’t forget to install virt-install and libguestfs-tools packages to add a root password.
Well, then, let’s go with our script to Resize and manage cloud-init in KVM for Centos QCOW2 images.
#!/bin/bash # Resize and manage cloud-init in KVM for Centos QCOW2 images # Usage ./script_name <node-name> <memory> <vcpus> <disk-GB> <ip-address> if ! [ $# -eq 5 ]; then echo "Usage: $0 <node-name> <memory> <vcpus> <disk-GB> <ip-address>" exit 1 fi # Check if domain already exists virsh dominfo $1 > /dev/null 2>&1 if [ "$?" -eq 0 ]; then echo -n "[WARNING] $1 already exists. " read -p "Do you want to overwrite $1 [y/N]? " -r if [[ $REPLY =~ ^[Yy]$ ]]; then echo "" else echo -e "\nNot overwriting $1. Exiting..." exit 1 fi fi # Directory to store images DIR=/var/lib/libvirt/images # Location of cloud image IMAGE=$DIR/CentOS-6-x86_64-GenericCloud.qcow2 # Amount of RAM in MB MEM=$2 # Number of virtual CPUs CPUS=$3 DISK_GB=$4 IPADDR=$5 GWTY=192.168.1.254 MSK=255.255.255.0 DNS=192.168.1.1 DOMAIN=nuage.lab # Cloud init files USER_DATA=user-data META_DATA=meta-data CI_ISO=$1-cidata.iso DISK=$1.qcow2 # Bridge for VMs (default on Fedora is bridge0) BRIDGE=bridge0 # Start clean rm -rf $DIR/$1 mkdir -p $DIR/$1 pushd $DIR/$1 > /dev/null # Create log file touch $1.log echo "$(date -R) Destroying the $1 domain (if it exists)..." # Remove domain with the same name virsh destroy $1 >> $1.log 2>&1 virsh undefine $1 >> $1.log 2>&1 # cloud-init config: set hostname, remove cloud-init package, # and add ssh-key cat > $USER_DATA << _EOF_ #cloud-config # Hostname management preserve_hostname: False hostname: $1 fqdn: $1.$DOMAIN # Remove cloud-init when finished with it runcmd: - [ yum, -y, remove, cloud-init ] - echo "GATEWAY=$GWTY" >> /etc/sysconfig/network - echo "nameserver $DNS" >> /etc/resolv.conf - echo "domain $DOMAIN" >> /etc/resolv.conf - /etc/init.d/network restart - ifdown eth0 - ifup eth0 # Configure where output will go output: all: ">> /var/log/cloud-init.log" chpasswd: list: | centos:reverse expire: False # configure interaction with ssh server ssh_svcname: ssh ssh_deletekeys: True ssh_genkeytypes: ['rsa', 'ecdsa'] # Install my public ssh key to the first user-defined user configured # in cloud.cfg in the template (which is centos for CentOS cloud images) ssh_authorized_keys: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCetM2yjjUNYO8pm4IJxj8KzOWJirdOYu/VNZvhQ95hcgvi6VtgDhwFrCsPRqCzOD8+XSfI2evkvNCsj8LOpB8K3VUJxsqNzcKuv5l2157rl6+XksyH8bLHUxA2XG1zPIYeFs+2cwbNvENnKRzl7ZgEeCRYKbS+OcAOmk0+rGBx7rHTSg+MfkLtX3VgfNdUxx+ZKeAMqDkSuKSTlOZJDjIbAW0pCffp mau@nuage.lab _EOF_ # Manging metadata cloud-init now cat > $META_DATA << _EOF_ instance-id: $1 local-hostname: $1 network-interfaces: | iface eth0 inet static address $IPADDR network ${IPADDR%.*}.0 netmask $MSK broadcast ${IPADDR%.*}.255 _EOF_ echo "$(date -R) Copying template image..." echo "INFO: qemu-img create -f qcow2 -o preallocation=metadata $DISK ${DISK_GB}G" qemu-img create -f qcow2 -o preallocation=metadata $DISK ${DISK_GB}G virt-resize --expand /dev/sda1 $IMAGE $DISK echo "Converting and sizing $IMAGE to $DISK" #cp $IMAGE $DISK # Create CD-ROM ISO with cloud-init config echo "$(date -R) Generating ISO for cloud-init..." genisoimage -output $CI_ISO -volid cidata -joliet -r $USER_DATA $META_DATA &>> $1.log echo "$(date -R) Installing the domain and adjusting the configuration..." echo "[INFO] Installing with the following parameters:" echo "virt-install --import --name $1 --ram $MEM --vcpus $CPUS --disk \ $DISK,format=qcow2,bus=virtio --disk $CI_ISO,device=cdrom --network \ bridge=$BRIDGE,model=virtio --os-type=linux --os-variant=rhel6 --noautoconsole --noapic" virt-install --import --name $1 --ram $MEM --vcpus $CPUS --disk \ $DISK,format=qcow2,bus=virtio --disk $CI_ISO,device=cdrom --network \ bridge=$BRIDGE,model=virtio --os-type=linux --os-variant=rhel6 --noautoconsole --noapic \ --accelerate #virsh console $1 FAILS=0 while true; do ping -c 1 $IPADDR >/dev/null 2>&1 if [ $? -ne 0 ] ; then #if ping exits nonzero... FAILS=$[FAILS + 1] echo "INFO: Checking if server $1 with IP $IPADDR is online. ($FAILS out of 20)" else echo "INFO: server $1 is alive. let's remove cloud init files" break fi if [ $FAILS -gt 20 ]; then echo "INFO: Server is still offline after 20min. I will end here!" exit fi sleep 60 done # Eject cdrom echo "$(date -R) Cleaning up cloud-init..." virsh change-media $1 hda --eject --config >> $1.log # Remove the unnecessary cloud init files rm $USER_DATA $CI_ISO echo "$(date -R) DONE. SSH to $1 using $IP, with username 'centos'." popd > /dev/null #End of script "Resize and manage cloud-init in KVM for Centos QCOW2 images" #Check more tips like those in cloud-native-everything.com
Running the script
The expected output is:
[root@localhost ~]# ./virt-create.sh test 1024 1 12 192.168.1.7 [WARNING] test already exists. Do you want to overwrite test [y/N]? y Mon, 01 Aug 2016 10:57:21 -0500 Destroying the test domain (if it exists)... Mon, 01 Aug 2016 10:57:22 -0500 Copying template image... INFO: qemu-img create -f qcow2 -o preallocation=metadata test.qcow2 12G Formatting 'test.qcow2', fmt=qcow2 size=12884901888 encryption=off cluster_size=65536 preallocation='metadata' lazy_refcounts=off Examining /var/lib/libvirt/images/CentOS-6-x86_64-GenericCloud.qcow2 ... 100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ 00:00 ********** Summary of changes: /dev/sda1: This partition will be resized from 8.0G to 12.0G. The filesystem ext4 on /dev/sda1 will be expanded using the 'resize2fs' method. ********** Setting up initial partition table on test.qcow2 ... Copying /dev/sda1 ... 100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ 00:00 100% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒⟧ 00:00 Expanding /dev/sda1 using the 'resize2fs' method ... Resize operation completed with no errors. Before deleting the old disk, carefully check that the resized disk boots and works correctly. Converting and sizing /var/lib/libvirt/images/CentOS-6-x86_64-GenericCloud.qcow2 to test.qcow2 Mon, 01 Aug 2016 11:00:47 -0500 Generating ISO for cloud-init... Mon, 01 Aug 2016 11:00:47 -0500 Installing the domain and adjusting the configuration... [INFO] Installing with the following parameters: virt-install --import --name test --ram 1024 --vcpus 1 --disk test.qcow2,format=qcow2,bus=virtio --disk test-cidata.iso,device=cdrom --network bridge=bridge0,model=virtio --os-type=linux --os-variant=rhel6 --noautoconsole --noapic WARNING KVM acceleration not available, using 'qemu'<span data-mce-type="bookmark" id="mce_SELREST_end" data-mce-style="overflow:hidden;line-height:0" style="overflow:hidden;line-height:0" ></span> Starting install... Creating domain... | 0 B 00:00:00 Domain creation completed. INFO: Checking if server test with IP 192.168.1.7 is online. (1 out of 20) INFO: Checking if server test with IP 192.168.1.7 is online. (2 out of 20) INFO: Checking if server test with IP 192.168.1.7 is online. (3 out of 20) INFO: Checking if server test with IP 192.168.1.7 is online. (4 out of 20) INFO: Checking if server test with IP 192.168.1.7 is online. (5 out of 20) INFO: server test is alive. let's remove cloud init files Mon, 01 Aug 2016 11:06:03 -0500 Cleaning up cloud-init... Mon, 01 Aug 2016 11:06:03 -0500 DONE. SSH to test using , with username 'centos'.
See you later and thanks for checking this out: “Resize and manage cloud-init in KVM for Centos QCOW2 images”