OpenStack Fundamentals and Deployment Guide

Cloud Computing Overview

Cloud computing delivers computing services over networks with key characteristics including on-demand resource allocation, pay-as-you-use pricing, and transparent backend infrastructure. Three primary deployment models exist: private clouds for single organizations, public clouds offered by providers like Amazon Web Services and Alibaba Cloud, and hybrid clouds combining both approaches.

Service delivery layers include:

  • Infrastructure as a Service (IaaS): Provides virtual machines, servers, and networking resources
  • Platform as a Service (PaaS): Offers integrated development platforms with middleware and databases
  • Software as a Service (SaaS): Delivers applications like email, antivirus, and file storage

OpenStack Architecture

OpenStack is an open-source IaaS platform originally developed by NASA and Rackspace under the Apache License. The platform consists of several core components:

  • Nova: Compute service managing virtual machine instances and hardware configurations
  • Neutron: Networking service providing virtual network creation and network segmentation
  • Cinder: Block storage service for persistent data volumes
  • Keystone: Identity service handling authentication and authorization
  • Horizon: Web-based dashboard for service management
  • Glance: Image service for virtual machine templates
  • Swift: Object storage optimized for write-once, read-many scenarios
  • Heat: Orchestration service enabling automated deployments through template definitions

Supporting infrastructure includes MySQL databases and RabbitMQ message brokers for inter-component communication.

Environment Setup

Initial configuration requires two nodes with static IP addresses:

  • node1.com: 192.168.4.16
  • node2.com: 192.168.4.17

Prerequisites include hostname configuration, hosts file updates, disabling iptables and SELinux, time synchronization, and configuring CentOS YUM repositories from https://repos.fedorapeople.org/repos/openstack/EOL/openstack-icehouse/epel-6/.

KVM Installation

yum install qemu-kvm qemu-kvm-tools virt-manager libvirt
brctl show

Create bridged networking:

#!/bin/bash
brctl addbr br0
brctl addif br0 eth0
ip addr del dev eth0 192.168.4.11/24
ifconfig br0 192.168.4.11/24 up
route add default gw 192.168.4.1

Database Configuration

Install MySQL server:

yum install mysql-server
cp /usr/share/mysql/my-medium.cnf /etc/my.cnf

Configure /etc/my.cnf with these parameters under [mysqld] section:

  • default-storage-engine = innodb
  • innodb_file_per_table
  • collation-server = utf8_general_ci
  • init-connect = 'SET NAMES utf8'
  • character-set-server = utf8
  • max_connections = 4096
  • bind-address = 0.0.0.0

Initialize and start the service:

/etc/init.d/mysqld start

Create component databases:

CREATE DATABASE keystone;
GRANT ALL ON keystone.* TO keystone@'192.168.4.0/255.255.255.0' IDENTIFIED BY 'keystone';

CREATE DATABASE glance;
GRANT ALL ON glance.* TO glance@'192.168.4.0/255.255.255.0' IDENTIFIED BY 'glance';

CREATE DATABASE nova;
GRANT ALL ON nova.* TO nova@'192.168.4.0/255.255.255.0' IDENTIFIED BY 'nova';

CREATE DATABASE neutron;
GRANT ALL ON neutron.* TO neutron@'192.168.4.0/255.255.255.0' IDENTIFIED BY 'neutron';

CREATE DATABASE cinder;
GRANT ALL ON cinder.* TO cinder@'192.168.56.0/255.255.255.0' IDENTIFIED BY 'cinder';

Message Broker Setup

Deploy RabbitMQ:

yum install rabbitmq-server
/etc/init.d/rabbitmq-server start
/usr/lib/rabbitmq/bin/rabbitmq-plugins enable rabbitmq_management

Management interface available on port 15672, AMQP protocol on 5672.

Identity Service (Keystone)

Install Keystone:

yum install openstack-keystone python-keystoneclient

Generate PKI tokens:

keystone-manage pki_setup --keystone-user keystone --keystone-group keystone
chown -R keystone:keystone /etc/keystone/ssl/
chmod -R o-rwx /etc/keystone/ssl/

