我們目前正在使用TeamCity進行CI構建,我們也嘗試設置自動化部署。自動部署到F5負載平衡環境
我目前正試圖部署的項目是一個位於F5負載平衡器下的Windows服務。在未來,我們還希望自動部署我們也位於F5下的IIS網站。
從TeamCity中,我們可以執行PowerShell腳本來取消所有服務器上的Windows服務,將文件推送到它,然後重新安裝服務。
但是,我很難弄清楚如何處理負載平衡器。我們希望一次禁用1個節點,注意所有連接的丟棄,然後部署我們的代碼並使節點恢復。
這看起來似乎是一個非常普遍的問題,但我卻發現了關於如何去做的驚人的小信息。
謝謝!
回答
感謝喬納森·羅西爲的iControl PowerShell命令!
對於其他用戶的緣故,這裏是關停,監測連接砸,推碼,然後通過PowerShell腳本
這些腳本工作,你義無反顧的F5負載均衡器的樣品首先必須從安裝在回答以下
#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
提供的鏈接F5的iControl cmdlet和這裏是可重複使用的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
@Kiquenet - 在「已答覆」標題下的上面的代碼片段是我們用來每天約5到10次將代碼部署到生產中的代碼片段。第二個代碼塊是由第一個代碼塊加載的模塊,這是如何使用該模塊的示例。唯一需要填寫的部分是在F5節點關閉時移動文件(移動文件,解壓縮,停止服務,重新啓動服務等)時實際執行的操作。請原諒不良的命名約定。當我寫這篇文章時,我剛剛接觸PowerShell。 – Michael
實際上,當我重新閱讀我的舊帖子時,我發現它比最終產品要成熟得多。 1.我將F5 funcitons腳本移動到安裝在構建服務器上的powershell模塊中,並使用Load-Module加載它。2. DeployToNodes函數應該爲ScriptBlock提供ScriptBlock和參數數組,而不是假定Deploy功能在其他地方聲明 3.功能應遵循動詞 - 名詞命名約定 4。我把更多的邏輯放在節點上,所以它會一次減少一半,允許sql遷移發生在中間 – Michael