OpenStack Affinity and Anti-Affinity

Server groups with affinity and anti-affinity policies control how the Nova scheduler places instances across compute hosts. Affinity keeps instances together on the same host; anti-affinity spreads them across different hosts. This is essential for high availability and performance optimization.

When to Use Each Policy

Policy Effect Use Case
affinity All group members on the same host Low-latency communication between VMs
anti-affinity Each member on a different host HA — survive single host failure
soft-affinity Prefer same host, but allow spread Best-effort colocation
soft-anti-affinity Prefer different hosts, but allow colocation HA with limited hosts

Prerequisites

Requirement Details
OpenStack 2024.2 Dalmatian
Compute hosts At least 2 (for anti-affinity)
Nova scheduler FilterScheduler with ServerGroupAffinityFilter enabled

Step 1: Enable the Scheduler Filters

Verify the required filters are enabled in /etc/nova/nova.conf on the controller:

[filter_scheduler]
enabled_filters = AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter

Restart Nova scheduler:

sudo systemctl restart nova-scheduler

Step 2: Create an Anti-Affinity Server Group

Anti-affinity ensures each instance lands on a different compute host:

openstack server group create \
  --policy anti-affinity \
  ha-web-group

Note the group ID from the output.

Step 3: Launch Instances in the Group

openstack server create \
  --flavor m1.medium \
  --image "Ubuntu 22.04" \
  --network tenant-net \
  --hint group=<ha-web-group-id> \
  web-01

openstack server create \
  --flavor m1.medium \
  --image "Ubuntu 22.04" \
  --network tenant-net \
  --hint group=<ha-web-group-id> \
  web-02

openstack server create \
  --flavor m1.medium \
  --image "Ubuntu 22.04" \
  --network tenant-net \
  --hint group=<ha-web-group-id> \
  web-03

Each instance will be placed on a different compute host. If there are not enough hosts, the launch fails (use soft-anti-affinity to relax this).

Step 4: Verify Placement

openstack server list --long -c Name -c Host

Expected output:

+--------+------------+
| Name   | Host       |
+--------+------------+
| web-01 | compute-01 |
| web-02 | compute-02 |
| web-03 | compute-03 |
+--------+------------+

Step 5: Create an Affinity Server Group

Affinity forces all instances onto the same host:

openstack server group create \
  --policy affinity \
  colocated-group

openstack server create \
  --flavor m1.small \
  --image "Ubuntu 22.04" \
  --network tenant-net \
  --hint group=<colocated-group-id> \
  app-01

openstack server create \
  --flavor m1.small \
  --image "Ubuntu 22.04" \
  --network tenant-net \
  --hint group=<colocated-group-id> \
  app-02

Both instances land on the same compute host.

Step 6: Use Soft Policies

Soft policies are best-effort—they prefer the policy but do not fail if it cannot be satisfied:

# Prefer different hosts, but allow colocation if needed
openstack server group create \
  --policy soft-anti-affinity \
  flexible-ha-group

# Prefer same host, but allow spread if needed
openstack server group create \
  --policy soft-affinity \
  flexible-colocated-group

Real-World Patterns

Database HA Cluster

openstack server group create --policy anti-affinity db-cluster
for i in 1 2 3; do
  openstack server create --flavor m1.xlarge \
    --image "Ubuntu 22.04" --network db-net \
    --hint group=<db-cluster-id> db-node-$i
done

Application + Cache Colocation

openstack server group create --policy affinity app-cache
openstack server create --flavor m1.medium \
  --image "Ubuntu 22.04" --network app-net \
  --hint group=<app-cache-id> app-server
openstack server create --flavor m1.small \
  --image "Ubuntu 22.04" --network app-net \
  --hint group=<app-cache-id> redis-cache

Managing Server Groups

# List all server groups
openstack server group list

# Show group details and members
openstack server group show <group-id>

# Delete a group (instances are not affected)
openstack server group delete <group-id>

Troubleshooting

Issue Fix
Instance fails with No valid host Not enough hosts for anti-affinity; use soft policy
Policy not enforced Verify scheduler filters include ServerGroup*Filter
Cannot add to group after creation Groups are set at launch via --hint; cannot add existing VMs
Soft policy always colocates Check if only one compute host is enabled

Summary

Server groups with affinity and anti-affinity policies give you control over instance placement. Use anti-affinity for high availability across hosts, affinity for low-latency colocation, and soft variants when flexibility is needed.