OpenStack has become the de facto standard for building private cloud infrastructure, offering the flexibility and control that many enterprises require. This comprehensive guide will walk you through deploying a production-ready OpenStack cloud on Rocky Linux, providing you with your own Infrastructure-as-a-Service (IaaS) platform.
Understanding OpenStack Architecture
OpenStack is a modular cloud platform consisting of several integrated components:
- Keystone: Identity and authentication service
- Glance: Image service for VM templates
- Nova: Compute service for VM management
- Neutron: Networking service
- Cinder: Block storage service
- Horizon: Web-based dashboard
- Swift: Object storage service
- Heat: Orchestration service
Prerequisites and Planning
Hardware Requirements
For a minimal production deployment:
- Controller Node: 8 CPU cores, 16GB RAM, 100GB SSD
- Compute Nodes (2+): 16 CPU cores, 32GB RAM, 500GB SSD
- Storage Node: 8 CPU cores, 16GB RAM, 1TB+ storage
- Network: 10Gbps recommended, minimum 1Gbps
Network Architecture
Plan your network topology:
- Management Network: 192.168.1.0/24
- Provider Network: 10.0.0.0/24 (External/Public)
- Overlay Network: 172.16.0.0/12 (Tenant networks)
- Storage Network: 192.168.2.0/24 (Optional)
Software Requirements
- Rocky Linux 9 (minimal installation)
- SELinux in permissive mode (for initial setup)
- Firewall configured appropriately
- Time synchronization (chrony)
Preparing the Environment
Initial System Configuration
On all nodes, perform base configuration:
# Set hostname (example for controller)
sudo hostnamectl set-hostname controller.openstack.local
# Update system
sudo dnf update -y
# Install base packages
sudo dnf install -y python3 python3-pip wget vim net-tools
# Disable firewall temporarily (configure properly later)
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# Set SELinux to permissive
sudo setenforce 0
sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config
# Configure hosts file
cat <<EOF | sudo tee -a /etc/hosts
192.168.1.10 controller controller.openstack.local
192.168.1.20 compute1 compute1.openstack.local
192.168.1.21 compute2 compute2.openstack.local
192.168.1.30 storage storage.openstack.local
EOF
Network Configuration
Configure network interfaces on controller:
# Management interface
sudo nmcli connection modify ens160 ipv4.addresses 192.168.1.10/24
sudo nmcli connection modify ens160 ipv4.gateway 192.168.1.1
sudo nmcli connection modify ens160 ipv4.dns 8.8.8.8
sudo nmcli connection modify ens160 ipv4.method manual
sudo nmcli connection up ens160
# Provider interface (no IP)
sudo nmcli connection add type ethernet con-name provider ifname ens192
sudo nmcli connection modify provider ipv4.method disabled ipv6.method ignore
sudo nmcli connection up provider
Time Synchronization
Configure NTP on all nodes:
# Install and configure chrony
sudo dnf install -y chrony
# On controller
sudo sed -i 's/^pool/#pool/g' /etc/chrony.conf
echo "server time.google.com iburst" | sudo tee -a /etc/chrony.conf
echo "allow 192.168.1.0/24" | sudo tee -a /etc/chrony.conf
# On compute/storage nodes
sudo sed -i 's/^pool/#pool/g' /etc/chrony.conf
echo "server controller iburst" | sudo tee -a /etc/chrony.conf
# Start service
sudo systemctl enable chronyd
sudo systemctl restart chronyd
# Verify
chronyc sources
Installing OpenStack Packages
Enable OpenStack Repository
On all nodes:
# Install OpenStack repository
sudo dnf config-manager --enable crb
sudo dnf install -y centos-release-openstack-yoga
# Update packages
sudo dnf update -y
# Install OpenStack client
sudo dnf install -y python3-openstackclient
# Install OpenStack SELinux policies
sudo dnf install -y openstack-selinux
Setting Up Database and Message Queue
Install MariaDB (Controller Node)
# Install MariaDB
sudo dnf install -y mariadb mariadb-server python3-PyMySQL
# Configure MariaDB
cat <<EOF | sudo tee /etc/my.cnf.d/openstack.cnf
[mysqld]
bind-address = 192.168.1.10
default-storage-engine = innodb
innodb_file_per_table = on
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8
EOF
# Start and enable service
sudo systemctl enable mariadb
sudo systemctl start mariadb
# Secure installation
sudo mysql_secure_installation
Install RabbitMQ (Controller Node)
# Install RabbitMQ
sudo dnf install -y rabbitmq-server
# Start and enable service
sudo systemctl enable rabbitmq-server
sudo systemctl start rabbitmq-server
# Add OpenStack user
sudo rabbitmqctl add_user openstack RABBIT_PASS
sudo rabbitmqctl set_permissions openstack ".*" ".*" ".*"
# Enable management plugin
sudo rabbitmq-plugins enable rabbitmq_management
# Verify
sudo rabbitmqctl list_users
Install Memcached (Controller Node)
# Install Memcached
sudo dnf install -y memcached python3-memcached
# Configure Memcached
sudo sed -i 's/127.0.0.1/192.168.1.10/g' /etc/sysconfig/memcached
# Start and enable service
sudo systemctl enable memcached
sudo systemctl start memcached
Installing Keystone (Identity Service)
Database Setup for Keystone
# Create Keystone database
mysql -u root -p <<EOF
CREATE DATABASE keystone;
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'KEYSTONE_DBPASS';
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'KEYSTONE_DBPASS';
FLUSH PRIVILEGES;
EOF
Install and Configure Keystone
# Install packages
sudo dnf install -y openstack-keystone httpd python3-mod_wsgi
# Configure Keystone
sudo cp /etc/keystone/keystone.conf /etc/keystone/keystone.conf.bak
sudo crudini --set /etc/keystone/keystone.conf database connection mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone
sudo crudini --set /etc/keystone/keystone.conf token provider fernet
# Populate database
sudo -u keystone keystone-manage db_sync
# Initialize Fernet keys
sudo keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
sudo keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
# Bootstrap Keystone
sudo keystone-manage bootstrap --bootstrap-password ADMIN_PASS \
--bootstrap-admin-url http://controller:5000/v3/ \
--bootstrap-internal-url http://controller:5000/v3/ \
--bootstrap-public-url http://controller:5000/v3/ \
--bootstrap-region-id RegionOne
Configure Apache for Keystone
# Configure Apache
sudo sed -i 's/#ServerName www.example.com:80/ServerName controller/g' /etc/httpd/conf/httpd.conf
# Create symlink
sudo ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/
# Start services
sudo systemctl enable httpd
sudo systemctl start httpd
# Create admin credentials file
cat <<EOF > ~/admin-openrc
export OS_USERNAME=admin
export OS_PASSWORD=ADMIN_PASS
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
EOF
# Source credentials
source ~/admin-openrc
# Verify
openstack token issue
Create Service Project and Users
# Create service project
openstack project create --domain default --description "Service Project" service
# Create demo project
openstack project create --domain default --description "Demo Project" demo
# Create demo user
openstack user create --domain default --password DEMO_PASS demo
# Create user role
openstack role create user
# Add user role to demo user
openstack role add --project demo --user demo user
Installing Glance (Image Service)
Database Setup for Glance
mysql -u root -p <<EOF
CREATE DATABASE glance;
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY 'GLANCE_DBPASS';
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY 'GLANCE_DBPASS';
FLUSH PRIVILEGES;
EOF
Configure Glance
# Create Glance user
source ~/admin-openrc
openstack user create --domain default --password GLANCE_PASS glance
openstack role add --project service --user glance admin
# Create Glance service
openstack service create --name glance --description "OpenStack Image" image
# Create endpoints
openstack endpoint create --region RegionOne image public http://controller:9292
openstack endpoint create --region RegionOne image internal http://controller:9292
openstack endpoint create --region RegionOne image admin http://controller:9292
# Install packages
sudo dnf install -y openstack-glance
# Configure Glance API
sudo cp /etc/glance/glance-api.conf /etc/glance/glance-api.conf.bak
sudo crudini --set /etc/glance/glance-api.conf database connection mysql+pymysql://glance:GLANCE_DBPASS@controller/glance
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken www_authenticate_uri http://controller:5000
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken auth_url http://controller:5000
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken memcached_servers controller:11211
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken auth_type password
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken project_domain_name Default
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken user_domain_name Default
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken project_name service
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken username glance
sudo crudini --set /etc/glance/glance-api.conf keystone_authtoken password GLANCE_PASS
sudo crudini --set /etc/glance/glance-api.conf paste_deploy flavor keystone
sudo crudini --set /etc/glance/glance-api.conf glance_store stores file,http
sudo crudini --set /etc/glance/glance-api.conf glance_store default_store file
sudo crudini --set /etc/glance/glance-api.conf glance_store filesystem_store_datadir /var/lib/glance/images/
# Populate database
sudo -u glance glance-manage db_sync
# Start services
sudo systemctl enable openstack-glance-api
sudo systemctl start openstack-glance-api
Upload Test Image
# Download CirrOS test image
wget http://download.cirros-cloud.net/0.6.1/cirros-0.6.1-x86_64-disk.img
# Upload image
openstack image create "cirros" \
--file cirros-0.6.1-x86_64-disk.img \
--disk-format qcow2 \
--container-format bare \
--public
# Verify
openstack image list
Installing Nova (Compute Service)
Database Setup for Nova
mysql -u root -p <<EOF
CREATE DATABASE nova_api;
CREATE DATABASE nova;
CREATE DATABASE nova_cell0;
GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS';
GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS';
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS';
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS';
GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS';
GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS';
FLUSH PRIVILEGES;
EOF
Install Nova on Controller
# Create Nova user and service
source ~/admin-openrc
openstack user create --domain default --password NOVA_PASS nova
openstack role add --project service --user nova admin
openstack service create --name nova --description "OpenStack Compute" compute
# Create endpoints
openstack endpoint create --region RegionOne compute public http://controller:8774/v2.1
openstack endpoint create --region RegionOne compute internal http://controller:8774/v2.1
openstack endpoint create --region RegionOne compute admin http://controller:8774/v2.1
# Install packages
sudo dnf install -y openstack-nova-api openstack-nova-conductor \
openstack-nova-novncproxy openstack-nova-scheduler
# Configure Nova
sudo cp /etc/nova/nova.conf /etc/nova/nova.conf.bak
# Database configuration
sudo crudini --set /etc/nova/nova.conf api_database connection mysql+pymysql://nova:NOVA_DBPASS@controller/nova_api
sudo crudini --set /etc/nova/nova.conf database connection mysql+pymysql://nova:NOVA_DBPASS@controller/nova
# RabbitMQ configuration
sudo crudini --set /etc/nova/nova.conf DEFAULT transport_url rabbit://openstack:RABBIT_PASS@controller:5672/
# Keystone configuration
sudo crudini --set /etc/nova/nova.conf api auth_strategy keystone
sudo crudini --set /etc/nova/nova.conf keystone_authtoken www_authenticate_uri http://controller:5000/
sudo crudini --set /etc/nova/nova.conf keystone_authtoken auth_url http://controller:5000/
sudo crudini --set /etc/nova/nova.conf keystone_authtoken memcached_servers controller:11211
sudo crudini --set /etc/nova/nova.conf keystone_authtoken auth_type password
sudo crudini --set /etc/nova/nova.conf keystone_authtoken project_domain_name Default
sudo crudini --set /etc/nova/nova.conf keystone_authtoken user_domain_name Default
sudo crudini --set /etc/nova/nova.conf keystone_authtoken project_name service
sudo crudini --set /etc/nova/nova.conf keystone_authtoken username nova
sudo crudini --set /etc/nova/nova.conf keystone_authtoken password NOVA_PASS
# VNC configuration
sudo crudini --set /etc/nova/nova.conf vnc enabled true
sudo crudini --set /etc/nova/nova.conf vnc server_listen '$my_ip'
sudo crudini --set /etc/nova/nova.conf vnc server_proxyclient_address '$my_ip'
# Glance configuration
sudo crudini --set /etc/nova/nova.conf glance api_servers http://controller:9292
# Placement configuration
sudo crudini --set /etc/nova/nova.conf placement region_name RegionOne
sudo crudini --set /etc/nova/nova.conf placement project_domain_name Default
sudo crudini --set /etc/nova/nova.conf placement project_name service
sudo crudini --set /etc/nova/nova.conf placement auth_type password
sudo crudini --set /etc/nova/nova.conf placement user_domain_name Default
sudo crudini --set /etc/nova/nova.conf placement auth_url http://controller:5000/v3
sudo crudini --set /etc/nova/nova.conf placement username placement
sudo crudini --set /etc/nova/nova.conf placement password PLACEMENT_PASS
# Other settings
sudo crudini --set /etc/nova/nova.conf DEFAULT my_ip 192.168.1.10
sudo crudini --set /etc/nova/nova.conf DEFAULT use_neutron true
sudo crudini --set /etc/nova/nova.conf DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
# Populate databases
sudo -u nova nova-manage api_db sync
sudo -u nova nova-manage cell_v2 map_cell0
sudo -u nova nova-manage cell_v2 create_cell --name=cell1 --verbose
sudo -u nova nova-manage db sync
# Verify
sudo -u nova nova-manage cell_v2 list_cells
# Start services
sudo systemctl enable openstack-nova-api openstack-nova-scheduler \
openstack-nova-conductor openstack-nova-novncproxy
sudo systemctl start openstack-nova-api openstack-nova-scheduler \
openstack-nova-conductor openstack-nova-novncproxy
Install Nova on Compute Nodes
On each compute node:
# Install packages
sudo dnf install -y openstack-nova-compute
# Configure Nova
sudo cp /etc/nova/nova.conf /etc/nova/nova.conf.bak
# Basic configuration
sudo crudini --set /etc/nova/nova.conf DEFAULT transport_url rabbit://openstack:RABBIT_PASS@controller
sudo crudini --set /etc/nova/nova.conf DEFAULT my_ip 192.168.1.20 # Change for each compute node
sudo crudini --set /etc/nova/nova.conf DEFAULT use_neutron true
sudo crudini --set /etc/nova/nova.conf DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
# Keystone configuration
sudo crudini --set /etc/nova/nova.conf api auth_strategy keystone
sudo crudini --set /etc/nova/nova.conf keystone_authtoken www_authenticate_uri http://controller:5000/
sudo crudini --set /etc/nova/nova.conf keystone_authtoken auth_url http://controller:5000/
sudo crudini --set /etc/nova/nova.conf keystone_authtoken memcached_servers controller:11211
sudo crudini --set /etc/nova/nova.conf keystone_authtoken auth_type password
sudo crudini --set /etc/nova/nova.conf keystone_authtoken project_domain_name Default
sudo crudini --set /etc/nova/nova.conf keystone_authtoken user_domain_name Default
sudo crudini --set /etc/nova/nova.conf keystone_authtoken project_name service
sudo crudini --set /etc/nova/nova.conf keystone_authtoken username nova
sudo crudini --set /etc/nova/nova.conf keystone_authtoken password NOVA_PASS
# VNC configuration
sudo crudini --set /etc/nova/nova.conf vnc enabled true
sudo crudini --set /etc/nova/nova.conf vnc server_listen 0.0.0.0
sudo crudini --set /etc/nova/nova.conf vnc server_proxyclient_address '$my_ip'
sudo crudini --set /etc/nova/nova.conf vnc novncproxy_base_url http://controller:6080/vnc_auto.html
# Glance configuration
sudo crudini --set /etc/nova/nova.conf glance api_servers http://controller:9292
# Placement configuration
sudo crudini --set /etc/nova/nova.conf placement region_name RegionOne
sudo crudini --set /etc/nova/nova.conf placement project_domain_name Default
sudo crudini --set /etc/nova/nova.conf placement project_name service
sudo crudini --set /etc/nova/nova.conf placement auth_type password
sudo crudini --set /etc/nova/nova.conf placement user_domain_name Default
sudo crudini --set /etc/nova/nova.conf placement auth_url http://controller:5000/v3
sudo crudini --set /etc/nova/nova.conf placement username placement
sudo crudini --set /etc/nova/nova.conf placement password PLACEMENT_PASS
# Check virtualization support
egrep -c '(vmx|svm)' /proc/cpuinfo
# If no hardware virtualization, use QEMU
sudo crudini --set /etc/nova/nova.conf libvirt virt_type qemu
# Start service
sudo systemctl enable libvirtd openstack-nova-compute
sudo systemctl start libvirtd openstack-nova-compute
Discover Compute Hosts
Back on the controller:
# Discover compute hosts
source ~/admin-openrc
sudo -u nova nova-manage cell_v2 discover_hosts --verbose
# Verify
openstack compute service list
openstack hypervisor list
Installing Neutron (Networking Service)
Database Setup for Neutron
mysql -u root -p <<EOF
CREATE DATABASE neutron;
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'NEUTRON_DBPASS';
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'NEUTRON_DBPASS';
FLUSH PRIVILEGES;
EOF
Install Neutron on Controller
# Create Neutron user and service
source ~/admin-openrc
openstack user create --domain default --password NEUTRON_PASS neutron
openstack role add --project service --user neutron admin
openstack service create --name neutron --description "OpenStack Networking" network
# Create endpoints
openstack endpoint create --region RegionOne network public http://controller:9696
openstack endpoint create --region RegionOne network internal http://controller:9696
openstack endpoint create --region RegionOne network admin http://controller:9696
# Install packages
sudo dnf install -y openstack-neutron openstack-neutron-ml2 \
openstack-neutron-openvswitch ebtables
# Configure Neutron
sudo cp /etc/neutron/neutron.conf /etc/neutron/neutron.conf.bak
# Database configuration
sudo crudini --set /etc/neutron/neutron.conf database connection mysql+pymysql://neutron:NEUTRON_DBPASS@controller/neutron
# Core configuration
sudo crudini --set /etc/neutron/neutron.conf DEFAULT core_plugin ml2
sudo crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins router
sudo crudini --set /etc/neutron/neutron.conf DEFAULT allow_overlapping_ips true
sudo crudini --set /etc/neutron/neutron.conf DEFAULT transport_url rabbit://openstack:RABBIT_PASS@controller
sudo crudini --set /etc/neutron/neutron.conf DEFAULT auth_strategy keystone
sudo crudini --set /etc/neutron/neutron.conf DEFAULT notify_nova_on_port_status_changes true
sudo crudini --set /etc/neutron/neutron.conf DEFAULT notify_nova_on_port_data_changes true
# Keystone configuration
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken www_authenticate_uri http://controller:5000
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_url http://controller:5000
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken memcached_servers controller:11211
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_type password
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken project_domain_name Default
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken user_domain_name Default
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken project_name service
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken username neutron
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken password NEUTRON_PASS
# Nova configuration
sudo crudini --set /etc/neutron/neutron.conf nova auth_url http://controller:5000
sudo crudini --set /etc/neutron/neutron.conf nova auth_type password
sudo crudini --set /etc/neutron/neutron.conf nova project_domain_name Default
sudo crudini --set /etc/neutron/neutron.conf nova user_domain_name Default
sudo crudini --set /etc/neutron/neutron.conf nova region_name RegionOne
sudo crudini --set /etc/neutron/neutron.conf nova project_name service
sudo crudini --set /etc/neutron/neutron.conf nova username nova
sudo crudini --set /etc/neutron/neutron.conf nova password NOVA_PASS
# Configure ML2 plugin
sudo cp /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugins/ml2/ml2_conf.ini.bak
sudo crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 type_drivers flat,vlan,vxlan
sudo crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types vxlan
sudo crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 mechanism_drivers openvswitch,l2population
sudo crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 extension_drivers port_security
sudo crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_flat flat_networks provider
sudo crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_vxlan vni_ranges 1:1000
sudo crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini securitygroup enable_ipset true
# Configure Open vSwitch agent
sudo cp /etc/neutron/plugins/ml2/openvswitch_agent.ini /etc/neutron/plugins/ml2/openvswitch_agent.ini.bak
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs bridge_mappings provider:br-provider
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs local_ip 192.168.1.10
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini agent tunnel_types vxlan
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini agent l2_population true
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini securitygroup enable_security_group true
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini securitygroup firewall_driver openvswitch
# Configure L3 agent
sudo cp /etc/neutron/l3_agent.ini /etc/neutron/l3_agent.ini.bak
sudo crudini --set /etc/neutron/l3_agent.ini DEFAULT interface_driver openvswitch
# Configure DHCP agent
sudo cp /etc/neutron/dhcp_agent.ini /etc/neutron/dhcp_agent.ini.bak
sudo crudini --set /etc/neutron/dhcp_agent.ini DEFAULT interface_driver openvswitch
sudo crudini --set /etc/neutron/dhcp_agent.ini DEFAULT dhcp_driver neutron.agent.linux.dhcp.Dnsmasq
sudo crudini --set /etc/neutron/dhcp_agent.ini DEFAULT enable_isolated_metadata true
# Configure metadata agent
sudo cp /etc/neutron/metadata_agent.ini /etc/neutron/metadata_agent.ini.bak
sudo crudini --set /etc/neutron/metadata_agent.ini DEFAULT nova_metadata_host controller
sudo crudini --set /etc/neutron/metadata_agent.ini DEFAULT metadata_proxy_shared_secret METADATA_SECRET
# Create symbolic link
sudo ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
# Configure Open vSwitch
sudo systemctl enable openvswitch
sudo systemctl start openvswitch
# Create provider bridge
sudo ovs-vsctl add-br br-provider
sudo ovs-vsctl add-port br-provider ens192 # Provider interface
# Populate database
sudo -u neutron neutron-db-manage --config-file /etc/neutron/neutron.conf \
--config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head
# Update Nova configuration for Neutron
sudo crudini --set /etc/nova/nova.conf neutron auth_url http://controller:5000
sudo crudini --set /etc/nova/nova.conf neutron auth_type password
sudo crudini --set /etc/nova/nova.conf neutron project_domain_name Default
sudo crudini --set /etc/nova/nova.conf neutron user_domain_name Default
sudo crudini --set /etc/nova/nova.conf neutron region_name RegionOne
sudo crudini --set /etc/nova/nova.conf neutron project_name service
sudo crudini --set /etc/nova/nova.conf neutron username neutron
sudo crudini --set /etc/nova/nova.conf neutron password NEUTRON_PASS
sudo crudini --set /etc/nova/nova.conf neutron service_metadata_proxy true
sudo crudini --set /etc/nova/nova.conf neutron metadata_proxy_shared_secret METADATA_SECRET
# Restart Nova services
sudo systemctl restart openstack-nova-api
# Start Neutron services
sudo systemctl enable neutron-server neutron-openvswitch-agent \
neutron-dhcp-agent neutron-metadata-agent neutron-l3-agent
sudo systemctl start neutron-server neutron-openvswitch-agent \
neutron-dhcp-agent neutron-metadata-agent neutron-l3-agent
Configure Neutron on Compute Nodes
# Install packages
sudo dnf install -y openstack-neutron-openvswitch ebtables ipset
# Configure Neutron
sudo cp /etc/neutron/neutron.conf /etc/neutron/neutron.conf.bak
sudo crudini --set /etc/neutron/neutron.conf DEFAULT transport_url rabbit://openstack:RABBIT_PASS@controller
sudo crudini --set /etc/neutron/neutron.conf DEFAULT auth_strategy keystone
# Keystone configuration
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken www_authenticate_uri http://controller:5000
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_url http://controller:5000
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken memcached_servers controller:11211
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_type password
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken project_domain_name Default
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken user_domain_name Default
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken project_name service
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken username neutron
sudo crudini --set /etc/neutron/neutron.conf keystone_authtoken password NEUTRON_PASS
# Configure Open vSwitch agent
sudo cp /etc/neutron/plugins/ml2/openvswitch_agent.ini /etc/neutron/plugins/ml2/openvswitch_agent.ini.bak
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs bridge_mappings provider:br-provider
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs local_ip 192.168.1.20 # Change for each compute
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini agent tunnel_types vxlan
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini agent l2_population true
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini securitygroup enable_security_group true
sudo crudini --set /etc/neutron/plugins/ml2/openvswitch_agent.ini securitygroup firewall_driver openvswitch
# Configure Nova for Neutron
sudo crudini --set /etc/nova/nova.conf neutron auth_url http://controller:5000
sudo crudini --set /etc/nova/nova.conf neutron auth_type password
sudo crudini --set /etc/nova/nova.conf neutron project_domain_name Default
sudo crudini --set /etc/nova/nova.conf neutron user_domain_name Default
sudo crudini --set /etc/nova/nova.conf neutron region_name RegionOne
sudo crudini --set /etc/nova/nova.conf neutron project_name service
sudo crudini --set /etc/nova/nova.conf neutron username neutron
sudo crudini --set /etc/nova/nova.conf neutron password NEUTRON_PASS
# Start Open vSwitch
sudo systemctl enable openvswitch
sudo systemctl start openvswitch
# Create provider bridge
sudo ovs-vsctl add-br br-provider
sudo ovs-vsctl add-port br-provider ens192 # Provider interface
# Restart services
sudo systemctl restart openstack-nova-compute
sudo systemctl enable neutron-openvswitch-agent
sudo systemctl start neutron-openvswitch-agent
Create Initial Networks
# Source credentials
source ~/admin-openrc
# Create provider network
openstack network create --share --external \
--provider-physical-network provider \
--provider-network-type flat provider
# Create provider subnet
openstack subnet create --network provider \
--allocation-pool start=10.0.0.100,end=10.0.0.200 \
--dns-nameserver 8.8.8.8 \
--gateway 10.0.0.1 \
--subnet-range 10.0.0.0/24 provider-subnet
# Create demo tenant network
source ~/demo-openrc
openstack network create demo-net
# Create demo subnet
openstack subnet create --network demo-net \
--dns-nameserver 8.8.8.8 \
--gateway 172.16.1.1 \
--subnet-range 172.16.1.0/24 demo-subnet
# Create router
openstack router create demo-router
# Add interfaces
openstack router add subnet demo-router demo-subnet
openstack router set --external-gateway provider demo-router
# Verify
openstack network list
openstack router list
Installing Horizon (Dashboard)
# Install packages
sudo dnf install -y openstack-dashboard
# Configure Horizon
sudo cp /etc/openstack-dashboard/local_settings /etc/openstack-dashboard/local_settings.bak
# Edit configuration
sudo sed -i 's/OPENSTACK_HOST = "127.0.0.1"/OPENSTACK_HOST = "controller"/g' /etc/openstack-dashboard/local_settings
sudo sed -i 's/ALLOWED_HOSTS = \[/ALLOWED_HOSTS = \["*", /g' /etc/openstack-dashboard/local_settings
# Configure session storage
echo "SESSION_ENGINE = 'django.contrib.sessions.backends.cache'" | sudo tee -a /etc/openstack-dashboard/local_settings
echo "CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'controller:11211',
}
}" | sudo tee -a /etc/openstack-dashboard/local_settings
# Configure Keystone API version
echo "OPENSTACK_KEYSTONE_URL = \"http://%s:5000/v3\" % OPENSTACK_HOST" | sudo tee -a /etc/openstack-dashboard/local_settings
echo "OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True" | sudo tee -a /etc/openstack-dashboard/local_settings
echo "OPENSTACK_API_VERSIONS = {
\"identity\": 3,
\"image\": 2,
\"volume\": 3,
}" | sudo tee -a /etc/openstack-dashboard/local_settings
echo "OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = \"Default\"" | sudo tee -a /etc/openstack-dashboard/local_settings
echo "OPENSTACK_KEYSTONE_DEFAULT_ROLE = \"user\"" | sudo tee -a /etc/openstack-dashboard/local_settings
# Configure timezone
sudo sed -i 's/TIME_ZONE = "UTC"/TIME_ZONE = "America\/New_York"/g' /etc/openstack-dashboard/local_settings
# Restart Apache
sudo systemctl restart httpd
# Access dashboard at http://controller/dashboard
Launching Your First Instance
Create Security Group Rules
# Source demo credentials
source ~/demo-openrc
# Create security group rule for SSH
openstack security group rule create --proto tcp --dst-port 22 default
# Create security group rule for ICMP
openstack security group rule create --proto icmp default
# Create SSH keypair
openstack keypair create --public-key ~/.ssh/id_rsa.pub mykey
Launch Instance
# List available resources
openstack flavor list
openstack image list
openstack network list
# Create flavor if needed
source ~/admin-openrc
openstack flavor create --ram 512 --disk 1 --vcpus 1 m1.tiny
# Launch instance
source ~/demo-openrc
openstack server create --flavor m1.tiny \
--image cirros \
--network demo-net \
--security-group default \
--key-name mykey \
test-instance
# Check status
openstack server list
openstack server show test-instance
# Create floating IP
openstack floating ip create provider
# Associate floating IP
openstack server add floating ip test-instance <FLOATING_IP>
# Access instance
ssh cirros@<FLOATING_IP>
Advanced Configuration
Adding Cinder (Block Storage)
# Create Cinder database
mysql -u root -p <<EOF
CREATE DATABASE cinder;
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'CINDER_DBPASS';
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY 'CINDER_DBPASS';
FLUSH PRIVILEGES;
EOF
# Create Cinder user and service
source ~/admin-openrc
openstack user create --domain default --password CINDER_PASS cinder
openstack role add --project service --user cinder admin
openstack service create --name cinderv3 --description "OpenStack Block Storage" volumev3
# Create endpoints
openstack endpoint create --region RegionOne volumev3 public http://controller:8776/v3/%\(project_id\)s
openstack endpoint create --region RegionOne volumev3 internal http://controller:8776/v3/%\(project_id\)s
openstack endpoint create --region RegionOne volumev3 admin http://controller:8776/v3/%\(project_id\)s
# Install packages
sudo dnf install -y openstack-cinder targetcli
# Configure Cinder
# ... (configuration similar to other services)
Performance Tuning
# Optimize MariaDB
cat <<EOF | sudo tee -a /etc/my.cnf.d/openstack.cnf
innodb_buffer_pool_size = 4G
innodb_log_file_size = 1G
innodb_flush_method = O_DIRECT
innodb_file_per_table = ON
query_cache_size = 64M
query_cache_type = 1
EOF
# Optimize RabbitMQ
sudo rabbitmqctl set_vm_memory_high_watermark 0.6
sudo rabbitmqctl set_disk_free_limit 5GB
# Nova compute optimization
sudo crudini --set /etc/nova/nova.conf DEFAULT cpu_allocation_ratio 16.0
sudo crudini --set /etc/nova/nova.conf DEFAULT ram_allocation_ratio 1.5
sudo crudini --set /etc/nova/nova.conf DEFAULT disk_allocation_ratio 1.0
Monitoring Your OpenStack Cloud
Enable Ceilometer (Telemetry)
# Install monitoring components
sudo dnf install -y openstack-ceilometer-central \
openstack-ceilometer-notification python3-ceilometerclient
# Configure for basic monitoring
# ... (configuration steps)
Integration with External Monitoring
# prometheus-openstack-exporter configuration
global:
cloud: default
refresh_interval: 300
clouds:
- name: default
auth_url: http://controller:5000/v3
username: admin
password: ADMIN_PASS
project_name: admin
domain_name: Default
Troubleshooting
Common Issues
-
Service Discovery Issues
# Check service catalog openstack catalog list # Verify endpoints openstack endpoint list
-
Network Connectivity Problems
# Check Open vSwitch sudo ovs-vsctl show # Check network namespaces sudo ip netns list
-
Instance Launch Failures
# Check compute service openstack compute service list # Check logs sudo journalctl -u openstack-nova-compute -f
Best Practices
-
Security
- Change all default passwords
- Enable SSL/TLS for all services
- Implement proper firewall rules
- Regular security updates
-
High Availability
- Deploy multiple controller nodes
- Use HAProxy for load balancing
- Implement database replication
- Configure service redundancy
-
Backup Strategy
- Regular database backups
- Configuration file backups
- Image and volume backups
- Disaster recovery planning
-
Monitoring
- Monitor all services
- Set up alerting
- Track resource usage
- Performance metrics
Conclusion
You’ve successfully deployed a functional OpenStack private cloud on Rocky Linux. This foundation provides you with a scalable, flexible infrastructure platform that can grow with your needs. Continue exploring advanced features like Heat orchestration, Swift object storage, and additional services to build a comprehensive cloud solution.
Remember that OpenStack is highly modular and customizable. Start with this base configuration and gradually add components and features as your requirements evolve. Regular maintenance, monitoring, and updates will ensure your cloud remains secure and performant.