Поделиться через


Увеличение масштаба кластера Service Fabric, не являющихся основными узлами

В этой статье описывается, как увеличить масштаб кластера Service Fabric не основного типа узла с минимальным временем простоя. Обновления SKU на месте не поддерживаются на узлах кластера Service Fabric, так как такие операции могут привести к потере данных и доступности. Ниже описан самый надежный и рекомендуемый способ масштабирования типа узла Service Fabric.

  1. Добавьте новый тип узла в кластер Service Fabric на основе обновленного (или измененного) SKU и конфигурации масштабируемого набора виртуальных машин. Этот шаг также включает настройку новой подсистемы балансировки нагрузки, подсети и общедоступного IP-адреса для масштабируемого набора.

  2. После параллельного выполнения исходных и обновленных масштабируемых наборов перенесите рабочую нагрузку, задав ограничения размещения для приложений на новый тип узла.

  3. Убедитесь, что кластер работоспособен, а затем удалите исходный масштабируемый набор (и связанные ресурсы) и состояние узла для удаленных узлов.

Ниже показано, как обновить размер виртуальной машины и операционную систему виртуальных машин, не относящихся к первичному типу, примера кластера с устойчивостью Silver, на основе одного масштабируемого набора с пятью узлами, используемыми в качестве вторичного типа узлов. Тип основного узла с системными службами Service Fabric останется нетронутым. Мы обновим не основной тип узла:

  • размер виртуальной машины будет изменен со Standard_D2_V2 на Standard_D4_V2;
  • От операционной системы виртуальной машины Windows Server 2019 Datacenter до Windows Server 2022 Datacenter.

Предупреждение

Прежде чем выполнять эту процедуру для кластера рабочей среды, рекомендуется изучить образцы шаблонов и применить шаги для тестового кластера.

Не пытайтесь выполнить процедуру увеличения масштаба не основного типа узла, если кластер находится в неработоспособном состоянии, так как это только еще больше дестабилизирует кластер. Мы будем использовать пошаговые шаблоны развертывания Azure, используемые в руководстве По масштабированию основного узла кластера Service Fabric . Однако мы изменим их, чтобы они не были специфичы для типов первичных узлов. Шаблоны доступны на сайте GitHub.

Настройка тестового кластера

Создадим начальный тестовый кластер Service Fabric. Сначала скачайте примеры шаблонов Azure Resource Manager, которые мы используем для выполнения этого сценария.

Затем войдите в учетную запись Azure.

# Sign in to your Azure account
Login-AzAccount -SubscriptionId "<subscription ID>"

Затем откройте файл parameters.json и измените значение параметра clusterName на уникальное (в Azure).

Следующие команды помогут создать новый самозаверяющий сертификат и развернуть тестовый кластер. Если у вас уже есть сертификат, который вы хотите использовать, перейдите к шагу Развертывание кластера с использованием существующего сертификата.

Создание самозаверяющего сертификата и развертывание кластера

Сначала назначьте переменные, которые потребуются для развертывания кластера Service Fabric. Измените значения resourceGroupName, certSubjectName, parameterFilePath и templateFilePath в соответствии со своей учетной записью и средой:

# Assign deployment variables
$resourceGroupName = "sftestupgradegroup"
$certOutputFolder = "c:\certificates"
$certPassword = "Password!1" | ConvertTo-SecureString -AsPlainText -Force
$certSubjectName = "sftestupgrade.southcentralus.cloudapp.azure.com"
$parameterFilePath = "C:\parameters.json"
$templateFilePath = "C:\Initial-TestClusterSetup.json"

Примечание

Перед выполнением команды для развертывания нового кластера Service Fabric убедитесь, что на локальном компьютере существует расположение certOutputFolder. Затем разверните тестовый кластер Service Fabric.

# Deploy the initial test cluster
New-AzServiceFabricCluster `
    -ResourceGroupName $resourceGroupName `
    -CertificateOutputFolder $certOutputFolder `
    -CertificatePassword $certPassword `
    -CertificateSubjectName $certSubjectName `
    -TemplateFile $templateFilePath `
    -ParameterFile $parameterFilePath

