目錄
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 入門
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
進行快速配置。如下返回則為正常配置成功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 防火牆例外將不執行。 將網路連線型別更改為域或專用,然後再次嘗試。
之後在Enabling PowerShell remoting fails due to Public network connection type找到了問題原因和解決方法。
由於我只改了當前所連線的網路設定為了專用網路,還有另外一個網路還是共有的。通過Get-NetConnectionProfile
命令可以看到網路型別,和網路和Internet設定中看到的時候一樣。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
再次嘗試快速配置,不再報錯。
PS C:\WINDOWS\system32> winrm qc 已在此計算機上執行 WinRM 服務。 在此計算機上設定了 WinRM 以進行遠端管理。
winrm qc是winrm quickconfig縮寫
根據Enabling PowerShell remoting fails due to Public network connection type在不改變網路型別的條件下,可以在開啟遠端呼叫功能的時候,過跳過網路型別檢查,即在下面第三部的時候新增指定引數跳過網路型別檢查。
檢視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
若上一步快速配置沒有成功,則會返回以下資訊
PS C:\Users\Dm_ca> winrm enumerate winrm/config/listener WSManFault Message ProviderFault WSManFault Message = 拒絕訪問。
啟用遠端呼叫
通過輸入
Enable-PSRemoting –Force
啟用Powershell遠端呼叫功能。
powershell PS C:\Users\Administrator> Enable-PSRemoting –Force 在此計算機上,WinRM 已設定為接收請求。 WinRM 已經進行了設定,以用於在此計算機上進行遠端管理。
若在第一步存在公用網路型別介面卡,則這一步需要在上面的命令中新增SkipNetworkProfileCheck
引數跳過網路檢查,然後再看下listener,可以看到已經開啟了監聽,不在報錯。PS C:\WINDOWS\system32> Enable-PSRemoting -SkipNetworkProfileCheck -Force PS C:\WINDOWS\system32> winrm enumerate winrm/config/listener Listener Address = * Transport = HTTP Port = 5985 Hostname Enabled = true URLPrefix = wsman CertificateThumbprint ListeningOn = 127.0.0.1, XXXXXXXXX
啟用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
設定白名單地址
TrustedHosts
表示的是白名單地址。
通過Set-Item wsman:\localhost\client\trustedhosts *
設定允許所有IP呼叫。
通過Set-Item wsman:\localhost\client\trustedhosts "127.0.0.1,127.0.0.2"
設定允許指定IP呼叫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
將伺服器地址傳入以及授權物件傳入即可執行遠端指令碼呼叫。
- 其中需要輸入伺服器的使用者名稱和密碼。通過
升級服務
通過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
- Enabling PowerShell remoting fails due to Public network connection type
本文地址:https://www.cnblogs.com/Jack-Blog/p/10922038.html
作者部落格:傑哥很忙
歡迎轉載,請在明顯位置給出出處及連結