如何备份 Azure DevOps Git 储存库

Azure DevOps 提供 99.9% 的 SLA 服务等级保证,表示一年之中必须要有 99.9% 的时间正常营运,如果 Azure DevOps 在特定月份遗漏 SLA,则会将每月费用的一部分退款。

换言之,无法提供服务的时间为 8 小时 45 分 36 秒。

(60秒 * 60分 * 24小时 * 365天 ) * 0.1% = 31536秒 = 8 小时 45 分 36 秒

为了防止意外删除资料,Microsoft 也会针对 Azure Blob 和 Azure SQL 资料库进行时间点备份。Azure DevOps 会利用这项功能维护您的资料 28 天,这些备份也会在配对区域中複写,以协助从区域中断复原。

Azure DevOps 可以在删除后最多 28 天复原已删除的组织或专案。

这些备份仅适用于商务持续性,并协助从中断或灾害案例中复原。不包括客户意外删除资产(例如储存库、工作专案、附件或成品)不支援还原客户意外删除的资产

虽然 Azure DevOps 有 99.9 的 SLA,但它仍然有趴下的可能性。

又或是哪天某位同事突然中邪把 Repository 给删了

在组织评估其资讯系统与资产所面临的潜在风险时,就必须将这一点纳入考量,尤其是资讯单位同时又担任 RD 的角色时,程式码版本管控伺服器的备援就相当重要。

在资讯安全风险评鉴的过程,我们就会列举资讯系统可能遇到的风险情境与影响範围,根据损害的等级与发生的可能性来估算风险值。

若超出可承受之风险值,组织就必须有所作为。
例如新增风险处理措施来备份 Azure DevOps Git 储存库,并评估残余风险值是否在可接受之範围。

如何备份 Azure DevOps Git 储存库
以下我们将了解如何使用 YAML 档案备份储存库。

包括以下步骤:

建立 Azure DevOps 个人存取权杖 (PAT)建立 YAML 文件建立订阅连接

建立 Azure DevOps 个人存取权杖 (PAT)
登入您的 Azure DevOps 门户,前往个人存取权杖。

点选 New Token 建立令牌

输入 Token 的名字,例如 Repo Backup Token。

选择您的 Organization

範围选择 Custom defined,只给予该 Token 对 Code 有读取权限

到期日可以选择 Custom defined,最久可以设定一年。

注意:複製并保存 Token,因为您将无法再次看到它。

建立 YAML 文件
前往 Pipelines,建立 Pipeline。

选择 Azure Repos Git

选择您要备份的 Repository。

选择 Starter pipeline

以下是您将看到的预设代码

将 yaml 更新为以下程式码

trigger:  branches:    include:      - '*'stages:  - stage: _default    jobs:      - job: Job        pool:           vmImage: windows-latest        steps:          - task: CmdLine@2            inputs:              script: git clone --mirror https://{pat-token}@dev.azure.com/{organization}/{project}/_git/{repo}          - task: ArchiveFiles@2            inputs:              rootFolderOrFile: $(System.DefaultWorkingDirectory)              includeRootFolder: true              archiveType: zip              archiveFile : $(Build.ArtifactStagingDirectory)/Backup.zip              replaceExistingArchive: true          - task: AzureFileCopy@3            displayName: AzureBlob File Copy            inputs:              SourcePath: $(Build.ArtifactStagingDirectory)/Backup.zip              azureSubscription: '{subscription-connection}'              Destination: 'AzureBlob'              storage: '{storage-name}'              ContainerName : '{container-name}'              BlobPrefix : '{blob-name}'

Trigger:通配符 * 将监视所有分支,储存库中有任何变更时都会触发管道。

CmdLine:呼叫 git clone –mirror 来建立储存库的副本,取得储存库时需要使用个人存取权杖 (PAT)。

存档档案:将取得上一个步骤中複製的 git 储存库,压缩为 Backup.zip。

档案複製:它将取得存档副本并将其传送至 Azure Blob 存储

建立订阅连接
前往专案设定

前往 Service Connections

建立 Service Connection

选择 Azure Resource Manager

认证方式选择 Service Principal (automatic)

选择您拥有储存帐户的资源群组

输入订阅连接的名字,例如 repobackup。

储存后完成

回到 YAML 文件

我们需要填写以下参数

{pat-token}:使用上面取得的 PAT 个人存取权杖{organization}:您的组织名称{project}:储存库所在的专案名称,例如 UPInstrument。{repo}:要备份的储存库,例如 Wpf_ASTM。{subscription-connection}:替换为 Azure Service Connection Name,例如 repobackup。{storage-name}:存放备份的储存体帐号名称{container-name}:存放备份的容器名称{blob-name}:设定 BlobPrefix,选用的。

确认完成后,点选 Save and Run。

第一次执行会遇到权限请求,点选 View。

允许存取

没有意外的话,通常会执行成功。

Pipeline 也会发信通知您

前往储存体帐号进行验证,资料果然产生了。

建议设定 BlobPrefix,会多一层资料夹方便我们区分备份档案。

点进去就可以看到储存库的备份了

我们也可以使用变数把日期加入档名