После завершения развертывания найдите PFX-файл ($certPfx) на локальном компьютере и импортируйте его в хранилище сертификатов.

cd c:\certificates
$certPfx = ".\sftestupgradegroup20200312121003.pfx"
Import-PfxCertificate `
     -FilePath $certPfx `
     -CertStoreLocation Cert:\CurrentUser\My `
     -Password (ConvertTo-SecureString Password!1 -AsPlainText -Force)

Эта операция вернет отпечаток сертификата, который можно использовать для подключения к новому кластеру и проверки его состояния работоспособности. (Пропустите следующий раздел, в котором описан альтернативный подход к развертыванию кластера.)

Развертывание кластера с использованием существующего сертификата

Для развертывания тестового кластера также можно использовать существующий сертификат Azure Key Vault. Для этого необходимо получить ссылки на Key Vault и отпечаток сертификата.

# Key Vault variables
$certUrlValue = "https://sftestupgradegroup.vault.azure.net/secrets/sftestupgradegroup20200309235308/dac0e7b7f9d4414984ccaa72bfb2ea39"
$sourceVaultValue = "/subscriptions/########-####-####-####-############/resourceGroups/sftestupgradegroup/providers/Microsoft.KeyVault/vaults/sftestupgradegroup"
$thumb = "BB796AA33BD9767E7DA27FE5182CF8FDEE714A70"

Затем назначьте для кластера имя группы ресурсов и укажите расположения templateFilePath и parameterFilePath.

Примечание

Указанная группа ресурсов должна уже существовать и находиться в том же регионе, что и Key Vault.

$resourceGroupName = "sftestupgradegroup"
$templateFilePath = "C:\Initial-TestClusterSetup.json"
$parameterFilePath = "C:\parameters.json"

Наконец, выполните следующую команду, чтобы развернуть исходный тестовый кластер:

# Deploy the initial test cluster
New-AzResourceGroupDeployment `
    -ResourceGroupName $resourceGroupName `
    -TemplateFile $templateFilePath `
    -TemplateParameterFile $parameterFilePath `
    -CertificateThumbprint $thumb `
    -CertificateUrlValue $certUrlValue `
    -SourceVaultValue $sourceVaultValue `
    -Verbose

Подключение к новому кластеру и проверка состояния работоспособности

Подключитесь к кластеру и убедитесь, что пять его узлов работоспособны (замените переменные clusterName и thumb, указав значения для своего кластера).

# Connect to the cluster
$clusterName = "sftestupgrade.southcentralus.cloudapp.azure.com:19000"
$thumb = "BB796AA33BD9767E7DA27FE5182CF8FDEE714A70"
Connect-ServiceFabricCluster `
    -ConnectionEndpoint $clusterName `
    -KeepAliveIntervalInSec 10 `
    -X509Credential `
    -ServerCertThumbprint $thumb  `
    -FindType FindByThumbprint `
    -FindValue $thumb `
    -StoreLocation CurrentUser `
    -StoreName My
# Check cluster health
Get-ServiceFabricClusterHealth

После этого все готово к процедуре обновления.

Развертывание нового типа узла, отличного от основного, с обновленным масштабируемым набором

Чтобы обновить (вертикально масштабировать) тип узла, сначала необходимо развернуть узел нового типа на базе нового масштабируемого набора и вспомогательных ресурсов. Новый масштабируемый набор будет помечен как не первичный (isPrimary: false), как и исходный масштабируемый набор. Если вы хотите увеличить масштаб основного узла, см. статью Масштабирование типа первичного узла кластера Service Fabric. Ресурсы, созданные в следующем разделе, в конечном итоге станут новым типом узла в кластере, а исходные ресурсы типа узла будут удалены.

Обновление шаблона кластера с использованием обновленного масштабируемого набора

Ниже приведены раздельные изменения исходного шаблона развертывания кластера для добавления нового типа узла и вспомогательных ресурсов.

