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.
Feljegyzés
Javasoljuk, hogy az Azure Az PowerShell modult használja az Azure-ral való interakcióhoz. Az első lépésekhez tekintse meg Az Azure PowerShell telepítése témakört. Az Az PowerShell-modulra történő migrálás részleteiről lásd: Az Azure PowerShell migrálása az AzureRM modulból az Az modulba.
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.
Feljegyzé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ési beállításainak>Engedélyezése a Site Recovery kezelésének engedélyezése területen 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 lehetőséget.
Feljegyzé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-AutoUpdateForVaultForPartner"
$TaskId = [guid]::NewGuid().ToString()
$SubscriptionId = "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"
$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ány-objektum, Automation-kapcsolati eszköz -, vagy az ujjlenyomat nem azonos a tanúsítvány és a kapcsolat 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.
Feljegyzés
A tanúsítvány megújítása után frissítse a lapot az aktuális állapot megjelenítéséhez.
Következő 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.