Подтвердить что ты не робот

Управление выпуском vNext Развертывание компонентов

Мы используем Release Management 2015 с шаблонами выпуска vNext. У нас есть развертывание компонентов на основе Powershell DSC для каждой из частей нашего приложения, и на самом деле у нас есть два различных приложения, которые развернуты и которые находятся в активной разработке и часто развертываются почти в одно и то же время.

Мы очень часто получаем следующую ошибку при развертывании:

OperationFailedException: новое развертывание не допускается по мере развертывания другого развертывания. Повторно повторите развертывание через некоторое время.

Полная трассировка стека показывает, что ошибка исходит не от самой Powershell, а из системы управления релизами, которая отвечает за выполнение powershell script на целевой машине:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Microsoft.TeamFoundation.Release.Common.Helpers.OperationFailedException: New deployment is not allowed as an another deployment is in progress. Retry the deployment after sometime.
   at Microsoft.TeamFoundation.Release.EnvironmentProvider.OnPrem.Implementation.OnPremDeploymentProvider.ReadDeploymentResponse(DeploymentResponse response)
   at Microsoft.TeamFoundation.Release.EnvironmentProvider.OnPrem.Implementation.OnPremDeploymentProvider.RunScript(String scriptPath, String configurationPath, MachineSpecification machine, StorageSpecification storage, Dictionary`2 configurationVariables)
   at Microsoft.TeamFoundation.Release.MonitorServices.Dsc.OnPrem.OnPremDeploymentActions.InvokePlatform(String activityId, MachineSpecification machineSpecification, StorageSpecification storageSpecification, String scriptPath, String configurationPath, Dictionary`2 configurationVariables)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.TeamFoundation.Release.DeploymentAgent.Services.Deployer.Dsc.DscComponentInstaller.InvokeMethodByReflection(String methodArguments)

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

Есть два сценария, которые вызывают это:

  • Два шаблона выпуска выполняют свои сценарии powershell на одном и том же целевом сервере одновременно
  • Один шаблон выпуска имеет параллельный поток управления, который содержит два разных компонента, которые выполняют сценарии на одном и том же целевом сервере.

Другими словами, механизм, который Управление релизами использует для запуска powershell script на удаленном сервере, может только когда-либо выполнять одиночный script за раз, и не имеет возможности ждать/удерживать для других пользователей полная.

Этот вид /sorta имеет смысл, если рассматриваемый script активно модифицирует сервер, на котором он выполняется, но в нашем случае сервер выступает в качестве основной области для запуска script. "Настоящая" цель script не имеет ничего общего с сервером, на котором выполняется powershell.

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

4b9b3361

Ответ 1

Как я уже объяснил в еще одном сообщении, способ развертывания MS Release Management немного интуитивно понятен: вместо того, чтобы просто выполнить развертывание Powershell script против целевого сервера с использованием PSRemoting, он использует PSRemoting для установки службы Windows (VisualStudioRemoteDeployer.exe) на целевом сервере. Затем эта служба запускает ваше развертывание script локально, а сервер MSRM регулярно обследует эту службу Windows (см. здесь), чтобы узнать, завершено ли это развёртывание.

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

Во всяком случае, эта служба Windows, вероятно, создает узкое место, потому что на сервере может быть только один экземпляр - отсюда возникает столкновение параллельных развертываний компонентов с одним и тем же сервером.

Я думаю, что ваши проблемы возникли из-за того, что вы выбрали настройку, где "сервер выступает в качестве основной области для запуска script" - MS Release Management 2013/2015 не очень хорошо работает в этом сценарии (как вы узнали об этом), вы должны действительно развернуть свои компоненты непосредственно на целевые серверы, на которых они должны быть установлены, тем самым избегая узких мест в промежуточной области.

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

Ответ 2

У меня возникла проблема с запуском сценариев Powershell на удаленных серверах. В итоге я пошел немного иначе. Вместо этого я просто запускаю обычную команду Powershell с блоком Invoke-Command. Я считаю, что вы должны иметь возможность запускать это параллельно.

Function Get-PSCredential($User,$Password) {
    $SecPass = ConvertTo-SecureString -AsPlainText -String $Password -Force
    $Creds = New-Object System.Management.Automation.PSCredential -ArgumentList $User,$SecPass
    Return $Creds
}    

$credential = Get-PSCredential -User $deployUser -Password $deployPass
$session = New-PSSession YourServerName -Credential $credential

Invoke-Command -Session $session -ScriptBlock {
    # do your work here
}

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

$session = New-PSSession YourServerName

Я только начал использовать Release Management на этой неделе, так что это казалось лучшим способом за это короткое время.

Кроме того, если вы никогда не использовали Invoke-Command раньше, все внутри блока script фактически находится в своей собственной области, поэтому вам нужно передать свои переменные с помощью -ArgumentList, если у вас есть. эту статью, если у вас есть еще вопросы об этом.