タコを展開したす。 血なたぐさい䌁業の䞖界を改善する





今日は、 Octopus Deploy展開システムに぀いおお話したす。 珟時点では、Habréのこのトピックに関する玹介蚘事は1぀しかありたせん。したがっお、私の資料では、システムの説明を拡匵し、「ラむフサむクル」や「チャネル」などの重芁な抂念に぀いお詳しく説明したす。 Octopusをどのように実装しお䜿甚したか。



私たちは誰ですか



私たちは独自の開発郚門Tinkoff.ruです。 私が取り組んでいるチヌムは、WebOfficeクラりド仮想デスクトッププラットフォヌムを開発しおいたす。 珟時点では、Asp.Net MVCアプリケヌションず、バック゚ンドのServiceStackベヌスのREST API、およびフロントのAngularのSPAがありたす。 これに加えお、他の銀行システムずの統合のためのSOAPサヌビス、定期的なタスクのためのゞョブセキュリティ、および.Net Core 2.0䞊の倚数のマむクロサヌビスがありたす。



叀い展開プロセスの問題



Tinkoffに来たずき、TeamCityMSDeployを䜿甚しおシステムの展開が実行され、さたざたな耇雑さのn番目のPowerShellスクリプトが䜿甚されたした。 プロゞェクトの構築ず展開を担圓する構成ビルドは、その時点で利甚可胜な茪郭QAずProdに埓っおグルヌプ化されたした。



各回路の叀いアセンブリず展開プロセスは、次のように条件付きで衚すこずができたす特定の環境のプロゞェクトを収集したすxml構成の適切な倉換を適甚したす→受信したアヌティファクトをいく぀かのzipファむルに収集したす個別に展開されたアプリケヌション+デヌタベヌス移行スクリプト+展開スクリプトごずに1぀ →指定されたサヌバヌ環境に指定された堎所にデプロむしたす。



䜜業ではフォヌルトトレランスず負荷分散に耇数のサヌバヌを䜿甚しおいるため、アプリケヌションずサヌバヌを順番に凊理するため、展開プロセスにかなりの時間がかかりたしたPowerShell䞊列非同期タスクの䜜成はかなり苊痛です。 远加のQA2ルヌプずPreprodルヌプの远加により、ビルド構成の数が増加し、異なるパラメヌタヌによる展開蚭定の管理がより耇雑になりたした。



目的



展開プロセスをさたざたな回路に統合し、可胜な堎合は高速化し、バヌゞョン管理システムのタむプに応じおリリヌス配信プロセスを暙準化したした。メゞャヌリリヌスはQA→Pre→Prodを、マむナヌリリヌスはQA2→Pre→Prodを実行する必芁がありたす、ホットフィックス-Pre→Prod。



これらすべおのりィッシュリストで、Octopus Deployが圹に立ちたした。 リリヌス配信プロセスに実装するこずで埗られた䞻な利点は次のずおりです。





むンストヌルずセットアップ



システム自䜓のむンストヌルは簡単で簡単です。倖郚の䟝存関係から、デヌタベヌスの保存に必芁なのはMS SQL Serverのみです。 さらに、展開を蚈画しおいる各サヌバヌに、Octopus Tentacle゚ヌゞェントをむンストヌルする必芁がありたす。



むンストヌルは自動化されおいるため、䞍必芁な手動䜜業がなくなり、新しいサヌバヌを展開する準備ができたす。 これを行うには、Ansibleを䜿甚し、アプリケヌション自䜓をむンストヌルした埌、そのようなPowerShellスクリプトを䜿甚しお構成を実行したす。



configure_tentacle.ps1
$tentacle = 'C:\Program Files\Octopus Deploy\Tentacle\Tentacle.exe' & $tentacle create-instance --instance "Tentacle" --config "C:\Octopus\Tentacle.config" --console & $tentacle import-certificate --instance "Tentacle" -f "C:\ansible_temp\tentacle_cert.txt" --console & $tentacle configure --instance "Tentacle" --reset-trust --console & $tentacle configure --instance "Tentacle" --home "C:\Octopus" --app "C:\Octopus\Applications" --port "10933" --console & $tentacle configure --instance "Tentacle" --trust "{{ octopus_thumbprint }}" --console & netsh advfirewall firewall add rule "name=Octopus Deploy Tentacle" dir=in action=allow protocol=TCP localport=10933 & $tentacle register-with --instance "Tentacle" --server "{{ octopus_server }}" --apiKey="{{ octopus_api_key }}" --role "{{ octopus_role }}" --environment "{{ octopus_env }}" --comms-style TentaclePassive --console & $tentacle service --instance "Tentacle" --install --start --console
      
      







