Skip to content

OpenStack — Day-2 Operations

🎯 Introduction

Day-2 Operations covers every operational task that comes after the initial OpenStack deployment. This guide covers:

  • ✅ Upgrades and updates
  • ✅ Backups and disaster recovery
  • ✅ Monitoring and alerting
  • ✅ Capacity planning
  • ✅ Recurring troubleshooting
  • ✅ Security management
  • ✅ Performance tuning

Daily Tasks

# Automated health check (via cron)
0 9 * * * /usr/local/bin/openstack-health-check.sh

# Check critical services
openstack compute service list
openstack network agent list
openstack volume service list

# Review error logs
docker logs --since 24h nova_compute | grep -i error
docker logs --since 24h neutron_openvswitch_agent | grep -i error

Weekly Tasks

# Clean up stale ERROR instances (>7 days)
openstack server list --all-projects --status ERROR \
  --long | awk '{print $1}' | xargs -I {} openstack server delete {}

# Clean up old snapshots (>30 days)
# Custom script, depending on your policy

# Verify backups
ls -lh /backups/openstack/ | tail -10

# Review resource usage
openstack hypervisor stats show
ceph df  # If Ceph is in use

Monthly Tasks

# Refresh base images
# Download new Ubuntu, CentOS, etc. releases
# Upload to Glance and mark the old ones as deprecated

# Capacity review
# Check trends in Grafana
# Plan an expansion if needed

# Security updates
apt update && apt upgrade  # On every node
# Reconfigure OpenStack if anything changed
kolla-ansible -i /etc/kolla/multinode reconfigure

Quarterly Tasks

# OpenStack upgrades (following the release cadence)
# See the Upgrades section below

# Disaster recovery drill
# Restore backups into a test environment

# Security review
# Audit users, roles and security groups
# Verify compliance

🔄 OpenStack Upgrades

Upgrade Strategy

OpenStack follows a SLURP model (stable releases roughly every year):

2023.1 (Antelope) → 2023.2 (Bobcat) → 2024.1 (Caracal) → 2024.2 (Dalmatian)

Recommendation: upgrade every 2-3 releases (skip the intermediate ones when using SLURP)

Pre-Upgrade Checklist

# 1. Check the current release
kolla-ansible --version
openstack --version

# 2. Full backup (see the Backups section)
./backup-openstack.sh

# 3. Check cluster health
kolla-ansible -i /etc/kolla/multinode prechecks

# 4. Read the release notes
# https://releases.openstack.org/caracal/index.html

# 5. Prepare the maintenance window
# Notify users, schedule the downtime

# 6. Check Kolla image compatibility
# https://quay.io/repository/openstack.kolla/

Upgrade Process (Kolla-Ansible)

# 1. Update Kolla-Ansible
pip install --upgrade kolla-ansible==18.0.0  # New version

# 2. Update Ansible dependencies
kolla-ansible install-deps

# 3. Regenerate passwords (for new services)
kolla-genpwd

# 4. Merge configuration
# Compare /etc/kolla/globals.yml against the new template
diff /etc/kolla/globals.yml \
  ~/kolla-venv/share/kolla-ansible/etc_examples/kolla/globals.yml

# 5. Pull the new images
kolla-ansible -i /etc/kolla/multinode pull

# 6. Prechecks
kolla-ansible -i /etc/kolla/multinode prechecks

# 7. Upgrade (no downtime when running HA)
kolla-ansible -i /etc/kolla/multinode upgrade

# 8. Post-upgrade checks
openstack service list
openstack compute service list
openstack network agent list

# 9. Launch a test instance
openstack server create --flavor m1.small --image cirros test-upgrade

Rollback Strategy

# If the upgrade fails:

# 1. Stop the new services
kolla-ansible -i /etc/kolla/multinode stop

# 2. Restore the previous images
# Edit /etc/kolla/globals.yml:
# openstack_release: "2023.2"  # Previous version