Большинство необходимых изменений для этого шага уже были внесены в файл шаблона Step1-AddPrimaryNodeType.json . Однако необходимо внести дополнительные изменения, чтобы файл шаблона работал для типов узлов, не являющихся первичными. В следующих разделах подробно описаны эти изменения, а при внесении изменений будут выполняться вызовы.

Примечание

Убедитесь, что вы используете имена, уникальные из исходного типа узла, масштабируемого набора, подсистемы балансировки нагрузки, общедоступного IP-адреса и подсети исходного типа не основного узла, так как эти ресурсы будут удалены на более позднем этапе процесса.

Создание новой подсети в виртуальной сети

{
    "name": "[variables('subnet1Name')]",
    "properties": {
        "addressPrefix": "[variables('subnet1Prefix')]"
    }
}

Создание нового общедоступного IP-адреса с уникальным значением domainNameLabel

{
    "apiVersion": "[variables('publicIPApiVersion')]",
    "type": "Microsoft.Network/publicIPAddresses",
    "name": "[concat(variables('lbIPName'),'-',variables('vmNodeType1Name'))]",
    "location": "[variables('computeLocation')]",
    "properties": {
        "dnsSettings": {
            "domainNameLabel": "[concat(variables('dnsName'),'-','nt1')]"
        },
        "publicIPAllocationMethod": "Dynamic"
    },
    "tags": {
        "resourceType": "Service Fabric",
        "clusterName": "[parameters('clusterName')]"
    }
}

Создание новой подсистемы балансировки нагрузки для общедоступного IP-адреса

"dependsOn": [
    "[concat('Microsoft.Network/publicIPAddresses/',concat(variables('lbIPName'),'-',variables('vmNodeType1Name')))]"
]

Создание нового масштабируемого набора виртуальных машин (с обновленными SKU виртуальных машин и ОС)

Справка по типам узлов

"nodeTypeRef": "[variables('vmNodeType1Name')]"

SKU виртуальной машины

"sku": {
    "name": "[parameters('vmNodeType1Size')]",
    "capacity": "[parameters('nt1InstanceCount')]",
    "tier": "Standard"
}

SKU ОС

"imageReference": {
    "publisher": "[parameters('vmImagePublisher1')]",
    "offer": "[parameters('vmImageOffer1')]",
    "sku": "[parameters('vmImageSku1')]",
    "version": "[parameters('vmImageVersion1')]"
}

Также включите все дополнительные расширения, необходимые для вашей рабочей нагрузки.

Добавление нового типа узла, отличного от основного, в кластер

Теперь, когда новый тип узла (vmNodeType1Name) имеет собственное имя, подсеть, IP-адрес, подсистему балансировки нагрузки и масштабируемый набор, он может повторно использовать все остальные переменные из исходного типа узла (например nt0applicationEndPort, , nt0applicationStartPortи nt0fabricTcpGatewayPort).

В существующем файле isPrimary шаблона параметру присваивается true значение для руководства по типу первичного узла кластера Service Fabric . Измените isPrimary на false на для типа узла, не являющихся основными:

"name": "[variables('vmNodeType1Name')]",
"applicationPorts": {
    "endPort": "[variables('nt0applicationEndPort')]",
    "startPort": "[variables('nt0applicationStartPort')]"
},
"clientConnectionEndpointPort": "[variables('nt0fabricTcpGatewayPort')]",
"durabilityLevel": "Bronze",
"ephemeralPorts": {
    "endPort": "[variables('nt0ephemeralEndPort')]",
    "startPort": "[variables('nt0ephemeralStartPort')]"
},
"httpGatewayEndpointPort": "[variables('nt0fabricHttpGatewayPort')]",
"isPrimary": false,
"reverseProxyEndpointPort": "[variables('nt0reverseProxyEndpointPort')]",
"vmInstanceCount": "[parameters('nt1InstanceCount')]"

После внесения всех изменений в файлы шаблонов и параметров перейдите к следующему разделу, чтобы получить ссылки Key Vault и развернуть обновления в кластере.

Получение ссылок Key Vault