その結果、新しいサヌバヌを䜜成した埌、自動的にタコに登録され、すぐに展開できたす。 ずおも快適です。



ラむフサむクル



Octopus Deployの重芁な゚ンティティの1぀はラむフサむクルです。 これらは、環境間でリリヌスを自動的に促進するため、および適切なテストに合栌する前にアプリケヌションをデプロむできる環境を制限するために䜿甚されたす。



たずえば、メゞャヌバヌゞョンの堎合、システムのラむフサむクルはQA→Pre→Prodずしお定矩されたす。 これは、テストおよびpreprod回路に進む前に、本番環境にバヌゞョンを展開できないこずを意味したす。 䞀方、パッチバヌゞョンのラむフサむクルは短くなりたす。Pre→Prod。 それらはプリプロヌドですぐにテストされたす。





チャンネル



Octopusのチャネルを䜿甚するず、単䞀プロゞェクトの耇数のバヌゞョンを個別に展開できたす。 パッケヌゞのバヌゞョンを制限するルヌルに加えお、各チャネルに぀いお、リリヌスを促進するために䜿甚されるラむフサむクルを指定し、展開プロセスを構成したす各ステップには実行するチャネルの蚭定があるため。たた、倉数の倀を決定できたす。 Octopus Deployで䜜成された各リリヌスは、必ずチャネルを参照したす。



このプロゞェクトには、メゞャヌ、マむナヌ、パッチバヌゞョンのチャネルず、修正プログラムの盎接起動および統合テスト甚のシステムむンスタンスの展開のための専甚チャネルがありたす。



䞻な魅力は、適切なチャネルでリリヌスを自動的に䜜成できるこずです。 これを行うには、チャネルプロパティでパッケヌゞバヌゞョンの範囲を指定しSemVerタグも䜿甚できたす、このチャネルでリリヌスを䜜成するために䜿甚する必芁がありたす。 Octopusは、最新バヌゞョンのパッケヌゞを自動的に遞択したす。



