删除存储卷的快照 - AWS Storage Gateway

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

删除存储卷的快照

可以删除存储卷的快照。例如,当您在一段时间内拍摄了存储卷的许多快照而不再需要较旧的快照时,您可能想要删除快照。由于快照是增量备份,因此删除某个快照的操作仅会删除其他快照不需要的数据。

在 Amazon EBS 控制台上,您可以一次删除一个快照。有关如何使用亚马逊EBS控制台删除快照的信息,请参阅亚马逊EC2用户指南中的删除亚马逊EBS快照

要一次删除多个快照,您可以使用其中一个支持 Storage Gateway 操作的快照。 AWS SDKs有关示例,请参阅 使用 AWS SDK适用于 Java 的,删除快照使用 for 删除快 AWS SDK照。 NET使用 AWS Tools for Windows PowerShell删除快照

使用 AWS SDK适用于 Java 的,删除快照

如需删除与卷关联的多个快照,您可以使用编程方法。以下示例演示如何使用 AWS SDK适用于 Java 的删除快照。如需使用示例代码,您应该熟悉 Java 控制台应用程序的运行方式。有关更多信息,请参阅 For Java 开发人员指南中的入门。AWS SDK如果您只需删除少量快照,请按 删除存储卷的快照 中所述使用控制台。

例 : 使用 AWS SDK适用于 Java 的删除快照

以下 Java 代码示例列出了网关各个卷的快照以及快照起始日期是在指定日期前还是之后。它使用 AWS SDK适用于 Java API 的 Storage Gateway 和 Amazon EC2。Amazon EC2 API 包括处理快照的操作。

更新代码以提供服务终端节点、您的网关 Amazon 资源名称 (ARN) 以及您想要保存快照的天数。此截止日期之前拍摄的快照都将被删除。您还需要指定布尔值 viewOnly,该值表明是要查看要删除的快照还是实际执行快照删除。先只带 view 选项 (即将 viewOnly 设置为 true) 运行代码,看看代码会删除什么。有关可以与 Storage Gateway 配合使用的 AWS 服务终端节点列表,请参阅中的AWS Storage Gateway 终端节点和配额AWS 一般参考

