While traditional infrastructure makes a clear distinction between images (OS templates) and snapshots (point-in-time volume states), OpenStack blurs this line for operational flexibility. The core differentiation lies in metadata properties and use case optimization:
# Glance image-show output comparison
# Standard image properties
glance image-show standard_image
| Property | Value |
|------------------|-----------------|
| disk_format | qcow2 |
| container_format | bare |
# Snapshot-derived image properties
glance image-show snapshot_image
| Property | Value |
|-----------------------|-----------------------|
| snapshot_id | a1b2c3d4 |
| instance_uuid | e5f6g7h8 |
| base_image_ref | i9j0k1l2 |
OpenStack's design serves two primary technical needs:
- Instance Portability: Snapshots maintain VM-specific configurations (
nova boot --image snapshot_image
preserves networking/IP settings) - Template Customization: Standard images support cloud-init injection during launch (
cloud_config
gets processed only on first boot)
Consider this Nova API sequence for creating a golden image:
# Create instance from base image
nova boot --image cirros --flavor 1 test_vm
# Create snapshot (becomes Glance image)
nova image-create test_vm vm_snapshot
# Convert to reusable template
glance image-update vm_snapshot \
--property image_type=golden \
--remove-property instance_uuid
Snapshot-backed images exhibit different storage behavior:
Metric | Standard Image | Snapshot Image |
---|---|---|
Launch time | Faster (raw copy) | Slower (COW layers) |
Storage efficiency | Lower (full copy) | Higher (differential) |
This Python snippet demonstrates snapshot lineage tracking:
from glanceclient import Client
gc = Client('2', session=keystone_session)
def get_image_lineage(image_id):
lineage = []
while True:
img = gc.images.get(image_id)
lineage.append(img.name)
if not hasattr(img, 'base_image_ref'):
break
image_id = img.base_image_ref
return lineage
OpenStack treats images and snapshots as fundamentally different entities despite their technical similarities in the Glance database. Here's why:
# Example: Creating an image from snapshot in OpenStack CLI
openstack image create --disk-format qcow2 --container-format bare \
--property image_type='snapshot' snapshot_from_instance
While both appear as Glance images, snapshots carry critical metadata:
# Sample API response showing snapshot-specific properties
{
"image": {
"id": "c6a3a7d0-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"name": "prod-server-snapshot",
"properties": {
"image_type": "snapshot",
"instance_uuid": "a1b2c3d4-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"base_image_ref": "67890abc-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
}
Three technical reasons for maintaining separation:
- Lifecycle Management: Snapshots maintain instance relationships for rollback scenarios
- Storage Optimization: Images use copy-on-write while snapshots preserve exact block states
- API Behavior: Certain operations (e.g., shelving) automatically generate snapshots
Here's how to properly convert between types:
# Convert snapshot to deployable image
openstack image create --disk-format qcow2 \
--property image_type='image' \
--file snapshot.qcow2 deployable_image
# Verify conversion succeeded
openstack image show deployable_image -f json | jq '.properties.image_type'
- Attempting to launch instances directly from large snapshots
- Assuming snapshot metadata persists through image conversions
- Neglecting to clean up orphaned snapshot-derived images
# Recommended snapshot retention policy
openstack image list --property image_type=snapshot \
--sort-column Created_at --limit 5 -f value -c ID | \
xargs -n1 openstack image delete