A Mobility szolgáltatás automatikus frissítése az Azure-ból Azure-ba replikációban
Az Azure Site Recovery havi kiadási ütemezéssel oldja meg a problémákat, fejleszti a meglévő funkciókat, vagy újakat ad hozzá. Ahhoz, hogy naprakész maradjon a szolgáltatással, minden hónapban meg kell terveznie a javítás üzembe helyezését. Az egyes frissítésekhez kapcsolódó többletterhelés elkerülése érdekében engedélyezheti a Site Recovery számára az összetevők frissítéseinek kezelését.
Ahogy az Azure-ról Az Azure-ba irányuló vészhelyreállítási architektúra is említi, a Mobility szolgáltatás minden olyan Azure-beli virtuális gépen (virtuális gépen) telepítve van, amelyek replikációja engedélyezve van az Egyik Azure-régióból a másikba. Automatikus frissítések használatakor minden új kiadás frissíti a Mobility szolgáltatás bővítményt.
Megjegyzés:
We recommend that you use the Azure Az PowerShell module to interact with Azure. See Install Azure PowerShell to get started. To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
Az automatikus frissítések működése
Amikor a Site Recoveryt használja a frissítések kezelésére, az üzembe helyez egy globális runbookot (amelyet az Azure-szolgáltatások használnak) egy automation-fiókon keresztül, amely a tárolóval azonos előfizetésben jön létre. Minden tároló egy automation-fiókot használ. A tárolóban lévő összes virtuális gép esetében a runbook ellenőrzi az aktív automatikus frissítéseket. Ha elérhető a Mobility szolgáltatás bővítmény újabb verziója, a frissítés telepítve lesz.
Az alapértelmezett runbook-ütemezés naponta 12:00-kor történik a replikált virtuális gép földrajzi helyének időzónájában. A runbook ütemezését az automation-fiókon keresztül is módosíthatja.
Megjegyzés:
A 35. kumulatív frissítéstől kezdve választhat egy meglévő automation-fiókot a frissítésekhez. A 35. kumulatív frissítés előtt a Site Recovery alapértelmezés szerint létrehozta az automation-fiókot. Ezt a beállítást csak akkor választhatja ki, ha engedélyezi a virtuális gépek replikációjának engedélyezését. Nem érhető el olyan virtuális gépekhez, amelyeken már engedélyezve van a replikáció. A kiválasztott beállítás az ugyanabban a tárolóban védett összes Azure-beli virtuális gépre vonatkozik.
Az automatikus frissítések bekapcsolása nem igényli az Azure-beli virtuális gépek újraindítását, és nem befolyásolja a folyamatos replikációt.
A feladatok számlázása az automation-fiókban az egy hónapban használt feladat futásidejű perceinek számán alapul. A feladat végrehajtása naponta néhány másodpercig körülbelül egy percig tart, és ingyenes egységként van lefedve. Alapértelmezés szerint az 500 perc ingyenes egységként jelenik meg egy automation-fiókhoz, ahogyan az az alábbi táblázatban is látható:
Ingyenes egységek (havonta) | Ár |
---|---|
Feladat futásideje 500 perc | ₹0,14/perc |
Automatikus frissítések engedélyezése
A Site Recovery többféleképpen kezelheti a bővítményfrissítéseket:
- Kezelés az engedélyezési replikációs lépés részeként
- A bővítményfrissítési beállítások váltása a tárolón belül
- Frissítések manuális kezelése
Kezelés az engedélyezési replikációs lépés részeként
Ha engedélyezi a virtuális gépek replikációjának engedélyezését a virtuálisgép-nézetből vagy a helyreállítási tárból kiindulva, engedélyezheti a Site Recovery számára a Site Recovery bővítmény frissítéseinek kezelését vagy manuálisan történő kezelését.
A bővítményfrissítési beállítások váltása a tárolón belül
A Recovery Services-tárolóból lépjen a Site Recovery-infrastruktúra kezelése>elemre.
Az Azure-beli virtuális gépek>bővítményfrissítése Gépház> Allow Site Recovery kezeléséhez válassza a Be lehetőséget.
A bővítmény manuális kezeléséhez válassza a Ki elemet.
Fontos
Amikor a Site Recovery kezelésének engedélyezése lehetőséget választja, a beállítás a tárolóban lévő összes virtuális gépre lesz alkalmazva.
Válassza a Mentés parancsot.
Megjegyzés:
Bármelyik lehetőség értesíti a frissítések kezeléséhez használt automation-fiókról. Ha először használja ezt a funkciót egy tárolóban, alapértelmezés szerint létrejön egy új automation-fiók. Másik lehetőségként testre szabhatja a beállítást, és kiválaszthat egy meglévő automatizálási fiókot. A definiálást követően az ugyanabban a tárolóban történő replikáció engedélyezéséhez szükséges összes további művelet ezt a kiválasztott automation-fiókot fogja használni. A legördülő menü jelenleg csak azokat az automatizálási fiókokat listázja, amelyek ugyanabban az erőforráscsoportban találhatók, mint a tároló.
Egyéni automation-fiók esetén használja a következő szkriptet:
Fontos
Futtassa a következő szkriptet egy automation-fiók kontextusában. Ez a szkript a rendszer által hozzárendelt felügyelt identitásokat használja hitelesítési típusként.
param(
[Parameter(Mandatory=$true)]
[String] $VaultResourceId,
[Parameter(Mandatory=$true)]
[ValidateSet("Enabled",'Disabled')]
[Alias("Enabled or Disabled")]
[String] $AutoUpdateAction,
[Parameter(Mandatory=$false)]
[String] $AutomationAccountArmId
)
$SiteRecoveryRunbookName = "Modify-AutoUpdateForVaultForPatner"
$TaskId = [guid]::NewGuid().ToString()
$SubscriptionId = "00000000-0000-0000-0000-000000000000"
$AsrApiVersion = "2021-12-01"
$ArmEndPoint = "https://management.azure.com"
$AadAuthority = "https://login.windows.net/"
$AadAudience = "https://management.core.windows.net/"
$AzureEnvironment = "AzureCloud"
$Timeout = "160"
$AuthenticationType = "SystemAssignedIdentity"
function Throw-TerminatingErrorMessage
{
Param
(
[Parameter(Mandatory=$true)]
[String]
$Message
)
throw ("Message: {0}, TaskId: {1}.") -f $Message, $TaskId
}
function Write-Tracing
{
Param
(
[Parameter(Mandatory=$true)]
[ValidateSet("Informational", "Warning", "ErrorLevel", "Succeeded", IgnoreCase = $true)]
[String]
$Level,
[Parameter(Mandatory=$true)]
[String]
$Message,
[Switch]
$DisplayMessageToUser
)
Write-Output $Message
}
function Write-InformationTracing
{
Param
(
[Parameter(Mandatory=$true)]
[String]
$Message
)
Write-Tracing -Message $Message -Level Informational -DisplayMessageToUser
}
function ValidateInput()
{
try
{
if(!$VaultResourceId.StartsWith("/subscriptions", [System.StringComparison]::OrdinalIgnoreCase))
{
$ErrorMessage = "The vault resource id should start with /subscriptions."
throw $ErrorMessage
}
$Tokens = $VaultResourceId.SubString(1).Split("/")
if(!($Tokens.Count % 2 -eq 0))
{
$ErrorMessage = ("Odd Number of tokens: {0}." -f $Tokens.Count)
throw $ErrorMessage
}
if(!($Tokens.Count/2 -eq 4))
{
$ErrorMessage = ("Invalid number of resource in vault ARM id expected:4, actual:{0}." -f ($Tokens.Count/2))
throw $ErrorMessage
}
if($AutoUpdateAction -ieq "Enabled" -and [string]::IsNullOrEmpty($AutomationAccountArmId))
{
$ErrorMessage = ("The automation account ARM id should not be null or empty when AutoUpdateAction is enabled.")
throw $ErrorMessage
}
}
catch
{
$ErrorMessage = ("ValidateInput failed with [Exception: {0}]." -f $_.Exception)
Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
Throw-TerminatingErrorMessage -Message $ErrorMessage
}
}
function Initialize-SubscriptionId()
{
try
{
$Tokens = $VaultResourceId.SubString(1).Split("/")
$Count = 0
$ArmResources = @{}
while($Count -lt $Tokens.Count)
{
$ArmResources[$Tokens[$Count]] = $Tokens[$Count+1]
$Count = $Count + 2
}
return $ArmResources["subscriptions"]
}
catch
{
Write-Tracing -Level ErrorLevel -Message ("Initialize-SubscriptionId: failed with [Exception: {0}]." -f $_.Exception) -DisplayMessageToUser
throw
}
}
function Invoke-InternalRestMethod($Uri, $Headers, [ref]$Result)
{
$RetryCount = 0
$MaxRetry = 3
do
{
try
{
$ResultObject = Invoke-RestMethod -Uri $Uri -Headers $Headers
($Result.Value) += ($ResultObject)
break
}
catch
{
Write-InformationTracing ("Retry Count: {0}, Exception: {1}." -f $RetryCount, $_.Exception)
$RetryCount++
if(!($RetryCount -le $MaxRetry))
{
throw
}
Start-Sleep -Milliseconds 2000
}
}while($true)
}
function Invoke-InternalWebRequest($Uri, $Headers, $Method, $Body, $ContentType, [ref]$Result)
{
$RetryCount = 0
$MaxRetry = 3
do
{
try
{
$ResultObject = Invoke-WebRequest -Uri $UpdateUrl -Headers $Header -Method 'PATCH' `
-Body $InputJson -ContentType "application/json" -UseBasicParsing
($Result.Value) += ($ResultObject)
break
}
catch
{
Write-InformationTracing ("Retry Count: {0}, Exception: {1}." -f $RetryCount, $_.Exception)
$RetryCount++
if(!($RetryCount -le $MaxRetry))
{
throw
}
Start-Sleep -Milliseconds 2000
}
}while($true)
}
function Get-Header([ref]$Header, $AadAudience){
try
{
$Header.Value['Content-Type'] = 'application\json'
Write-InformationTracing ("The Authentication Type is system Assigned Identity based.")
$endpoint = $env:IDENTITY_ENDPOINT
$endpoint
$Headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$Headers.Add("X-IDENTITY-HEADER", $env:IDENTITY_HEADER)
$Headers.Add("Metadata", "True")
$authenticationResult = Invoke-RestMethod -Method Get -Headers $Headers -Uri ($endpoint +'?resource=' +$AadAudience)
$accessToken = $authenticationResult.access_token
$Header.Value['Authorization'] = "Bearer " + $accessToken
$Header.Value["x-ms-client-request-id"] = $TaskId + "/" + (New-Guid).ToString() + "-" + (Get-Date).ToString("u")
}
catch
{
$ErrorMessage = ("Get-BearerToken: failed with [Exception: {0}]." -f $_.Exception)
Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
Throw-TerminatingErrorMessage -Message $ErrorMessage
}
}
function Get-ProtectionContainerToBeModified([ref] $ContainerMappingList)
{
try
{
Write-InformationTracing ("Get protection container mappings : {0}." -f $VaultResourceId)
$ContainerMappingListUrl = $ArmEndPoint + $VaultResourceId + "/replicationProtectionContainerMappings" + "?api-version=" + $AsrApiVersion
Write-InformationTracing ("Getting the bearer token and the header.")
Get-Header ([ref]$Header) $AadAudience
$Result = @()
Invoke-InternalRestMethod -Uri $ContainerMappingListUrl -Headers $header -Result ([ref]$Result)
$ContainerMappings = $Result[0]
Write-InformationTracing ("Total retrieved container mappings: {0}." -f $ContainerMappings.Value.Count)
foreach($Mapping in $ContainerMappings.Value)
{
if(($Mapping.properties.providerSpecificDetails -eq $null) -or ($Mapping.properties.providerSpecificDetails.instanceType -ine "A2A"))
{
Write-InformationTracing ("Mapping properties: {0}." -f ($Mapping.properties))
Write-InformationTracing ("Ignoring container mapping: {0} as the provider does not match." -f ($Mapping.Id))
continue;
}
if($Mapping.Properties.State -ine "Paired")
{
Write-InformationTracing ("Ignoring container mapping: {0} as the state is not paired." -f ($Mapping.Id))
continue;
}
Write-InformationTracing ("Provider specific details {0}." -f ($Mapping.properties.providerSpecificDetails))
$MappingAutoUpdateStatus = $Mapping.properties.providerSpecificDetails.agentAutoUpdateStatus
$MappingAutomationAccountArmId = $Mapping.properties.providerSpecificDetails.automationAccountArmId
$MappingHealthErrorCount = $Mapping.properties.HealthErrorDetails.Count
if($AutoUpdateAction -ieq "Enabled" -and
($MappingAutoUpdateStatus -ieq "Enabled") -and
($MappingAutomationAccountArmId -ieq $AutomationAccountArmId) -and
($MappingHealthErrorCount -eq 0))
{
Write-InformationTracing ("Provider specific details {0}." -f ($Mapping.properties))
Write-InformationTracing ("Ignoring container mapping: {0} as the auto update is already enabled and is healthy." -f ($Mapping.Id))
continue;
}
($ContainerMappingList.Value).Add($Mapping.id)
}
}
catch
{
$ErrorMessage = ("Get-ProtectionContainerToBeModified: failed with [Exception: {0}]." -f $_.Exception)
Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
Throw-TerminatingErrorMessage -Message $ErrorMessage
}
}
$OperationStartTime = Get-Date
$ContainerMappingList = New-Object System.Collections.Generic.List[System.String]
$JobsInProgressList = @()
$JobsCompletedSuccessList = @()
$JobsCompletedFailedList = @()
$JobsFailedToStart = 0
$JobsTimedOut = 0
$Header = @{}
$AzureRMProfile = Get-Module -ListAvailable -Name AzureRM.Profile | Select Name, Version, Path
$AzureRmProfileModulePath = Split-Path -Parent $AzureRMProfile.Path
Add-Type -Path (Join-Path $AzureRmProfileModulePath "Microsoft.IdentityModel.Clients.ActiveDirectory.dll")
$Inputs = ("Tracing inputs VaultResourceId: {0}, Timeout: {1}, AutoUpdateAction: {2}, AutomationAccountArmId: {3}." -f $VaultResourceId, $Timeout, $AutoUpdateAction, $AutomationAccountArmId)
Write-Tracing -Message $Inputs -Level Informational -DisplayMessageToUser
$CloudConfig = ("Tracing cloud configuration ArmEndPoint: {0}, AadAuthority: {1}, AadAudience: {2}." -f $ArmEndPoint, $AadAuthority, $AadAudience)
Write-Tracing -Message $CloudConfig -Level Informational -DisplayMessageToUser
ValidateInput
$SubscriptionId = Initialize-SubscriptionId
Get-ProtectionContainerToBeModified ([ref]$ContainerMappingList)
$Input = @{
"properties"= @{
"providerSpecificInput"= @{
"instanceType" = "A2A"
"agentAutoUpdateStatus" = $AutoUpdateAction
"automationAccountArmId" = $AutomationAccountArmId
"automationAccountAuthenticationType" = $AuthenticationType
}
}
}
$InputJson = $Input | ConvertTo-Json
if ($ContainerMappingList.Count -eq 0)
{
Write-Tracing -Level Succeeded -Message ("Exiting as there are no container mappings to be modified.") -DisplayMessageToUser
exit
}
Write-InformationTracing ("Container mappings to be updated has been retrieved with count: {0}." -f $ContainerMappingList.Count)
try
{
Write-InformationTracing ("Start the modify container mapping jobs.")
ForEach($Mapping in $ContainerMappingList)
{
try {
$UpdateUrl = $ArmEndPoint + $Mapping + "?api-version=" + $AsrApiVersion
Get-Header ([ref]$Header) $AadAudience
$Result = @()
Invoke-InternalWebRequest -Uri $UpdateUrl -Headers $Header -Method 'PATCH' `
-Body $InputJson -ContentType "application/json" -Result ([ref]$Result)
$Result = $Result[0]
$JobAsyncUrl = $Result.Headers['Azure-AsyncOperation']
Write-InformationTracing ("The modify container mapping job invoked with async url: {0}." -f $JobAsyncUrl)
$JobsInProgressList += $JobAsyncUrl;
# Rate controlling the set calls to maximum 60 calls per minute.
# ASR throttling for set calls is 200 in 1 minute.
Start-Sleep -Milliseconds 1000
}
catch{
Write-InformationTracing ("The modify container mappings job creation failed for: {0}." -f $Ru)
Write-InformationTracing $_
$JobsFailedToStart++
}
}
Write-InformationTracing ("Total modify container mappings has been initiated: {0}." -f $JobsInProgressList.Count)
}
catch
{
$ErrorMessage = ("Modify container mapping jobs failed with [Exception: {0}]." -f $_.Exception)
Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
Throw-TerminatingErrorMessage -Message $ErrorMessage
}
try
{
while($JobsInProgressList.Count -ne 0)
{
Sleep -Seconds 30
$JobsInProgressListInternal = @()
ForEach($JobAsyncUrl in $JobsInProgressList)
{
try
{
Get-Header ([ref]$Header) $AadAudience
$Result = Invoke-RestMethod -Uri $JobAsyncUrl -Headers $header
$JobState = $Result.Status
if($JobState -ieq "InProgress")
{
$JobsInProgressListInternal += $JobAsyncUrl
}
elseif($JobState -ieq "Succeeded" -or `
$JobState -ieq "PartiallySucceeded" -or `
$JobState -ieq "CompletedWithInformation")
{
Write-InformationTracing ("Jobs succeeded with state: {0}." -f $JobState)
$JobsCompletedSuccessList += $JobAsyncUrl
}
else
{
Write-InformationTracing ("Jobs failed with state: {0}." -f $JobState)
$JobsCompletedFailedList += $JobAsyncUrl
}
}
catch
{
Write-InformationTracing ("The get job failed with: {0}. Ignoring the exception and retrying the next job." -f $_.Exception)
# The job on which the tracking failed, will be considered in progress and tried again later.
$JobsInProgressListInternal += $JobAsyncUrl
}
# Rate controlling the get calls to maximum 120 calls each minute.
# ASR throttling for get calls is 10000 in 60 minutes.
Start-Sleep -Milliseconds 500
}
Write-InformationTracing ("Jobs remaining {0}." -f $JobsInProgressListInternal.Count)
$CurrentTime = Get-Date
if($CurrentTime -gt $OperationStartTime.AddMinutes($Timeout))
{
Write-InformationTracing ("Tracing modify cloud pairing jobs has timed out.")
$JobsTimedOut = $JobsInProgressListInternal.Count
$JobsInProgressListInternal = @()
}
$JobsInProgressList = $JobsInProgressListInternal
}
}
catch
{
$ErrorMessage = ("Tracking modify cloud pairing jobs failed with [Exception: {0}]." -f $_.Exception)
Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser
Throw-TerminatingErrorMessage -Message $ErrorMessage
}
Write-InformationTracing ("Tracking modify cloud pairing jobs completed.")
Write-InformationTracing ("Modify cloud pairing jobs success: {0}." -f $JobsCompletedSuccessList.Count)
Write-InformationTracing ("Modify cloud pairing jobs failed: {0}." -f $JobsCompletedFailedList.Count)
Write-InformationTracing ("Modify cloud pairing jobs failed to start: {0}." -f $JobsFailedToStart)
Write-InformationTracing ("Modify cloud pairing jobs timedout: {0}." -f $JobsTimedOut)
if($JobsTimedOut -gt 0)
{
$ErrorMessage = "One or more modify cloud pairing jobs has timedout."
Write-Tracing -Level ErrorLevel -Message ($ErrorMessage)
Throw-TerminatingErrorMessage -Message $ErrorMessage
}
elseif($JobsCompletedSuccessList.Count -ne $ContainerMappingList.Count)
{
$ErrorMessage = "One or more modify cloud pairing jobs failed."
Write-Tracing -Level ErrorLevel -Message ($ErrorMessage)
Throw-TerminatingErrorMessage -Message $ErrorMessage
}
Write-Tracing -Level Succeeded -Message ("Modify cloud pairing completed.") -DisplayMessageToUser
Frissítések manuális kezelése
Ha a virtuális gépekre telepített Mobility szolgáltatás új frissítéseket talál, a következő értesítés jelenik meg: Új Site Recovery replikációs ügynök frissítése érhető el. Kattintson ide a telepítéshez.
Válassza ki az értesítést a virtuális gép kijelölési oldalának megnyitásához.
Válassza ki a frissíteni kívánt virtuális gépeket, majd kattintson az OK gombra. A frissítési Mobility szolgáltatás minden kijelölt virtuális gépnél elindul.
Gyakori problémák és hibaelhárítás
Ha az automatikus frissítésekkel kapcsolatos probléma merül fel, hibaüzenet jelenik meg a tároló irányítópultjának konfigurációs problémái között.
Ha nem tudja engedélyezni az automatikus frissítéseket, tekintse meg az alábbi gyakori hibákat és az ajánlott műveleteket:
Hiba: Nincs engedélye azure-beli futtató fiók (szolgáltatásnév) létrehozására és a közreműködői szerepkör szolgáltatásnévnek való megadására.
Javasolt művelet: Győződjön meg arról, hogy a bejelentkezett fiók közreműködőként van hozzárendelve, majd próbálkozzon újra. Az engedélyek hozzárendelésével kapcsolatos további információkért tekintse meg a How to: Use the portal to create a Microsoft Entra application and service principal to access resources (Útmutató: A portál használata az erőforrásokhoz hozzáférő Microsoft Entra-alkalmazás és szolgáltatásnév létrehozásához) című szakaszt.
Az automatikus frissítések engedélyezése után felmerülő legtöbb probléma megoldásához válassza a Javítás lehetőséget. Ha a javítási gomb nem érhető el, tekintse meg a bővítményfrissítés beállításai panelen megjelenő hibaüzenetet.
Hiba: A futtató fiók nem rendelkezik engedéllyel a helyreállítási szolgáltatások erőforrásának eléréséhez.
Javasolt művelet: Törölje, majd hozza létre újra a futtató fiókot. Vagy győződjön meg arról, hogy az Automation futtató fiók Microsoft Entra-alkalmazása hozzáfér a helyreállítási szolgáltatások erőforrásához.
Hiba: A futtató fiók nem található. Ezek egyikét törölték vagy nem hozták létre – Microsoft Entra-alkalmazás, szolgáltatásnév, szerepkör, Automation-tanúsítványobjektum, Automation Csatlakozás ion-objektum -, vagy az ujjlenyomat nem azonos a tanúsítvány és a Csatlakozás ion között.
Javasolt művelet: Törölje, majd hozza létre újra a futtató fiókot.
Hiba: Az automation-fiók által használt Azure Run as Certificate hamarosan lejár.
A futtató fiókhoz létrehozott önaláírt tanúsítvány a létrehozástól számított egy évig érvényes. A tanúsítványt bármikor meg lehet újítani a lejárata előtt. Ha feliratkozott az e-mail-értesítésekre, e-maileket is kap, ha az Ön részéről műveletre van szükség. Ez a hiba a lejárati dátum előtt két hónappal jelenik meg, és kritikus hibára változik, ha a tanúsítvány lejárt. A tanúsítvány lejártát követően az automatikus frissítés csak akkor lesz működőképes, ha ugyanazt megújítja.
Javasolt művelet: A probléma megoldásához válassza a Javítás , majd a Tanúsítvány megújítása lehetőséget.
Megjegyzés:
A tanúsítvány megújítása után frissítse a lapot az aktuális állapot megjelenítéséhez.
További lépések
További információ az Automation-fiókok hitelesítési típusának felügyelt identitásokba való migrálásáról.