全部产品
Search
文档中心

云服务器 ECS:通过Go SDK创建应用一致性快照

更新时间:Nov 01, 2023

阿里云支持通过API或SDK等方式创建应用一致性快照进行整机保护,适用于批量运维或者二次开发等场景。本文通过Go SDK示例介绍如何创建Linux和Windows的应用一致性快照。

前提条件

  • ECS实例的操作系统在以下范围中:

    • Windows:Windows Server 2022/2019/2016/2012 R2。

    • Linux:CentOS 7.6及以上版本、Ubuntu 18.04及以上版本和Alibaba Cloud Linux 2/3。

  • ECS实例中云盘必须是ESSD类型云盘,且文件系统为EXT3、EXT4、XFS或NTFS。同时,不支持网络文件系统和共享文件系统。

  • ECS实例已安装云助手Agent。具体操作,请参见安装云助手Agent

    说明

    2017年12月01日之后使用公共镜像创建的ECS实例,已默认预装云助手Agent

  • 已经创建应用一致性相关的RAM角色。

    具体操作,请参见操作步骤中的步骤1~步骤4。

  • 已经安装Go运行环境。

    具体操作,请参见下载和安装Golang

  • 已经下载和安装阿里云Go SDK。

    具体操作,请参见开始使用

背景信息

文件系统一致性快照和应用一致性快照的区别,如下表所示。

类型

说明

实现方式

应用一致性快照

应用一致性快照在快照创建时刻备份内存数据及正在进行中的数据库事务,保证应用系统数据和数据库事务的一致性。通过应用一致性快照,没有数据的损坏及丢失,避免数据库启动时日志回滚,确保应用处于一致性的启动状态。

应用一致性快照以标签APPConsistent:True标识。

根据操作系统类型,实现方式如下:

  • Windows:通过卷影复制服务VSS(Volume Shadow Copy Service)实现。

  • Linux:通过执行自定义Shell脚本(需要您根据应用自行编写脚本)实现。应用一致性的效果,由您自己编写的脚本负责保证。

文件系统一致性快照

如果开启应用一致性功能,但不满足相关条件,系统将会为您创建文件系统一致性快照。

文件系统一致性确保在快照创建时刻同步文件系统内存和磁盘信息,冻结文件系统写操作,使得文件系统处于一致性的状态。通过文件系统一致性快照,可以避免操作系统在重启后进行chkdsk或fsck等磁盘检查修复操作。

文件系统一致性快照以标签FsConsistent:True标识。

根据操作系统类型,实现方式如下:

  • Windows:如果无Windows操作系统上特定应用的VSS Writer参与时,默认创建的为文件系统一致性。

  • Linux:如果无对应的应用脚本,默认创建的为文件系统一致性。

步骤一:为ECS实例配置RAM角色

通过调用接口AttachInstanceRamRole为目标ECS实例设置RAM角色(AppSnapshotRoleName)。

以下为Go SDK代码示例:

package main
import (
    "fmt"
    "os"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
)

func main() {
		// 请确保代码运行环境设置了环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
    // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取AccessKey的方式进行调用,建议使用更安全的STS方式。
    client, err := ecs.NewClientWithAccessKey(
        "cn-hangzhou",       
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),     
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")) 

    //调用AttachInstanceRamRole为实例绑定RAM角色
    request := ecs.CreateAttachInstanceRamRoleRequest()
    request.Scheme = "https"

    request.RamRoleName = "AppSnapshotRoleName"          //设置RAM角色名称
    request.InstanceIds = "[\"i-bp17r83nppqf141v****\"]" //设置实例ID

    response, err := client.AttachInstanceRamRole(request)
    if err != nil {
        fmt.Print(err.Error())
    }

    fmt.Println(response.String())
}

调用结果示例如下所示,返回参数说明,请参见AttachInstanceRamRole调用结果

步骤二:调用RunCommand为实例创建文件系统一致性保护

Linux实例

通过调用云助手接口RunCommand为一台或多台Linux实例创建文件系统一致性快照。

以下为Go SDK代码示例:

package main

import (
    "fmt"
    "os"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
)