# 3. Reconfigure with the previous version
kolla-ansible -i /etc/kolla/multinode reconfigure

# 4. Restore the DB if needed
# See the Backups section

# 5. Verify everything works
openstack server list

💾 Backups

What to Back Up

Component What to Back Up Frequency Retention
MariaDB All databases Daily 30 days
Config Files /etc/kolla On change 90 days
Glance Images Images pool (Ceph) or /var/lib/glance Weekly 60 days
Cinder Volumes Critical volumes Per SLA Per SLA
Keystone User/role dump Weekly 90 days

MariaDB Backup Script

#!/bin/bash
# /usr/local/bin/backup-openstack-dbs.sh

BACKUP_DIR="/backups/openstack/mariadb"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

mkdir -p $BACKUP_DIR

# Get the MariaDB password
DB_PASSWORD=$(grep database_password /etc/kolla/passwords.yml | awk '{print $2}')

# Back up each database
for db in keystone glance nova nova_api nova_cell0 neutron cinder heat; do
  echo "Backing up $db..."
  docker exec mariadb mysqldump \
    -uroot -p$DB_PASSWORD \
    --single-transaction \
    --routines \
    --triggers \
    $db | gzip > $BACKUP_DIR/${db}_${DATE}.sql.gz
done

# Full backup (alternative)
docker exec mariadb mysqldump \
  -uroot -p$DB_PASSWORD \
  --all-databases \
  --single-transaction \
  --routines \
  --triggers | gzip > $BACKUP_DIR/all_databases_${DATE}.sql.gz

# Prune old backups
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete

echo "Backup completed: $BACKUP_DIR"
ls -lh $BACKUP_DIR | tail -5

Restoring MariaDB

#!/bin/bash
# restore-openstack-db.sh

BACKUP_FILE="/backups/openstack/mariadb/keystone_20260125_100000.sql.gz"
DB_NAME="keystone"
DB_PASSWORD=$(grep database_password /etc/kolla/passwords.yml | awk '{print $2}')

# Stop the services using this DB
kolla-ansible -i /etc/kolla/multinode stop --tags keystone

# Restore
zcat $BACKUP_FILE | docker exec -i mariadb mysql -uroot -p$DB_PASSWORD $DB_NAME

# Restart the services
kolla-ansible -i /etc/kolla/multinode deploy --tags keystone

# Verify
openstack user list

Ceph Backups (if in use)

# Snapshot of the whole pool
rbd snap create images@backup-$(date +%Y%m%d)
rbd snap create volumes@backup-$(date +%Y%m%d)

# Incremental export (more efficient)
rbd export-diff images/<image-name> /backups/ceph/image-diff-$(date +%Y%m%d).diff

# Automate it with cron
0 2 * * * /usr/local/bin/backup-ceph-pools.sh

Disaster Recovery Plan

## DR Procedure (RTO: 4 hours, RPO: 24 hours)

1. **Prepare the replacement infrastructure** (1h)
   - Provision hardware/VMs
   - Set up basic networking

2. **Restore the controllers** (1.5h)
   - Fresh Kolla-Ansible deploy
   - Restore /etc/kolla
   - Restore MariaDB from backup

3. **Restore the Compute nodes** (30min)
   - Deploy nova-compute
   - Sync with the DB

4. **Restore Storage** (30min)
   - Restore the Ceph cluster, or
   - Mount the storage backends

5. **Verification** (30min)
   - Launch test instances
   - Check access to volumes and images
   - Test connectivity

📊 Monitoring and Alerting

Monitoring Stack

Prometheus:  # Metrics
  - OpenStack Exporter
  - Ceph Exporter (MGR module)
  - Node Exporter (hardware)
  - cAdvisor (containers)

Grafana:  # Visualization
  - Dashboards pre-configured by Kolla
  - Custom dashboards

Elasticsearch + Kibana:  # Centralized logs
  - Logs from every OpenStack service
  - Event correlation

Alertmanager:  # Alerts
  - PagerDuty/Slack/Email
  - Escalation policies

