简体   繁体   English

自动部署到 F5 负载平衡环境

[英]Automated Deployment to an F5 Load Balanced Environment

We are currently using TeamCity for CI builds and we are trying to set up automated deployments as well.我们目前正在使用 TeamCity 进行 CI 构建,并且我们也在尝试设置自动化部署。

The project I'm currently trying to deploy is a Windows service that sits under an F5 load balancer.我目前正在尝试部署的项目是位于 F5 负载均衡器下的 Windows 服务。 In the future we would also like to automate the deployment of our IIS websites which also sit under the F5.将来,我们还希望自动部署同样位于 F5 下的 IIS 网站。

From TeamCity we can execute PowerShell scripts to unistall the windows service on the desired server, push our files to it, then reinstall the service.在 TeamCity 中,我们可以执行 PowerShell 脚本来卸载所需服务器上的 Windows 服务,将我们的文件推送到它,然后重新安装该服务。

However, I'm having trouble figuring out how to deal with the load balancer.但是,我无法弄清楚如何处理负载均衡器。 We would want to disable 1 node at a time, watch for all the connections to drop, then deploy our code and bring the node back up.我们希望一次禁用 1 个节点,观察所有连接断开,然后部署我们的代码并重新启动节点。

This seems like it would be a very common issue, but I'm finding surprisingly little information about how to do it.这似乎是一个非常普遍的问题,但我发现关于如何做到这一点的信息令人惊讶地少。

Thanks!谢谢!

Answered已回答

Thanks Jonathon Rossi for the iControl Powershell cmdlets!感谢 Jonathon Rossi 提供 iControl Powershell cmdlet!

For other users' sakes, here is a sample of shutting down, monitoring for connections to drop, pushing code, and then turning back on the F5 load balancer through a powershell script为其他用户着想,这里有一个关闭、监控连接断开、推送代码,然后通过 powershell 脚本重新打开 F5 负载均衡器的示例

For these scripts to work you will first have to install the F5 iControl cmdlets from the links provided in the Answer below要使这些脚本正常工作,您首先必须从以下答案中提供的链接安装 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

And here is the reusable F5Functions script这是可重用的 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
}

I haven't used it, but have you looked at the F5 iControl web service API and the F5 iControl PowerShell cmdlets provided by F5.我没用过,但是你看过 F5 提供的F5 iControl Web 服务 API 和F5 iControl PowerShell cmdlet The PowerShell cmdlets have been around since 2007 and can be downloaded from F5 DevCentral . PowerShell cmdlet 自2007 年以来一直存在,可以从F5 DevCentral下载。

It looks like there are Enable-Member and Disable-Member cmdlets that you'll be able to use.看起来您可以使用Enable-MemberDisable-Member cmdlet。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM