OpenStack, KVM, OVS: Controller Node (Part 2)

The Controller Node

In this tutorial, we will use Ubuntu Server 16.04.3 LTS.

You should be able to spin off VMs from the horizon dashboard at the end of this tutorial. Please change the interface name to reflect your host NIC. The controller in this tutorial is also used as a compute node.

Note: each green line is a command, be patient, paste them one by one.

#this command will save a lot of time:

sudo su root
#disable firewall:

ufw disable
#edit interface setting:

vim /etc/network/interfaces

#paste, change interface name matching your host NIC:

auto enp0s25
iface enp0s25 inet static
         address 192.168.1.11
         network 255.255.255.0
         gateway 192.168.1.1
         dns-nameservers 8.8.8.8
#change hostname:

vim /etc/hostname

#paste:

controller
#edit:

vim /etc/hosts

#paste:

192.168.1.11 controller 
192.168.2.11 compute
#install NTP:

apt install chrony
service chrony restart
#update everything and reboot:

apt-get update & dist-upgrade -y
reboot
#install libvirt tool:

apt install libvirt-bin
#clone the Openstack directory:

apt install software-properties-common
add-apt-repository cloud-archive:newton
#again update everything and reboot:

apt update && apt dist-upgrade -y
reboot
#install python installer for Openstack:

apt install python-openstackclient
#install rabbitmq, create user and set permissions:

apt install rabbitmq-server
rabbitmqctl add_user openstack changemenow
rabbitmqctl set_permissions openstack ".*" ".*" ".*"
#install opensource MariaDB database:

apt install mariadb-server python-pymysql
#create configuration file for MariaDB:

vim /etc/mysql/mariadb.conf.d/99-openstack.cnf
#paste following under the heading [mysqld]:

[mysqld]
bind-address = 192.168.1.11
default-storage-engine = innodb
innodb_file_per_table
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8
#restart the database and make it secure 
#above command will ask few questions say 'Y' to all
#use the password changemenow

service mysql  restart
mysql_secure_installation

Keystone

#create a database for Keystone and set permissions:

mysql -u root -pchangemenow
#create following database and set privileges:

CREATE DATABASE keystone;
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'changemenow';
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'changemenow';
exit
#install Keystone:

apt install keystone
#remove default configuration file and create new:

mv /etc/keystone/keystone.conf /etc/keystone/keystone.conf.old
vim /etc/keystone/keystone.conf
#paste following in terminal:

[DEFAULT]
log_dir = /var/log/keystone
[assignment]
[auth]
[cache]
[catalog]
[cors]
[cors.subdomain]
[credential]
[database]
connection = mysql+pymysql://keystone:changemenow@controller/keystone
[domain_config]
[endpoint_filter]
[endpoint_policy]
[eventlet_server]
[federation]
[fernet_tokens]
[identity]
[identity_mapping]
[kvs]
[ldap]
[matchmaker_redis]
[memcache]
[oauth1]
[os_inherit]
[oslo_messaging_amqp]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_messaging_zmq]
[oslo_middleware]
[oslo_policy]
[paste_deploy]
[policy]
[profiler]
[resource]
[revoke]
[role]
[saml]
[security_compliance]
[shadow_users]
[signing]
[token]
provider = fernet
[tokenless_auth]
[trust]
[extra_headers]
Distribution = Ubuntu
#sync keystone database and create cresential:

/bin/sh -c "keystone-manage db_sync" keystone
keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
#bootstrap keystone:

keystone-manage bootstrap --bootstrap-password changemenow --bootstrap-admin-url http://controller:35357/v3/ --bootstrap-internal-url http://controller:35357/v3/ --bootstrap-public-url http://controller:5000/v3/ --bootstrap-region-id RegionOne
#edit apache configuration:

vim /etc/apache2/apache2.conf
#paste:

ServerName controller 
#restart apache:

service apache2 restart
#remove default sqlite database:

rm -f /var/lib/keystone/keystone.db
#each time you open a shell
#you need to set your shell environmental parameter 
#create an RC file as follows

vim rc.admin
#paste following:
export OS_USERNAME=admin
export OS_PASSWORD=changemenow
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://controller:35357/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
#make it executable:

