Jenkins持续部署-Windows环境持续部署探究1
Jenkins持续部署-Windows环境持续部署探究1
目录
Jenkins持续集成学习-Windows环境进行.Net开发1
Jenkins持续集成学习-Windows环境进行.Net开发2
Jenkins持续集成学习-Windows环境进行.Net开发3
Jenkins持续集成学习-Windows环境进行.Net开发4
Jenkins持续集成学习-搭建jenkins问题汇总
Jenkins持续部署-Windows环境持续部署探究1
前言
在之前的文章中,对Windows环境下的持续集成方案进行探究,接下来对Windows环境下持续部署的方案进行学习与研究。
目的
当jenkins集成编译成功后,将文件上传到指定的服务器FTP目录。本文将介绍关于持续部署需要的一些技术方案的实现,在后续文章中继续对持续集成具体的逻辑进行细化梳理。
方案流程
当jenkins编译完成之后,我们需要处理以下事项完成持续部署。
打包文件
打包文件 -.-> 上传到服务器
上传到服务器 -.-> 关闭原服务
关闭原服务 -.-> 升级服务
升级服务 -.-> 启动服务
``` -->
- jenkins编译成功,则将所有的exe和dll文件先压缩打包,文件名可以命名为Job名称或者版本号
- 压缩完成后将压缩文件上传到指定的FTP
- 上传完成后,则需要关闭服务器上的指定服务
- 关闭完成后替换原始的程序目录下的文件
- 启动服务
这里暂时不探讨服务可用性的具体细节,也不讨论服务升级失败的回退工作等具体细节。
技术实现
可以分析出上述流程中涉及到的技术要点。
- 调用脚本对指定的文件进行压缩,在windows上使用PowerShell执行脚本再合适不过了。
- 通过FTP上传到服务器,可以通过jenkins的FTP插件或者通过PowerShell脚本将文件上传到指定服务器上。
- 关闭服务器上的指定服务,这里就需要支持远程调用,在windows上可以通过winrm执行远程服务调用。
PowerShell
Windows PowerShell 是专门为系统管理员设计的 Windows 命令行 Shell。 Windows PowerShell 包括可以单独或组合使用的交互提示和脚本编写环境。这里不探讨PowerShell的使用细节,因为这不是本篇文章的关注重点,具体的关于PowerShell的介绍可以看微软的官方文档Windows PowerShell 入门
由于各种因素限制,因此在后续文章中的PowerShell脚本都是在`PowerShell 2.0`上执行的,而`PowerShell 2.0`是基于`Microsoft.NET framework 3.5`,从`PowerShell 3.0`开始则是基于`Microsoft.NET framework 4`。本篇文章编写时,最新的PowerShell脚本为`PowerShell 6`以及`PowerShell core`。具体关于`PowerShell`不同版本的问题可以查看[安装 Windows PowerShell 2.0 引擎](https://docs.microsoft.com/zh-cn/powershell/scripting/install/installing-the-windows-powershell-2.0-engine?view=powershell-6) -->
FTP上传插件
jenkins上有支持的FTP插件,比如Publish Over FTP Plugin,下载之后安装重启jenkins。
插件配置
在系统管理-系统设置下找到Publish over FTP
项的设置,添加FTP服务的地址,端口,用户名和密码等相关配置,然后点击TestConfiguration
按钮,若显示Success表示配置成功。可以手工添加多个FTP配置。
点击Advanced
按钮修改端口或超时时间等配置
配置完成后到Job中添加FTP上传功能,在Build
中点击Add Build step
选择Send file over FTP
在Name
通过下拉选择前面配置的FTP站点,在Transfers
配置需要上传的文件和上传到远程的目录。
Source files
:支持通配符,如上传所有文件*.*
,或bin/Release/
下的所有文件
Remove prefix
:表示上传文件去除前缀,FTP默认会将文件的相对路径一起上传,若不需要bin/Release
则可以配置去除该相对路径,如bin/Release/Test.exe
上传到FTP上若没有指定FTP远程相对路径,则为FTP根目录下的Test.exe
文件。
Remote directory
:表示上传到FTP目录下的哪个相对目录中,一般来说我们可以按Job名称分文件夹,可以通配置Jenkins内置的环境变量,如$JOB_NAME
/
上传FTP前需要保证FTP上目录结构存在,否则会上传失败。因此上传FTP前需要通过脚本到服务器的FTP目录上创对应的文件夹路径。
一般来说我们编译完成后需要将程序按版本号分目录存在,比如1.0.X的存放到1.0的目录中。2.0.X的存放到2.0的目录中。因此我们可以在Remote directory
填写${JOB_NAME}/$PROCESS_VERSION
,如下图所示
而$PROCESS_VERSION
变量的值我们需要在前面的脚本中获取,由于在jenkinsBuild
步骤中创建的每个powershell脚本块,jenkins都会将其保存到临时的XXXX.ps1
脚本文件中,因此不同的步骤产生的变量是在不同的脚本文件中,也就是在不同的作用域中。因此在前面创建的脚本获取到的版本号,无法直接在下一个脚本中获取。
关于powershell的变量作用域可以查看Powershell变量的作用域。
如下图所示,第一个脚本中赋值的$PROCESS_VERSION
在后面的脚本以及FTP目录中都是获取不到该变量的。
因此我们可以通过将变量保存到文件,然后重新载入到Jenkins的环境变量中,Jenkins的环境变量在Jenkins当前Job中都可以获取到。
环境变量插件
使用Jenkins的环境变量插件EnvInject Plugin实现上述功能。安装完插件之后重启Jenkins。
如果我们多个Job需要用到同样的参数常量,那我们可以将参数直接在Jenkins配置中注入到环境变量中,然后可以通过环境变量$Env:XXXX
获取到我们配置的变量值。
配置全局环境变量
在系统管理-系统设置下找到Global properties
项,勾选环境变量,后即可设置全局的环境变量。这样当这些变量修改后,只需要在设置中修改一次,而无需修改每个Job中的脚本变量值。
使用环境变量
我们现在可以直接在Job中使用配置好的全局环境变量。在构建之后,可以在当前构建项的Environment Variables
查看到已加载的环境变量
、
从文件注入环境变量
现在我们就可以将将版本号信息存入到文件中,然后重新加载到全局环境变量中了。
首先在通过脚本获取到程序的版本号,将它保存到文件中,保存格式为变量名=变量值
,如将PROCESS_VERSION="1.0.0.0"
保存到Version.txt
文件中。
然后通过环境变量注入插件从文本中读取环境变量,在Build
中添加Inject environment variables
步骤,在Properties File Path
中填写Version.txt
,则会从文本中读取环境变量,多个环境变量通过换行分割。
默认PowerShell保存的格式是含有BOM的Unicode编码,而Jenkins读取ASCII编码格式。因此需要指定文本输出编码为ASCII
脚本执行
通过Powershell脚本也可以调用.Net库将文件压缩或上传,这里暂时不讨论脚本编写细节问题。后续文章将给出完整的解决方案。
远程调用
在Linux环境下可以通过SSH进行远程调用,而在Windows环境下则可以使用Windows 远程管理 (Windows Remote Management,简称WinRM)。
WinRM是微软实现的WS-Management协议的, 这是一种基于标准的简单对象访问协议(SOAP), 由于它是基于防火墙友好的协议, 因此允许来自不同供应商的硬件和操作系统交互。关于WinRM具体的介绍可以查看Windows Remote Management
我们可以理解为WinRM提供了一个服务端,同时向外暴露了相关的API,而同时Powershell可以与WinRM进行交互,即Powershell本身就是一个远程调用的客户端,通过Powershell执行相关的命令与WinRM交互,从而实现远程调用,执行自定义脚本,甚至是执行服务器上的指定路径下的脚本。
因此我们若需要进行远程调用,首先在对应的服务器上需要开启WinRM的相关功能。
启用WinRM服务
快速配置
微软为了简化WinRM的配置,提供了一个快捷命令进行默认的快速配置。通过调用
winrm quickconfig
进行快速配置。也可以跳过该步骤,直接运行第二步骤开启WinRM服务。
如下返回则为正常配置成功
PS C:\Users\Administrator> winrm quickconfig
在此计算机上,WinRM 已设置为接收请求。
WinRM 没有设置成为了管理此计算机而允许对其进行远程访问。
必须进行以下更改: 在 HTTP://* 上创建 WinRM 侦听程序接受 WS-Man 对此机器上任意 IP 的请求
启用 WinRM 防火墙异常。
配置 LocalAccountTokenFilterPolicy 以远程向本地用户授予管理权限。 进行这些更改吗[y/n]? y WinRM 已经进行了更新,以用于远程管理。 在 HTTP://* 上创建 WinRM 侦听程序接受 WS-Man 对此机器上任意 IP 的请求
WinRM 防火墙异常已启用。
已配置 LocalAccountTokenFilterPolicy 以远程向本地用户授予管理权限。
需要注意的是,在我本地win10环境,无法执行快速配置,提示说网络连接类型是公用。
PS C:\Users\Dm_ca> winrm quickconfig
已在此计算机上运行 WinRM 服务。
WSManFault
Message
ProviderFault
WSManFault
Message = 由于此计算机上的网络连接类型之一设置为公用,因此 WinRM 防火墙例外将不运行。 将网络连接类型更改为域或专用,然后再次尝试。 错误编号: -2144108183 0x80338169
由于此计算机上的网络连接类型之一设置为公用,因此 WinRM 防火墙例外将不运行。 将网络连接类型更改为域或专用,然后再次尝试。
通过
Get-NetConnectionProfile
命令可以看到网络类型(和网络和Internet设置中看到的是一样的)其中NetworkCategory : Public
即显示该网络的种类。PS C:\WINDOWS\system32> Get-NetConnectionProfile Name : Seven
InterfaceAlias : WLAN
InterfaceIndex : 17
NetworkCategory : Private
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic Name : 未识别的网络
InterfaceAlias : vEthernet (Default Switch)
InterfaceIndex : 29
NetworkCategory : Public
IPv4Connectivity : NoTraffic
IPv6Connectivity : NoTraffic
通过管理员权限运行
Set-NetConnectionProfile -NetworkCategory Private
将所有网络设置为专用网络类型后
再次尝试快速配置。PS C:\WINDOWS\system32> Set-NetConnectionProfile -NetworkCategory Private
PS C:\WINDOWS\system32> Get-NetConnectionProfile Name : Seven
InterfaceAlias : WLAN
InterfaceIndex : 17
NetworkCategory : Private
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic Name : 未识别的网络
InterfaceAlias : vEthernet (Default Switch)
InterfaceIndex : 29
NetworkCategory : Private
IPv4Connectivity : NoTraffic
IPv6Connectivity : NoTraffic
winrm qc是winrm quickconfig缩写
启用远程服务
通过输入
Enable-PSRemoting –Force
启用Powershell远程调用功能。若没有-Force
会有若干选项需要你进行确认。输入了-Force
则自动会确认,建议带上该参数。PS C:\Users\Administrator> Enable-PSRemoting –Force
在此计算机上,WinRM 已设置为接收请求。
WinRM 已经进行了设置,以用于在此计算机上进行远程管理。
若第一步骤
winrm qc
存在网络类型为公网无法进行配置时,当前命令添加SkipNetworkProfileCheck
跳过网络类型检查,完整命令为Enable-PSRemoting -SkipNetworkProfileCheck -Force
。若输入
Enable-PSRemoting
,则可以不再输入winrm qc
进行配置。前者做的工作已经包含了后者所做的所有工作。查看WinRM服务监听
通过
winrm enumerate winrm/config/listener
可以查看WinRM服务的当前监听信息PS C:\Users\Administrator> winrm enumerate winrm/config/listener
Listener
Address = *
Transport = HTTP
Port = 5985
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
ListeningOn = 10.60.45.239, 127.0.0.1, XXXXXXXXXXX
若上一步WINRM配置没有成功,则会返回以下信息
PS C:\Users\Dm_ca> winrm enumerate winrm/config/listener
WSManFault
Message
ProviderFault
WSManFault
Message = 拒绝访问。
启用Powershell本地脚本执行
若需要在服务上执行本地脚本,则需要启用本地脚本执行权限。通过执行
set-ExecutionPolicy RemoteSigned
允许本地脚本执行。PS C:\Users\Administrator> set-ExecutionPolicy RemoteSigned 执行策略更改
执行策略可以防止您执行不信任的脚本。更改执行策略可能会使您面临 about_Execution_Policies
帮助主题中所述的安全风险。是否要更改执行策略?
[Y] 是(Y) [N] 否(N) [S] 挂起(S) [?] 帮助 (默认值为“Y”): y
获取winrm客户端配置信息
通过上述4个步骤,服务端的远程调用已经开启,由于winrm本身有白名单安全策略,因此需要配置以下客户端的配置,允许指定的ip执行远程调用。通过输入
winrm get winrm/config/client
获取客户端配置。PS C:\Users\Administrator> winrm get winrm/config/client
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false
Auth
Basic = true
Digest = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts
Get-Item WSMan:\localhost\Client\TrustedHosts
效果也一样。设置白名单地址
TrustedHosts
表示的是白名单地址。
通过Set-Item wsman:\localhost\client\trustedhosts *
设置允许所有IP调用。
通过Set-Item wsman:\localhost\client\trustedhosts "127.0.0.1,127.0.0.2"
设置允许指定IP调用cmd
下可以输入winrm set winrm/config/client @{TrustedHosts="*"}
,测试了powershell下不支持该命令Set-Item wsman:\localhost\client\trustedhosts "127.0.0.1,127.0.0.2" WinRM 安全配置。
此命令修改 WinRM 客户端的 TrustedHosts 列表。TrustedHosts
列表中的计算机可能不会经过身份验证。该客户端可能会向这些计算机发送凭据信息。是否确实要修改此列表?
[Y] 是(Y) [N] 否(N) [S] 暂停(S) [?] 帮助 (默认值为“Y”): y
PS C:\WINDOWS\system32> winrm get winrm/config/client
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false
Auth
Basic = true
Digest = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts = 127.0.0.1,127.0.0.2
客户端远程调用
当设置好上述配置我们就可以测试以下远程调用是否完成,通过在d盘放一个
hellworld.ps1
脚本,填写以下内容。hello world!
然后就可以在本地powershell中输入以下指令测试远程调用是否正常返回hello world!
$account = "administrator"
$password = "test1"
$address="127.0.0.1"
$secpwd = convertto-securestring $password -asplaintext -force
$cred = new-object System.Management.Automation.PSCredential -argumentlist $account,$secpwd
invoke-command -computername $address -Credential $cred -command {d:helloworld.ps1}
- 其中需要输入服务器的用户名和密码。通过
convertto-securestring
将明文密码转换为安全字符串,这样避免了明文密码在网络上传输泄露。 - 然后通过用户名和密码创建一个身份授权对象。
- 最终通过
invoke-command
将服务器地址传入以及授权对象传入即可执行远程脚本调用。
想更详细的了解启用远程服务的细节可以查看Enable Powershell Remoting
需要注意的是,若使用域账户用户名进行远程调用时,用户名需要使用
域名\用户名
,而使用非域账户用户名进行远程调用时,用户名需要使用\用户名
。否则可能出现如下的错误信息
比如我要远程登录的用户是非域用户,用户名为administrator
,则使用\administrator
。域账号是把帐号存储于域中的某一台服务器,分享给同一个域中的所有计算机使用。
- 其中需要输入服务器的用户名和密码。通过
升级服务
通过powershell与winrm实现远程调用,服务升级就是将上传到FTP的程序替换原有的程序即可。
启动服务
这里需要说明的一点是,控制台程序和含有GUI界面的程序可以通过调用命令杀掉进行实现关闭程序,但是要通过powershell启用相关的控制他程序或含有用户界面的程序,则很难做到。主要原因是在windows环境下远程命令执行和登录windows用户一样,都是基于会话执行。在Windows安全模型设计上,是不支持启动其他会话的程序。相关问题可以查看Use Powershell to start a GUI program on a remote machine。
换句话说,在会话连接释放时,则会自动注销会话相关的资源。因此当WinRM远程调用结束后则会释放临时会话资源。
为了实现启用GUI程序,可以使用PsExec。PsExec 是一款轻量级的远程替换设备, 可让您在其他系统上执行进程, 并为控制台应用程序提供完整的交互功能, 而无需手动安装客户端软件。对于PsExec具体使用暂时没有验证过,有时间后面再做探讨,这里不进行深究。
另一种方案是Powershell所能实现的是,基于Windows的定时任务,可以设定在1分钟后启动GUI的exe文件。(Windows任务最小时间单位是1分钟)实际上来说服务中断1分钟可不是好事,虽然能实现启动服务,但是不建议使用,不做过多探讨。
最好的方式是将服务器上的程序注册为Windows服务,那么就很好的支持服务的关闭和启动。
总结
本文对Windows下的持续部署方案所设计到相关的技术进行了简单介绍,后续的持续集成将完全使用本篇文章设计到的Powershell脚本和远程调用相关技术实现,后续持续集成唯一的要点就是持续集成逻辑的脚本编写。在后续文章中,将会介绍powershell的压缩解压,ftp脚本上传,以及通过脚本生成差量更新包等具体工作。
- Windows PowerShell 入门
- Powershell变量的作用域
- Windows Remote Management
- windows服务器远程执行命令(PowerShell+WinRM)
- winServer-常用winrm命令
- Use Powershell to start a GUI program on a remote machine
- Enable Powershell Remoting
- Enabling PowerShell remoting fails due to Public network connection type
- Automating with Jenkins and PowerShell on Windows - Part 2
微信扫一扫二维码关注订阅号杰哥技术分享
本文地址:https://www.cnblogs.com/Jack-Blog/p/10922038.html
作者博客:杰哥很忙
欢迎转载,请在明显位置给出出处及链接
Jenkins持续部署-Windows环境持续部署探究1的更多相关文章
- docker部署-windows环境
docker部署-windows环境 1. docker windows 1.1. 安装 win7或者win8需要利用docker toolbox来安装,其是一个docker工具集,w ...
- 在Windows环境下部署Axis2/C服务
Apache Axis2/C是C语言实现的网络服务引擎,基于Axis2架构,支持SOAP1.1和SOAP1.2协议,并且支持RESTful风格的Web service. 下面是本人在Windows 7 ...
- Windows环境下部署Tomcat服务器图文教程
Tomcat是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选. 本文将详细介绍在Windows环境下 ...
- Django Windows环境下部署
环境准备 本文将介绍如何在Windows系统上部署Django web项目,本次部署基于下面的架构: Windows10 64位+Python3.6+Django1.11+Apache2.4+mod_ ...
- Yapi接口管理平台 本地部署 windows环境 -
YApi 是高效.易用.功能强大的 api 管理平台,旨在为开发.产品.测试人员提供更优雅的接口管理服务.可以帮助开发者轻松创建.发布.维护 API,YApi 还为用户提供了优秀的交互体验,开发人员只 ...
- jenkins maven git windows code 自动部署
本人刚刚接触 写的不好就对付看看吧 哈哈哈O(∩_∩)O哈哈~ 最近看见别人弄得自动部署 自己也是手痒痒 也想弄一个 所以就弄了一个 windows的 我用的是https的 在网上看了很多都是 s ...
- 在windows环境下部署nuxt项目(线上发布部署)
因为公司项目需要兼容SEO,同时我们也一直希望能够真正的实现前后端分离,于是毫不犹豫的选择了nuxt. 话说要重构前后端分离真是一个大工程,由于各种原因我们团队花了近两年时间都没有完成,最近才又重启把 ...
- 【Azure 应用服务】App Service For Windows 环境中部署Python站点后,如何继续访问静态资源文件呢(Serving Static Files)?
问题描述 当创建一个App Service 后,运行时环境和版本选择Windows 和 Python 3.6. 登录Kudu 站点查看,默认的文件有 web.config, hostingstart- ...
- jenkins介绍及部署tomcat环境、部署Maven项目及密码忘记修改
安装配置jenkins: jenkins安装方式一:war包 1.先安装tomcat将jenkins,war直接放到webapps目录下 2.通过java-jar jenkins.war --http ...
随机推荐
- Java--容器/集合类(Collection)理解和使用
.数组和集合的比较 数组:长度固定,用来存放基本类型的数据 集合:长度不固定,用来存放对象的引用 二.集合类的基本概念 1.java.util包中提供了一些集合类,这些集合类也被称为容器. 常用的集合 ...
- 【meet in middle】poj1840Eqs
震惊!map的常数居然如此之大 Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43 ...
- 用python实现自动玩21点小游戏
1. 背景 前段时间发现一个论坛上(https://npupt.com/blackjack.php)有21点小游戏. 这个21点小游戏的规则是每个人开局都会获得随机点数,如果觉得点数小,可以继续摸牌. ...
- The Three Day
函数基础-练习 #.写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批了修改操作 # def modify_file(filename,old,new): # import os # w ...
- ajax以及文件上传的几种方式
方式一:通过form表单中,html input 标签的“file”完成 # 前端代码uoload.html <form method="post" action=" ...
- selenium.common.exceptions.WebDriverException: Message: u'unknown error: cannot get automation extension\nfrom unknown error: page could not be found: chrome-extension://aapnijgdinlhnhlmodcfapnahmbfeb
Python2.7 selenium3.4.1在使用chrome driver时报错:selenium.common.exceptions.WebDriverException: Message: u ...
- LeetCode(99) Recover Binary Search Tree
题目 Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without chang ...
- 和为s的两个数字 和为s的连续正数序列
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可. #include <iostream> using namesp ...
- POJ 2955 区间DP Brackets
求一个括号的最大匹配数,这个题可以和UVa 1626比较着看. 注意题目背景一样,但是所求不一样. 回到这道题上来,设d(i, j)表示子序列Si ~ Sj的字符串中最大匹配数,如果Si 与 Sj能配 ...
- linux c中需要记住的东西
1.记住常见的字符的ASCII值 a------------97 b------------98 A------------65 B------------66 空格' ...