當項目愈來愈龐大,部署環境愈來愈多之後,就會愈來愈依賴於自動化。好比本人公司的項目,目前有6個web和4個windows service,同時本地有兩套環境:開發自測試環境和QA測試環境。每次版本發佈,須要先部署開發自測試環境;開發人員自測試經過之後,將部署的版本部署到QA測試環境;QA測試經過之後,將本次版本打包做爲發佈版本,交給運維人員部署生產環境。web
在以往,每次本地部署的流程是:開發人員獲取最新代碼-編譯發佈-遠程鏈接部署機-上傳版本文件-備份項目-實施部署(文件覆蓋)。每次操做千篇一概,重複性很高,又很是耗時,極大影響了開發人員的工做效率。上週,我開始調研項目的自動化部署,今天搭建完畢,說下這段時間的心得。shell
調研開始,我就首先了採用Jenkins做爲操做工具,它提供了SVN/Git,MSBuild等插件,能夠知足自動獲取代碼和編譯;同時提供了完善的UI,方便操做。windows
最開始的設想,是在構建步驟中能夠經過命令行函數與操做系統交互。可是因爲咱們環境的特殊性(須要部署不一樣的環境,同時同一環境包含不止一臺服務器),單純的命令行函數沒法跨服務器執行。最後決定採用PowerShell,主要是看中它如下優勢:服務器
我選擇的PowerShell版本是V5.0。網上搜索一下安裝包,下載後在服務器安裝便可。做爲安裝PowerShell的先決條件,.Net Framework 4.5也是必須安裝的。
首先是選擇一臺獨立的自動化部署服務器,在此服務器安裝Jenkins,PowerShell。最好也把VisualStudio裝上,不然GAC會缺乏一些關鍵的類庫。此服務器須要遠程調用其它服務器的PowerShell命令,所以是個客戶端機,在安裝完PowerShell後,須要設置服務器白名單。session
PS C:\Users\53738> winrm set winrm/config/client '@{TrustedHosts="*"}'
全部的環境服務器須要安裝PowerShell,同時開啓遠程訪問運維
PS C:\Users\53738> winrm quickconfig
經過MSBuild,能夠實現.Net項目的編譯與打包。
如下是我發佈web的命令:函數
PS C:\Users\53738> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe 'xxx.csproj' /p:DeployOnBuild=true /p:PublishProfile='$($project.PublishFile)' /p:SolutionDir='$($project.SolutionDir)' /p:VisualStudioVersion=14.0
幾個參數的含義:工具
xxx.csproj:項目文件路徑測試
PublishProfile:在用VS執行發佈操做時,會生成這個文件。裏面指定了發佈操做的各類配置參數,好比發佈路徑,基於X86/X64平臺等ui
SolutionDir:解決方案文件夾
VisualStudioVersion:安裝VisualStudio時會安裝一些SDK,這個參數告訴MSBuild該去哪裏找這些SDK。因爲我安裝的是VisualStudio 2013,所以此處填寫了14.0。若是不想每次都填寫這個參數,也能夠在csproj裏面搜索這個參數名稱,填寫一個默認值。
如下是我發佈WindowsService的命令
PS C:\Users\53738> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe 'xxx.csproj' /p:SolutionDir='$($project.SolutionDir)' /p:VisualStudioVersion=14.0 /p:Platform=x64 /p:Configuration=Release
要遠程訪問服務器,首先是利用PowerShell的New-PSSession命令,填寫遠程服務器的管理員帳號密碼登錄,獲取Session
PS C:\Users\53738> New-PSSession -ComputerName RemoteComputerName -Credential Get-Credential
Get-Credential是個交互函數,執行時會彈出一個用戶名密碼對話框,所以咱們要人爲構造一個PSCredential。改寫一下方法
PS C:\Users\53738> $pass=ConvertTo-SecureString -String 'your password' -AsPlainText -Force $cre=New-Object pscredential('your username', $pass) $session=New-PSSession -ComputerName $server -Credential $cre
獲取Session之後,遠程服務器已經徹底落入咱們的掌心。如今能夠經過Invoke-Command遠程執行命令,能夠用Enter-PSSession直接進入遠程會話,能夠經過Copy-Item實現文件傳輸。如下是我在部署過程當中遇到的經常使用的命令。
遠程中止Windows Service:
PS C:\Users\53738> Invoke-Command -Session $session -ScriptBlock{ Stop-Service -Name 'your service name' }
遠程中止Web:
PS C:\WINDOWS\system32> Invoke-Command -Session $session -ScriptBlock{ $site=Get-Item 'IIS:\Sites\Your site' $site.Stop() }
拷貝本地文件到遠程服務器
PS C:\WINDOWS\system32> ls "local folder" | cp -Destination "remote folder" -ToSession $session -Recurse -Force
拷貝遠程服務器文件到本地
PS C:\WINDOWS\system32> cp -FromSession $session -Path "Remote File" -Destination "Local Folder" -Recurse -Force
將文件打包成zip
PS C:\WINDOWS\system32> Compress-Archive "Folder" -DestinationPath "Zip File Name" -Force
將zip文件解壓
PS C:\WINDOWS\system32> Expand-Archive "Zip File Name" -DestinationPath "Folder" -Force
釋放PSSession
PS C:\WINDOWS\system32> Remove-PSSession -Id $session.Id #使用完畢後必定記得釋放PSSesion
Jenkins提供了PowerShell Plugin,實現了與PowerShell的集成。可是最好修改Jenkins的服務爲以管理員用戶登陸,不然Jenkins默認以本地用戶方式調用PowerShell,在執行遠程腳本時會出現權限問題。修改方式很簡單,進入服務-右鍵Jenkins-屬性-登陸,按下圖方式配置
我在Jenkins建立了2個項目,一個用於部署研發自測試環境,一個用於部署QA測試環境。
以部署研發自測試環境爲例,整個流程大體以下:
這樣,就完成了整個項目的自動化部署,每次部署時操做人員只須要進入Jenkins站點,點擊幾下按鈕就能夠完成操做。
但願這篇文章能幫助到你們。