Configure /etc/keystone/keystone.conf:

  • Set admin_token=ADMIN
  • Configure database connection: connection=mysql://keystone:keystone@192.168.1.36/keystone
  • Enable debugging: debug=true
  • Set log location: log_file=/var/log/keystone/keystone.log

Initialize database schema:

keystone-manage db_sync

Start Keystone service:

chown -R keystone:keystone /var/log/keystone/*
/etc/init.d/openstack-keystone start
chkconfig openstack-keystone on

API endpoints listen on ports 35357 (admin) and 5000 (public).

Set administrative environment:

export OS_SERVICE_TOKEN=ADMIN
export OS_SERVICE_ENDPOINT=http://192.168.1.36:35357/v2.0

Create administrative user:

keystone user-create --name=admin --pass=admin --email=admin@example.com
keystone role-create --name=admin
keystone tenant-create --name=admin --description="Admin Tenant"
keystone user-role-add --user=admin --tenant=admin --role=admin

Register demo user:

keystone user-create --name=demo --pass=demo
keystone tenant-create --name=demo --description="Demo Tenant"
keystone user-role-add --user=demo --role=_member_ --tenant=demo

Configure service accounts:

keystone tenant-create --name=service
keystone service-create --name=keystone --type=identity
keystone endpoint-create \
  --service-id=$(keystone service-list | awk '/ identity / {print $2}') \
  --publicurl=http://192.168.1.36:5000/v2.0 \
  --internalurl=http://192.168.1.36:5000/v2.0 \
  --adminurl=http://192.168.1.36:35357/v2.0

Create credential files for convenience:

# keystone-admin
export OS_TENANT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=admin
export OS_AUTH_URL=http://192.168.1.36:35357/v2.0

# keystone-demo
export OS_TENANT_NAME=demo
export OS_USERNAME=demo
export OS_PASSWORD=demo
export OS_AUTH_URL=http://192.168.1.36:35357/v2.0

Image Service (Glance)

Install Glance components:

yum install openstack-glance python-glanceclient python-crypto

Configure API settings in /etc/glance/glance-api.conf:

  • log_file=/var/log/glance/api.log
  • connection=mysql://glance:glance@192.168.1.36/glance

Registry configuration in /etc/glance/glance-registry.conf:

  • log_file=/var/log/glance/registry.log
  • connection=mysql://glance:glance@192.168.1.36/glance

Initialize database:

glance-manage db_sync

Configure RabbitMQ integration:

  • notifier_strategy = rabbit
  • rabbit_host=192.168.1.36
  • rabbit_port=5672
  • rabbit_userid=guest
  • rabbit_password=guest

Register service user:

source keystone-admin
keystone user-create --name=glance --pass=glance
keystone user-role-add --user=glance --tenant=service --role=admin

Configure Keystone authentication in both configuration files:

  • auth_host=192.168.1.36
  • auth_port=35357
  • auth_protocol=http
  • admin_tenant_name=service
  • admin_user=glance
  • admin_password=glance
  • flavor=keystone

Register service endpoints:

keystone service-create --name=glance --type=image
keystone endpoint-create \
  --service-id=$(keystone service-list | awk '/ image / {print $2}') \
  --publicurl=http://192.168.1.36:9292 \
  --internalurl=http://192.168.1.36:9292 \
  --adminurl=http://192.168.1.36:9292

Start services:

chown -R glance:glance /var/log/glance/
/etc/init.d/openstack-glance-api start
/etc/init.d/openstack-glance-registry start

Verify operation by listing images:

glance image-list

Import test image:

wget http://download.cirros-cloud.net/0.3.2/cirros-0.3.2-x86_64-disk.img
glance image-create --name "cirros-0.3.2-x86_64" \
  --disk-format qcow2 \
  --container-format bare \
  --is-public True \
  --file cirros-0.3.2-x86_64-disk.img

Compute Service (Nova)

Instal Nova packages:

yum install openstack-nova-api openstack-nova-cert openstack-nova-conductor \
  openstack-nova-console openstack-nova-novncproxy \
  openstack-nova-scheduler python-novaclient

Database configuraton in /etc/nova/nova.conf:

  • connection=mysql://nova:nova@192.168.1.36/nova

Enitialize schema:

nova-manage db sync

Message broker settings:

  • rabbit_host=192.168.1.36
  • rabbit_port=5672
  • rabbit_userid=guest
  • rabbit_password=guest
  • rpc_backend=rabbit

Register service user:

source keystone-admin
keystone user-create --name=nova --pass=nova
keystone user-role-add --user=nova --tenant=service --role=admin

Authentication configuration:

  • auth_strategy=keystone
  • auth_host=192.168.1.36
  • auth_port=35357
  • auth_protocol=http
  • admin_user=nova
  • admin_password=nova
  • admin_tenant_name=service

Image service integration:

  • my_ip=192.168.1.36
  • glance_host=$my_ip

Additional settings:

  • state_path=/var/lib/nova
  • instances_path=$state_path/instances
  • compute_driver=libvirt.LibvirtDriver
  • novncproxy_base_url=http://192.168.1.36:6080/vnc_auto.html
  • vncserver_listen=0.0.0.0
  • vncserver_proxyclient_address=192.168.1.36

Register endpoints:

keystone service-create --name=nova --type=compute
keystone endpoint-create \
  --service-id=$(keystone service-list| awk ' / compute / {print $2}') \
  --publicurl=http://192.168.1.36:8774/v2/%(tenant_id)s \
  --internalurl=http://192.168.1.36:8774/v2/%(tenant_id)s \
  --adminurl=http://192.168.1.36:8774/v2/%(tenant_id)s

Start controller services:

for service in api cert conductor consoleauth novncproxy scheduler; do
  service openstack-nova-$service start
done

Deploy compute node:

yum install -y qemu-kvm libvirt openstack-nova-compute python-novaclient

Check hardware virtualization support:

egrep -c '(vmx|svm)' /proc/cpuinfo

If unsupported, configure QEMU fallback in /etc/nova/nova.conf:

virt_type=qemu

Distribute configuration:

scp /etc/nova/nova.conf 192.168.1.37:/etc/nova/

Update compute-specific settings:

  • vncserver_proxyclient_address=192.168.1.37

Start compute services:

/etc/init.d/libvirtd start
/etc/init.d/messagebus start
/etc/init.d/openstack-nova-compute start

Networking Service (Neutron)

Install components:

yum install openstack-neutron openstack-neutron-ml2 python-neutronclient \
  openstack-neutron-linuxbridge

Basic configuration in /etc/neutron/neutron.conf:

  • debug = true
  • core_plugin = ml2
  • service_plugins = router,firewall,lbaas
  • connection = mysql://neutron:neutron@192.168.1.36:3306/neutron

Register service user:

source keystone-admin
keystone user-create --name neutron --pass neutron
keystone user-role-add --user neutron --tenant service --role admin

Authentication settings:

  • auth_strategy = keystone
  • auth_host = 192.168.1.36
  • auth_port = 35357
  • auth_protocol = http
  • admin_tenant_name = service
  • admin_user = neutron
  • admin_password = neutron

Message broker configuration:

  • rabbit_host = 192.168.1.36
  • rabbit_port = 5672
  • rabbit_userid = guest
  • rabbit_password = guest

Nova integration:

  • notify_nova_on_port_status_changes = true
  • notify_nova_on_port_data_changes = true
  • nova_url = http://192.168.1.36:8774/v2
  • nova_admin_username = nova
  • nova_admin_tenant_id = [SERVICE_TENANT_ID]
  • nova_admin_password = nova
  • nova_admin_auth_url = http://192.168.1.36:35357/v2.0

ML2 plugin configuration in /etc/neutron/plugins/ml2/ml2_conf.ini:

  • type_drivers = flat,vlan,gre,vxlan
  • tenant_network_types = flat,vlan,gre,vxlan
  • mechanism_drivers = linuxbridge,openvswitch
  • flat_networks = physnet1

Linux bridge driver in /etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini:

  • network_vlan_ranges = physnet1
  • physical_interface_mappings = physnet1:eth0

Nova networking integration in /etc/nova/nova.conf:

  • network_api_class=nova.network.neutronv2.api.API
  • neutron_url=http://192.168.1.36:9696
  • neutron_admin_username=neutron
  • neutron_admin_password=neutron
  • neutron_admin_auth_url=http://192.168.1.36:5000/v2.0

Restart Nova services:

for service in api conductor scheduler; do
  service openstack-nova-$service restart
done

Distribute configuration to compute node:

scp /etc/nova/nova.conf 192.168.1.37:/etc/nova/

Update compute node IP address and restart:

/etc/init.d/openstack-nova-compute restart

Register service endpoints:

keystone service-create --name neutron --type network
keystone endpoint-create \
  --service-id=$(keystone service-list | awk '/ network / {print $2}') \
  --publicurl=http://192.168.1.36:9696 \
  --internalurl=http://192.168.1.36:9696 \
  --adminurl=http://192.168.1.36:9696

Test server startup:

neutron-server --config-file=/etc/neutron/neutron.conf \
  --config-file=/etc/neutron/plugins/ml2/ml2_conf.ini \
  --config-file=/etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini

Modify startup scripts to reference correct configuration paths:

# /etc/init.d/neutron-server
/etc/neutron/neutron.conf
/etc/neutron/plugins/ml2/ml2_conf.ini
/etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini

# /etc/init.d/neutron-linuxbridge-agent
/etc/neutron/neutron.conf
/etc/neutron/plugins/ml2/ml2_conf.ini
/etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini

Start services:

/etc/init.d/neutron-server start
/etc/init.d/neutron-linuxbridge-agent start

Deploy Neutron agents on compute nodes:

yum install openstack-neutron openstack-neutron-ml2 python-neutronclient \
  openstack-neutron-linuxbridge

scp /etc/neutron/neutron.conf 192.168.1.37:/etc/neutron/
scp /etc/neutron/plugins/ml2/ml2_conf.ini 192.168.1.37:/etc/neutron/plugins/ml2/
scp /etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini 192.168.1.37:/etc/neutron/plugins/linuxbridge/
scp /etc/init.d/neutron-* 192.168.1.37:/etc/init.d/

/etc/init.d/neutron-linuxbridge-agent start

Dashboard (Horizon)

Install web interface:

yum install -y httpd mod_wsgi memcached python-memcached openstack-dashboard

Start caching service:

/etc/init.d/memcached start

Configure /etc/openstack-dashboard/local_settings:

CACHES = {
    'default': {
        'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION' : '127.0.0.1:11211',
    }
}

OPENSTACK_HOST = "192.168.1.36"
ALLOWED_HOSTS = ['horizon.example.com', 'localhost','192.168.1.36']

Launch web server:

/etc/init.d/httpd start

Access via browser at http://192.168.1.36/dashboard/

Create network infrastructure:

TENANT_ID=$(keystone tenant-list | awk '/demo/ {print $2}')
neutron net-create --tenant-id $TENANT_ID flat_net \
  --shared --provider:network_type flat --provider:physical_network physnet1

Define subnet:

neutron subnet-create flat_net 10.96.20.0/24 \
  --name flat_subnet \
  --gateway 10.96.20.1 \
  --allocation-pool start=10.96.20.120,end=10.96.20.130 \
  --dns-nameservers list=true 123.125.81.6

Block Storage (Cinder)

Install Cinder:

yum install openstack-cinder python-cinderclient

Configuration in /etc/cinder/cinder.conf:

  • rabbit_host=192.168.1.36
  • rpc_backend=rabbit
  • my_ip=192.168.1.36
  • glance_host=$my_ip
  • auth_strategy=keystone
  • connection=mysql://cinder:cinder@192.168.1.36/cinder
  • Authentication credentials for service user

Initialize database:

cinder-manage db sync

Register service:

keystone user-create --name=cinder --pass=cinder
keystone user-role-add --user=cinder --tenant=service --role=admin

keystone service-create --name=cinder --type=volume
keystone endpoint-create \
  --service-id=[SERVICE_ID] \
  --publicurl=http://192.168.1.36:8776/v1/%\(tenant_id\)s \
  --internalurl=http://192.168.1.36:8776/v1/%\(tenant_id\)s \
  --adminurl=http://192.168.1.36:8776/v1/%\(tenant_id\)s

keystone service-create --name=cinderv2 --type=volumev2
keystone endpoint-create \
  --service-id=[SERVICE_ID_V2] \
  --publicurl=http://192.168.1.36:8776/v2/%\(tenant_id\)s \
  --internalurl=http://192.168.1.36:8776/v2/%\(tenant_id\)s \
  --adminurl=http://192.168.1.36:8776/v2/%\(tenant_id\)s

Start controller services:

/etc/init.d/openstack-cinder-api start
/etc/init.d/openstack-cinder-scheduler start

Deploy storage node with iSCSI target:

pvcreate /dev/sdb
vgcreate cinder-volumes /dev/sdb

# Update /etc/lvm/lvm.conf
filter = [ "a/sda1/", "a/sdb/", "r/.*/" ]

