Skip to content

Apache CloudStack Ubuntu/KVM Install Guide

This is a build your own IaaS private cloud guide using Apache CloudStack, Ubuntu 22.04/24.04 (LTS) and KVM. If you’re new to Apache CloudStack, here a video for you: CloudStack 101: The Best Way to Build Your Private Cloud

First install Ubuntu 22.04/24.04 LTS on your x86_64 system that has at least 8GB RAM (prerably 16GB RAM or more) with Intel VT-X or AMD-V enabled. Ensure that the universe repository is enabled in /etc/apt/sources.list.

Install basic packages:

Terminal window
apt-get install openntpd openssh-server sudo vim htop tar

Optionally, if you’ve Intel based system install/update CPU microcode:

Terminal window
apt-get install intel-microcode

Allow the root user for ssh access using password, fix /etc/ssh/sshd_config. Change and remember the root password:

Terminal window
passwd root

Setup Linux bridges that will handle CloudStack’s public, guest, management and storage traffic. For simplicity, we will use a single bridge cloudbr0 to be used for all these networks. Install bridge utilities:

Terminal window
apt-get install bridge-utils

This guide assumes that you’re in a 192.168.1.0/24 network which is a typical RFC1918 private network.

Starting Ubuntu bionic, admins can use netplan to configure networking. The default installation creates a file at /etc/netplan/50-cloud-init.yaml that you should comment, and create a file at /etc/netplan/01-netcfg.yaml applying your network and interface/name specific changes:

/etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
eno1:
dhcp4: false
dhcp6: false
optional: true
bridges:
cloudbr0:
addresses: [192.168.1.10/24]
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
interfaces: [eno1]
dhcp4: false
dhcp6: false
parameters:
stp: false
forward-delay: 0
/etc/netplan/01-netcfg.yaml
ethernets:
eno1:
match:
macaddress: 00:01:2e:4f:f7:d0
mtu: 1550
dhcp4: false
dhcp6: false
enp3s0:
mtu: 1550

Apply network config and reboot/re-ssh:

Terminal window
netplan generate
netplan apply

For Ubuntu 22.04, 24.04 and onwards run this to setup the CloudStack repository:

Terminal window
mkdir -p /etc/apt/keyrings
wget -O- http://packages.shapeblue.com/release.asc | gpg --dearmor | sudo tee /etc/apt/keyrings/cloudstack.gpg > /dev/null
echo deb [signed-by=/etc/apt/keyrings/cloudstack.gpg] http://packages.shapeblue.com/cloudstack/upstream/debian/4.20 / > /etc/apt/sources.list.d/cloudstack.list
apt-get update -y

This should be run on all hosts where CloudStack software packages (management server, usage server, agent etc) needs to be installed.

Install CloudStack management server and MySQL server: (run as root, once the CloudStack repository is setup)

Terminal window
apt-get update -y
apt-get install cloudstack-management mysql-server

Optionally, if you want usage server you can run:

Terminal window
apt-get install cloudstack-usage

Make a note of the MySQL server’s root user password. Configure InnoDB settings in mysql server’s /etc/mysql/mysql.conf.d/mysqld.cnf:

[mysqld]
server_id = 1
sql-mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_ENGINE_SUBSTITUTION"
innodb_rollback_on_timeout=1
innodb_lock_wait_timeout=600
max_connections=1000
log-bin=mysql-bin
binlog-format = 'ROW'

Restart MySQL server and setup database:

Terminal window
systemctl restart mysql
cloudstack-setup-databases cloud:cloud@localhost --deploy-as=root:<root password, or leave default blank if MySQL server has no root password> -i <cloudbr0 IP here>

Install NFS server:

Terminal window
apt-get install nfs-kernel-server quota

Create exports:

Terminal window
echo "/export *(rw,async,no_root_squash,no_subtree_check)" > /etc/exports
mkdir -p /export/primary /export/secondary
exportfs -a

Configure and restart NFS server:

