蓝鲸持续集成平台(蓝盾)是一个免费并开源的 CI 服务。本文会介绍蓝盾 Agent 安装的整体流程。
1. 背景
在蓝盾中,构建机 Agent 是执行具体构建任务的核心组件。本文以蓝盾社区版 7.1 为例,详细梳理 Agent 的安装流程。
2. 手动安装流程
按照官方文档的说明,手动安装 Agent 的步骤如下:
- 进入蓝盾页面:服务 -> 环境管理 -> 节点
- 点击右上角的”导入私有构建机”按钮
- 在弹窗中选择目标机器的操作系统(支持 Linux/Windows/MacOS)
- 复制安装命令到目标机器执行
- 安装完成后点击刷新,确认节点状态
- 点击导入完成节点接入
3. 自动化安装方案
除了手动操作外,我们也可以通过调用接口实现 Agent 的自动化安装。主要涉及以下步骤:
3.1. 生成安装命令
GET /ms/environment/api/user/environment/thirdPartyAgent/projects/${projectId}/os/${os}/generateLink |
请求示例:
curl -X GET \ |
返回结果:
{ |
3.2. 执行安装并查询状态
在目标机器执行安装命令:
curl -H \"X-DEVOPS-PROJECT-ID: demo\" https://devops.example.com/environment/api/external/thirdPartyAgent/njmkqvml/install | bash
查询 Agent 状态:
GET /ms/environment/api/user/environment/thirdPartyAgent/projects/${projectId}/agents/${agentId}/status
导入节点:
POST /ms/environment/api/user/environment/thirdPartyAgent/projects/${projectId}/agents/${agentId}/import
4. Agent 安装实现分析
4.1. 生成安装命令(generateLink)
生成安装命令的实现主要分为三层:
API层 - 接口定义:
fun generateLink(
String, userId:
String, projectId:
OS, os:
String? zoneName:
): Result<ThirdPartyAgentLink>Service层 - 参数校验:
override fun generateLink(userId: String, projectId: String, os: OS, zoneName: String?): Result<ThirdPartyAgentLink> {
checkUserId(userId)
checkProjectId(projectId)
return Result(thirdPartyAgentService.generateAgent(userId, projectId, os, zoneName))
}具体实现 - 核心逻辑:
fun generateAgent(userId: String, projectId: String, os: OS, zoneName: String?): ThirdPartyAgentLink {
// 1. 获取网关信息
val gateway = slaveGatewayService.getGateway(zoneName)
// 2. 检查未导入的agent
val unimportAgent = thirdPartyAgentDao.listUnimportAgent(
dslContext = dslContext,
projectId = projectId,
userId = userId,
os = os
)
// 3. 生成或复用agent记录
val agentRecord = if (unimportAgent.isEmpty()) {
// 生成新agent
val secretKey = generateSecretKey()
val id = thirdPartyAgentDao.add(...)
thirdPartyAgentDao.getAgent(dslContext, id)!!
} else {
// 复用已有agent
unimportAgent[0]
}
// 4. 根据操作系统生成安装命令
return if (os == OS.WINDOWS) {
ThirdPartyAgentLink(
agentId = agentHashId,
link = agentUrlService.genAgentUrl(agentRecord)
)
} else {
ThirdPartyAgentLink(
agentId = agentHashId,
link = agentUrlService.genAgentInstallScript(agentRecord)
)
}
}
4.2. 获取安装脚本
蓝盾通过模板渲染的方式生成不同操作系统的安装脚本。主要流程:
API接口定义:
fun downloadAgentInstallScript(
agentId: String
): Response核心实现:
fun downloadInstallScript(agentId: String): Response {
// 1. 获取Agent记录
val agentRecord = getAgentRecord(agentId)
// 2. 根据OS选择安装脚本模板
val fileName = if (agentRecord.os == OS.WINDOWS.name) {
"install.bat"
} else {
"install.sh"
}
val scriptFile = File(agentPackage, "script/${agentRecord.os.toLowerCase()}/$fileName")
// 3. 替换模板变量
val map = getAgentReplaceProperties(agentRecord) // 获取替换变量
var result = scriptFile.readText(Charset.forName("UTF-8"))
map.forEach { (t, u) ->
result = result.replace("##$t##", u)
}
// 4. 返回生成的脚本
return Response.ok(StreamingOutput { output ->
output.write(result.toByteArray())
output.flush()
}, MediaType.APPLICATION_OCTET_STREAM_TYPE)
.header("content-disposition", "attachment; filename = $fileName")
.build()
}安装脚本目录结构:
script/
├── linux/
│ ├── install.sh # Linux安装脚本模板
│ ├── start.sh # 启动脚本
│ ├── stop.sh # 停止脚本
│ └── uninstall.sh # 卸载脚本
├── macos/
│ ├── install.sh # MacOS安装脚本模板
│ └── ...
└── windows/
├── install.bat # Windows安装脚本模板
├── devopsctl.vbs # VBS控制脚本
└── ...模板变量说明:
##agent_url## - Agent包下载地址
##projectId## - 项目ID
##agentId## - AgentID
##agentSecretKey## - Agent密钥
##gateWay## - 网关地址
##fileGateway## - 文件网关地址
4.3. Linux安装脚本实现
install.sh脚本是Agent安装的核心,主要实现以下功能:
4.3.1. 初始化环境
workspace=`pwd` # 工作目录 |
4.3.2. 下载并解压Agent包
function download_agent() { |
4.3.3. Agent包下载实现
Agent包下载接口:
|
主要实现步骤:
- 根据操作系统准备文件:
- JAR包: worker-agent.jar
- JRE: 对应系统的jre.zip
- 二进制文件: devopsAgent、devopsDaemon等
- 安装脚本: install.sh/bat等
- 配置文件
- 打包成agent.zip返回
注意:macOS JDK 必须带 Contents/Home 结构。若 Intel 版 jre.zip 缺失该路径,临时可以执行命令 mkdir -p Contents/Home && unzip -d Contents/Home jre.zip && zip -r jre.zip Contents 修正;后续需更新 environment 模块中的 jre.zip,并制作新的镜像。
4.3.4. 各系统服务注册实现
Linux (通过 rc.local)
function installAgentService() { |
MacOS (通过 launchd)
|
Windows (通过 Windows Service)
sc create %service_name% binPath= "%work_dir%\devopsDaemon.exe" start= auto |
4.3.5. Agent进程启动
主要通过start.sh/bat脚本实现:
- 创建工作目录
- 解压配置JDK环境
- 启动devopsDaemon守护进程
- 写入pid文件
- 检查进程状态
核心启动代码:
function start() { |
5. 总结
蓝盾 Agent 安装方式:
- 手动安装:通过 Web 界面操作,适合少量节点
- 自动化安装:通过 API 接口,适合批量部署
了解底层实现原理后,我们可以根据实际需求选择合适的安装方式,并进行二次开发和流程优化。