web-dev-qa-db-ja.com

自動スナップショットを作成および回転する方法は?

Compute Engineでは、基本的にバックアップであるスナップショットを作成できます。毎日自動化されたスナップショットを作成し、4つのスナップショットを保持するスクリプトを作成する方法を理解してみてください。これは、Google Cloudでの唯一の懸念事項であり、サーバーのバックアップがスケジュールされていないことです。

20
Imran Rashid

ドキュメント それを行う方法についてはかなり明確です:

gcloud compute disks snapshot DISK

ご了承ください

スナップショットは常に、最後に成功したスナップショットに基づいて作成されます

そして、スナップショットを削除する前に、その図を見てください: enter image description here

詳細 APIに関する情報。

10

[〜#〜] update [〜#〜]

この答えを最初に出してからスクリプトは大きく変わりました-最新のコードについてはGithubリポジトリを参照してください: https://github.com/jacksegal/google-compute-snapshot

元の回答:

私は同じ問題を抱えていたので、毎日スナップショットを取り、7日間ですべてのスナップショットを削除する単純なシェルスクリプトを作成しました: https://github.com/Forward-Action/google-compute-snapshot

#!/usr/bin/env bash
export PATH=$PATH:/usr/local/bin/:/usr/bin

#
# CREATE DAILY SNAPSHOT
#

# get the device name for this vm
DEVICE_NAME="$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/device-name" -H "Metadata-Flavor: Google")"

# get the device id for this vm
DEVICE_ID="$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/id" -H "Metadata-Flavor: Google")"

# get the zone that this vm is in
INSTANCE_ZONE="$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/zone" -H "Metadata-Flavor: Google")"

# strip out the zone from the full URI that google returns
INSTANCE_ZONE="${INSTANCE_ZONE##*/}"

# create a datetime stamp for filename
DATE_TIME="$(date "+%s")"

# create the snapshot
echo "$(gcloud compute disks snapshot ${DEVICE_NAME} --snapshot-names gcs-${DEVICE_NAME}-${DEVICE_ID}-${DATE_TIME} --zone ${INSTANCE_ZONE})"


#
# DELETE OLD SNAPSHOTS (OLDER THAN 7 DAYS)
#

# get a list of existing snapshots, that were created by this process (gcs-), for this vm disk (DEVICE_ID)
SNAPSHOT_LIST="$(gcloud compute snapshots list --regexp "(.*gcs-.*)|(.*-${DEVICE_ID}-.*)" --uri)"

# loop through the snapshots
echo "${SNAPSHOT_LIST}" | while read line ; do

   # get the snapshot name from full URL that google returns
   SNAPSHOT_NAME="${line##*/}"

   # get the date that the snapshot was created
   SNAPSHOT_DATETIME="$(gcloud compute snapshots describe ${SNAPSHOT_NAME} | grep "creationTimestamp" | cut -d " " -f 2 | tr -d \')"

   # format the date
   SNAPSHOT_DATETIME="$(date -d ${SNAPSHOT_DATETIME} +%Y%m%d)"

   # get the expiry date for snapshot deletion (currently 7 days)
   SNAPSHOT_EXPIRY="$(date -d "-7 days" +"%Y%m%d")"

   # check if the snapshot is older than expiry date
if [ $SNAPSHOT_EXPIRY -ge $SNAPSHOT_DATETIME ];
        then
     # delete the snapshot
         echo "$(gcloud compute snapshots delete ${SNAPSHOT_NAME} --quiet)"
   fi
done
30
Jack Segal

私の解決策は少し簡単です。プライマリディスクだけでなく、すべてのディスクのスナップショットを作成します。

プロジェクト内のすべてのディスクをリストすることにより、gcloudプロジェクト内で実行されている限り(およびプロジェクトサーバーの外部でも実行するように変更できる限り)、1つのスクリプトからすべてのサーバーを処理します。

古いスナップショットを整理するには、フィルタを使用してgcloudコマンドラインから処理できるため、複雑な日付処理は必要ありません。

https://gitlab.com/alan8/google-cloud-auto-snapshot

#!/bin/bash
# loop through all disks within this project  and create a snapshot
gcloud compute disks list | tail -n +2 | while read DISK_NAME ZONE c3 c4; do
  gcloud compute disks snapshot $DISK_NAME --snapshot-names auto-$DISK_NAME-$(date "+%s") --zone $ZONE 