Terminal window
sed -i -e 's/^RPCMOUNTDOPTS="--manage-gids"$/RPCMOUNTDOPTS="-p 892 --manage-gids"/g' /etc/default/nfs-kernel-server
sed -i -e 's/^STATDOPTS=$/STATDOPTS="--port 662 --outgoing-port 2020"/g' /etc/default/nfs-common
echo "NEED_STATD=yes" >> /etc/default/nfs-common
sed -i -e 's/^RPCRQUOTADOPTS=$/RPCRQUOTADOPTS="-p 875"/g' /etc/default/quota
service nfs-kernel-server restart

Install KVM and CloudStack agent, configure libvirt:

Terminal window
apt-get install qemu-kvm cloudstack-agent

Note: configure the CloudStack repo if your KVM host is not also the management server

Enable VNC for console proxy:

Terminal window
sed -i -e 's/\#vnc_listen.*$/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf

On older Ubuntu versions (18.04/20.04), enable libvirtd in listen mode:

Terminal window
sed -i -e 's/.*libvirtd_opts.*/libvirtd_opts="-l"/' /etc/default/libvirtd

On Ubuntu 22.04, add LIBVIRTD_ARGS="--listen" to /etc/default/libvirtd instead:

Terminal window
echo LIBVIRTD_ARGS=\"--listen\" >> /etc/default/libvirtd

For Ubuntu 20.04/22.04/24.04 and later, the traditional socket/listen based configuration may not be supported, we can get the old behaviour as follows:

Terminal window
systemctl mask libvirtd.socket libvirtd-ro.socket libvirtd-admin.socket libvirtd-tls.socket libvirtd-tcp.socket
systemctl restart libvirtd

Configure libvirt to connect to libvirtd and not to per-driver daemons, especially important on newer distros such as EL9 and Ubuntu 24.04 by editing the /etc/libvirt/libvirt.conf and add the following:

/etc/libvirt/libvirt.conf
remote_mode="legacy"

Configure default libvirtd config:

Terminal window
echo 'listen_tls=0' >> /etc/libvirt/libvirtd.conf
echo 'listen_tcp=1' >> /etc/libvirt/libvirtd.conf
echo 'tcp_port = "16509"' >> /etc/libvirt/libvirtd.conf
echo 'mdns_adv = 0' >> /etc/libvirt/libvirtd.conf
echo 'auth_tcp = "none"' >> /etc/libvirt/libvirtd.conf
systemctl restart libvirtd

On certain hosts where you may be running docker and other services, you may need to add the following in /etc/sysctl.conf and then run sysctl -p:

/etc/sysctl.conf
net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-call-iptables = 0
Terminal window
sysctl -p

Optional: If you’ve a server vendor, they may fail to make each server unique and libvirtd can complain that servers are not unique. To make them unique setup host specific UUID in libvirtd config:

Terminal window
apt-get install uuid
UUID=$(uuid)
echo host_uuid = \"$UUID\" >> /etc/libvirt/libvirtd.conf
systemctl restart libvirtd

By default ufw may be disabled and this may not be required. If your system uses ufw (you can check using ufw status), you may run the following:

Terminal window
ufw allow mysql
ufw allow proto tcp from any to any port 22
ufw allow proto tcp from any to any port 1798
ufw allow proto tcp from any to any port 16509
ufw allow proto tcp from any to any port 16514
ufw allow proto tcp from any to any port 5900:6100
ufw allow proto tcp from any to any port 49152:49216

Alternatively, you can configure firewall rules using iptables for your management network:

Terminal window
# configure firewall rules to allow useful ports
NETWORK=192.168.1.0/24
iptables -A INPUT -s $NETWORK -m state --state NEW -p udp --dport 111 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 111 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 2049 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 32803 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p udp --dport 32769 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 892 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 875 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 662 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 8250 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 8080 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 9090 -j ACCEPT
iptables -A INPUT -s $NETWORK -m state --state NEW -p tcp --dport 16514 -j ACCEPT
apt-get install iptables-persistent

You must check and disable apparmour:

Terminal window
# Disable apparmour on libvirtd
ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/
ln -s /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper /etc/apparmor.d/disable/
apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd
apparmor_parser -R /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper

Start your cloud:

Terminal window
cloudstack-setup-management
systemctl status cloudstack-management
tail -f /var/log/cloudstack/management/management-server.log

After management server is UP, proceed to http://192.168.1.10(i.e. the cloudbr0-IP):8080/client and log in using the default credentials - username admin and password password.