chmod +x rc.admin
#set your environmental variable as admin 
#note: this will not work if you already the root 
#as root, rather copy-paste all 'export' on terminal

./rc.admin
#Openstack use service project for admin.
#we will create a second project called demo for none admin users

openstack project create --domain default --description "Openstack Project" service
openstack project create --domain default --description "Demo Project" demo
openstack user create --domain default --password-prompt demo
openstack role create user
openstack role add --project demo --user demo user
#verify openstack projects, it should show you a table:

openstack project list
#try to issue a fernet token, it should show you a table:

openstack --os-auth-url http://controller:35357/v3 --os-project-domain-name default --os-user-domain-name default --os-project-name admin --os-username admin token issue
#create RC file for demo user:

vim rc.demo
chmod +x rc.demo
#paste following:

export OS_PROJECT_DOMAIN_NAME=default
export OS_USER_DOMAIN_NAME=default
export OS_PROJECT_NAME=demo
export OS_USERNAME=demo
export OS_PASSWORD=changemenow
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
#make sure demo user can issue token:

./rc.demo
openstack token issue

Glance

#creating a database for Glance:

mysql -u root -pchangemenow
#paste following on the MariaDB prompt:

CREATE DATABASE glance;
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY 'changemenow';
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY 'changemenow';
exit
#create a user, add a role, create API endpoints and install glance. 
#once prompted use changemenow as password: 

openstack user create --domain default --password-prompt glance
openstack role add --project service --user glance admin
openstack service create --name glance --description "OpenStack Image" image
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
apt install glance
#remove default configuration and create new:

mv /etc/glance/glance-api.conf /etc/glance/glance-api.conf.old
vim /etc/glance/glance-api.conf
#paste following:

[DEFAULT]
[cors]
[cors.subdomain]
[database]
connection = mysql+pymysql://glance:changemenow@controller/glance

[glance_store]
stores = file,http
default_store = file
filesystem_store_datadir = /var/lib/glance/images/

[image_format]
disk_formats = ami,ari,aki,vhd,vhdx,vmdk,raw,qcow2,vdi,iso,root-tar

[keystone_authtoken]
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = glance
password = changemenow

[matchmaker_redis]
[oslo_concurrency]
[oslo_messaging_amqp]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_messaging_zmq]
[oslo_middleware]
[oslo_policy]
[paste_deploy]

flavor = keystone

[profiler]
[store_type_location_strategy]
[task]
[taskflow_executor]
#let's do the same with image metadata configuration:

mv /etc/glance/glance-registry.conf /etc/glance/glance-registry.conf.old
vim /etc/glance/glance-registry.conf
#paste:

[DEFAULT]
[database]
connection = mysql+pymysql://glance:changemenow@controller/glance

[keystone_authtoken]
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = glance
password = changemenow

[matchmaker_redis]
[oslo_messaging_amqp]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_messaging_zmq]
[oslo_policy]
[paste_deploy]

flavor = keystone
[profiler]
#now sync glance database with above configuration 
#and restart the service:

/bin/sh -c "glance-manage db_sync" glance
service glance-registry restart
service glance-api restart
#verify by making a new Ubuntu image:

wget https://uec-images.ubuntu.com/releases/16.04/release-20170330/ubuntu-16.04-server-cloudimg-amd64-disk1.img
openstack image create "ubuntu_16.04" --file ubuntu-16.04-server-cloudimg-amd64-disk1.img --disk-format qcow2 --container-format bare --public
#verify using the following command:

openstack image list

Nova

Following subsystems run only on controller nodes:
nova api
nova conductor
nova consoleauth
nova novncproxy
nova scheduler 
#let's prepare the database first:

mysql -u root -pchangemenow
#paste following on MariaDB prompt:

CREATE DATABASE nova_api;
CREATE DATABASE nova;
GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY 'changemenow';
GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY 'changemenow';
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'changemenow';
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'changemenow';
exit
#create user, assign role, and create API endpoints:
#once prompted use changemenow as password:  

