当项目愈来愈庞大,部署环境愈来愈多之后,就会愈来愈依赖于自动化。好比本人公司的项目,目前有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站点,点击几下按钮就能够完成操做。
但愿这篇文章能帮助到你们。