赞
踩
前面第6章介绍过使用pipeline编写各阶段,包括:checkout、nuget restore, Build, Publish。这些属于CI 也就是持续集成。在第9章介绍过多分支构建,本篇在6,9章基础上继续。
后续还需要的阶段包括:pack(打包),根据分支不同上传到不同的服务器再执行脚本部署,这些属于CD 也就是持续部署。
本节重点讲如何打包zip上传到目标服务器。使用 Publish Over SSH插件来实现。
准备工作包括:
1)用到的工具:PowerShell Server 2020
2)Jenkins插件:Publish Over SSH
2)部署环境:windows客户端(是jenkins本机属于内网)到windows服务端(iis目标服务器阿里云 windows server 2016) ip为131
3)生成秘钥
在jenkins本机上,cmd命令窗口中,使用ssh命令,必须先安装了OpenSSH
安装下载介绍: https://docs.microsoft.com/zh-cn/windows-server/administration/openssh/openssh_install_firstuse
步骤1 生成秘钥命令如下所示,其中 passphrase为1234567
- C:\Users\AndyH>ssh-keygen -t rsa
- Generating public/private rsa key pair.
- Enter file in which to save the key (C:\Users\AndyH/.ssh/id_rsa):
- C:\Users\AndyH/.ssh/id_rsa already exists.
- Overwrite (y/n)? y
- Enter passphrase (empty for no passphrase):
- Enter same passphrase again:
- Your identification has been saved in C:\Users\AndyH/.ssh/id_rsa.
- Your public key has been saved in C:\Users\AndyH/.ssh/id_rsa.pub.
- The key fingerprint is:
- SHA256:tafBvaPd9LH9WOQDSdpBtS5Q6N+Zt6U7d50bhPXmp6Q mogultech\andyh@AndyH
步骤2 公钥文件复制到131目标服务器
远程连接到目标服务器,将id_rsa.pub文件复制到目标服务器(自己选择存放目录),我这里放的位置是C:\Users\Administrator\.ssh\id_rsa.pub
Publish Over SSH是jenkins插件,主要的功能有两个:
把jenkins本机上的文件,传输到远程iis服务器的指定目录。
远程执行bat命令和脚本。
安装后如下所示:
官方解释:很容易安装和配置SSH 2.0服务器,使您能够从任何SSH客户端远程管理窗口,添加一个SFTP服务器窗口,和安全的远程访问本地资源。
下面解释一下服务端与客户端: 服务端是要部署的目标服务器131,需要安装powershell Server 2020。而jenkins要自动化部署到目标服务器,所以jenkins本机是客户端,需要安装Publish Over SSH插件。
目标服务器下载PowerShell Server 2020 试用版下载:https://www.nsoftware.com/powershell/server/download.aspx
安装后,打开默认如下所示
为了Jenkins不乱码,选择gb2312,并且log Mode选择"Verbose" 原因是能看到更多日志信息,帮助排错, 如下所示:
接着再设置SFTP目录,也是就jenkins要上传打包文件.zip的目录
接着配置公钥Key,这里的key目录是上面2.2中已存放好的目录,并启动。
这里的目的:确保连够连接到目标服务器131
Manger Jenkins-->System Configuration-->Configure System
配置好后(秘钥密码是:1234567),进行测试成功,表示jenkins本机ssh已连接上了目标服务器131,如下所示
在131目标服务器的PowerShell Server中查看日志如下所示:
在前面第9章中,学习到了多分支构建,job项目为multibranch-jenkenhellowrold,下面包括master分支和develop分支, 上面目标服务器131用于部署master分支。在multibranch-jenkenhellowrold项目中进行配置。
配置路径:multibranch-jenkenhellowrold-->流水线语法-->片断生成器-->下拉中选择sshPublisher:Send build artifacts over SSH
最后点击“生成流水线的脚本” 放入jenkinsfile文件中,配置的解释看下面介绍
https://www.cnblogs.com/zongyl/p/9157488.html
Publish Over SSH | Jenkins plugin
- def packzipFileName //定义打包的文件名称 整个流水线共享变量,注意首行def定义的变量不能使用=赋值。
-
- pipeline {
-
- agent any
- options{
- //pipeline超时时间
- timeout(time:10, unit:'MINUTES')
- //pipeline重试次数
- retry(1)
- //同一个pipeline,禁止同时执行
- disableConcurrentBuilds()
- //daysToKeepStr保持构建的天数,numToKeepStr保持构建的最大个数
- buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '3', numToKeepStr: '10')
- }
-
- environment{
- publishOutput='./jenkenhellowrold/JenkinsBuilds/' //编译后发布的路径是指:C:\Users\AndyH\AppData\Local\Jenkins\.jenkins\workspace\branch-jenkenhellowrold_master_2\jenkenhellowrold
- }
- stages {
- stage('NuGet Restore') {
- steps {
- echo 'NuGet Restore Begin'
- //restore会从解决方案或项目的根目录寻找 NuGet.config 文件,如果找不到,则会使用全局的 NuGet.config,也可以自己指定NuGet.config路径
- //还可以是还原项目如:dotnet ./jenkenhellowrold/jenkenhellowrold.csproj
- //-nowarn不显示警告
- bat 'dotnet restore -nowarn:msb3202,nu1503,cs1591 jenkenhellowrold.sln'
- //清理解决方案中所有生成的文件,如obj和bin件
- bat 'dotnet clean --nologo jenkenhellowrold.sln'
- echo 'NuGet Restore End'
- }
- }
-
- stage('Bulid Project'){
- steps{
- echo 'Bulid Project Begin'
- //生成项目及其所有依赖项
- bat 'dotnet build -nowarn:msb3202,nu1503,cs1591 --no-restore jenkenhellowrold.sln'
- echo 'Bulid Project End'
- }
- }
- stage('Publish'){
- steps{
- echo 'Publish Begin'
- script
- {
- //每次先删除之前的所有发布文件
- def publishOutputdir= env.publishOutput.replace("/","\\");
- def exist=fileExists(publishOutputdir)
- if(exist==true){
- //echo "publishOutputdir:${exist}"
- bat 'rd /S/Q '+publishOutputdir
- }
- def output=env.publishOutput+env.GIT_BRANCH+env.BUILD_NUMBER
- // echo "${output}"//使用变量时用双引号
- //--nologo不显示启动版权标志或版权消息,。netcore 3.0可用
- //-c|--configuration 指定是Debug或Release
- bat 'dotnet publish --nologo -nowarn:msb3202,nu1503,cs1591 --no-restore ./jenkenhellowrold/jenkenhellowrold.csproj -c Release -o '+output
- }
- echo 'Publish End'
- }
- }
- stage('Pack zip')
- {
- steps{
- echo 'Pack zip Begin'
- script
- {
- //定义打包的文件名
- packzipFileName=env.GIT_BRANCH+env.BUILD_NUMBER+".zip"
- //echo "aaaaa${packzipFileName}"
- def packOutput=env.publishOutput.replace("/","\\")
- //需要压缩的地址文件
- def rarInFile=packOutput+env.GIT_BRANCH+env.BUILD_NUMBER
- //压缩后存放的地址文件
- def rarOutFile=packOutput+'\\pack\\'
- def exist=fileExists(rarOutFile)
- //echo "${exist}"
- if(exist==false){
- bat 'md '+rarOutFile
- }
- //打包前删除配置文件
- delFilesForWeb = ["web.config","appsettings.json","appsettings.Development.json"] as String[] //需要删除的文件
- delFilesForWeb.each{
- echo 'del file:'+it
- bat 'del /f/q '+ rarInFile+'\\'+it
- }
- //rar 文件路径已添加到jenkins全局配置中,本机路径 D:\Program Files\WinRAR a代表备份所有文件 ep是排除路径
- bat env.RAR_PATH+' a -r -ep ' +rarOutFile+packzipFileName+' '+rarInFile
- }
- echo 'Pack zip End'
- }
- }
- stage('Deploy To Dev'){
- when{
- branch 'develop'
- }
- steps{
- echo "Deploy To Dev"
- }
- }
- stage('Deploy To pro131'){
- when{
- branch 'master'
- }
- steps{
- echo "Deploy To pro131 Begin"
- //配置时有的目录是指jenkins服务器上的,有些是指目标服务器上的如131服务器
- //remoteDirectory: 131服务器目录文件夹,不存在会自动创建,服务器安装了PowerShell Server并指定的SFTP目录
- //removePrefix:上传到131服务器目录时,这里是移出多层目录,最终上传目录层次是:C:\SFTP\jenkenhellowrold\master56.zip
- //sourceFiles:填写jenkins服务器相对路径,根目录是C:\Users\AndyH\AppData\Local\Jenkins\.jenkins\workspace\branch-jenkenhellowrold_master_2
- //remoteDirectorySDF:true 远程目录使用日期格式,那么remoteDirectory也要配置格式
- //execCommand:转输文件后(.zip),要在131服务器执行的bat文件,这里指定服务器存放bat文件的目录
- sshPublisher(publishers: [sshPublisherDesc(configName: 'remote_131', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:"cmd /c call C:/SFTP/jenkenhellowrold/deploy.bat ${packzipFileName}", execTimeout: 120000, flatten: false, makeEmptyDirs: true, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/jenkenhellowrold', remoteDirectorySDF: false, removePrefix: '/jenkenhellowrold/JenkinsBuilds/pack', sourceFiles: '**/JenkinsBuilds/pack/*', useSftpForExec: false)], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
- echo 'Deploy To pro 131 End'
- }
- }
- }
- post{
- failure{
- echo 'ִfail send email'
- }
- success
- {
- echo 'ִsuccess send email'
- }
- }
- }
ssh execCommand要执行的131上deploy.bat文件 如下所示:
- @echo off
- rem 该文件需要放入目标服务器, 用于jenkinfile文件的ssh execCommand 执行路径, cmd模拟执行:deploy.bat master146.zip
- rem 停止iis应用程序池和站点
- "C:\Windows\System32\inetsrv\appcmd.exe" stop apppool /apppool.name:"jenkinshelloworld"
- "C:\\Windows\\System32\\inetsrv\\appcmd.exe" stop site jenkinshelloworld
- rem 目标服务器是用的winrar解压
- "C:\Program Files\WinRAR\WinRAR.exe" X -o C:\SFTP\jenkenhellowrold\%1 C:\IIS\jenkinshelloworld
- rem 启动iis应用程序池和站点
- "C:\Windows\System32\inetsrv\appcmd.exe" start apppool /apppool.name:"jenkinshelloworld"
- "C:\\Windows\\System32\\inetsrv\\appcmd.exe" start site jenkinshelloworld
- exit 0
查看日志重点的信息列出来
- SSH: Connecting from host [AndyH]
- SSH: Connecting with configuration [remote_131] ...
- SSH: EXEC: completed after 401 ms
- SSH: Disconnecting configuration [remote_131] ...
- SSH: Transferred 1 file(s)
- SSH: Transferred 1 file(s) 1代表上传到目标服务器一个文件
-
1)jenkins服务器发布的目录,pack是打包存放文件夹,每次构建前都会先删除JenkinsBuilds下所有文件
2.目标服务器131上传的文件,deploy.bat文件作用:解压每次构建的.zip文件,解压到iis站点目录中
最终源码地址:https://git.code.tencent.com/Studies/pipeline-hello-world.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。