yum install -y scsi-target-utils
# Add to /etc/tgt/targets.conf
include /etc/cinder/volumes/*

/etc/init.d/tgtd start

Distribute configuration:

scp /etc/cinder/cinder.conf 192.168.1.37:/etc/cinder/

Configure iSCSI driver in /etc/cinder/cinder.conf:

  • iscsi_ip_address=$my_ip
  • volume_backend_name=iSCSI-Storage
  • iscsi_helper=tgtadm
  • volume_driver=cinder.volume.drivers.lvm.LVMISCSIDriver

Start volume service:

/etc/init.d/openstack-cinder-volume start

Define storage types:

cinder type-create iSCSI
cinder type-key iSCSI set volume_backend_name=iSCSI-Storage

Alternative NFS backend setup:

yum install nfs-utils rpcbind
mkdir -p /data/nfs

# Configure /etc/exports
/data/nfs *(rw,no_root_squash)

/etc/init.d/rpcbind start
/etc/init.d/nfs start

NFS Cinder configuration:

  • volume_backend_name=NFS-Storage
  • nfs_shares_config=/etc/cinder/nfs_shares
  • nfs_mount_point_base=$state_path/mnt
  • volume_driver=cinder.volume.drivers.nfs.NfsDriver

Configure shares in /etc/cinder/nfs_shares:

192.168.1.36:/data/nfs

Restart volume service:

/etc/init.d/openstack-cinder-volume restart

Register NFS type:

cinder type-create NFS
cinder type-key NFS set volume_backend_name=NFS-Storage

For multi-backend deployments supporting both NFS and GlusterFS:

enabled_backends=NFS_Driver,GlusterFS_Driver

[NFS_Driver]
volume_group=NFS_Driver
volume_driver=cinder.volume.drivers.nfs.NfsDriver
volume_backend_name=NFS-Storage
  
[GlusterFS_Driver]
volume_group=GlusterFS_Driver
volume_driver=cinder.volume.drivers.glusterfs.GlusterfsDriver
volume_backend_name=GlusterFS-Storage

Load Balancing (LBaaS)

Enable LBaaS in Horizon:

# /etc/openstack-dashboard/local_settings
OPENSTACK_NEUTRON_NETWORK = {
    'enable_lb': True,
}

Restart dashboard:

/etc/init.d/httpd restart

Install HAProxy:

yum install haproxy

Configure /etc/neutron/lbaas_agent.ini:

  • interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver
  • device_driver = neutron.services.loadbalancer.drivers.haproxy.namespace_driver.HaproxyNSDriver

Update agent startup script:

# /etc/init.d/neutron-lbaas-agent
configs=(
    "/etc/neutron/neutron.conf" \
    "/etc/neutron/lbaas_agent.ini" \
)

Start LBaaS agent:

/etc/init.d/neutron-lbaas-agent start

Automated deployment options available at https://github.com/unixhot/salt-openstack

Tags: openstack cloud-computing iaas deployment nova

Posted on Mon, 13 Jul 2026 16:55:45 +0000 by dirkbonenkamp