Key Metrics to Monitor

Compute (Nova):
  - Hypervisor utilization (CPU, RAM, disk)
  - Instance count per tenant
  - Failed instance spawns
  - Instance migration errors

Network (Neutron):
  - Agent status (all should be UP)
  - Router count
  - Floating IP exhaustion
  - DHCP failures

Storage (Cinder + Ceph):
  - Volume creation failures
  - Ceph health (HEALTH_OK)
  - OSD utilization
  - Slow ops

Database:
  - MariaDB connections
  - Query latency
  - Galera cluster status

APIs:
  - Response time per endpoint
  - Error rate (4xx, 5xx)
  - Request rate

Critical Alerts (Examples)

# prometheus-alerts.yml

groups:
  - name: openstack_critical
    rules:
      - alert: HypervisorDown
        expr: openstack_nova_agent_state{service="nova-compute"} == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Hypervisor {{ $labels.hostname }} is down"

      - alert: CephHealthError
        expr: ceph_health_status == 2
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Ceph cluster is in HEALTH_ERR state"

      - alert: APIResponseTimeSlow
        expr: histogram_quantile(0.99, http_request_duration_seconds) > 5
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "API response time is high (p99 > 5s)"

📈 Capacity Planning

Capacity Calculation

# capacity_calculator.py

def calculate_capacity(current_vms, growth_rate_monthly, months):
    """
    Calculates the future capacity required

    Args:
        current_vms: current VMs
        growth_rate_monthly: monthly growth rate in % (e.g. 10 = 10%)
        months: months to project
    """
    future_vms = current_vms * ((1 + growth_rate_monthly/100) ** months)

    # Assuming an average of 4 vCPUs and 8GB RAM per VM
    vcpus_needed = future_vms * 4
    ram_gb_needed = future_vms * 8

    # With 1.5x CPU overcommit and 1.2x RAM
    physical_cores = vcpus_needed / 1.5
    physical_ram_gb = ram_gb_needed / 1.2

    print(f"Projection over {months} months:")
    print(f"  Estimated VMs: {int(future_vms)}")
    print(f"  vCPUs needed: {int(vcpus_needed)}")
    print(f"  Physical cores: {int(physical_cores)}")
    print(f"  Physical RAM: {int(physical_ram_gb)} GB")
    print(f"  Servers needed (32c, 256GB): {int(physical_ram_gb / 256) + 1}")

# Example
calculate_capacity(current_vms=500, growth_rate_monthly=5, months=12)
# Query Prometheus to see usage trends
# Instance growth (last 30 days)
rate(openstack_nova_running_vms[30d])

# Average hypervisor utilization
avg(openstack_nova_vcpus_used / openstack_nova_vcpus) * 100

# Capacity projection (example with Grafana)
# Find out when 80% utilization will be reached

When to Scale

Metric Expansion Threshold
Hypervisor CPU >70% sustained average
Hypervisor RAM >80% sustained average
Disk Storage >75% used
Ceph OSDs >70% used (any OSD)
Network bandwidth >60% sustained peak
Failed spawns >5% of attempts

🔒 Security Management

Post-Deployment Security Hardening

# 1. Enable TLS on every API
# See the deployment guide

# 2. Rotate passwords regularly
vim /etc/kolla/passwords.yml
# Change the critical passwords:
# - keystone_admin_password
# - database_password
# - rabbitmq_password

kolla-ansible -i /etc/kolla/multinode reconfigure

# 3. Audit inactive users
openstack user list --long
# Disable users inactive for more than 90 days
openstack user set --disable <user-id>

# 4. Review permissive security groups
openstack security group list --all-projects
openstack security group rule list default
# Remove any unnecessary 0.0.0.0/0 rules

# 5. Enable audit logging
# Edit /etc/kolla/config/keystone/keystone.conf:
[audit]
enabled = True

kolla-ansible -i /etc/kolla/multinode reconfigure --tags keystone