Для развертывания обновленной конфигурации потребуется несколько ссылок на сертификат кластера, хранящийся в Key Vault. Проще всего найти эти значения через портал Azure. Что вам понадобится

  • URL-адрес сертификата кластера в Key Vault. В хранилище Key Vault на портале Azure выберите Сертификаты>нужный вам сертификат>Идентификатор секрета:

    $certUrlValue="https://sftestupgradegroup.vault.azure.net/secrets/sftestupgradegroup20200309235308/dac0e7b7f9d4414984ccaa72bfb2ea39"
    
  • Отпечаток сертификата кластера. (Возможно, у вас уже есть эти значения, если вы подключились к первоначальному кластеру для проверки его работоспособности.) Из той же колонки сертификата (Сертификаты>нужный вам сертификат) на портале Azure скопируйте отпечаток X. 509 SHA-1 (в шестнадцатеричном формате) :

    $thumb = "BB796AA33BD9767E7DA27FE5182CF8FDEE714A70"
    
  • Идентификатор ресурса для Key Vault. В хранилище Key Vault на портале Azure выберите Свойства>Идентификатор ресурса:

    $sourceVaultValue = "/subscriptions/########-####-####-####-############/resourceGroups/sftestupgradegroup/providers/Microsoft.KeyVault/vaults/sftestupgradegroup"
    

Развертывание обновленного шаблона

Измените параметр templateFilePath соответствующим образом и выполните приведенную ниже команду.