func main() {
		// 请确保代码运行环境设置了环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
    // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取AccessKey的方式进行调用,建议使用更安全的STS方式。
    client, err := ecs.NewClientWithAccessKey(
        "cn-hangzhou",    //设置实例所在地域
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),     
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))

    //调用RunCommand为实例创建文件系统一致性快照。
    request := ecs.CreateRunCommandRequest()
    request.Scheme = "https"

    request.Type = "RunShellScript"
    //创建文件系统一致性快照的命令,具体信息,请参见CommandContent内容说明。
    request.CommandContent = "acs-plugin-manager --exec --plugin app-snapshot-plugin --params=-RamRoleName=\"AppSnapshotRoleName\",-InstantAccess=true,-EnableFsFreeze=true,-TimeoutInSeconds=30,-PreScriptPath=\"/tmp/prescript.sh\",-PostScriptPath=\"/tmp/postscript.sh\",-InstantAccessRentationDays=1,-ExcludeDiskId=\"\",-Name=\"LinuxApp1\""
    request.InstanceId = &[]string{"i-bp17r83nppqf141v****"} //设置实例ID

    response, err := client.RunCommand(request)
    if err != nil {
        fmt.Print(err.Error())
    }
    fmt.Printf("response is %#v\n", response)
}

CommandContent参数中内容说明:

  • acs-plugin-manager --exec --plugin app-snapshot-plugin:表示执行云助手插件app-snapshot-plugin

  • --params=表示插件的配置参数,具体参数说明,如下表所示。

    参数

    类型

    是否必传

    描述

    ExcludeDiskId

    String

    ECS实例中不需要创建快照的云盘。

    InstantAccess

    Boolean

    是否开启快照极速可用功能。取值如下:

    • true:开启

    • false:关闭

    说明

    2023年10月12日11:00起,快照极速可用能力升级(按地域逐步灰度中),ESSD PL0/1/2/3及ESSD AutoPL云盘新建的快照将默认为创建后极速可用,无需额外配置该参数。更多信息,请参见快照极速可用能力

    InstantAccessRentationDays

    Integer

    快照极速可用功能保留天数,到期后自动关闭。

    取值范围:1~65536。默认值:1

    Name

    String

    快照一致性组名称。

    Description

    String

    快照一致性组描述信息。

    RamRoleName

    String

    ECS实例绑定的RAM角色,取值请参见步骤一:为ECS实例配置RAM角色

    PreScriptPath

    String

    应用冻结脚本路径(/tmp/prescript.sh)。prescript.sh脚本需要符合以下条件:

    • 在权限上,仅root作为owner用户具有读、写、执行权限,即700权限。

    • 在内容上,脚本内容需要根据应用自己定制。

    说明

    Linux实例创建应用一致性快照时必须设置此参数。如果脚本设置错误(例如权限、保存路径或文件名设置错误等),最终创建的快照为文件系统一致性快照。

    PostScriptPath

    String

    应用解冻脚本路径(/tmp/postscript.sh)。postscript.sh脚本需要符合以下条件:

    • 在权限上,仅root作为owner用户具有读、写、执行权限,即700权限。

    • 在内容上,脚本内容需要根据应用自己定制。

    说明

    Linux实例创建应用一致性快照时必须设置此参数。如果脚本设置错误(例如权限、保存路径或文件名设置错误等),最终创建的快照为文件系统一致性快照。

    EnableFsFreeze

    Boolean

    是否在创建存储快照前使用Linux的FsFreeze机制确保文件系统处于只读一致性。

    默认为True。

    TimeoutInSeconds

    Integer

    IO冻结超时时间。

    默认为30秒。

    ScriptTimeoutInSeconds

    Integer

    脚本执行超时时间。

    默认值为1800秒。

调用结果示例如下所示,返回参数说明,请参见RunCommandlinux

Windows实例

通过调用云助手API接口RunCommand为一台或多台Windows实例创建应用一致性快照。

以下为Go SDK示例:

package main

import (
    "fmt"
  	"os"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
)

func main() {
    // 请确保代码运行环境设置了环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
    // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取AccessKey的方式进行调用,建议使用更安全的STS方式。
    client, err := ecs.NewClientWithAccessKey(
        "cn-hangzhou",       //设置实例所在地域
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),     
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))

    request := ecs.CreateRunCommandRequest()
    request.Scheme = "https"

    request.Type = "RunBatScript"
    //创建应用一致性快照的命令,具体信息,请参见CommandContent内容说明。
    request.CommandContent = "acs-plugin-manager --exec --plugin app-snapshot-plugin-win --params=-RamRoleName=\"AppSnapshotRoleName\",-InstantAccess=true,-EnableWriters=true,-Description=\"AppSnapshot\",-InstantAccessRentationDays=1,-ExcludeDiskId=\"\",-Name=\"APPSnapshot-1\""
    request.InstanceId = &[]string{"i-bp11vqwgh574****"} //设置实例ID
    request.Timeout = "1800"

    response, err := client.RunCommand(request)
    if err != nil {
        fmt.Print(err.Error())
    }
    fmt.Printf("response is %#v\n", response)
}

