OpenStack First-Use Configuration

Target Outcome

By the end of Phase 8 you should have:

1. Horizon dashboard reachable
2. Admin OpenStack CLI working
3. Core services registered
4. Glance image uploaded
5. Public/provider network created
6. Private tenant network created
7. Router connecting private network to provider network
8. Flavor created
9. SSH keypair added
10. Security group opened for ICMP and SSH
11. Test instance booted
12. Floating IP attached
13. SSH into the test VM working

8.1 Load the OpenStack Admin Environment

Run on ctrl:

source /opt/kolla-ansible/kolla-env.sh
export KOLLA_INVENTORY=/opt/kolla-ansible/inventory/multinode-homelab

Run post-deploy if you have not already:

kolla-ansible post-deploy -i "$KOLLA_INVENTORY"

This should create:

/etc/kolla/admin-openrc.sh

Load it:

source /etc/kolla/admin-openrc.sh

Confirm authentication works:

openstack token issue

Expected: a token table is returned.


8.2 Check Core OpenStack Services

Run:

openstack service list

You should see services like:

keystone
glance
placement
nova
neutron

Check endpoints:

openstack endpoint list

Check Nova services:

openstack compute service list

Expected services:

nova-api
nova-scheduler
nova-conductor
nova-compute on cmp
nova-compute on gpu

Check hypervisors:

openstack hypervisor list

Expected:

cmp
gpu

Check Neutron agents:

openstack network agent list

Expected agents:

Open vSwitch agent on ctrl
Open vSwitch agent on cmp
Open vSwitch agent on gpu
DHCP agent on ctrl
L3 agent on ctrl
Metadata agent on ctrl

8.3 Check Horizon UI

From your browser:

http://192.168.1.50/

or:

http://192.168.1.50/dashboard

Get the admin password:

sudo grep keystone_admin_password /etc/kolla/passwords.yml

Login:

Domain: Default
User: admin
Password: <keystone_admin_password>

8.4 Upload a Test Cloud Image

Use CirrOS first. It is tiny and ideal for proving Nova/Neutron works.

On ctrl:

mkdir -p ~/openstack-images
cd ~/openstack-images

wget https://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img

Upload to Glance:

openstack image create "cirros-0.6.2" \
--file cirros-0.6.2-x86_64-disk.img \
--disk-format qcow2 \
--container-format bare \
--public

Verify:

openstack image list

Expected:

cirros-0.6.2

8.5 Create Basic Flavors

Create a tiny CirrOS flavor:

openstack flavor create m1.tiny \
--id 1 \
--ram 512 \
--disk 1 \
--vcpus 1

Create a small Ubuntu-ready flavor for later:

openstack flavor create m1.small \
--id 2 \
--ram 2048 \
--disk 20 \
--vcpus 1

Verify:

openstack flavor list

8.6 Understand Your Network Model

Your Kolla config uses:

network_interface: "eth0"
api_interface: "eth0"
tunnel_interface: "eth0"
neutron_external_interface: "enp6s19"
neutron_plugin_agent: "openvswitch"
neutron_tenant_network_types: "vxlan"

Meaning:

eth0      = management/API/tunnel network
enp6s19 = external/provider network, no IP on host
VXLAN = tenant/private networks
OVS = bridge/agent implementation

Your OpenStack external/provider network should map to enp6s19.


8.7 Create the External Provider Network

You need to decide which IP range to expose as OpenStack floating IPs.

Assuming your LAN is:

192.168.1.0/24
Gateway: 192.168.1.1
DNS: 192.168.1.1 or 8.8.8.8
OpenStack VIP: 192.168.1.50
ctrl: 192.168.1.51
cmp: 192.168.1.52
gpu: 192.168.1.53

Choose a free floating IP range that does not overlap with DHCP or existing hosts.

Example:

Floating IP range: 192.168.1.200 - 192.168.1.220
Gateway: 192.168.1.1
Subnet: 192.168.1.0/24

Create the external network:

openstack network create public1 \
--external \
--provider-network-type flat \
--provider-physical-network physnet1

Create the external subnet:

openstack subnet create public1-subnet \
--network public1 \
--subnet-range 192.168.1.0/24 \
--allocation-pool start=192.168.1.200,end=192.168.1.220 \
--gateway 192.168.1.1 \
--dns-nameserver 192.168.1.1 \
--no-dhcp

Verify:

openstack network list
openstack subnet list

Important: this assumes Kolla maps your external bridge to physnet1. If this fails, we will inspect /etc/kolla/neutron-openvswitch-agent/openvswitch_agent.ini on ctrl.


