メインコンテンツにスキップ
バージョン: 3.0

スナップショットから仮想マシン(インスタンス)を復元する

このガイドでは、snapshot-restore.sh スクリプトを使用して、アタッチされた OpenStack ボリュームを、その Cinder スナップショットのいずれかから復元する方法について説明します。

スクリプトでは、プロジェクト、サーバー、アタッチされたボリューム、およびスナップショットの選択を求められます。 その後、サーバーを停止し、選択した Ceph RBD スナップショットをロールバックしてから、サーバーを再起動します。 復元ワークフローの完全な例については、完全な復元セッションの出力例を参照してください。

データ損失のリスク

スナップショットからボリュームを復元すると、現在のボリュームのデータが上書きされます。 スナップショットの作成後に加えた変更はすべて失われます。

始める前に

スクリプトを実行するホストが、必要な OpenStack および Ceph へのアクセス権限を持っていることを確認してください。

SSH 経由で root としてクラスタに接続する

SSH を使用して CubeCOS クラスタのルートシェルに接続し、管理タスクを実行する方法について学びましょう。

  1. ターミナルアプリを開いてください。

  2. 次のコマンドを使用して、SSH(Secure Shell)経由でCubeCOSクラスタに接続します:

    ssh root@<your-cluster-vip>
  3. プロンプトが表示されたら、SSHパスワードを入力してください。

スナップショットからボリュームを復元する

  1. スクリプトを snapshot-restore.sh という名前で保存してください。 スクリプトは、完全復元スクリプトから入手してください。

  2. スクリプトに実行権限を設定してください。

    Make the restore script executable
    chmod +x snapshot-restore.sh
  3. スクリプトを実行してください。

    Run snapshot-restore.sh
    ./snapshot-restore.sh
  4. 復元対象の仮想マシンが配置されているプロジェクト番号を入力してください。

    Project selection
    Select a project by number:
    1. admin
    2. _diagnostics
    3. bigstack
    Enter the number: 3
  5. 復元したいインスタンスの番号を入力してください。 インスタンスは、インスタンス名またはUUIDのいずれかを使用して特定できます。

    Server selection
    Select a server by number:
    1. vm-snap-restore (52d7f3fa-4d6f-4868-b271-e018c78a061f)
    Enter the number: 1
  6. 復元するボリュームの番号を入力してください。

    オペレーティングシステムがインストールされているルートディスクは通常 /dev/sda ですが、その他のデータディスクはそれより小さいインデックス番号のデバイスに割り当てられています。 各ボリュームを特定するには、「Compute」>「Instances」 に移動し、復元するインスタンスを選択してから、「Volumes」 タブをクリックしてボリュームに関する情報を表示します。

    Volume selection
    Select a volume by number:
    1. d11dfee8-3067-4031-8e4d-da3bc867c913 (Device: /dev/sda)
    2. 684483a5-4bd6-448f-810a-81517d82754f (Device: /dev/sdb)
    Enter the number: 1
  7. 復元元のスナップショットの番号を入力してください。

    Snapshot selection
    Select a snapshot by number:
    1. snapshot for add-data-v3 - Created: 2025-02-06 05:42:57
    2. snapshot for add-data-v1 - Created: 2025-02-06 05:42:11
    3. snapshot for snap-data - Created: 2025-02-06 02:01:19
    Enter the number: 1
  8. 復元を確認してください。

    このスクリプトは、選択されたボリュームとスナップショットのIDを表示し、確認を求めます:

    :::危険[データ損失]

    スナップショットからボリュームを復元すると、現在のボリュームのデータが上書きされます。 スナップショットの作成後に加えた変更はすべて失われます。

    :::

    Restore confirmation prompt
    WARNING: This operation will revert the volume
    (d11dfee8-3067-4031-8e4d-da3bc867c913) to the selected snapshot
    (50927e68-9330-46d6-bf8a-1dac0db8e652).
    The associated server will be SHUTDOWN, and all current disk data will be LOST.
    Type 'YES' to confirm:
    • 続行するには、YES と入力してください。
    • キャンセルするには、それ以外の文字を入力してください。

復元後に、サーバーとボリュームが正常に動作していることを確認してください

スクリプトの実行が完了したら、サーバーと復元されたボリュームが正常に動作していることを確認してください。

  1. サーバーのステータスが Active であることを確認してください。
  2. 対象のボリュームがまだ接続されていること、およびボリュームのステータスが**「使用中」**であることを確認してください。
  3. サーバーにログインし、復元されたデータまたはファイルシステムの状態を確認してください。

完全復元スクリプト

snapshot-restore.sh
#!/bin/bash
source /etc/admin-openrc.sh

# Get the list of project names
projects=($(openstack project list -c Name -f value))

# Display the numbered list
echo "Select a project by number:"
for i in "${!projects[@]}"; do
echo "$((i+1)). ${projects[i]}"
done