done
#
# snapshots are incremental and dont need to be deleted, deleting snapshots will merge snapshots, so deleting doesn't loose anything
# having too many snapshots is unwieldy so this script deletes them after 60 days
#
gcloud compute snapshots list --filter="creationTimestamp<$(date -d "-60 days" "+%Y-%m-%d") AND (auto.*)" --uri | while read SNAPSHOT_URI; do
  gcloud compute snapshots delete --quiet $SNAPSHOT_URI
done
#

また、OSXユーザーの場合、次のようなものを使用する必要があります。

$(date -j -v-60d "+%Y-%m-%d")

creationTimestampフィルター用

11
Alan Fuller

GCPで利用可能な「スナップショットスケジュール」と呼ばれる機能があります。

まだベータ版のようで、この機能に関するドキュメントはまだありません。しかし、それを可能にするのは簡単なプロセスです。最初にスナップショットスケジュールを作成し、セットアップ後に永続ディスクに割り当てることができます。

Snapshot Schedule Creation via GUI

コマンドラインリファレンスも参照して、対応するgcloudコマンドでスケジュールを作成してください。

gcloud beta compute resource-policies create-snapshot-schedule

https://cloud.google.com/sdk/gcloud/reference/beta/compute/resource-policies/create-snapshot-schedule

永続ディスクにスケジュールを割り当てるには、次のコマンドを使用できます

gcloud beta compute disks add-resource-policies

https://cloud.google.com/sdk/gcloud/reference/beta/compute/disks/add-resource-policies

2019-02-15の更新:昨日以来、スケジュールされたスナップショット機能についての ブログ発表 と、 スケジュールされたスナップショット のCompute Engineドキュメント。

4
Daniel Härter

スクリプトは、$ HOSTNAMEがdisk-nameと同じであると想定しています(私のプライマリシステムディスクは、VMインスタンスまたは$ HOSTNAME-(お好みに変更)と同じ名前を想定しています) $ HOSTNAME、VMのシステムディスクを指す必要があります。

gcloudは差分差分スナップショットを作成します。最も古いものには、ほとんどの情報が含まれます。完全なスナップショットの作成について心配する必要はありません。最も古いものを削除すると、新しい最も古いスナップショットが、将来のインクリメンタルのベースとなるプライマリになります。これはすべてGoogle側のロジックで行われるため、gcloudの自動処理です。

このスクリプトは、cronジョブで1時間ごとに実行されるように設定されています。増分スナップショット(abt 1〜2GB)を作成し、保存日より古いものを削除します。 Googleは、最も古いスナップショット(以前は増分)を魔法のようにサイズ変更して、ベーススナップショットにします。これをテストするには、ベーススナップショットを削除し、スナップショットリスト(console.cloud.google.com)を更新します。「マジック」はバックグラウンドで発生するため、リベースするには1分ほどかかる場合があります。その後、最も古いスナップショットがベースであり、そのサイズがスナップショットを実行しているディスクの使用済み部分を反映していることに気付くでしょう。

$>スナップショット

#!/bin/bash

    . ~/.bash_profile > /dev/null 2>&1  # source environment for cron jobs

    retention=7 #days

    zone=`gcloud info|grep zone:|awk -F\[ '{print $2}'|awk -F\] '{print $1}'`
    date=`date +"%Y%m%d%H%M"`
    expire=`date -d "-${retention} days" +"%Y%m%d%H%M"`

    snapshots=`gcloud compute snapshots list --regexp "(${HOSTNAME}-.*)" --uri`

    # Delete snapshots older than $expire
    for line in "${snapshots[@]}"
    do
      snapshot=`echo ${line}|awk -F\/  '{print $10}'|awk -F\  '{print $1}'`
      snapdate=`echo $snapshot|awk -F\- '{print $3}'`
      if (( $snapdate <= $expire )); then
        gcloud compute snapshots delete $snapshot --quiet
      fi
    done

    # Create New Snapshot
    gcloud compute disks snapshot $HOSTNAME --snapshot-name ${HOSTNAME}-${date} --zone $zone --description "$HOSTNAME Disk snapshot ${date}"
2
Neal Garrett

以下は、このタスクを達成するための非常に無礼なRubyスクリプトです。インスピレーションを得るための例として考えてください。

それを改善するためのフィードバックは大歓迎です;-)

require 'date'

ARCHIVE = 30 # Days
DISKS   = [] # The names of the disks to snapshot
FORMAT  = '%y%m%d'

