Jenkins 創建 Node 到 Windows
一. 新建 Node
Dashboard -> Manage Jenkins -> Manage Nodes and Clouds
Dashboard -> Nodes -> New Node
二. 配置節點
Node:節點名
Description:節點描述
Number of executors:節點最大同時執行任務數量
Remote root directory:節點 代理機器上保存 Jenkins 啟動文件的目錄,最好使用絕對路徑
Labels:節點標簽,可以是多個,中間以空格分隔
Usage:控制何時構建時使用這個 Node,這里選擇的 Only build jobs with label expressions matching this node:構建時只有當 任務Label 選擇為此節點中包含的 Label 時,才會執行這個節點
Launch method :啟動方法,這里選擇了 Launch agents via SSH 通過 SSH 啟動
Host:真正運行Node 的電腦的 ip
Credentials:憑證,上面選擇了 Launch agents via SSH,這里需要選擇一個 SSH 的憑證
Jenkins 配置 Credentials 憑證
Host Key Verfication Strategy:控制Jenkins在連接時如何驗證遠程主機提供的SSH密鑰
Availability:控制Jenkins何時啟動和停止此代理,此處選擇了 Keep this agent online as much as possible:盡可能讓這個代理保持在線狀態
Tool Locations:用到的工具在 Windows 電腦上的路徑
上面配置了 git,如果不配置,默認使用的是 啟動 Jenkins電腦系統上配置的 git,會報錯
最后點擊 Save 保存
三. 創建如下
此時 節點 WinTest 圖標上標記一個 紅色 X,說明這個節點還未啟動
點擊 WinTest 節點名,打開節點
Status:節點狀態,此時節點未啟動
Deleta Agent:刪除節點
Configure:節點配置,點擊打開 回到 二. 配置節點
四.配置 SSH 服務
回到第二步看 Host 填寫的 ip 這個是真正運行 Node 的 Windows 電腦的 ip
Jenkins 是在 Mac 電腦上運行,Node 配置中Launch method :啟動方法,選擇了 Launch agents via SSH
到 Windows 電腦 Windows 配置 SSH 服務
Mac 電腦上的 公鑰 配置到 Windows 電腦中,具體位置在 Windows 配置 SSH 服務 找
測試 Mac 通過 SSH 連接 Windows 電腦,如果能成功連接,到 第五步. 啟動節點
注意:Jenkins 中 創建的 SSH 憑證中填寫的 UserName 需要配置為 Windows電腦的登錄用戶名,否則驗證失敗
五. 啟動節點
到 Status 頁簽,點擊 Launch agent
下面幾種報錯原因以及解決方案
1.
Connection refused (Connection refused)
SSH Connection failed with IOException: "Connection refused (Connection refused)", retrying in 15 seconds. There are 7 more retries left.
Connection refused (Connection refused)
原因:代理機器系統是 Win10,代理機器上還沒有啟動 SSH 服務
Windows 啟動 SSH 服務
再次執行 Launch Agent
Warning: no key algorithms provided; JENKINS-42959 disabled
SSHLauncher{host='10.0.40.182', port=22, credentialsId='liqiangWin', jvmOptions='', javaPath='', prefixStartSlaveCmd='', suffixStartSlaveCmd='', launchTimeoutSeconds=60, maxNumRetries=10, retryWaitTime=15, sshHostKeyVerificationStrategy=hudson.plugins.sshslaves.verifiers.KnownHostsFileKeyVerificationStrategy, tcpNoDelay=true, trackCredentials=true}
[02/18/25 21:20:44] [SSH] Opening SSH connection to 10.0.40.182:22.
Searching for 10.0.40.182 in /Users/townest/.ssh/known_hosts
Searching for 10.0.40.182:22 in /Users/townest/.ssh/known_hosts
[02/18/25 21:20:44] [SSH] WARNING: No entry currently exists in the Known Hosts file for this host. Connections will be denied until this new host and its associated key is added to the Known Hosts file.
Key exchange was not finished, connection is closed.
SSH Connection failed with IOException: "Key exchange was not finished, connection is closed.", retrying in 15 seconds. There are 10 more retries left.
Searching for 10.0.40.182 in /Users/townest/.ssh/known_hosts
Searching for 10.0.40.182:22 in /Users/townest/.ssh/known_hosts
[02/18/25 21:20:59] [SSH] WARNING: No entry currently exists in the Known Hosts file for this host. Connections will be denied until this new host and its associated key is added to the Known Hosts file.
Key exchange was not finished, connection is closed.
報錯提示連接的 SSH 主機的身份沒有經過驗證,可能存在中間人攻擊的風險。
為了確保安全,SSH 客戶端需要驗證連接的服務器的身份,以防止被偽裝或受到中間人攻擊
回到 第二步 Host Key Verfication Strategy:Known hosts file Verification Strategy
主機密鑰驗證策略 配置的為 從 Known 文件驗證
可以到 Mac 電腦上到 ~/.ssh 路徑,可以看到一個 known_hosts 文件,這里邊存放了需要訪問的電腦的 ip
打開會看到 每行以一個 ip 地址開頭,后跟 ssh 公鑰
比如上面 啟動 SSH 服務的 Windows 電腦 ip 為 10.0.40.182
解決方案有多種,這里只處理一種
# ssh-keyscan -H hostname >> ~/.ssh/known_hosts
# hostname 就是啟動 SSH 服務電腦的 IP
ssh-keyscan -H 10.0.40.182 >> ~/.ssh/known_hosts
這個命令會獲取主機10.0.40.182
的公鑰并將其追加到 ~/.ssh/known_hosts 文件中
SSHLauncher{host='10.0.40.182', port=22, credentialsId='liqiangWin', jvmOptions='', javaPath='', prefixStartSlaveCmd='', suffixStartSlaveCmd='', launchTimeoutSeconds=60, maxNumRetries=10, retryWaitTime=15, sshHostKeyVerificationStrategy=hudson.plugins.sshslaves.verifiers.NonVerifyingKeyVerificationStrategy, tcpNoDelay=true, trackCredentials=true}
[02/19/25 11:27:27] [SSH] Opening SSH connection to 10.0.40.182:22.
[02/19/25 11:27:27] [SSH] WARNING: SSH Host Keys are not being verified. Man-in-the-middle attacks may be possible against this connection.
ERROR: Server rejected the 1 private key(s) for xxxxx (credentialId:Win/method:publickey)
[02/19/25 11:27:27] [SSH] 認證失敗。
認證失敗。
[02/19/25 11:27:27] Launch failed - cleaning up connection
[02/19/25 11:27:27] [SSH] 連接關閉。
SSH 服務器上配置了 Mac 電腦的公鑰,不了解的看這里 Windows 配置 SSH 服務
上面這個報錯是 SSH服務器 通過 Mac 的公鑰驗證 Mac 電腦的私鑰 失敗
ERROR: Server rejected the 1 private key(s) for xxxxx (credentialId:Win/method:publickey)
看上面報錯日志中的 for xxxxx 這個 xxxxx 是導致驗證失敗的原因
這是因為 我在Jenkins 中配置 SSH密鑰憑證的時候 UserName 沒有寫成 開啟 SSH 服務的 Windows 電腦的登錄賬號名
回到 SSH 密鑰憑證,修改密鑰憑證的 UserName為 SSH 服務的 Windows 電腦的登錄賬號名
[SSH] Starting agent process: cd "F:\Jenkins" && E:\JDK12/bin/java -jar remoting.jar -workDir D:\jenkins_ws -jar-cache D:\jenkins_ws/remoting/jarCache
Error: Unable to access jarfile remoting.jar
Agent JVM has terminated. Exit code=1
上面報錯原因是 通過 JDK 啟動 jenkins 的時候沒有對 remoting.jar 的權限
(1) remoting.jar 文件的作用:我們這里是 Mac 電腦上配置的 Jenkins 添加一個 Node 到 Windows 電腦上,那么Windows 電腦需要從 Mac 電腦的 Jenkins 中下載一個 remoting.jar 有的是 agent.jar 到 Windows 電腦上,然后通過 JDK命令執行這個 remoting.jar 或者 agent.jar,啟動Jenkins 在 Windows 電腦上運行
(2) 對于命令中的幾個路徑從哪里來的做個解釋
cd "F:\Jenkins" && E:\JDK12/bin/java -jar remoting.jar -workDir D:\jenkins_ws -jar-cache D:\jenkins_ws/remoting/jarCache
先到 Node 配置界面
Remote root directory 配置為 F:\Jenkins
Remoting Work directory 配置為 D:\jenkins_ws
這個命令是一個組合命令
先執行 cd "F:\Jenkins"
切換路徑
在執行 E:\JDK12/bin/java -jar remoting.jar -workDir D:\jenkins_ws -jar-cache D:\jenkins_ws/remoting/jarCache
Jenkins 執行 通過 SSH 連接到 SSH 服務的時候其實是在路徑 C:\Users\Administrator>
remoting.jar 文件是被 Jenkins 放到路徑 F:\Jenkins,所以要先 cd 到這個路徑
Error: Unable to access jarfile remoting.jar
純屬是個人 Windows 系統 cmd 環境不同導致的報錯
經過測試發現有的電腦 cmd 不管當前在哪個盤符
執行 cd "F:\Jenkins" && E:\JDK12/bin/java -jar remoting.jar -workDir D:\jenkins_ws -jar-cache D:\jenkins_ws/remoting/jarCache
就是成功的
我的電腦上 如果 cmd 當前盤符不是 F盤 那么就會報這個錯
修改命令在 cd 后邊加上 /d
cd /d "F:\Jenkins" && E:\JDK12/bin/java -jar remoting.jar -workDir D:\jenkins_ws -jar-cache D:\jenkins_ws/remoting/jarCache
執行發現可以執行成功
解釋:在命令行中使用 /d 參數的作用是允許跨磁盤驅動器切換目錄
如果不加 /d 參數,cd 命令通常只能在同一磁盤驅動器內切換目錄
例如
如果當前目錄在 C 盤,使用 cd 命令切換到 C 盤的其他目錄是可以正常工作的
但如果要切換到 D 盤的某個目錄則會失敗
而加上 /d 參數后,就可以跨磁盤驅動器切換目錄,例如從 C 盤切換到 D 盤的某個目錄?
因為這個命令行是 Jenkins 拼接的,我沒找到在哪里配置的,所以我沒法加 /d
我的修改方案是,Remote root directory:C:\Jenkins
直接修改到 C盤
再次重新 Launch agent
[SSH] Starting agent process: cd "C:\Jenkins" && E:\JDK12/bin/java -jar remoting.jar -workDir D:\jenkins_ws -jar-cache D:\jenkins_ws/remoting/jarCache
org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir
: Using D:\jenkins_ws\remoting as a remoting work directory
rg.jenkinsci.remoting.engine.WorkDirManager setupLogging
Both error and output logs will be printed to D:\jenkins_ws\remoting
<===[JENKINS REMOTING CAPACITY]===>channel started
Remoting version: 4.10
上面日志顯示節點啟動成功
[02/21/25 14:14:07] [SSH] Starting agent process: cd "C:\Jenkins_2" && java -jar remoting.jar -workDir C:\Jenkins_2 -jar-cache C:\Jenkins_2/remoting/jarCache
2�� 21, 2025 2:14:07 ���� org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir
��?: Using C:\Jenkins_2\remoting as a remoting work directory
2�� 21, 2025 2:14:07 ���� org.jenkinsci.remoting.engine.WorkDirManager setupLogging
��?: Both error and output logs will be printed to C:\Jenkins_2\remoting
<===[JENKINS REMOTING CAPACITY]===>channel started
2�� 21, 2025 2:14:07 ���� hudson.remoting.UserRequest perform
����: LinkageError while performing UserRequest:hudson.slaves.SlaveComputer$SlaveVersion@455044b3
java.lang.UnsupportedClassVersionError: Failed to load hudson.slaves.SlaveComputer$SlaveVersionat hudson.remoting.RemoteClassLoader.loadClassFile(RemoteClassLoader.java:472)at hudson.remoting.RemoteClassLoader.loadRemoteClass(RemoteClassLoader.java:301)at hudson.remoting.RemoteClassLoader.loadWithMultiClassLoader(RemoteClassLoader.java:277)at hudson.remoting.RemoteClassLoader.findClass(RemoteClassLoader.java:236)at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)at java.base/java.lang.Class.forName0(Native Method)at java.base/java.lang.Class.forName(Class.java:398)at hudson.remoting.MultiClassLoaderSerializer$Input.resolveClass(MultiClassLoaderSerializer.java:133)at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1886)at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)at hudson.remoting.UserRequest.deserialize(UserRequest.java:312)at hudson.remoting.UserRequest.perform(UserRequest.java:196)at hudson.remoting.UserRequest.perform(UserRequest.java:50)at hudson.remoting.Request$2.run(Request.java:391)at hudson.remoting.InterceptingExecutorService.lambda$wrap$0(InterceptingExecutorService.java:81)at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.UnsupportedClassVersionError: hudson/slaves/SlaveComputer$SlaveVersion has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0at java.base/java.lang.ClassLoader.defineClass1(Native Method)at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:877)at hudson.remoting.RemoteClassLoader.loadClassFile(RemoteClassLoader.java:470)... 22 moreAgent JVM has not reported exit code. Is it still running?
[02/21/25 14:14:10] Launch failed - cleaning up connection
[02/21/25 14:14:10] [SSH] Connection closed.
ERROR: Connection terminated
上面日志 cd "C:\Jenkins_2" && java -jar remoting.jar -workDir C:\Jenkins_2 -jar-cache C:\Jenkins_2/remoting/jarCache
執行已經成功了,下面還有報錯
找到日志中
Caused by: java.lang.UnsupportedClassVersionError: hudson/slaves/SlaveComputer$SlaveVersion has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0
這表明當前使用的 Java 運行時只能處理到 class 文件版本 55.0,而 Jenkins 代碼則是用 class 文件版本 61.0 編譯的
根據 Java 的版本對應關系:
Class file version 61.0 對應 Java 17
Class file version 55.0 對應 Java 11
因此,這個錯誤的解決方案是確保 Jenkins 節點 也就是 Windows 使用 Java 17 或更高版本來運行,安裝 JDK17