The following is an example of how you can setup an advanced zone (without security groups) in a typical (home/private) 192.168.1.0/24 network.

  1. Create Zone:

    Go to Infrastructure > Zone and click on add zone button, select advanced zone and provide following configuration:

    Name - any name
    Public DNS 1 - 8.8.8.8
    Internal DNS1 - 192.168.1.1
    Hypervisor - KVM
  2. Setup Network

    Use the default, which is VLAN isolation method on a single physical nic (on the host) that will carry all traffic types (management, public, guest etc).

    Note: If you’ve iproute2 installed and host’s physical NIC MTUs configured, you can used VXLAN as well.

    Public traffic configuration:

    Gateway - 192.168.1.1
    Netmask - 255.255.255.0
    VLAN/VNI - (leave blank for vlan://untagged or in case of VXLAN use vxlan://untagged)
    Start IP - 192.168.1.20
    End IP - 192.168.1.50
  3. Pod Configuration:

    Name - any name
    Gateway - 192.168.1.1
    Start/end reserved system IPs - 192.168.1.51 - 192.168.1.80
  4. Guest traffic:

    VLAN/VNI range: 700-900
  5. Create a cluster with following:

    Name - any name
    Hypervisor - Choose KVM
  6. Add your default/first host:

    Hostname - 192.168.1.10
    Username - root
    Password - <password for root user, or leave blank to add by public key>

    Note: root user ssh-access is disabled by default, please enable it. The recommended approach is to add the KVM host using ssh public-key based access, add the management server SSH public key which is usually at /var/cloudstack/management/.ssh/id_rsa.pub to the root user of the KVM host(s) at /root/.ssh/authorized_keys.

  7. Add primary storage:

    Name - any name
    Scope - zone-wide
    Protocol - NFS
    Server - 192.168.1.10
    Path - /export/primary
  8. Add secondary storage:

    Provider - NFS
    Name - any name
    Server - 192.168.1.10
    Path - /export/secondary
  9. Next, click Launch Zone which will perform following actions:

    Create Zone
    Create Physical networks:
    - Add various traffic types to the physical network
    - Update and enable the physical network
    - Configure, enable and update various network provider and elements such as the virtual network element
    Create Pod
    Configure public traffic
    Configure guest traffic (vlan range for physical network)
    Create Cluster
    Add host
    Create primary storage (also mounts it on the KVM host)
    Create secondary storage
    Complete zone creation
  10. Enable Zone

    Finally, confirm and enable the zone. Wait for the system VMs to come up under Infrastructure -> System VMs, then you can proceed using your IaaS cloud.

You can register publicly available cloud-init enabled guest templates such as:

If you’re stuck on to something and have questions, then:

Further reading:

A page with a wide variety of different Markdown syntax or components to show how these look together. See the following pages for individual examples.

Be not afeard; the isle is full of noises,
Sounds and sweet airs, that give delight and hurt not.

Check this out

Interesting content you want to highlight.

Other feature

More information you want to share.

Computer stuff

Build internet things with your computation machine.

Starlight ready

Just add Starlight and this theme comes to life.

  • Note
  • Success
  • Tip
  • Caution
  • Danger
  • Small
  • Medium
  • Large
example.astro
---
// this is a code block example
---
<p>Code can include something dynamic: {Astro.props.variable}</p>
Or highlight important lines!
Including insertions or deletions.
Terminal window
echo "Welcome, world!"

Code block without a frame:

// for example
console.log('Welcome, world!');
labeled-line-markers.jsx
<button
role="button"
{...props}
value={value}
className={buttonClassName}
disabled={disabled}
active={active}
>
{children && !active && (typeof children === 'string' ? <span>{children}</span> : children)}
</button>
  • astro.config.mjs
  • package.json
  • Directorysrc
    • Directorycomponents
      • Header.astro
      • Title.astro
    • Directorypages/
Get started

Configuration Reference

Learn more

Sirius, Vega, Betelgeuse

Where and when is the Andromeda constellation most visible?

The Andromeda constellation is most visible in the night sky during the month of November at latitudes between +90° and −40°.

LeftCenteredRight
This is leftText is centeredAnd this is right-aligned
More textEven more textAnd even more to the right