today = Date.today
date = today.strftime(FORMAT).to_i
limit = (today - ARCHIVE).strftime(FORMAT).to_i

# Backup
`gcloud compute disks snapshot #{DISKS.join(' ')} --snapshot-names #{DISKS.join("-#{date},")}-#{date}`

# Rotate
snapshots = []
`gcloud compute snapshots list`.split("\n").each do |row|
  name = date
  row.split("\s").each do |cell|
    name = cell
    break
  end
  next if name == 'NAME'
  snapshots << name if name[-6, 6].to_i < limit
end
`yes | gcloud compute snapshots delete #{snapshots.join(' ')}` if snapshots.length > 0
1
panteo

この例では、MySQLのスナップショットを作成するメンテナンスウィンドウがあります。サービスアカウントにgcloud snapshotsコマンドを実行する権限があることを前提としています。それが役に立てば幸い:

#!/bin/bash

days_to_keep=7

disk=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/disks/1/device-name" -H "Metadata-Flavor: Google"`
zone=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/zone" -H "Metadata-Flavor: Google"`
project=`curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google"`
zone=`basename ${zone}`
storage_location=`echo ${zone}|sed 's/-[a-z]$//'`


systemctl stop mysqld
sleep 5
# flush file system buffers
sync
# create snapshot
gcloud -q compute disks snapshot ${disk} --project=${project} --snapshot-names=${disk}-$(date +%s) --zone=${zone} --storage-location=${storage_location}

systemctl start mysqld


delete_date=$(date -d "-${days_to_keep} days" "+%Y-%m-%d")

# get list of snapshots to delete
to_del=$(gcloud compute snapshots list  --filter="name ~ ${disk}* AND creationTimestamp<$delete_date" --format "csv[no-heading](name)")

# delete bulk of old snapshots
if [[ ! -z ${to_del} ]]
then
    gcloud compute snapshots delete -q ${to_del}
fi
1
Maoz Zadok

また、これを書いている時点では、Windowsインスタンスはボリュームシャドウコピーサービス(VSS)をサポートしていますが、Linuxインスタンスはサポートしていません。

したがって、インスタンスの実行中に--guest-flushスイッチを使用してWindowsドライブのスナップショットを安全に作成できますが、Linuxドライブの場合はそうではありません。

Linuxドライブのスナップショットを作成する前に、スナップショットの準備のために他のメカニズムが必要になります。つまり、ドライブをフリーズする、ドライブを切り離す、またはインスタンスの電源をオフにします。

0
Richard Salt

[--set-scheduling]がシチュエーションgcloudフラグであり、そのプロセスが完了するまで現在のコマンドが実行されないようにするwait [process]があることを他に何も知らない場合。それを&&演算子と組み合わせて(前のステートメントが完了した後に同じステートメントのコマンドを実行します)、この吸盤をつなぎ合わせることはそれほど難しくないはずです。起動時に(起動コマンドオプションがあるインスタンスを作成するときに)実行し、時間をカウントするか、定期メンテナンス機能の1つがコマンドをトリガーするようにします。しかし、正直なところ、必要がないのに構文を混ぜるのはなぜですか?

これは動作する可能性があります(コピー/貼り付けしないでください)

gcloud config set compute/zone wait [datetime-function] && \
gcloud compute disks snapshot snap1 snap2 snap3 \
        --snapshot-names ubuntu12 ubuntu14 debian8  \
        --description=\
            '--format="multi(\
                info:format=list always-display-title compact,\
                data:format=list always-display-title compact\
                )"'

理論上、gcloudは計算/ゾーンを設定しますが、指定された時間まで待機する必要があります。二重アンパサンド(&&)があるため、次のコマンドは最初のコマンドが完了するまで実行されません。私は説明をやりすぎたかもしれませんが、その簡潔さを示すためにそうしました。それはそのままでは機能しないことはわかっていますが、それほど遠くないことも知っています。すべてのコードを確認した後、不滅のシーケンスを解決しようとしていると思うかもしれません。 bashファイルで作業するのが最善の方法ではないと思います。 gcloudは、コマンドラインを知らない人のためにコマンドラインを作成しました。環境に対して適切な方法でコードを書くことを教えられました(または学んだ...またはまだ学んでいない)。ここでそれを適用し、CLOUD SDKを使用して利点があると言います。

0
user1586275