Creating a Morpheus VMware Image¶
Morpheus comes out of the box with a default set of blueprints for use in many modern deployment scenarios. These consist mostly of base operating system images with a few additional adjustments. These adjustments typically include the addition of cloud-init (which is highly recommended to be used in most environments, but not mandatory). However, in many on-premise deployments there are custom image requirements as well as networking requirements. This guide will go over how to create a VMware Images for use within Morpheus.
Creating a Windows Image¶
Supported Versions¶
2008R2, 2012, 2012R2, 2016, 2019, 2022
Image Preparation¶
Create a new machine in VMware vCenter and install a base version of your preferred Windows build. The smaller the VMDK drive, typically the faster you can clone and deploy. Utilizing Morpheus, provisioning and post deploy scripts can expand drives to desired sizing.
Ensure VMware Tools is installed on the operating system.
Apply any service packs / updates to the operating system.
Configure WinRM to allow remote management and open the firewall. This is optional if using VMware Tools RPC mode for agent install and Morpheus Agent for guest exec. To enable this, under local computer Administrator, open a command prompt and run
winrm quickconfig
Install .Net at least 4.5.2
Ensure Windows Firewall will allow WinRM connections.
Shutdown the virtual machine and convert to a template.
Note
WinRM is not required and is used as a fallback when using vmtools guest exec and customizations
Note
Morpheus will sysprep images based on the “Force Guest Customizations” flag under the Virtual Image’s settings when using DHCP. Ensure a sysprep has not been performed on the template if this flag is enabled or if using Static IPs/IP Pools when provisioning, which will always use Guest Customizations and trigger a sysprep.
Creating a CentOS/RHEL 7 Image¶
Create a new virtual machine in VMware vCenter and install a base version of your preferred Linux distro build. If you are using cloud init as part of your image you will need to ensure your virtual machine has a cdrom.
Before installing the operating system setup a single
ext
orxfs
partition without a swap disk (This is so that growpart can extend the disk. growpart currently does not support lvm)Install the distro and apply any updates to the operating system and security updates
Install cloud-init using command
yum install cloud-init
Install cloud-utils-growpart using command
yum install cloud-utils-growpart
Install open-vm-tools using command
yum install open-vm-tools
Install git by running
yum install git
Install epel-release repo using command
yum install epel-release
selinux set to permissive (enforced can cause problems with cloud-init)
sudo vi /etc/selinux/config
Cloud-Init¶
To get started with a base CentOS image we first install cloud-init. This is a relatively simple process using yum:
yum -y install epel-release
yum -y install git wget ntp curl cloud-init dracut-modules-growroot
rpm -qa kernel | sed 's/^kernel-//' | xargs -I {} dracut -f /boot/initramfs-{}.img {}
There are two parts to this yum installation. We are first ensuring some core dependencies are installed for automation as well as cloud-init. git for example is installed for use by ansible playbook automation down the line and is therefore optional if not using ansible. The dracut-modules-growroot is responsible for resizing the root partition upon first boot to match the virtual disk size that was potentially adjusted during provisioning.
A great benefit to using cloud-init is credentials don’t have to be locked into the blueprint. It is advisable, within Morpheus , to configure the default cloud-init user that gets created when the vm boots automatically by cloud-init. This is located in Administration > Settings > Provisioning, within the Cloud-Init Settings section.
Network Interfaces¶
A slightly annoying change with centOS 7 is that the network interfaces have changed naming convention. You may notice when running ifconfig that the primary network interface is set to something like ens2344 or some other random number. This naming is dynamic typically by hardware id and we don’t want this to fluctuate when provisioning the blueprint in various VMware environments. Fortunately, there is a way to turn this functionality off and restore the interface back to eth0.
Firstly we need to adjust our bootloader to disable interface naming like this.
sed -i -e 's/quiet/quiet net.ifnames=0 biosdevname=0/' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
The above command adds a few arguments to the kernel args list (namely net.ifnames=0
and biosdevname=0
. It may be useful to view the /etc/default/grub
file and ensure these settings were indeed applied.
The next step is to adjust the network-scripts in centOS. we need to ensure we have a file called /etc/sysconfig/network-scripts/ifcfg-eth0
Below is a script that we run on our packer builds to prepare the machines network configuration files.
export iface_file=$(basename "$(find /etc/sysconfig/network-scripts/ -name 'ifcfg*' -not -name 'ifcfg-lo' | head -n 1)")
export iface_name=${iface_file:6}
echo $iface_file
echo $iface_name
sudo mv /etc/sysconfig/network-scripts/$iface_file /etc/sysconfig/network-scripts/ifcfg-eth0
sudo sed -i -e "s/$iface_name/eth0/" /etc/sysconfig/network-scripts/ifcfg-eth0
sudo bash -c 'echo NM_CONTROLLED=\"no\" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
This script tries to ensure there is a new ifcfg-eth0 config created to replace the old ens config file. Please do verify this config exists after running. If it does not you will have to be sure to build one on your own.
TYPE=Ethernet
DEVICE=eth0
NAME=eth0
ONBOOT=yes
NM_CONTROLLED="no"
BOOTPROTO="dhcp"
DEFROUTE=yes
Creating a CentOS/RHEL 8 Image¶
Create a new virtual machine in VMware vCenter and install a base version of your preferred Linux build. You must be running ESXi 6.7 Update 2 or later.
Prepare The New CentOS 8/RHEL8 Image¶
Install epel-release:
yum -y install epel-release
(This step is not necessary for RHEL)Install git, wget, curl, cloud-init, cloud-utils-gropart, and open-vm-tools:
yum -y install git wget curl cloud-init cloud-utils-growpart open-vm-tools
Update:
yum -y update
Finally run:
rpm -qa kernel | sed 's/^kernel-//' | xargs -I {} dracut -f /boot/initramfs-{}.img {}
SELinux Settings¶
If allowed by your internal IT policies, set SELinux to permissive to avoid potential issues with cloud-init down the road.
Edit the following:
vi /etc/selinux/config
Make the following change:
setenforce 0
Network Interfaces¶
Run the following to rename the network NIC. Values inside angle brackets should be filled in with the appropriate value for your environment (ex. <varname>):
sed -i -e 's/quiet/quiet net.ifnames=0 biosdevname=0/' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
(location may be different, could be located at /boot/efi/EFI/centos/grub.cfg)ifdown <orginal-nic>
mv /etc/sysconfig/network-scripts/<orginal-nic> /etc/sysconfig/network-scripts/ifcfg-eth0
(this changes name/device to eth0)Edit
ifcfg-eth0
and change the NAME toeth0
bash -c 'echo NM_CONTROLLED=\"no\" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
ip link set <orginal-nic> down
ip link set <orginal-nic> name eth0
ip link set eth0 up
ifup eth0
Final VMWare Tasks¶
Detach any install media
Shutdown the VM
Convert the VM to template on the Morpheus side
Refresh the Morpheus Cloud to allow the new template to sync
Creating an Ubuntu 20.04 Image¶
Download the Ubuntu 20.04 ISO from Canonical, and upload the base image to vCetner. Then, create a new virtual machine in vCenter.
Note
Since we’ll include cloud-init with our image, we will need to ensure the virtual machine has a cdrom. Select the Ubuntu 20.04 ISO we just downloaded from the CD/DVD drive dropdown menu when creating the new virtual machine.
Before installing the operating system, set up a single ext partition without a swap disk. Then, continue on installing Ubuntu making the following selections during the setup process:
Update to the latest installer if a later version is available
Use the entire disk and deselect the option to set up the disk as an LVM group
Configure an account and set a password
Opt to install OpenSSH Server
Other optional packages aren’t needed for this basic Ubuntu image
Complete the installation process and reboot the machine. Update the package list and apply any upgrades:
apt-get update
apt-get upgrade
Change the network interface to eth0
by editing /etc/default/grub
. The line GRUB_CMDLINE_LINUX=""
should be edited to GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"
.
Update GRUB:
update-grub
Update the 70-persistent-net.rules
file:
cat << EOF > /etc/udev/rules.d/70-persistent-net.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{dev_id}=="0x0", ATTR{type}=="1", NAME="eth0"
EOF
Remove subiquity-disable-cloudinit-networking.cfg
as cloud-init will skip network configuration if it’s present:
rm -f /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg
Update 99-pve.cfg
:
cat << EOF > /etc/cloud/cloud.cfg.d/99-pve.cfg
datasource_list: [ConfigDrive, NoCloud]
EOF
Remove Netplan files, they will not be regenerated if they exist:
rm -f /etc/netplan/00-installer-config.yaml
rm -f /etc/netplan/50-cloud-init.yaml
Run cloud-init clean:
cloud-init clean
Next, reboot the system and confirm the network interface is labeled eth0
once the machine comes back up. Then, clear BASH history for root. The history entry has a copy in the memory and it will flush back to the file when you log out. You can avoid this with the following command:
cat /dev/null > ~/.bash_history && history -c && exit
Shutdown the system:
shutdown -h now
Convert the VM to a template in vCenter before moving back to Morpheus to onboard the image and use it to begin building your provisioning library.
Gotchas¶
SELinux can cause issues with cloud-init when in enforced mode. It may be advisable to set this to permissive unless it is mandatory within your organization to use an enforced SELinux configuration. If that is the case please see the documentation for the cloud_init_t security policies.
Network Manager will also prevent the required restart of the Network Service when assigning static IP’s. Disable Network Manager when possible or Static IP assignment may not work until the Network Service is restarted manually.
A Note on Proxies¶
Proxy configurations are known to vary in some organizations and makes building a base blueprint a little more difficult. In order to fully configure proxies a few environment variables must be set in the /etc/environment file (This can be done automatically in a default user-data script for cloud-init as well in edit cloud).
http_proxy="http://myproxyaddress:8080"
https_proxy="http://myproxyaddress:8080"
ftp_proxy="http://myproxyaddress:8080"
no_proxy=127.0.0.1,localhost,applianceUrl
https_no_proxy=127.0.0.1,localhost,applianceUrl
Important
It is very important to properly set the no_proxy list (applianceUrl) should be replaced with the actual appliance url. In future releases, morpheus plans to automatically take care of this.
Note
If using cloud-init agent install mode these settings need to be set in the custom Cloud-Init User data section of “Edit Cloud” or “Edit Virtual Image”
Important
If using this virtual machine as a docker host, proxy settings must also be configured in the docker config. See Docker guides for instructions on how to properly set this. If necessary this can be wrapped in a task automation workflow for your own use.