【问题标题】:Automated Deployment to an F5 Load Balanced Environment自动部署到 F5 负载平衡环境
【发布时间】:2013-06-19 02:45:20
【问题描述】:

我们目前正在使用 TeamCity 进行 CI 构建,并且我们也在尝试设置自动化部署。

我目前尝试部署的项目是位于 F5 负载平衡器下的 Windows 服务。将来,我们还希望自动部署同样位于 F5 下的 IIS 网站。

从 TeamCity 中,我们可以执行 PowerShell 脚本来卸载所需服务器上的 Windows 服务,将我们的文件推送到它,然后重新安装该服务。

但是,我无法弄清楚如何处理负载平衡器。我们希望一次禁用 1 个节点,观察所有连接断开,然后部署我们的代码并重新启动节点。

这似乎是一个非常普遍的问题,但我发现关于如何做到这一点的信息非常少。

谢谢!

已回答

感谢 Jonathon Rossi 提供 iControl Powershell cmdlet!

为了其他用户的利益,这里是一个关闭、监控连接断开、推送代码,然后通过 powershell 脚本重新打开 F5 负载均衡器的示例

要使这些脚本正常工作,您首先必须通过以下答案中提供的链接安装 F5 iControl cmdlet

#PULL IN OUR F5 UTILITY FUNCTIONS
. .\F5Functions.ps1


#DEFINE LOGIC TO DEPLOY CODE TO A NODE THAT HAS ALREADY BEEN REMOVED FROM THE LOAD BALANCER
function Deploy(
    [F5Node]$Node
)
{
    Write-Host "Deploying To: "$Node.Name
    #TODO: Remotely shut down services, push code, start back up services
}


#DEFINE NODES
$nodes = @()
$nodes += New-Object F5Node -ArgumentList @("TestNode1", "1.1.1.1")
$nodes += New-Object F5Node -ArgumentList @("TestNode2", "1.1.1.2")

#DEPLOY
DeployToNodes -Nodes $nodes -F5Host $F5Host -F5UserName $F5UserName -F5Password $F5Password

这是可重复使用的 F5Functions 脚本

#Load the F5 powershell iControl snapin
Add-PSSnapin iControlSnapin;

Write-Host "Imported F5 function!!!"

Add-Type @'
    public class F5Node
    {
        public F5Node(string name, string address){
            Address = address;
            Name = name;
        }
        public string Address {get;set;}
        public string Name {get;set;}
        public string QualifiedName {get{return "/Common/" + Name;}}
    }
'@

function DeployToNodes(
    [string]$F5Host = $(throw "Missing Required Parameter"),
    [string]$F5UserName = $(throw "Missing Required Parameter"),
    [string]$F5Password = $(throw "Missing Required Parameter"),
    [F5Node[]]$Nodes = $(throw "Missing Required Parameter"),    
    [int]$MaxWaitTime = 300 #seconds... defaults to 5 minutes
){
    Authenticate -F5Host $F5Host -F5UserName $F5UserName -F5Password $F5Password

    foreach($node in $Nodes){
        DisableNode -Node $node

        WaitForConnectionsToDrop -Node $node -MaxWaitTime $MaxWaitTime

        #Assume the Script that included this script defined a Deploy Method with a Node param
        Deploy -Node $node    

        EnableNode -Node $node
    }
}

function Authenticate(
    [string]$F5Host = $(throw "Missing Required Parameter"),
    [string]$F5UserName = $(throw "Missing Required Parameter"),
    [string]$F5Password = $(throw "Missing Required Parameter")
)
{
    Write-Host "Authenticating to F5..."
    Initialize-F5.iControl -HostName $F5Host -Username $F5UserName -Password $F5Password
    Write-Host "Authentication Success!!!"
}

function ParseStatistic(
        [iControl.CommonStatistic[]]$StatsCollection = $(throw "Missing Required Parameter"),
        [string]$StatName = $(throw "Missing Required Parameter")
    )
{
    for($i=0; $i -lt $StatsCollection.Count; $i++){   
        if($StatsCollection[$i].type.ToString() -eq $StatName){
            return $StatsCollection[$i].value.low  
            break
        }                      
    }
}