# Read user input
read -p "Enter the number: " choice

# Validate input
if [[ $choice -ge 1 && $choice -le ${#projects[@]} ]]; then
project_name=(${projects[$((choice-1))]})
echo "You selected: ${projects[$((choice-1))]}"
else
echo "Invalid choice. Exiting."
exit 1
fi
## - End of Project -

# Get the list of servers (Name and ID)
mapfile -t servers < <(openstack server list --project="$project_name" --long -c Name -c ID -f value)

# Check if there are any servers
if [ ${#servers[@]} -eq 0 ]; then
echo "No servers found for project $project_name."
exit 1
fi

# Display the numbered list
echo "Select a server by number:"
for i in "${!servers[@]}"; do
selected_server_id=$(echo "${servers[i]}" | awk '{print $1}') # Extract server ID
server_name=$(echo "${servers[i]}" | awk '{$1=""; print $0}' | sed 's/^ *//') # Extract server name
echo "$((i+1)). $server_name ($selected_server_id)"
done

# Read user input
read -p "Enter the number: " choice

# Validate input
if [[ $choice -ge 1 && $choice -le ${#servers[@]} ]]; then
selected_server="${servers[$((choice-1))]}"
selected_server_id=$(echo "$selected_server" | awk '{print $1}') # Extract server ID
server_name=$(echo "$selected_server" | awk '{$1=""; print $0}' | sed 's/^ *//') # Extract server name
echo "You selected: $server_name ($selected_server_id)"
else
echo "Invalid choice. Exiting."
exit 1
fi
## - End of Server -

volumes_json=$(openstack server show "$selected_server_id" -c attached_volumes -f json)

# Extract volume IDs
mapfile -t volume_ids < <(echo "$volumes_json" | jq -r '.attached_volumes[].id')

# Check if there are any attached volumes
if [ ${#volume_ids[@]} -eq 0 ]; then
echo "No attached volumes found for server $selected_server_id."
exit 1
fi

# Get details of each attached volume
volume_info=()
for volume_id in "${volume_ids[@]}"; do
volume_json=$(openstack volume show "$volume_id" -c attachments -f json)
device=$(echo "$volume_json" | jq -r '.attachments[0].device')

# Store volume info (ID and device)
volume_info+=("$volume_id $device")
done

# Display numbered list
echo "Select a volume by number:"
for i in "${!volume_info[@]}"; do
volume_id=$(echo "${volume_info[i]}" | awk '{print $1}')
device=$(echo "${volume_info[i]}" | awk '{print $2}')
echo "$((i+1)). $volume_id (Device: $device)"
done

# Get user input
read -p "Enter the number: " choice

# Validate input
if [[ $choice -ge 1 && $choice -le ${#volume_info[@]} ]]; then
selected_volume_id=$(echo "${volume_info[$((choice-1))]}" | awk '{print $1}')
echo "You selected volume: $selected_volume_id"
else
echo "Invalid choice. Exiting."
exit 1
fi

## - End of Volume -

# Get all snapshots for the project "bigstack"
snapshots_json=$(openstack volume snapshot list --project="$project_name" --long -f json)

# Extract snapshots related to the selected volume
mapfile -t snapshot_info < <(echo "$snapshots_json" | jq -c --arg vol "$selected_volume_id" \
'.[] | select(.Volume == $vol) | {name: .Name, id: .ID, created_at: .["Created At"]}')

# Check if there are any snapshots
if [ ${#snapshot_info[@]} -eq 0 ]; then
echo "No snapshots found for volume: $selected_volume_id"
exit 1
fi

# Convert "Created At" to human-readable format and display options
echo "Select a snapshot by number:"
for i in "${!snapshot_info[@]}"; do
name=$(echo "${snapshot_info[i]}" | jq -r '.name') # Extract snapshot name
id=$(echo "${snapshot_info[i]}" | jq -r '.id') # Extract snapshot ID
created_at=$(echo "${snapshot_info[i]}" | jq -r '.created_at') # Extract Created At

# Convert to human-readable format
human_date=$(date -d "$created_at" '+%Y-%m-%d %H:%M:%S' 2>/dev/null)

# If date conversion fails, set a fallback
if [[ -z "$human_date" ]]; then
human_date="Invalid Date"
fi

echo "$((i+1)). $name - Created: $human_date"
done

# Get user selection
read -p "Enter the number: " choice

# Validate input
if [[ $choice -ge 1 && $choice -le ${#snapshot_info[@]} ]]; then
selected_snapshot_id=$(echo "${snapshot_info[$((choice-1))]}" | jq -r '.id') # Extract snapshot ID
echo "You selected snapshot: $selected_snapshot_id"
else
echo "Invalid choice. Exiting."
exit 1
fi

## - End of Snapshot -

# Ask for final confirmation
echo ""
echo "WARNING: This operation will revert the volume ($selected_volume_id) to the selected snapshot ($selected_snapshot_id)."
echo "The associated server will be SHUTDOWN, and all current disk data will be LOST."
echo ""
read -p "Type 'YES' to confirm: " confirmation

# Check if the user entered exactly "YES"
if [[ "$confirmation" != "YES" ]]; then
echo "Operation canceled. No changes were made."
exit 1
fi

# Proceed with the revert operation, ensure the server is SHUTOFF before proceeding
echo "Stopping the server ($selected_server_id)..."
openstack server stop "$selected_server_id"

# Wait until the server is fully stopped
echo "Waiting for server ($selected_server_id) to shut down..."
while true; do
vm_state=$(openstack server show "$selected_server_id" -c vm_state -f value)
if [[ "$vm_state" == "stopped" ]]; then
echo "✅ Server is now stopped."
break
fi
echo "⏳ Server is still stopping... checking again in 5 seconds."
sleep 5
done

echo "Reverting volume $selected_volume_id to snapshot $selected_snapshot_id..."
rbd snap rollback cinder-volumes/volume-"$selected_volume_id"@snapshot-"$selected_snapshot_id"

echo "Revert operation completed successfully."

echo "Starting the server ($selected_server_id)..."
openstack server start "$selected_server_id"

echo "Server started successfully."

完全復元セッションの出力例

Example restore session
Select a project by number:
1. admin
2. _diagnostics
3. bigstack
Enter the number: 3
You selected: bigstack
Select a server by number:
1. vm-snap-restore (52d7f3fa-4d6f-4868-b271-e018c78a061f)
Enter the number: 1
You selected: vm-snap-restore (52d7f3fa-4d6f-4868-b271-e018c78a061f)
Select a volume by number:
1. d11dfee8-3067-4031-8e4d-da3bc867c913 (Device: /dev/sda)
2. 684483a5-4bd6-448f-810a-81517d82754f (Device: /dev/sdb)
Enter the number: 1
You selected volume: d11dfee8-3067-4031-8e4d-da3bc867c913
Select a snapshot by number:
1. snapshot for add-data-v3 - Created: 2025-02-06 05:42:57
2. snapshot for add-data-v1 - Created: 2025-02-06 05:42:11
3. snapshot for snap-data - Created: 2025-02-06 02:01:19
Enter the number: 1
You selected snapshot: 50927e68-9330-46d6-bf8a-1dac0db8e652

WARNING: This operation will revert the volume
(d11dfee8-3067-4031-8e4d-da3bc867c913) to the selected snapshot
(50927e68-9330-46d6-bf8a-1dac0db8e652).
The associated server will be SHUTDOWN, and all current disk data will be LOST.

Type 'YES' to confirm: YES
Stopping the server (52d7f3fa-4d6f-4868-b271-e018c78a061f)...
Waiting for server (52d7f3fa-4d6f-4868-b271-e018c78a061f) to shut down...
Server is still stopping. Checking again in 5 seconds.
Server is now stopped.
Reverting volume d11dfee8-3067-4031-8e4d-da3bc867c913 to snapshot 50927e68-9330-46d6-bf8a-1dac0db8e652...
Rolling back to snapshot: 100% complete...done.
Revert operation completed successfully.
Starting the server (52d7f3fa-4d6f-4868-b271-e018c78a061f)...
Server started successfully.

復元時の一般的なエラーのトラブルシューティング

スクリプトはプロジェクトを一覧表示できません

/etc/admin-openrc.sh が存在し、有効な OpenStack 認証情報が含まれていることを確認してください。

認証をテストするには:

Test OpenStack authentication
openstack project list

サーバーは表示されていません

選択したプロジェクトにサーバーが含まれていること、および自分の認証情報でそれらを読み取れることを確認してください:

List servers in a project
openstack server list --project PROJECT_NAME --long

関連付けられたボリュームが見つかりません

選択したサーバーにボリュームがアタッチされていることを確認してください:

Show attached server volumes
openstack server show SERVER_ID -c attached_volumes

スナップショットが見つかりません

選択したボリュームに、選択したプロジェクト内のスナップショットが存在することを確認してください:

List volume snapshots
openstack volume snapshot list --project PROJECT_NAME --long

サーバーは停止しません

サーバーの状態とハイパーバイザーのステータスを確認します:

Check server state
openstack server show SERVER_ID -c status -c vm_state -c OS-EXT-SRV-ATTR:host

サーバーが停止するまでは、RBDのロールバックを実行しないでください。

ロールバックに失敗しました

Cephプール、ボリュームID、およびスナップショットIDが正しいことを確認してください:

List RBD snapshots for a volume
rbd snap ls cinder-volumes/volume-VOLUME_ID

次に、ロールバック先が存在することを確認します:

Verify the rollback target
rbd info cinder-volumes/volume-VOLUME_ID@snapshot-SNAPSHOT_ID