2017-06-27 41 views
1

我有一个用于部署到数据库服务器的OctopusDeploy进程。 这些步骤包括将数据库备份从位置复制到本地服务器,将它们还原到SQL Server中,然后针对它们运行dacpac以将它们升级到特定版本。OctopusDeploy - SQL Always-On部署

这一切工作正常,但我们现在已经添加了一个新的环境,我不能解决如何配置它的部署过程。

最初,服务器是一个Windows群集环境,触手作为群集服务运行(这意味着一个部署目标)。

不过,该公司建立我们的服务器无法得到聚类无论出于何种原因工作,现在给我们的东西之间:
我们有两个服务器,每个服务器安装的触手,配置并在其上运行。
每把触手都有一个独特的指纹,并且始终可以正常运行。
在Windows服务器上,SQL Server已安装并配置为“始终开启”,其中一台服务器是主服务器,另一台服务器是次服务器。

这个想法是,如果主要模具,二手拿起件,运行良好。

从概念上讲,这适用于我们,因为我们为SQL服务器连接提供了“集群”IP,而我们的Web应用程序不会注意到它们之间的差异。

(需要注意的是很重要的,我不能改变这个设置 - 这是与我们给出了哪些工作的情况下......)现在

,在八达通,我只需要部署到一个在这个环境中的服务器,就像我要部署到两个服务器一样,我要么复制任务(如果作为滚动部署运行),要么更具有冲突的部署(如果运行异步)。

我最初尝试向每个服务器(“PrimaryNode”,“SecondaryNode”)添加辅助角色,但我发现Octopus将角色视为“或”而不是“和”,所以这不适用于我们开箱即用

然后,我看了一下编写powershell脚本,检查角色为“dbserver”和“primarynode”的计算机的状态为“联机”,健康状况为“健康”,然后设置输出变量的基础上的状态:

##CONFIG## 
$APIKey = "API-OBSCURED" 
$MainRole = "DBServer" 
$SecondaryRole = "PrimaryNode" 

$roles = $OctopusParameters['Octopus.Machine.Roles'] -split "," 

$enableFailoverDeployment = $false 

foreach($role in $roles) 
{ 
    if ($role -eq "FailoverNode") 
    { 
     #This is the failovernode - check if the primary node is up and running 
     Write-Host "This is the failover database node. Checking if primary node is available before attempting deployment." 

     $OctopusURL = "https://myOctourl" ##$OctopusParameters['Octopus.Web.BaseUrl'] 
     $EnvironmentID = $OctopusParameters['Octopus.Environment.Id'] 
     $header = @{ "X-Octopus-ApiKey" = $APIKey } 
     $environment = (Invoke-WebRequest -UseBasicParsing "$OctopusURL/api/environments/$EnvironmentID" -Headers $header).content | ConvertFrom-Json 
     $machines = ((Invoke-WebRequest -UseBasicParsing ($OctopusURL + $environment.Links.Machines) -Headers $header).content | ConvertFrom-Json).items 
     $MachinesInRole = $machines | ?{$MainRole -in $_.Roles} 
     $MachinesInRole = $MachinesInRole | ?{$SecondaryRole -in $_.Roles} 
     $measure = $MachinesInRole | measure 
     $total = $measure.Count 

     if ($total -gt 0) 
     { 
      $currentMachine = $MachinesInRole[0] 
      $machineUri = $currentMachine.URI 

      if ($currentMachine.Status -eq "Online") 
      { 
       if ($currentMachine.HealthStatus -eq "Healthy") 
       { 
        Write-Host "Primary node is online and healthy." 
        Write-Host "Setting flag to disable failover deployment." 
        $enableFailoverDeployment = $false 
       } 
       else 
       { 
        Write-Host "Primary node has a health status of $($currentMachine.HealthStatus)." 
        Write-Host "Setting flag to enable failover deployment." 
        $enableFailoverDeployment = $true 
       } 
      } 
      else 
      { 
       Write-Host "Primary node has a status of $($currentMachine.Status)." 
       Write-Host "Setting flag to enable failover deployment." 
       $enableFailoverDeployment = $true 
      } 
     } 
     break; 
    } 
} 

Set-OctopusVariable -name "EnableFailoverDeployment" -value $enableFailoverDeployment 

这看似工程 - 我可以告诉如果我应该部署到主要或辅助。

但是,我现在坚持如何让我的部署过程使用它。
显然,如果主节点处于脱机状态,那么无论如何都不会发生部署。然而,如果两个触角在线和健康,那么章鱼只会试图展开给他们。

部署过程包含约12个独特的步骤,而在其他几个环境(所有的单服务器配置)成功地使用,但是如前所述,现在需要也部署到一个奇怪的主动/温暖的环境。

任何想法,我可能会做到这一点? (如果只有你可以在角色中指定“AND”..根据结果​​)

更新1 现在我发现,您可以更新特定机器“IsDisabed”通过网络API,所以我加了码以上,使年底/禁用辅助节点而不是设置输出变量。

尽管这确实会更新机器的状态,但它实际上并未影响正在进行的部署过程。 如果我停止并重新启动整个过程,机器会相应地被启用/禁用,但是如果在部署期间状态发生变化,Octopus似乎并不“足够聪明”,无法识别这一点选项。 (我曾尝试在此脚本前后添加健康检查步骤以查看是否有所作为,但健康检查员认识到该机器已被禁用,但对其余步骤仍然没有影响)

更新2 我现在也在API中找到了“Deployment”的“ExcludedMachineIds”属性,但在部署过程中尝试更新时出现405(不允许)错误。
gah ..为什么这不容易?

+0

我不知道你是否可以把你的启用/禁用检查定制健康检查:https://octopus.com/docs/key-concepts/environments/machine-policies#MachinePolicies-Customhealthcheckscripts – gvee

+0

也许,更好的是,有健康检查添加/删除角色,例如这些目标上的“DB-Master”和“DB-Slave”,然后将您的部署过程设置为仅针对主设备! – gvee

回答

0

OK - 所以我们带着这个路线是具有对群集的Always-On SQL实例,它确定的主要和次要节点上运行脚本,如下所示:

SELECT TOP 1 hags.primary_replica 
FROM sys.dm_hadr_availability_group_states hags 
INNER JOIN sys.availability_groups ag 
    ON ag.group_id = hags.group_id 
WHERE ag.name = '$alwaysOnClusterInstance'; 

这让我获取主服务器的主机名。 然后我决定在OctopusDeploy内的机器的实际显示名称中包含主机名。

我然后做一个简单的“喜欢”从上述SQL和结果之间与Powershell的比较当前机显示名称($OctopusParameters['Octopus.Machine.Name']

如果有一个匹配,则我设置一个输出变量来自该步骤等于($OctopusParameters['Octopus.Machine.Id']

最后,在每个步骤的开始,我只是比较当前机器ID与上面提到的输出变量,以确定我是在主节点上还是在辅助节点上,并相应地采取行动(通常通过立即退出步骤,如果它是辅助节点的话)

要注意的最后一件事是,我关心正在运行的步骤的每一步都必须作为“滚动步骤”运行,其窗口大小为1.

幸运的是,如果我们不在主节点上,我们通常会退出,这不会为我们的部署过程添加任何实时。