# Deploy the new node type and its resources
$templateFilePath = "C:\Step1-AddPrimaryNodeType.json"
New-AzResourceGroupDeployment `
    -ResourceGroupName $resourceGroupName `
    -TemplateFile $templateFilePath `
    -TemplateParameterFile $parameterFilePath `
    -CertificateThumbprint $thumb `
    -CertificateUrlValue $certUrlValue `
    -SourceVaultValue $sourceVaultValue `
    -Verbose

После завершения развертывания снова проверьте работоспособность кластера и убедитесь, что все узлы обоих типов работоспособны.

Get-ServiceFabricClusterHealth

Перенос рабочих нагрузок на новый тип узла

Подождите, пока все приложения переместятся на новый тип узла и не будут работоспособными.

Отключение узлов в наборе масштабирования исходного типа узла

После миграции всех начальных узлов в новый масштабируемый набор можно отключить узлы исходного набора.

# Disable the nodes in the original scale set.
$nodeType = "nt0vm"
$nodes = Get-ServiceFabricNode
Write-Host "Disabling nodes..."
foreach($node in $nodes)
{
  if ($node.NodeType -eq $nodeType)
  {
    $node.NodeName
    Disable-ServiceFabricNode -Intent RemoveNode -NodeName $node.NodeName -Force
  }
}

Для отслеживания перехода узлов в исходном масштабируемом наборе из состояния Отключение в состояние Отключен используйте Service Fabric Explorer. Дождитесь, пока все узлы достигнут состояния "Отключено ".

Отключение обработки данных на отключенных узлах

Теперь можно отключить обработку данных на отключенных узлах.

# Stop data on the disabled nodes.
foreach($node in $nodes)
{
  if ($node.NodeType -eq $nodeType)
  {
    $node.NodeName
    Start-ServiceFabricNodeTransition -Stop -OperationId (New-Guid) -NodeInstanceId $node.NodeInstanceId -NodeName $node.NodeName -StopDurationInSeconds 10000
  }
}

Удаление исходного типа узла и очистка его ресурсов

Теперь мы готовы удалить исходный тип узла и связанные с ним ресурсы, чтобы завершить процедуру вертикального масштабирования.

Удаление исходного масштабируемого набора

Сначала удалите базовый масштабируемый набор типа узла.

$scaleSetName = "nt0vm"
$scaleSetResourceType = "Microsoft.Compute/virtualMachineScaleSets"
Remove-AzResource -ResourceName $scaleSetName -ResourceType $scaleSetResourceType -ResourceGroupName $resourceGroupName -Force

Удаление исходных ресурсов IP-адреса и подсистемы балансировки нагрузки

Теперь можно удалить исходные ресурсы IP-адреса и подсистемы балансировки нагрузки. На этом шаге вы также обновите DNS-имя.

Примечание

Этот шаг является необязательным, если уже используются общедоступный IP-адрес и подсистема балансировки нагрузки SKU уровня Стандартный. В этом случае в одной подсистеме балансировки нагрузки может быть несколько масштабируемых наборов или типов узлов. Выполните следующие команды, изменив значение $lbname.

# Delete the original IP and load balancer resources
$lbName = "LB-sftestupgrade-nt0vm"
$lbResourceType = "Microsoft.Network/loadBalancers"
$ipResourceType = "Microsoft.Network/publicIPAddresses"
$oldPublicIpName = "PublicIP-LB-FE-nt0vm"
$newPublicIpName = "PublicIP-LB-FE-nt1vm"
$oldPublicIP = Get-AzPublicIpAddress -Name $oldPublicIpName  -ResourceGroupName $resourceGroupName
$nonPrimaryDNSName = $oldNonPrimaryPublicIP.DnsSettings.DomainNameLabel
$nonPrimaryDNSFqdn = $oldNonPrimaryPublicIP.DnsSettings.Fqdn
Remove-AzResource -ResourceName $lbName -ResourceType $lbResourceType -ResourceGroupName $resourceGroupName -Force
Remove-AzResource -ResourceName $oldPublicIpName -ResourceType $ipResourceType -ResourceGroupName $resourceGroupName -Force
$PublicIP = Get-AzPublicIpAddress -Name $newPublicIpName  -ResourceGroupName $resourceGroupName
$PublicIP.DnsSettings.DomainNameLabel = $nonPrimaryDNSName
$PublicIP.DnsSettings.Fqdn = $nonPrimaryDNSFqdn
Set-AzPublicIpAddress -PublicIpAddress $PublicIP

Удаление состояния узла из исходного типа узла

Для узлов исходного типа теперь в качестве состояния работоспособности будет отображаться ошибка. Удалите состояние узла из кластера.

# Remove state of the obsolete nodes from the cluster
$nodeType = "nt0vm"
$nodes = Get-ServiceFabricNode
Write-Host "Removing node state..."
foreach($node in $nodes)
{
  if ($node.NodeType -eq $nodeType)
  {
    $node.NodeName
    Remove-ServiceFabricNodeState -NodeName $node.NodeName -Force
  }
}

Теперь в Service Fabric Explorer должны отражаться только пять узлов нового типа узла (nt1vm) с состоянием работоспособности ОК. Мы устраним эту ошибку на следующем шаге: обновим шаблон, чтобы отразить в нем последние изменения, и повторно развернем его.

Обновите шаблон развертывания, чтобы он отражал только что масштабируемый тип узла, не являющегося первичным

Большинство необходимых изменений для этого шага уже были внесены в файл шаблона Step3-CleanupOriginalPrimaryNodeType.json . Однако необходимо внести дополнительные изменения, чтобы файл шаблона работал для типов узлов, не являющихся первичными. В следующих разделах подробно описаны эти изменения, а при внесении изменений будут сделаны выноски.

Обновление конечной точки управления кластером

Обновите кластер managementEndpoint в шаблоне развертывания таким образом, чтобы в нем использовался новый IP-адрес (путем изменения параметра vmNodeType0Name на vmNodeType1Name).

  "managementEndpoint": "[concat('https://',reference(concat(variables('lbIPName'),'-',variables('vmNodeType1Name'))).dnsSettings.fqdn,':',variables('nt0fabricHttpGatewayPort'))]",

Удаление ссылки на исходный тип узла

Удалите исходную ссылку на тип узла из ресурса Service Fabric в шаблоне развертывания.

В существующем файле isPrimary шаблона параметру присваивается значение true для руководства По типу основного узла кластера Service Fabric . Измените isPrimary на false для типа узла, не являющегося первичным:

"name": "[variables('vmNodeType0Name')]",
"applicationPorts": {
    "endPort": "[variables('nt0applicationEndPort')]",
    "startPort": "[variables('nt0applicationStartPort')]"
},
"clientConnectionEndpointPort": "[variables('nt0fabricTcpGatewayPort')]",
"durabilityLevel": "Bronze",
"ephemeralPorts": {
    "endPort": "[variables('nt0ephemeralEndPort')]",
    "startPort": "[variables('nt0ephemeralStartPort')]"
},
"httpGatewayEndpointPort": "[variables('nt0fabricHttpGatewayPort')]",
"isPrimary": false,
"reverseProxyEndpointPort": "[variables('nt0reverseProxyEndpointPort')]",
"vmInstanceCount": "[parameters('nt0InstanceCount')]"

Настройка политик работоспособности для игнорирования существующих ошибок

Только для кластеров с уровнем устойчивости Silver и выше: обновите ресурс кластера в шаблоне и настройте политики работоспособности так, чтобы игнорировать работоспособность приложения fabric:/System, добавив applicationDeltaHealthPolicies в свойства ресурса кластера, как показано ниже. Приведенная ниже политика должна игнорировать существующие ошибки, но при этом не допускать новых ошибок работоспособности.

"upgradeDescription":  
{ 
 "forceRestart": false, 
 "upgradeReplicaSetCheckTimeout": "10675199.02:48:05.4775807", 
 "healthCheckWaitDuration": "00:05:00", 
 "healthCheckStableDuration": "00:05:00", 
 "healthCheckRetryTimeout": "00:45:00", 
 "upgradeTimeout": "12:00:00", 
 "upgradeDomainTimeout": "02:00:00", 
 "healthPolicy": { 
   "maxPercentUnhealthyNodes": 100, 
   "maxPercentUnhealthyApplications": 100 
 }, 
 "deltaHealthPolicy":  
 { 
   "maxPercentDeltaUnhealthyNodes": 0, 
   "maxPercentUpgradeDomainDeltaUnhealthyNodes": 0, 
   "maxPercentDeltaUnhealthyApplications": 0, 
   "applicationDeltaHealthPolicies":  
   { 
       "fabric:/System":  
       { 
           "defaultServiceTypeDeltaHealthPolicy":  
           { 
                   "maxPercentDeltaUnhealthyServices": 0 
           } 
       } 
   } 
 } 
}

Удаление вспомогательных ресурсов для исходного типа узла

Удалите из шаблона ARM и файла параметров все прочие ресурсы, связанные с исходным типом узла. Удалите:

    "vmImagePublisher": {
      "value": "MicrosoftWindowsServer"
    },
    "vmImageOffer": {
      "value": "WindowsServer"
    },
    "vmImageSku": {
      "value": "2019-Datacenter"
    },
    "vmImageVersion": {
      "value": "latest"
    },

Развертывание окончательной версии шаблона

Наконец, разверните измененный шаблон Azure Resource Manager.

# Deploy the updated template file
$templateFilePath = "C:\Step3-CleanupOriginalPrimaryNodeType"
New-AzResourceGroupDeployment `
    -ResourceGroupName $resourceGroupName `
    -TemplateFile $templateFilePath `
    -TemplateParameterFile $parameterFilePath `
    -CertificateThumbprint $thumb `
    -CertificateUrlValue $certUrlValue `
    -SourceVaultValue $sourceVaultValue `
    -Verbose

Примечание

Выполнение этого шага занимает определенное время, обычно не более двух часов. В результате этого обновления изменятся параметры для InfrastructureService, в связи с чем потребуется перезагрузка узла. В данном случае значение параметра forceRestart игнорируется. Параметр upgradeReplicaSetCheckTimeout задает максимальное время, в течение которого Service Fabric ожидает перехода секции в безопасное состояние, если она еще не находится в нем. После завершения проверок безопасности для всех секций на узле Service Fabric начинает обновление на этом узле. Значение параметра upgradeTimeout можно уменьшить до 6 часов, однако для максимальной безопасности следует задать 12 часов.

После завершения развертывания убедитесь на портале Azure, что ресурс Service Fabric находится в состоянии Готов. Убедитесь, что вы можете подключиться к новой конечной точке Service Fabric Explorer, состояние работоспособности кластера — ОК, а все развернутые приложения работают правильно.

Таким образом, вы вертикально масштабировали тип узла кластера, не являющегося первичным!

Дальнейшие действия