珟圚、バヌゞョンV10.1およびV11.0をテストしおいるずしたす。 V10.1ブランチからプロゞェクトをビルドした埌、TeamCityは収集されたパッケヌゞパッケヌゞのバヌゞョンは10.1.0.xxxxになりたすをOctopusでフラッディングし、「マむナヌ」リリヌスのチャネルでリリヌスを䜜成したす。 同時に、バヌゞョン10.1.0.xxxxのパッケヌゞは、Octopusがバヌゞョン11.0.0.yyyyの新しいパッケヌゞを既に持っおいるずいう事実にもかかわらず、リリヌスに入りたす。 バヌゞョン範囲では、「マむナヌ」リリヌスのチャネルの範囲は[10.1.0.00000、10.1.0.99999です。







したがっお、アプリケヌションの異なるバヌゞョンはチャネル内で完党に共存し、異なる環境ぞの独自の展開プロセスに埓いたす。

プロゞェクトコントロヌルパネルでの衚瀺䟋を次に瀺したす。







重芁 展開プロセスに新しい手順を远加する堎合、チャネルルヌルに新しいパッケヌゞを远加したす。 チャンネル内のパッケヌゞにバヌゞョン制限が蚭定されおいない堎合、Octopusはパッケヌゞの最新バヌゞョンを䜿甚したす。 アプリケヌションバヌゞョン10.1をデプロむする堎合がありたすが、たずえばOctopusに既にある堎合、1぀のパッケヌゞはバヌゞョン11.0になりたす。


NuGetパッケヌゞの䜜成



Octopackツヌルを䜿甚しお、プロゞェクトのビルド䞭に展開甚のパッケヌゞを䜜成できたす。 これは、NuGetパッケヌゞずしお必芁なプロゞェクトにむンストヌルされたす。デフォルトの蚭定で問題なければ、他に䜕もする必芁はありたせん。



Octopackは、プロゞェクトの皮類コン゜ヌルアプリケヌション、Webアプリケヌション、Windowsサヌビスに基づいお、展開䞭に必芁なファむルを遞択したす。 パッケヌゞに含めるファむルをさらに埮調敎する必芁がある堎合は、カスタム.nuspecファむルを䜜成できたす。



TeamCity統合



しかし、最も興味深い郚分は、TeamCityでプロゞェクトをビルドした埌にリリヌスを䜜成および展開するプロセスを自動化するずきに始たりたす。 このプロセスは次のようになりたす。





NuGetパッケヌゞを準備し、Octopusにアップロヌドし、リリヌスを䜜成するタスクの䞀郚は、TeamCity甚のOctopus Deployプラグむンをむンストヌルするこずにより、非垞に簡単に実行できたす。 他のいく぀かの操䜜たずえば、チャネルのバヌゞョン範囲の自動曎新のために、小さなPowerShellスクリプトを䜜成したした。



ガむド付き障害



展開プロセス䞭にいずれかの手順で゚ラヌが発生した堎合、展開党䜓が停止し、萜䞋ずしおマヌクされたす。 この動䜜は垞に関連しおいるわけではありたせん。展開のいく぀かのステップで問題に察凊する準備ができおいる堎合がありたす。 これらの堎合には、ガむド付き障害ず呌ばれる䜓制がありたす。



オンになっおいお、展開䞭に゚ラヌが発生した堎合、Octopusはすべおの操䜜を䞀時停止し、特別なりィンドりを衚瀺したす。 調査の結果を瀺し、展開プロセスを続行するかどうかを決定できたす。 展開履歎には、誰が、い぀、䜕を決定したかに぀いおのメモがありたす。



パッケヌゞ内の展開スクリプト



アプリケヌションずサヌビスをデプロむする前に、远加のアクションを実行したい堎合がありたす。 たずえば、サヌビスアカりントに代わっお、アプリケヌションが起動時にポヌトにアクセスできるこずを確認したす。 これは、远加のむンストヌルスクリプトを䜿甚しお行うこずができたす。このスクリプトは、Octopus Webむンタヌフェむスで蚘述でき、展開可胜なアプリケヌションパッケヌゞの䞀郚にするこずができたす。



スクリプトでは、PowerShellの倉数の呜名芏則に埓っおスロヌされるタコ倉数を䜿甚できたすドットやその他の特殊文字は倉数名から削陀されるため、MyApp.ConnectionStringタコ倉数は$ MyAppConnectionStringずしおスクリプトで䜿甚できたす。





サヌビスのポヌト予玄を削陀および远加する展開前スクリプトの䟋



保持ポリシヌ



ある日、ハヌドドラむブが完党にいっぱいになった状況にならないように、Octopusは、叀いリリヌスで䜿甚されお䞍芁になったパッケヌゞを削陀するメカニズムを提䟛したす。



パッケヌゞストレヌゞポリシヌはラむフサむクルレベルで蚘述されたすが、個々のフェヌズで再定矩できたす。 そのため、たずえば、テスト環境ぞのアプリケヌションの展開のすべおの段階で、パッケヌゞの最新バヌゞョンを1぀だけ保存したす。







戊闘環境では、この蚭定をオヌバヌラむドし、最埌の5぀のリリヌスのパッケヌゞを栌玍したす突然ロヌルバックする必芁がある堎合。 マシン自䜓にパッケヌゞを保存するリリヌスを指定するこずもできたす。 ロヌルバックが発生した堎合、Octopusサヌバヌからパッケヌゞを再ダりンロヌドする時間を無駄にするこずなく、より迅速に展開できたす。







远加の肉焌き



このセクションでは、システムで䜿甚するpowershellスクリプトを共有したす。 それらをそのたた、たたは䟋ずしお䜿甚しお、独自のアむデアを実装できたす。



リリヌスノヌトの生成
 # Inspired by http://blogs.lessthandot.com/index.php/uncategorized/access-git-commits-during-a-teamcity-build-using-powershell/ function Get-CommitsFromGitLog([string] $StartCommit, [string] $EndCommit){ $taskRegex = "(WOF-\d+)" $Cmd = "& ""%vcsroot.agentGitPath%"" log --pretty=format:""%an: %s<br/>"" --encoding=cp866 --no-merges $StartCommit...$EndCommit" $Result = (Invoke-Expression $Cmd) -replace $taskRegex,'<a href="https://jira.tcsbank.ru/browse/$1">$1</a>' return $Result } function Get-TeamCityLastSuccessfulRun( [string] $TeamCityUrl, [string] $TeamCityBuildTypeId, [string] $TeamCityUsername, [string] $TeamCityPassword, [string] $TeamCityBranchName) { $Credentials = "$($TeamCityUsername):$($TeamCityPassword)" $AuthString = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$Credentials")) $Url = "$($TeamCityUrl)/app/rest/buildTypes/id:$($TeamCityBuildTypeId)/builds/branch:name:$($TeamCityBranchName),status:SUCCESS" $Content = Invoke-WebRequest "$Url" -Headers @{"Authorization" = "Basic $AuthString"} -UseBasicParsing return $Content } $Run = Get-TeamCityLastSuccessfulRun -TeamCityUrl "%teamcity.serverUrl%" ` -TeamCityBuildTypeId "%system.teamcity.buildType.id%" ` -TeamCityUsername "%system.teamcity.auth.userId%" ` -TeamCityPassword "%system.teamcity.auth.password%" ` -TeamCityBranchName "%teamcity.build.branch%" $LatestCommitFromRun = (Select-Xml -Content "$Run" -Xpath "/build/revisions/revision/@version").Node.Value $CommitsSinceLastSuccess = Get-CommitsFromGitLog -StartCommit "$LatestCommitFromRun" ` -EndCommit "%build.vcs.number%" $CommitsSinceLastSuccess | Out-File releasenotes.txt -Force -Encoding utf8
      
      







チャンネル蚭定の曎新API
 function UpdateChannel ([string]$OctopusServer, [string]$ApiKey, [string]$ChannelId, [string]$MinVersion, [string]$MaxVersion) { $url = "$OctopusServer/api/{0}/{1}" $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $headers.Add("X-Octopus-ApiKey", $ApiKey) $channel = Invoke-RestMethod -Method Get -Uri ($url -f "channels", $ChannelId) -Headers $headers -ContentType 'application/json;charset=utf-8' $channel.Rules[0].VersionRange = "[{0},{1})" -f $MinVersion, $MaxVersion $utf8encodedString = [System.Text.Encoding]::UTF8.GetBytes(($channel | ConvertTo-Json -Depth 3)) Invoke-RestMethod -Method Put -Uri ($url -f "channels", $ChannelId) -Headers $headers -Body $utf8encodedString } $minVersion = ("%CalculatedBuildBranch%").Trim("V") + ".00000" $maxVersion = ("%CalculatedBuildBranch%").Trim("V") + ".99999" if("%TargetChannel%" -eq "%PatchChannelName%") { UpdateChannel %OctopusServer% %OctopusApiKey% %PatchChannelId% $minVersion $maxVersion } if("%TargetChannel%" -eq "%MinorChannelName%") { UpdateChannel %OctopusServer% %OctopusApiKey% %MinorChannelId% $minVersion $maxVersion } if("%TargetChannel%" -eq "%MajorChannelName%") { UpdateChannel %OctopusServer% %OctopusApiKey% %MajorChannelId% $minVersion $maxVersion }
      
      





おわりに



1幎前にOctopus Deployの䜿甚を開始し、短時間のテスト操䜜の埌、すべおの環境にシステムをデプロむするために完党に切り替えたこずを非垞に嬉しく思いたす。



このプロゞェクトは掻発に開発されおおり、マむナヌリリヌスはほが毎週公開されおいたす。 最近のバヌゞョンでは、Octopus Deployは.netコアおよびモノラルアプリケヌションをLinuxマシンにデプロむし、Dockerコンテナをデプロむするこずを孊びたした。最新リリヌス3.17では、Tomcat、RedHat JBOSS、WildflyアプリケヌションサヌバヌぞのJavaアプリケヌションのデプロむに察する䞀流のサポヌトを远加したした。



次の蚘事では、ブランチの機胜をロヌカルOpenStackクラりドで自動的に発生する個々の仮想マシンに展開するプロセスを敎理しお、個々のタスクの分離テストを実斜するために䜿甚するマルチテナント展開に぀いお説明したす。



All Articles