openstack user create --domain default --password-prompt nova
openstack role add --project service --user nova admin
openstack service create --name nova --description "OpenStack Compute" compute
openstack endpoint create --region RegionOne compute public http://controller:8774/v2.1/%\(tenant_id\)s
openstack endpoint create --region RegionOne compute internal http://controller:8774/v2.1/%\(tenant_id\)s
openstack endpoint create --region RegionOne compute admin http://controller:8774/v2.1/%\(tenant_id\)s
#these nova sub-systems run on controller node only:

apt install nova-api nova-conductor nova-consoleauth nova-novncproxy nova-scheduler
#removing default configuration with a new one:

mv /etc/nova/nova.conf /etc/nova/nova.conf.old
vim /etc/nova/nova.conf
#paste:

[DEFAULT]
dhcpbridge_flagfile=/etc/nova/nova.conf
dhcpbridge=/usr/bin/nova-dhcpbridge
log-dir=/var/log/nova
state_path=/var/lib/nova
force_dhcp_release=True
verbose=True
ec2_private_dns_show_ip=True
enabled_apis=osapi_compute,metadata
transport_url = rabbit://openstack:changemenow@controller
auth_strategy = keystone
my_ip = 192.168.1.11
use_neutron = True
firewall_driver = nova.virt.firewall.NoopFirewallDriver
compute_driver = libvirt.LibvirtDriver
scheduler_default_filters = RetryFilter, AvailabilityZoneFilter, RamFilter, ComputeFilter, ComputeCapabilitiesFilter, ImagePropertiesFilter, ServerGroupAntiAffinityFilter, ServerGroupAffinityFilter

[database]
connection = mysql+pymysql://nova:changemenow@controller/nova

[api_database]
connection = mysql+pymysql://nova:changemenow@controller/nova_api

[oslo_concurrency]
lock_path = /var/lib/nova/tmp

[libvirt]
use_virtio_for_bridges=True

[wsgi]
api_paste_config=/etc/nova/api-paste.ini

[keystone_authtoken]
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = nova
password = changemenow

[vnc]
enabled = True
vncserver_listen = $my_ip
vncserver_proxyclient_address = $my_ip
novncproxy_base_url = http://controller:6080/vnc_auto.html

[glance]
api_servers = http://controller:9292

[libvirt]
virt_type = kvm

[neutron]
url = http://controller:9696
auth_url = http://controller:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = neutron
password = changemenow
service_metadata_proxy = True
metadata_proxy_shared_secret = changemenow
#sync databases:

/bin/sh -c "nova-manage api_db sync" nova
/bin/sh -c "nova-manage db sync" nova
#nova compute runs on compute node
#in our case controller is also a compute node
#install nova-compute on controller:

apt install nova-compute
#create configuration file for nova-compute:

mv /etc/nova/nova-compute.conf /etc/nova/nova-compute.conf.old
vim /etc/nova/nova-compute.conf
#paste following:

[DEFAULT]
compute_driver=libvirt.LibvirtDriver

[libvirt]
virt_type=kvm

Neutron

Following subsystems runs on controller nodes only:
neutron server
neutron ml2 plugin
#install OVS:

apt install openvswitch-switch -y
#verify OVS:

lsmod | grep switch
ovs-vsctl show
#setup database:

mysql -u root -pchangemenow
#paste following on MariaDB prompt:

CREATE DATABASE neutron;
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'changemenow';
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'changemenow';
exit
#create a user, assign role, and create endpoints
#use password changemenow

openstack user create --domain default --password-prompt neutron
openstack role add --project service --user neutron admin
openstack service create --name neutron --description "OpenStack Networking" network
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 neutron server, plugin, and agents:

apt install neutron-server neutron-plugin-ml2
apt install neutron-plugin-openvswitch-agent neutron-l3-agent neutron-dhcp-agent neutron-metadata-agent
#neutron server configuration:

mv /etc/neutron/neutron.conf /etc/neutron/neutron.conf.old
vim /etc/neutron/neutron.conf
#paste:

[DEFAULT]
core_plugin = ml2
service_plugins = router
allow_overlapping_ips = True
transport_url = rabbit://openstack:changemenow@controller
auth_strategy = keystone
notify_nova_on_port_status_changes = True
notify_nova_on_port_data_changes = True