8.8 Create a Private Tenant Network

Create a private VXLAN tenant network:

openstack network create private1

Create a private subnet:

openstack subnet create private1-subnet \
--network private1 \
--subnet-range 10.10.10.0/24 \
--gateway 10.10.10.1 \
--dns-nameserver 192.168.1.1

Verify:

openstack network list
openstack subnet list

8.9 Create a Router

Create the router:

openstack router create router1

Attach it to the external provider network:

openstack router set router1 --external-gateway public1

Attach the private subnet:

openstack router add subnet router1 private1-subnet

Verify:

openstack router list
openstack router show router1
openstack port list --router router1

8.10 Create an SSH Keypair

Use your existing SSH public key if available:

ls -l ~/.ssh/*.pub

Create an OpenStack keypair:

openstack keypair create \
--public-key ~/.ssh/id_ed25519.pub \
homelab-key

If you do not have a key yet:

ssh-keygen -t ed25519 -f ~/.ssh/openstack_homelab -C "openstack-homelab"

openstack keypair create \
--public-key ~/.ssh/openstack_homelab.pub \
homelab-key

Verify:

openstack keypair list

8.11 Open Security Group Rules

Allow ping:

openstack security group rule create default \
--protocol icmp \
--ingress

Allow SSH:

openstack security group rule create default \
--protocol tcp \
--dst-port 22 \
--ingress

Verify:

openstack security group rule list default

8.12 Boot the First Test Instance

Create the CirrOS instance:

openstack server create test-cirros-01 \
--image cirros-0.6.2 \
--flavor m1.tiny \
--network private1 \
--key-name homelab-key

Watch it build:

watch -n 2 openstack server list

Expected:

test-cirros-01  ACTIVE

Check details:

openstack server show test-cirros-01

8.13 Attach a Floating IP

Create a floating IP:

openstack floating ip create public1

List it:

openstack floating ip list

Assign it to the test VM:

FLOATING_IP=$(openstack floating ip list -f value -c "Floating IP Address" | head -1)

openstack server add floating ip test-cirros-01 "$FLOATING_IP"

echo "$FLOATING_IP"

Verify:

openstack server list
openstack floating ip list

8.14 Test Network Access

Ping the floating IP from ctrl:

ping -c 4 "$FLOATING_IP"

Try SSH.

For CirrOS:

ssh cirros@"$FLOATING_IP"

Default CirrOS login is commonly:

username: cirros
password: gocubsgo

If using your SSH key:

ssh -i ~/.ssh/id_ed25519 cirros@"$FLOATING_IP"

or, if you created a dedicated key:

ssh -i ~/.ssh/openstack_homelab cirros@"$FLOATING_IP"

8.15 Check Placement and Hypervisor Resources

Run:

openstack hypervisor list
openstack hypervisor stats show

Show details:

openstack hypervisor show cmp
openstack hypervisor show gpu

Check compute services:

openstack compute service list

Check resource providers:

openstack resource provider list

8.16 Check Neutron Agent Health

Run:

openstack network agent list

You want all relevant agents alive:

neutron-openvswitch-agent  ctrl  Alive :-)
neutron-openvswitch-agent cmp Alive :-)
neutron-openvswitch-agent gpu Alive :-)
neutron-dhcp-agent ctrl Alive :-)
neutron-l3-agent ctrl Alive :-)
neutron-metadata-agent ctrl Alive :-)

If DHCP or metadata fails, check:

docker logs --tail 100 neutron_dhcp_agent
docker logs --tail 100 neutron_metadata_agent
docker logs --tail 100 neutron_l3_agent

8.17 Verify From Horizon

In Horizon:

Project → Compute → Instances
Project → Network → Networks
Project → Network → Routers
Project → Network → Floating IPs
Admin → Compute → Hypervisors
Admin → System → System Information

You should see:

test-cirros-01
private1
public1
router1
floating IP allocation
cmp and gpu hypervisors

8.18 Useful Troubleshooting Commands

Check all containers

Avoid Docker Go-template quoting inside Ansible. Use:

ansible -i "$KOLLA_INVENTORY" control,compute \
-m shell \
-a "hostname; docker ps | sort" \
-b

Check unhealthy containers

ansible -i "$KOLLA_INVENTORY" control,compute \
-m shell \
-a "hostname; docker ps --filter health=unhealthy || true" \
-b

Check exited containers

ansible -i "$KOLLA_INVENTORY" control,compute \
-m shell \
-a "hostname; docker ps -a --filter status=exited || true" \
-b

Check OpenStack service catalog

openstack catalog list

Check Nova logs on controller

docker logs --tail 100 nova_api
docker logs --tail 100 nova_scheduler
docker logs --tail 100 nova_conductor

Check Nova logs on compute nodes

ansible -i "$KOLLA_INVENTORY" compute \
-m shell \
-a "hostname; docker logs --tail 100 nova_compute" \
-b

Check Neutron logs

On ctrl:

docker logs --tail 100 neutron_server
docker logs --tail 100 neutron_l3_agent
docker logs --tail 100 neutron_dhcp_agent
docker logs --tail 100 neutron_metadata_agent
docker logs --tail 100 neutron_openvswitch_agent

On compute nodes:

ansible -i "$KOLLA_INVENTORY" compute \
-m shell \
-a "hostname; docker logs --tail 100 neutron_openvswitch_agent" \
-b

8.19 Save a Phase 8 Environment Helper

Create a helper file:

cat > ~/phase8-openstack-env.sh <<'EOF'
#!/usr/bin/env bash

source /opt/kolla-ansible/kolla-env.sh
export KOLLA_INVENTORY=/opt/kolla-ansible/inventory/multinode-homelab
source /etc/kolla/admin-openrc.sh

echo "Kolla inventory: $KOLLA_INVENTORY"
echo "OpenStack cloud: $OS_AUTH_URL"
openstack token issue >/dev/null && echo "OpenStack auth: OK"
EOF

chmod +x ~/phase8-openstack-env.sh

Use it:

source ~/phase8-openstack-env.sh

8.20 Full Phase 8 Runbook

You can run this after confirming your floating IP range is safe:

source /opt/kolla-ansible/kolla-env.sh
export KOLLA_INVENTORY=/opt/kolla-ansible/inventory/multinode-homelab

kolla-ansible post-deploy -i "$KOLLA_INVENTORY"

source /etc/kolla/admin-openrc.sh

openstack token issue
openstack service list
openstack endpoint list
openstack compute service list
openstack hypervisor list
openstack network agent list

mkdir -p ~/openstack-images
cd ~/openstack-images
wget -nc https://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img

openstack image create "cirros-0.6.2" \
--file cirros-0.6.2-x86_64-disk.img \
--disk-format qcow2 \
--container-format bare \
--public

openstack flavor create m1.tiny \
--id 1 \
--ram 512 \
--disk 1 \
--vcpus 1

openstack flavor create m1.small \
--id 2 \
--ram 2048 \
--disk 20 \
--vcpus 1

openstack network create public1 \
--external \
--provider-network-type flat \
--provider-physical-network physnet1

openstack subnet create public1-subnet \
--network public1 \
--subnet-range 192.168.1.0/24 \
--allocation-pool start=192.168.1.200,end=192.168.1.220 \
--gateway 192.168.1.1 \
--dns-nameserver 192.168.1.1 \
--no-dhcp

openstack network create private1

openstack subnet create private1-subnet \
--network private1 \
--subnet-range 10.10.10.0/24 \
--gateway 10.10.10.1 \
--dns-nameserver 192.168.1.1

openstack router create router1

openstack router set router1 --external-gateway public1

openstack router add subnet router1 private1-subnet

openstack keypair create \
--public-key ~/.ssh/id_ed25519.pub \
homelab-key

openstack security group rule create default \
--protocol icmp \
--ingress

openstack security group rule create default \
--protocol tcp \
--dst-port 22 \
--ingress

openstack server create test-cirros-01 \
--image cirros-0.6.2 \
--flavor m1.tiny \
--network private1 \
--key-name homelab-key

watch -n 2 openstack server list

Then in another shell:

source /etc/kolla/admin-openrc.sh

openstack floating ip create public1

FLOATING_IP=$(openstack floating ip list -f value -c "Floating IP Address" | head -1)

openstack server add floating ip test-cirros-01 "$FLOATING_IP"

ping -c 4 "$FLOATING_IP"

ssh cirros@"$FLOATING_IP"

Phase 8 Success Criteria

Phase 8 is complete when these all pass:

openstack token issue
openstack service list
openstack compute service list
openstack hypervisor list
openstack network agent list
openstack image list
openstack flavor list
openstack network list
openstack router list
openstack server list
openstack floating ip list

And your test VM reaches:

ACTIVE

with working:

ping floating-ip
ssh floating-ip

Then your homelab OpenStack is not just deployed; it is operational.