import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import com.amazonaws.auth.PropertiesCredentials; import com.amazonaws.services.ec2.AmazonEC2Client; import com.amazonaws.services.ec2.model.DeleteSnapshotRequest; import com.amazonaws.services.ec2.model.DescribeSnapshotsRequest; import com.amazonaws.services.ec2.model.DescribeSnapshotsResult; import com.amazonaws.services.ec2.model.Filter; import com.amazonaws.services.ec2.model.Snapshot; import com.amazonaws.services.storagegateway.AWSStorageGatewayClient; import com.amazonaws.services.storagegateway.model.ListVolumesRequest; import com.amazonaws.services.storagegateway.model.ListVolumesResult; import com.amazonaws.services.storagegateway.model.VolumeInfo; public class ListDeleteVolumeSnapshotsExample { public static AWSStorageGatewayClient sgClient; public static AmazonEC2Client ec2Client; static String serviceURLSG = "https://storagegateway.us-east-1.amazonaws.com"; static String serviceURLEC2 = "https://ec2.us-east-1.amazonaws.com"; // The gatewayARN public static String gatewayARN = "*** provide gateway ARN ***"; // The number of days back you want to save snapshots. Snapshots before this cutoff are deleted // if viewOnly = false. public static int daysBack = 10; // true = show what will be deleted; false = actually delete snapshots that meet the daysBack criteria public static boolean viewOnly = true; public static void main(String[] args) throws IOException { // Create a Storage Gateway and amazon ec2 client sgClient = new AWSStorageGatewayClient(new PropertiesCredentials( ListDeleteVolumeSnapshotsExample.class.getResourceAsStream("AwsCredentials.properties"))); sgClient.setEndpoint(serviceURLSG); ec2Client = new AmazonEC2Client(new PropertiesCredentials( ListDeleteVolumeSnapshotsExample.class.getResourceAsStream("AwsCredentials.properties"))); ec2Client.setEndpoint(serviceURLEC2); List<VolumeInfo> volumes = ListVolumesForGateway(); DeleteSnapshotsForVolumes(volumes, daysBack); } public static List<VolumeInfo> ListVolumesForGateway() { List<VolumeInfo> volumes = new ArrayList<VolumeInfo>(); String marker = null; do { ListVolumesRequest request = new ListVolumesRequest().withGatewayARN(gatewayARN); ListVolumesResult result = sgClient.listVolumes(request); marker = result.getMarker(); for (VolumeInfo vi : result.getVolumeInfos()) { volumes.add(vi); System.out.println(OutputVolumeInfo(vi)); } } while (marker != null); return volumes; } private static void DeleteSnapshotsForVolumes(List<VolumeInfo> volumes, int daysBack2) { // Find snapshots and delete for each volume for (VolumeInfo vi : volumes) { String volumeARN = vi.getVolumeARN(); String volumeId = volumeARN.substring(volumeARN.lastIndexOf("/")+1).toLowerCase(); Collection<Filter> filters = new ArrayList<Filter>(); Filter filter = new Filter().withName("volume-id").withValues(volumeId); filters.add(filter); DescribeSnapshotsRequest describeSnapshotsRequest = new DescribeSnapshotsRequest().withFilters(filters); DescribeSnapshotsResult describeSnapshotsResult = ec2Client.describeSnapshots(describeSnapshotsRequest); List<Snapshot> snapshots = describeSnapshotsResult.getSnapshots(); System.out.println("volume-id = " + volumeId); for (Snapshot s : snapshots){ StringBuilder sb = new StringBuilder(); boolean meetsCriteria = !CompareDates(daysBack, s.getStartTime()); sb.append(s.getSnapshotId() + ", " + s.getStartTime().toString()); sb.append(", meets criteria for delete? " + meetsCriteria); sb.append(", deleted? "); if (!viewOnly & meetsCriteria) { sb.append("yes"); DeleteSnapshotRequest deleteSnapshotRequest = new DeleteSnapshotRequest().withSnapshotId(s.getSnapshotId()); ec2Client.deleteSnapshot(deleteSnapshotRequest); } else { sb.append("no"); } System.out.println(sb.toString()); } } } private static String OutputVolumeInfo(VolumeInfo vi) { String volumeInfo = String.format( "Volume Info:\n" + " ARN: %s\n" + " Type: %s\n", vi.getVolumeARN(), vi.getVolumeType()); return volumeInfo; } // Returns the date in two formats as a list public static boolean CompareDates(int daysBack, Date snapshotDate) { Date today = new Date(); Calendar cal = new GregorianCalendar(); cal.setTime(today); cal.add(Calendar.DAY_OF_MONTH, -daysBack); Date cutoffDate = cal.getTime(); return (snapshotDate.compareTo(cutoffDate) > 0) ? true : false; } }

使用 for 删除快 AWS SDK照。 NET

如需删除与卷关联的多个快照,您可以使用编程方法。以下示例演示如何使用 for 删除快照。 AWS SDK NET版本 2 和 3。要使用示例代码,您应该熟悉如何运行。 NET控制台应用程序。有关更多信息,请参阅 for 中的AWS SDK入门。 NET开发者指南。如果您只需删除少量快照,请按 删除存储卷的快照 中所述使用控制台。

例 :使用 for 删除快 AWS SDK照。 NET

在以下 C# 代码示例中, AWS Identity and Access Management 用户可以列出网关每个卷的快照。然后,该用户可以判断快照的起始时间是在指定日期 (保留期) 之前还是之后,并删除过了保留期的快照。该示例使用 fo AWS SDK r。 NETAPI适用于 Storage Gateway 和 Amazon EC2。Amazon EC2 API 包括处理快照的操作。

以下代码示例使用 fo AWS SDK r。 NET版本 2 和 3。您可以迁移旧版本的。 NET到较新的版本。有关更多信息,请参阅将您的代码迁移到最新版本 AWS SDK的。 NET

更新代码以提供服务终端节点、您的网关 Amazon 资源名称 (ARN) 以及您想要保存快照的天数。此截止日期之前拍摄的快照都将被删除。您还需要指定布尔值 viewOnly,该值表明是要查看要删除的快照还是实际执行快照删除。先只带 view 选项 (即将 viewOnly 设置为 true) 运行代码,看看代码会删除什么。有关可以与 Storage Gateway 配合使用的 AWS 服务终端节点列表,请参阅中的AWS Storage Gateway 终端节点和配额AWS 一般参考

首先,创建用户并将最低IAM策略附加到该用户。然后为您的网关制定自动快照计划。

以下代码创建允许用户删除快照的最小权限策略。在本示例中,策略的名称为 sgw-delete-snapshot

{ "Version": "2012-10-17", "Statement": [ { "Sid": "StmtEC2Snapshots", "Effect": "Allow", "Action": [ "ec2:DeleteSnapshot", "ec2:DescribeSnapshots" ], "Resource": [ "*" ] }, { "Sid": "StmtSgwListVolumes", "Effect": "Allow", "Action": [ "storagegateway:ListVolumes" ], "Resource": [ "*" ] } ] }

以下 C# 代码在指定网关中查找与卷和指定截止期匹配的所有快照并将其删除。

using System; using System.Collections.Generic; using System.Text; using Amazon.EC2; using Amazon.EC2.Model; using Amazon.StorageGateway.Model; using Amazon.StorageGateway; namespace DeleteStorageGatewaySnapshotNS { class Program { /* * Replace the variables below to match your environment. */ /* IAM AccessKey */ static String AwsAccessKey = "AKIA................"; /* IAM SecretKey */ static String AwsSecretKey = "*******************************"; /* Account number, 12 digits, no hyphen */ static String OwnerID = "123456789012"; /* Your Gateway ARN. Use a Storage Gateway ID, sgw-XXXXXXXX* */ static String GatewayARN = "arn:aws:storagegateway:ap-southeast-2:123456789012:gateway/sgw-XXXXXXXX"; /* Snapshot status: "completed", "pending", "error" */ static String SnapshotStatus = "completed"; /* Region where your gateway is activated */ static String AwsRegion = "ap-southeast-2"; /* Minimum age of snapshots before they are deleted (retention policy) */ static int daysBack = 30; /* * Do not modify the four lines below. */ static AmazonEC2Config ec2Config; static AmazonEC2Client ec2Client; static AmazonStorageGatewayClient sgClient; static AmazonStorageGatewayConfig sgConfig; static void Main(string[] args) { // Create an EC2 client. ec2Config = new AmazonEC2Config(); ec2Config.ServiceURL = "https://ec2." + AwsRegion + ".amazonaws.com"; ec2Client = new AmazonEC2Client(AwsAccessKey, AwsSecretKey, ec2Config); // Create a Storage Gateway client. sgConfig = new AmazonStorageGatewayConfig(); sgConfig.ServiceURL = "https://storagegateway." + AwsRegion + ".amazonaws.com"; sgClient = new AmazonStorageGatewayClient(AwsAccessKey, AwsSecretKey, sgConfig); List<VolumeInfo> StorageGatewayVolumes = ListVolumesForGateway(); List<Snapshot> StorageGatewaySnapshots = ListSnapshotsForVolumes(StorageGatewayVolumes, daysBack); DeleteSnapshots(StorageGatewaySnapshots); } /* * List all volumes for your gateway * returns: A list of VolumeInfos, or null. */ private static List<VolumeInfo> ListVolumesForGateway() { ListVolumesResponse response = new ListVolumesResponse(); try { ListVolumesRequest request = new ListVolumesRequest(); request.GatewayARN = GatewayARN; response = sgClient.ListVolumes(request); foreach (VolumeInfo vi in response.VolumeInfos) { Console.WriteLine(OutputVolumeInfo(vi)); } } catch (AmazonStorageGatewayException ex) { Console.WriteLine(ex.Message); } return response.VolumeInfos; } /* * Gets the list of snapshots that match the requested volumes * and cutoff period. */ private static List<Snapshot> ListSnapshotsForVolumes(List<VolumeInfo> volumes, int snapshotAge) { List<Snapshot> SelectedSnapshots = new List<Snapshot>(); try { foreach (VolumeInfo vi in volumes) { String volumeARN = vi.VolumeARN; String volumeID = volumeARN.Substring(volumeARN.LastIndexOf("/") + 1).ToLower(); DescribeSnapshotsRequest describeSnapshotsRequest = new DescribeSnapshotsRequest(); Filter ownerFilter = new Filter(); List<String> ownerValues = new List<String>(); ownerValues.Add(OwnerID); ownerFilter.Name = "owner-id"; ownerFilter.Values = ownerValues; describeSnapshotsRequest.Filters.Add(ownerFilter); Filter statusFilter = new Filter(); List<String> statusValues = new List<String>(); statusValues.Add(SnapshotStatus); statusFilter.Name = "status"; statusFilter.Values = statusValues; describeSnapshotsRequest.Filters.Add(statusFilter); Filter volumeFilter = new Filter(); List<String> volumeValues = new List<String>(); volumeValues.Add(volumeID); volumeFilter.Name = "volume-id"; volumeFilter.Values = volumeValues; describeSnapshotsRequest.Filters.Add(volumeFilter); DescribeSnapshotsResponse describeSnapshotsResponse = ec2Client.DescribeSnapshots(describeSnapshotsRequest); List<Snapshot> snapshots = describeSnapshotsResponse.Snapshots; Console.WriteLine("volume-id = " + volumeID); foreach (Snapshot s in snapshots) { if (IsSnapshotPastRetentionPeriod(snapshotAge, s.StartTime)) { Console.WriteLine(s.SnapshotId + ", " + s.VolumeId + ", " + s.StartTime + ", " + s.Description); SelectedSnapshots.Add(s); } } } } catch (AmazonEC2Exception ex) { Console.WriteLine(ex.Message); } return SelectedSnapshots; } /* * Deletes a list of snapshots. */ private static void DeleteSnapshots(List<Snapshot> snapshots) { try { foreach (Snapshot s in snapshots) { DeleteSnapshotRequest deleteSnapshotRequest = new DeleteSnapshotRequest(s.SnapshotId); DeleteSnapshotResponse response = ec2Client.DeleteSnapshot(deleteSnapshotRequest); Console.WriteLine("Volume: " + s.VolumeId + " => Snapshot: " + s.SnapshotId + " Response: " + response.HttpStatusCode.ToString()); } } catch (AmazonEC2Exception ex) { Console.WriteLine(ex.Message); } } /* * Checks if the snapshot creation date is past the retention period. */ private static Boolean IsSnapshotPastRetentionPeriod(int daysBack, DateTime snapshotDate) { DateTime cutoffDate = DateTime.Now.Add(new TimeSpan(-daysBack, 0, 0, 0)); return (DateTime.Compare(snapshotDate, cutoffDate) < 0) ? true : false; } /* * Displays information related to a volume. */ private static String OutputVolumeInfo(VolumeInfo vi) { String volumeInfo = String.Format( "Volume Info:\n" + " ARN: {0}\n" + " Type: {1}\n", vi.VolumeARN, vi.VolumeType); return volumeInfo; } } }

使用 AWS Tools for Windows PowerShell删除快照

如需删除与卷关联的多个快照,您可以使用编程方法。以下示例演示如何使用 AWS Tools for Windows PowerShell删除快照。要使用示例脚本,您应该熟悉如何运行 PowerShell 脚本。有关更多信息,请参阅 https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-started.html 中的AWS Tools for Windows PowerShell入门。如果您只需要删除少量快照,请按 删除存储卷的快照 中所述使用控制台。

例 : 使用删除快照 AWS Tools for Windows PowerShell

以下 PowerShell 脚本示例列出了网关每个卷的快照以及快照开始时间是在指定日期之前还是之后。它使用 Storage Gateway 和 Amazon 的 AWS Tools for Windows PowerShell cmdlet。EC2Amazon EC2 API 包括处理快照的操作。

您需要更新脚本并提供网关 Amazon 资源名称 (ARN) 以及您想要保存快照的天数。此截止日期之前拍摄的快照都将被删除。您还需要指定布尔值 viewOnly,该值表明是要查看要删除的快照还是实际执行快照删除。先只带 view 选项 (即将 viewOnly 设置为 true) 运行代码,看看代码会删除什么。

<# .DESCRIPTION Delete snapshots of a specified volume that match given criteria. .NOTES PREREQUISITES: 1) AWS Tools for Windows PowerShell from https://aws.amazon.com/powershell/ 2) Credentials and AWS Region stored in session using Initialize-AWSDefault. For more info see, https://docs.aws.amazon.com/powershell/latest/userguide/specifying-your-aws-credentials.html .EXAMPLE powershell.exe .\SG_DeleteSnapshots.ps1 #> # Criteria to use to filter the results returned. $daysBack = 18 $gatewayARN = "*** provide gateway ARN ***" $viewOnly = $true; #ListVolumes $volumesResult = Get-SGVolume -GatewayARN $gatewayARN $volumes = $volumesResult.VolumeInfos Write-Output("`nVolume List") foreach ($volumes in $volumesResult) { Write-Output("`nVolume Info:") Write-Output("ARN: " + $volumes.VolumeARN) write-Output("Type: " + $volumes.VolumeType) } Write-Output("`nWhich snapshots meet the criteria?") foreach ($volume in $volumesResult) { $volumeARN = $volume.VolumeARN $volumeId = ($volumeARN-split"/")[3].ToLower() $filter = New-Object Amazon.EC2.Model.Filter $filter.Name = "volume-id" $filter.Value.Add($volumeId) $snapshots = get-EC2Snapshot -Filter $filter Write-Output("`nFor volume-id = " + $volumeId) foreach ($s in $snapshots) { $d = ([DateTime]::Now).AddDays(-$daysBack) $meetsCriteria = $false if ([DateTime]::Compare($d, $s.StartTime) -gt 0) { $meetsCriteria = $true } $sb = $s.SnapshotId + ", " + $s.StartTime + ", meets criteria for delete? " + $meetsCriteria if (!$viewOnly -AND $meetsCriteria) { $resp = Remove-EC2Snapshot -SnapshotId $s.SnapshotId #Can get RequestId from response for troubleshooting. $sb = $sb + ", deleted? yes" } else { $sb = $sb + ", deleted? no" } Write-Output($sb) } }