function GetStats(
        [F5Node]$Node = $(throw "Missing Required Parameter")
    )
{
    $arr = @($Node.QualifiedName)
    $nodeStats = (Get-F5.iControl).LocalLBNodeAddressV2.get_statistics($arr)
    return $nodeStats.statistics.statistics

    #foreach($memberStats in $poolStats.statistics){
    #    if($memberStats.member.address.ToString() -eq $Node -and $memberStats.member.port -eq $Port){
    #        return $memberStats.statistics
    #    }  
    #}
}

function GetStatistic(
        [F5Node]$Node = $(throw "Missing Required Parameter"),
        [string]$StatName = $(throw "Missing Required Parameter")
    )
{
    $stats = GetStats -Node $Node
    $stat = ParseStatistic -StatsCollection $stats -StatName $StatName

    return $stat
}

function DisableNode(
    [F5Node]$Node = $(throw "Missing Required Parameter")
)
{    
    Disable-F5.LTMNodeAddress -Node $Node.Address
    Write-Host "Disabled Node '$Node'"
}

function EnableNode(
    [F5Node]$Node = $(throw "Missing Required Parameter")
)
{
    Enable-F5.LTMNodeAddress -Node $Node.Address
    Write-Host "Enabled Node '$Node'"
}

function WaitForConnectionsToDrop(
    [F5Node]$Node = $(throw "Missing Required Parameter"),
    [int]$MaxWaitTime = 300
)
{
    $connections = GetCurrentConnections -Node $Node

    $elapsed = [System.Diagnostics.Stopwatch]::StartNew();
    while($connections -gt 0 -and $elapsed.ElapsedMilliseconds -lt ($MaxWaitTime * 1000)){        

        Start-Sleep -Seconds 10

        $connections = GetCurrentConnections -Node $Node
    }
}

function GetCurrentConnections(
    [F5Node]$Node = $(throw "Missing Required Parameter")
)
{
    $connections = GetStatistic -Node $Node -StatName "STATISTIC_SERVER_SIDE_CURRENT_CONNECTIONS"
    $name = $Node.Name + ":" + $Node.Address
    Write-Host "$connections connections remaining on '$name'"
    return $connections
}

【问题讨论】:

  • 任何带有完整源代码示例的最终解决方案?
  • @Kiquenet - “已回答”标题下的上述代码 sn-ps 是我们用来将代码部署到生产环境的代码,每天大约 5 到 10 次。第二个代码块是第一个代码块加载的模块,这是一个如何使用模块的示例。您需要填写的唯一部分是您在 F5 节点关闭时部署代码的实际操作(移动文件、解压缩、停止服务、重新启动服务等)。请原谅糟糕的命名约定。写这篇文章时,我是 powershell 新手。
  • 实际上,当我重新阅读我的旧帖子时,我发现它远没有最终产品成熟。 1. 我将 F5 函数脚本移动到安装在构建服务器上的 powershell 模块,并使用 Load-Module 加载它 2. DeployToNodes 函数应该接受 ScriptBlock 和 ScriptBlock 的参数数组,而不是假设 Deploy 函数是在别处声明 3. 函数应该遵循动词-名词命名约定 4. 我把更多的逻辑放在删除节点上,所以它会一次删除一半,允许 sql 迁移发生在中间
  • 您是否设法自动安装 iControl msi 包本身?

标签: .net powershell continuous-integration continuous-deployment f5


【解决方案1】:

我没用过,但是你看过F5提供的F5 iControlweb服务API和F5 iControl PowerShell cmdlets。 PowerShell cmdlet 自 2007 以来一直存在,可以从 F5 DevCentral 下载。

您似乎可以使用 Enable-MemberDisable-Member cmdlet。

【讨论】:

  • 这是完美的。启用/禁用命令以及从此 api 方法查询 STATISTIC_SERVER_SIDE_CURRENT_CONNECTIONS:devcentral.f5.com/wiki/…
猜你喜欢
  • 2010-12-14
  • 1970-01-01
  • 2015-08-02
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
  • 1970-01-01
相关资源
最近更新 更多