CommandContent参数中内容说明:

  • acs-plugin-manager --exec --plugin app-snapshot-plugin-win:表示执行云助手插件app-snapshot-plugin-win

  • --params=表示插件的配置参数,具体参数说明,如下表所示。

    参数

    类型

    是否必传

    描述

    ExcludeDiskId

    String

    ECS实例中不需要创建快照的云盘。

    InstantAccess

    Boolean

    是否开启快照极速可用功能。取值如下:

    • true:开启

    • false:关闭

    说明

    2023年10月12日11:00起,快照极速可用能力升级(按地域逐步灰度中),ESSD PL0/1/2/3及ESSD AutoPL云盘新建的快照将默认为创建后极速可用,无需额外配置该参数。更多信息,请参见快照极速可用能力

    InstantAccessRentationDays

    Integer

    快照极速可用功能保留天数,到期后自动关闭。

    取值范围:1~65536。默认值:1

    Name

    String

    快照一致性组名称。

    Description

    String

    快照一致性组描述信息。

    RamRoleName

    String

    ECS实例绑定的RAM角色,取值请参见步骤一:为ECS实例配置RAM角色

    EnableWriters

    Boolen

    是否设置应用一致性快照。取值如下:

    • true:创建应用一致性快照

    • false:创建文件系统一致性快照

    默认值为true。

调用结果示例如下所示,返回参数说明,请参见RunCommandwin查询结果

步骤三:调用DescribeInvocationResults查看快照创建结果

通过调用接口DescribeInvocationResults查看是否执行成功。

以下为Go SDK示例:

package main

import (
    "fmt"
    "os"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
)

func main() {
    // 请确保代码运行环境设置了环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
    // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取AccessKey的方式进行调用,建议使用更安全的STS方式。
    client, err := ecs.NewClientWithAccessKey(
        "cn-hangzhou",    //设置实例所在地域
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),     
        os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")) 

    //通过DescribeInvocationResults查询结果
    request := ecs.CreateDescribeInvocationResultsRequest()
    request.Scheme = "https"

    request.InvokeId = "t-hz01qsegaxi****"        //命令执行ID,可在上一步骤的执行结果中查看。
    request.InstanceId = "i-bp17r83nppqf141v****" //实例ID
    request.CommandId = "c-hz01qsegaxd****"       //命令ID,可在上一步骤的执行结果中查看。

    response, err := client.DescribeInvocationResults(request)
    if err != nil {
        fmt.Print(err.Error())
    }
    fmt.Printf("response is %#v\n", response)
}

调用结果示例如下所示,返回参数说明,请参见DescribeInvocationResults查看结果

  • ExitCode返回错误码信息,取值为0表示执行成功;如果取值不为0,请根据错误码信息排查问题。更多信息,请参见错误码信息

  • Output为命令执行后的输出信息,内容通过Base64编码。

    如果执行成功,Output内容经过Base64解码后会包含创建的快照一致性组ID,如下所示。

    [snapshotgroup="ssg-bp170v57ca9j01jb****"][message="Finish whole Processes of Snapshot successfully"]

错误码信息

应用一致性快照创建后,会返回错误码(ExitCode)。如果创建失败,您可以根据错误码信息排查问题。

错误码(ExitCode)

说明

0

表示创建成功。

1

条件检查错误。可能错误如下:

  • 云盘类型不支持。

  • 快照名称不符合要求。

  • 网络不通。

  • ECS实例没有RAM角色授权。

  • 操作系统版本不支持。

2

--params后设置的参数类型或个数错误。

3

可能错误如下:

  • ECS实例没有挂载ESSD云盘。

  • ECS实例的RAM角色未设置快照接口的访问权限。

4

创建快照一致性组失败。

5

快照一致性组状态错误。

6

创建快照一致性组超时。

7

快照一致性组内单个云盘快照的状态不符合预期。

8

为快照设置标签失败。

9

执行应用冻结脚本失败。

10

执行应用解冻脚本失败。

11

冻结IO失败。

12

解冻IO失败。

13

ECS实例没有RAM角色授权。

14

快照个数超过限制。

15

快照状态错误。

16

在没有启动快照及时可用功能的情况下,前一个快照正在创建中。

255

未知失败。