本文档介绍了如何在 Jenkins 中配置 SSH 部署密钥,以便更稳定地拉取 Git 仓库代码,避免常见的 RPC 错误。
1. 背景
在使用 Jenkins 进行持续集成时,常常需要从 Git 仓库拉取代码。如果使用 HTTP/HTTPS 协议,有时会遇到 RPC 错误,这可能是由于网络不稳定或大文件传输导致的。使用 SSH 协议可以提供更稳定的连接,并且在处理大文件时表现更好。
2. 常见的 RPC 错误
常见的错误信息如下:
remote: Enumerating objects: 12443, done.
remote: Counting objects: 100% (946/946), done.
remote: Compressing objects: 100% (762/762), done.
error: RPC failed; curl 92 HTTP/2 stream 7 was not closed cleanly: INTERNAL_ERROR (err 2)
error: 40022 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
remote: Enumerating objects: 12443, done.
remote: Counting objects: 100% (946/946), done.
remote: Compressing objects: 100% (762/762), done.
error: RPC failed; curl 56 GnuTLS recv error (-9): Error decoding the received TLS packet.
error: 9443 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
这个错误信息表明在 Jenkins 中使用 Git 插件进行代码拉取时,出现了一个与 RPC(远程过程调用)相关的错误。具体来说,HTTP/2 流在关闭时没有正常关闭,并且在读取 sideband 包时发生了意外断开连接。
而使用 SSH 通常更稳定,并且在处理大文件或大量数据时表现更好。
3. 配置 SSH 部署密钥
3.1 本地生成 SSH 密钥对
在本地终端或构建代理上运行:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f deploy_key
说明:
-t rsa
:密钥类型为 RSA;-b 4096
:密钥长度 4096 位,增强安全性;-C
:注释,可填邮箱或用途;-f deploy_key
:密钥输出文件名。
执行后生成两个文件:
deploy_key
:私钥,用于身份验证;deploy_key.pub
:公钥,需添加到远程仓库的部署密钥列表中。
3.2 将公钥添加到 Git 仓库
具体操作方式视平台而定:
- GitHub:仓库 → Settings → Deploy keys → Add deploy key;
- GitLab:仓库 → Settings → Repository → Deploy Keys;
- Bitbucket:仓库 → Repository Settings → Access keys。
💡 一般建议使用 只读权限 的 Deploy Key,以提升安全性。
4. 在 Jenkins 中配置 SSH 凭据
4.1 添加 SSH 凭据
- 登录 Jenkins,进入 系统管理 → 凭据。
- 选择对应的作用域(如
全局
)。 - 点击
Add Credentials
,选择SSH Username with private key
填写以下信息:
字段 | 内容说明 |
---|---|
Id | 内部唯一ID,可以为空,会自动生成一个,本案例中也可以填 deploy_user |
Username | 任意标识名(如 git 或 deploy_user ) |
Private Key | 选择 “Enter directly”,粘贴 deploy_key 的内容 |
Passphrase | 如果有设置过密钥密码,则在此输入 |
- 保存凭据。
4.2 在 Jenkins Job 中配置 Git 仓库
在你的构建 Job 中:
-
在
Source Code Management
中选择 Git; -
将 Git 仓库地址改为 SSH 格式,如:
git@github.com:username/repo.git
-
在
Credentials
中选择你刚刚添加的 SSH 凭据; -
保存配置并尝试构建。
不出意外,你应该能看到类似下图的输出:
这是因为 Jenkins 第一次连接时需要验证 SSH 主机密钥。我们接下来将配置主机密钥验证策略。
4.3 配置 SSH 主机密钥验证
Jenkins 的 Git 插件支持自定义 SSH 主机密钥验证策略,以防止中间人攻击。可选策略说明(参考 Git Client Plugin 文档):
策略名称 | 说明 |
---|---|
Known hosts file (默认) | 使用 ~/.ssh/known_hosts 进行校验 |
Accept first connection | 第一次连接自动信任并缓存主机密钥(适用于自动化场景) |
Manually provided keys | 手动维护一组受信任的主机密钥 |
No verification (不推荐) | 完全跳过验证,存在安全风险 |
在 Jenkins 中配置方式:
- 进入 系统管理 → 全局安全设置;
- 找到
Git plugin
部分; - 设置
Git Host Key Verification Configuration
。
- 这里我们选择
Manually provided keys
,并将 GitHub 的SSH 公钥添加到文本框中。可以使用本地的known_hosts
文件,或者直接从 GitHub 获取:
ssh-keyscan -t rsa github.com
5. 验证与测试
完成上述配置后:
- 手动运行一次 Job,确认能成功克隆代码;
- 查看控制台输出是否有如下类似信息:
Cloning the remote Git repository...
Using credentials github-ssh> git init ...> git fetch --tags --progress git@github.com:xxx/xxx.git ...
若成功,则表示 SSH 配置无误。
6. 常见问题与排查建议
问题 | 原因 | 解决方案 |
---|---|---|
构建报错 “Permission denied (publickey)” | 公钥未配置正确 | 检查公钥是否添加至 Git 仓库 |
报错 “Host key verification failed” | 主机密钥未受信任 | 设置正确的主机验证策略或添加到 known_hosts |
连接 GitHub 太慢 | 国内网络问题 | 尝试使用加速服务或镜像仓库 |
7. 总结
通过配置 SSH 部署密钥,你可以:
- 避免 Jenkins 使用 HTTP 协议拉取代码时的 RPC 错误;
- 提升 CI 流程中的稳定性;
- 加强身份验证安全性。
建议将
deploy_key
设置为项目独立密钥,避免多个项目共享同一密钥,提高安全性与可维护性。