[agent]
root_helper = sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf

[cors]
[cors.subdomain]
[database]
connection = mysql+pymysql://neutron:changemenow@controller/neutron

[keystone_authtoken]
auth_uri = http://controller:5000
auth_url = http://controller:35357
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = changemenow

[matchmaker_redis]
[nova]
auth_url = http://controller:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = nova
password = changemenow

[oslo_concurrency]
[oslo_messaging_amqp]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_messaging_zmq]
[oslo_policy]
[qos]
[quotas]
[ssl]
#create neutron core ml2 plugin configuration file:

mv /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugins/ml2/ml2_conf.ini.old
vim /etc/neutron/plugins/ml2/ml2_conf.ini
#paste:

[DEFAULT]
[ml2]
type_drivers = flat,vlan,vxlan
tenant_network_types = vxlan
mechanism_drivers = openvswitch,l2population
extension_drivers = port_security

[ml2_type_flat]
flat_networks = provider
[ml2_type_geneve]
[ml2_type_gre]
[ml2_type_vlan]
[ml2_type_vxlan]
vni_ranges = 1:1000

[securitygroup]
enable_ipset = True
#create OVS agent configuration file:

mv /etc/neutron/plugins/ml2/openvswitch_agent.ini /etc/neutron/plugins/ml2/openvswitch_agent.ini.old
vim /etc/neutron/plugins/ml2/openvswitch_agent.ini
#paste:

[ovs]
local_ip = 192.168.1.11

[agent]
tunnel_types = vxlan
l2_population = True
prevent_arp_spoofing = True

[securitygroup]
firewall_driver = iptables_hybrid
enable_security_group = True
#create DHCP agent configuration file:

mv /etc/neutron/dhcp_agent.ini /etc/neutron/dhcp_agent.ini.old
vim /etc/neutron/dhcp_agent.ini
#paste:

[DEFAULT]
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = True
interface_driver = openvswitch
[AGENT]
#create metadata agent configuration file:

mv /etc/neutron/metadata_agent.ini /etc/neutron/metadata_agent.ini.old
vim /etc/neutron/metadata_agent.ini
#paste:

[DEFAULT]
nova_metadata_ip = controller
metadata_proxy_shared_secret = changemenow
[AGENT]
[cache]
#create L3 agent configuration:

mv /etc/neutron/l3_agent.ini /etc/neutron/l3_agent.ini.old
vim /etc/neutron/l3_agent.ini
#paste following, 
#as per neutron documentation external_network_bridge 
#intentioannly do not have any value

[DEFAULT]
interface_driver = openvswitch
enable_isolated_metadata = True
external_network_bridge =
#sync neutron database:

/bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron
#restart nova and neutron service:

service neutron-server restart
/etc/init.d/openvswitch-switch restart
service neutron-dhcp-agent restart
service neutron-metadata-agent restart
service neutron-l3-agent restart
service nova-api restart
service nova-compute restart
service nova-consoleauth restart
service nova-scheduler restart
service nova-conductor restart
service nova-novncproxy restart
#verify nova, output provided in compute node section:

openstack compute service list
#verify neutron, output provided in compute node section:

openstack network agent list

Horizon

#Install horizon dashboard:

apt install openstack-dashboard -y
#replace few default parameter in the configuration:
 
sed -i 's/ubuntu/default/' /etc/openstack-dashboard/local_settings.py
sed -i 's/v2.0/v3/' /etc/openstack-dashboard/local_settings.py
sed -i 's/_member_/user/' /etc/openstack-dashboard/local_settings.py
sed -i 's/127.0.0.1/controller/' /etc/openstack-dashboard/local_settings.py
#few more on dashboard configuration: 

vim /etc/openstack-dashboard/local_settings.py

#paste following,be careful about python indentation:

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "Default"
OPENSTACK_API_VERSIONS = {
    "identity": 3,
    "image": 2,
}
#restart apache server:

service apache2 restart
#access the dashboard using the following URL
#user admin or demo user created earlier for login


http://controller/horizon
Part 2: The Compute Node…