trigger:  branches:    include:      - '*'variables:   backup_date: $[format('{0:yyyy}-{0:MM}-{0:dd}T{0:HH}-{0:mm}-{0:ss}', pipeline.startTime)]stages:  - stage: _default    jobs:      - job: Job        pool:           vmImage: windows-latest        steps:          - task: CmdLine@2            inputs:              script: git clone --mirror https://{pat-token}@dev.azure.com/{organization}/{project}/_git/{repo}          - task: ArchiveFiles@2            inputs:              rootFolderOrFile: $(System.DefaultWorkingDirectory)              includeRootFolder: true              archiveType: zip              archiveFile : $(Build.ArtifactStagingDirectory)/$(backup_date)_Backup.zip              replaceExistingArchive: true          - task: AzureFileCopy@3            displayName: AzureBlob File Copy            inputs:              SourcePath: $(Build.ArtifactStagingDirectory)/$(backup_date)_Backup.zip              azureSubscription: '{subscription-connection}'              Destination: 'AzureBlob'              storage: '{storage-name}'              ContainerName : '{container-name}'              BlobPrefix : '{blob-name}'

每次产出的备份档案就不会被覆写了

定期删除备份
我们可以到 Stroage Account 的 Lifecycle Management,新增规则。

输入规则名称

若 Blob 超过 30 天没有修改,则进行删除。
当然您也可以设定先搬至冷储存在进行删除,来节省储存体的费用。

还原备份档案
接下来我们要透过 Backup.zip 去还原 Azure DevOps 的 Repository,很多人备份都不做还原测试,等出事之后才发现备份档根本无效,我们事情不要做半套阿。

If you don’t like your job, you don’t strike! You just go in every day and do it really half-assed. That’s the American way.

如果你不喜欢你的工作,你不主动出击,你就每天一样去上班,然后把事情乱做或做一半,这就是美国人的做法。

下载备份档案

接其解压缩

使用命令提示字元切换到该路径底下

就可以透过下列指令进行还原到原本的 Repository

git push --force --mirror https://dev.azure.com/{your_organization}/{your_project}/_git/{your_repo}

发生错误,缺少 ForcePush 权限。

Total 0 (delta 0), reused 0 (delta 0), pack-reused 0To https://dev.azure.com/{your_organization}/UPInstrument/_git/Wpf_ASTM * [new reference]   origin/main -> origin/main ! [remote rejected] main (TF401027: You need the Git 'ForcePush' permission to perform this action. Details: identity '61d9f138-8c41-45f6-8c24-e69e4dc9b580\ivan_cheng@domain', scope 'branch'.)error: failed to push some refs to 'https://dev.azure.com/{your_organization}/UPInstrument/_git/Wpf_ASTM'

前往专案设定,调整自己所属角色的权限允许 ForcePush。

再试一次就成功了

Enumerating objects: 12, done.Counting objects: 100% (12/12), done.Delta compression using up to 8 threadsCompressing objects: 100% (12/12), done.Writing objects: 100% (12/12), 9.00 KiB | 4.50 MiB/s, done.Total 12 (delta 1), reused 0 (delta 0), pack-reused 0remote: Analyzing objects... (12/12) (7 ms)remote: Validating commits... (2/2) done (0 ms)remote: Storing packfile... done (50 ms)remote: Storing index... done (66 ms)To https://dev.azure.com/{your_organization}/UPInstrument/_git/Wpf_ASTM - [deleted]         origin/dd11a2ae47a38e348d72515e83759e37436c97a1 - [deleted]         origin/main * [new branch]      ivan -> ivan * [new branch]      main -> main * [new branch]      master -> master

也可以还原到新的 Repository,建立一个新的叫 Wpf_ASTM_Restore

Enumerating objects: 38, done.Counting objects: 100% (38/38), done.Delta compression using up to 8 threadsCompressing objects: 100% (37/37), done.Writing objects: 100% (38/38), 12.73 KiB | 2.54 MiB/s, done.Total 38 (delta 9), reused 0 (delta 0), pack-reused 0remote: Analyzing objects... (38/38) (7 ms)remote: Validating commits... (12/12) done (0 ms)remote: Storing packfile... done (49 ms)remote: Storing index... done (50 ms)To https://dev.azure.com/{your_organization}/UPInstrument/_git/Wpf_ASTM_Restore + 80e8be0...dd11a2a main -> main (forced update) * [new branch]      ivan -> ivan * [new branch]      master -> master

回到 Repository 检查,程式码都顺利回来啰。

还原到 GitHub 也是没问题

git push --force --mirror https://github.com/jieshiun/Wpf_ASTM.git
Enumerating objects: 38, done.Counting objects: 100% (38/38), done.Delta compression using up to 8 threadsCompressing objects: 100% (37/37), done.Writing objects: 100% (38/38), 12.57 KiB | 559.00 KiB/s, done.Total 38 (delta 9), reused 0 (delta 0), pack-reused 0remote: Resolving deltas: 100% (9/9), done.To https://github.com/jieshiun/Wpf_ASTM.git * [new branch]      ivan -> ivan * [new branch]      main -> main * [new branch]      master -> master

今天的分享就到这边,谢谢大家。

后续更新
如何在 Azure DevOps 备份多个储存库

参考文件

https://learn.microsoft.com/zh-tw/azure/devops/organizations/security/data-protection?view=azure-devopshttps://www.cloudfronts.com/azure/azure-devops-services/backup-azure-devops-git-repositoriehttps://learn.microsoft.com/zh-tw/azure/devops/pipelines/tasks/reference/azure-file-copy-v3?view=azure-pipelineshttps://charbelnemnom.com/how-to-backup-azure-devops-git-repositories

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章