Patch Management

# Automate it with Ansible
# Create the playbook patch-openstack.yml:

---
- hosts: all
  become: yes
  tasks:
    - name: Update all packages
      apt:
        upgrade: dist
        update_cache: yes
      when: ansible_os_family == "Debian"

    - name: Check if reboot required
      stat:
        path: /var/run/reboot-required
      register: reboot_required

    - name: Reboot if needed
      reboot:
        reboot_timeout: 300
      when: reboot_required.stat.exists

# Run it in a rolling fashion (one node at a time)
ansible-playbook -i inventory patch-openstack.yml --limit compute01
# Wait for it to come back and migrate the VMs
# Repeat for each compute node

🚨 Incident Response

Procedure for a Critical Outage

## Incident Response Runbook

### Severity 1: Core Service Down (RTO: 1 hour)

1. **Detection** (0-5 min)
   - Monitoring alert
   - Check the scope: `openstack service list`

2. **Communication** (5-10 min)
   - Notify stakeholders
   - Update the status page

3. **Diagnosis** (10-20 min)
   - `docker ps -a` - find containers that are down
   - `docker logs <service>` - identify the root cause
   - `ceph -s` if it is a storage issue

4. **Mitigation** (20-40 min)
   - Restart services: `docker restart <service>`
   - Failover to standby (if running HA)
   - Roll back if there was a recent upgrade

5. **Resolution** (40-60 min)
   - Permanent fix
   - Verify end-to-end functionality
   - Launch test instance

6. **Post-Mortem** (after the incident)
   - Root cause analysis
   - Prevent recurrence
   - Update the runbooks

Audit Logs

# Enable auditing in Keystone
# /etc/kolla/config/keystone/keystone.conf
[audit]
enabled = True
audit_map_file = /etc/keystone/api_audit_map.conf

# Review the audit trail
# In Kibana, filter by the "audit" tag

# Examples of events worth auditing:
# - User creation/deletion
# - Role changes
# - Failed logins
# - Quota changes

🎓 Runbooks for Common Operations

Adding a New Compute Node

# 1. Prepare the hardware and OS
# 2. Configure networking (see the deployment guide)
# 3. Add it to the inventory
vim /etc/kolla/multinode
# Add compute03 under [compute]

# 4. Deploy only on the new node
kolla-ansible -i /etc/kolla/multinode deploy --limit compute03

# 5. Verify
openstack hypervisor list

Draining a Compute Node (Maintenance)

# 1. Disable scheduling
openstack compute service set --disable compute01 nova-compute \
  --disable-reason "Scheduled maintenance"

# 2. Migrate the instances
# List the instances running on the host
openstack server list --all-projects --host compute01

# Migrate each one (cold migration if there is no shared storage)
for vm in $(openstack server list --host compute01 -f value -c ID); do
  openstack server migrate $vm --wait
done

# 3. Confirm no VMs are left
openstack server list --host compute01

# 4. Proceed with the maintenance
# Reboot, patch, etc.

# 5. Re-enable it
openstack compute service set --enable compute01 nova-compute

Cleaning Up Orphaned Resources

#!/bin/bash
# cleanup-orphaned-resources.sh

echo "Cleaning up orphaned resources..."

# Ports with no device
echo "1. Ports with no device:"
openstack port list --device-owner none -f value -c ID | while read port; do
  echo "  Deleting port $port"
  openstack port delete $port
done

# Volumes in ERROR for >7 days
echo "2. Volumes in ERROR (stale):"
# Requires a Python script to filter by date

# Unassigned floating IPs
echo "3. Unused floating IPs:"
openstack floating ip list --status DOWN -f value -c ID | while read fip; do
  echo "  Releasing floating IP $fip"
  openstack floating ip delete $fip
done

echo "Cleanup completed"

📚 References


Day-2 Operations in Place

With these practices, your OpenStack cloud is ready for long-term production use.

Automation

Automate as much as possible with Ansible, scripts and proactive monitoring.