Jenkins 管理配置集合与静态资源
本指南将租户的配置文件和静态网站制品纳入 Jenkins 发布:配置集合负责配置资源,静态资源接口负责上传或替换业务文件,最后检查引擎同步和实际业务版本。
选择发布方式
| 变更内容 | Jenkins 操作 | 成功依据 |
|---|---|---|
| 地址、服务器池、策略、虚拟服务等配置 | 上传 YAML/JSON 到配置集合并同步 | 同步状态和消息成功,再检查业务 |
| 上传包型静态资源的 HTML、CSS、JS | 创建或替换 .zip / .tar.gz | 目标引擎同步完成,业务返回本次版本标记 |
| 目录映射型静态资源 | 将文件部署到所有承载引擎,再通过配置集合切换目录及关联配置 | 各引擎文件一致,配置同步成功,业务返回本次版本 |
配置集合中的 /slb/static_resource/ 只定义目录映射资源,不传输压缩包。两种静态资源流程分别见下文。
租户身份与权限
- 在 Web 控制台切换到目标租户,确认当前角色具备配置集合、静态资源及本次涉及配置资源的权限。
- 点击用户头像 →“生成 Token”,设置有效秒数并复制 Token,按客户凭据有效期要求安排轮换。
- 保存为 Jenkins Secret text 凭据,例如
normae-tenant7-release-token。不同租户分别配置凭据、配置目录和任务参数。 - 记录目标租户 ID。使用该 Token 调用
GET /system/tenant/current/获取tenant_id、tenant_name,将期望 ID 固定在对应任务中。
Token 绑定生成时的用户、租户和角色,通过 X-NORMAE-AUTH-TOKEN 请求头携带身份。--tenant-id 是校验参数:脚本先读取当前身份,与期望租户不同即失败,尚未创建、上传或同步资源。它不能改变 Token 的租户,也不替代角色授权。
export NORMAE_BASE_URL='https://controller.example.com'
export NORMAE_TOKEN='<由 Jenkins 凭据注入>'
curl --fail --silent --show-error \
-H "X-NORMAE-AUTH-TOKEN: $NORMAE_TOKEN" \
"$NORMAE_BASE_URL/system/tenant/current/"例如响应含 "tenant_id": 7,后续使用 --tenant-id 7;替换为实际 ID。不要每次将查询到的 ID 自动作为期望值,否则无法发现凭据选错租户。
同一用户、租户和角色重新生成 Token 会使旧 Token 失效,轮换后更新 Jenkins 凭据。Token 保留在凭据系统,不写入脚本、Jenkinsfile、配置文件或仓库。
下载脚本与准备目录
下载并纳入客户代码仓库:
- config_set_sync.py:配置集合上传与同步。
- static_resource_publish.py:静态资源上传及业务验收,与前一个 Python 文件放在同一目录。
- requirements.txt:Python 依赖。
- Jenkinsfile:组合发布流水线。
- addr.yaml:最小配置格式示例。
project/
├── Jenkinsfile
├── ci/
│ ├── config_set_sync.py
│ ├── static_resource_publish.py
│ └── requirements.txt
├── config-sets/
│ └── tenant7/
│ ├── address.yaml
│ └── virtual-service.yaml
└── dist/ 前端构建输出Jenkins Agent 使用 Linux、Python 3.8+、venv 和项目实际构建工具。安装依赖:
python3 -m venv .venv
.venv/bin/python -m pip install -r ci/requirements.txt脚本默认校验 HTTPS 证书。私有 CA 使用 REQUESTS_CA_BUNDLE=/path/to/private-ca.pem;上面的 curl 使用 --cacert /path/to/private-ca.pem。管理节点和业务入口使用不同 CA 时,提供包含所需 CA 的信任文件。
一、管理配置集合
配置文件以 API 资源路径为顶层键,值为资源列表。例如 address.yaml:
"/slb/addr/":
- name: "portal-addresses"
content:
- "192.0.2.10"
- "198.51.100.0/24"上述为文档专用地址,请修改为实际配置。其他资源字段和名称引用按当前管理节点 API 文档配置,见 配置集合控制台管理。不要直接将普通 REST 查询结果中的对象 ID 作为跨环境配置引用。
.venv/bin/python ci/config_set_sync.py config-sets/tenant7 \
--tenant-id 7 --name tenant7-portal --sync-timeout 300脚本先校验租户,再按名称精确查询集合;不存在则创建,存在则复用。按文件名顺序上传目录第一层的 .json、.jsonc、.yaml、.yml,全部上传成功后同步一次,再查询结果。状态与状态消息都表示成功时才退出 0。目录为空或任一上传失败时不执行同步。
--name 省略时使用目录名。旧用法仍可运行,但多租户任务应始终指定 --tenant-id。--sync-timeout 是同步 POST 的 HTTP 请求超时秒数,不是后台任务取消时间。隐藏文件、子目录和其他扩展名不上传。
同步包含配置变更发布,任务随后仍需验证实际业务行为。脚本采用增量上传:新增或覆盖同名文件,本地缺少的文件不会自动删除远端文件。需要删除资源时,在集合详情中明确删除对应文件,再同步;先检查引用和影响范围。
二、发布上传包型静态资源
首次初始化
- 构建静态文件,将首页和
release.txt放在压缩包根目录;版本标记使用唯一构建编号或 Git 提交号。 - 用下文
upload创建资源;同租户已有同名上传包资源时,该命令执行替换。 - 通过控制台或普通虚拟服务/七层分发规则 API,将资源关联到虚拟服务并执行变更,核对承载引擎出现在资源同步状态中。见 静态资源托管指南。
- 用
verify核对引擎与业务版本,初始化完成后再接入日常流水线。
首次关联和更换关联需单独处理。 当前配置集合可按 static_resource_name 引用已上传资源,但首次关联上传包的引擎登记需要上述普通配置操作。日常流水线适用于已经完成关联、引擎登记正确的资源;单靠集合同步新建或更换引用,不能保证上传包被分发到新增引擎。
引用已上传资源时,不在配置集合中放同名 /slb/static_resource/ 定义,以免按目录映射处理。七层规则使用 handle_type: 5、static_resource_name 和 URL 映射字段;虚拟服务默认处理放在 default_profile 下。其余必填字段按目标 API 文档配置。
日常上传与替换
假定前端构建已产出 dist/:
printf '%s\n' "$GIT_COMMIT" > dist/release.txt
tar -czf portal.tar.gz -C dist .
.venv/bin/python ci/static_resource_publish.py upload \
--tenant-id 7 --name customer-portal --archive portal.tar.gz脚本在目标租户内按名称查询:不存在则向 POST /slb/static_resource/ 携带 name 和 file 创建资源;存在则向 POST /slb/static_resource/{id}/tree/ 上传替换文件,保留资源 ID 和现有引用。同名资源是目录映射类型或仍在上传/同步时失败。
upload 退出码 0 表示请求已受理,尚未证明业务切换完成。verify 退出 0 才表示同步与业务版本验收通过,失败返回非零。随后执行:
.venv/bin/python ci/static_resource_publish.py verify \
--tenant-id 7 --name customer-portal \
--engine-id 31 --engine-id 32 \
--url https://portal.example.com/release.txt \
--expected-file dist/release.txt --timeout 300替换31、32为所有预期承载引擎 ID,URL 为真实虚拟服务入口。脚本要求指定引擎出现在同步列表中、全部列表项返回状态1,并核对业务标记 SHA256 与构建一致。空列表、只有其他引擎、同步未完成或仍返回旧版本,都不能通过。
业务请求使用独立连接,不携带管理 Token;带版本查询参数和 Cache-Control: no-cache 降低旧缓存干扰。版本标记需随包更新并直接可访问,CDN、缓存或重写规则应允许验证真实内容。VIP 验证只证明该入口返回本次版本;主备或多活部署还需按拓扑逐入口或切换承载后检查,不能据此声称已测到所有引擎业务流量。
三、组合 Jenkins Pipeline
完整的 Jenkinsfile 示例适用于已完成首次关联的上传包资源,顺序为:构建 → 上传/替换静态内容 → 同步配置集合 → 等待引擎与业务版本验收。失败即停止后续步骤。
核心发布阶段如下:
stage('发布与验收') {
environment {
NORMAE_TOKEN = credentials('normae-tenant7-release-token')
}
steps {
sh '''
set +x
set -eu
.venv/bin/python ci/static_resource_publish.py upload \
--tenant-id "$NORMAE_TENANT_ID" \
--name "$STATIC_RESOURCE_NAME" --archive portal.tar.gz
.venv/bin/python ci/config_set_sync.py "$CONFIG_DIR" \
--tenant-id "$NORMAE_TENANT_ID" --name "$CONFIG_SET_NAME"
.venv/bin/python ci/static_resource_publish.py verify \
--tenant-id "$NORMAE_TENANT_ID" --name "$STATIC_RESOURCE_NAME" \
--engine-id "$ENGINE_A_ID" --engine-id "$ENGINE_B_ID" \
--url "$RELEASE_URL" --expected-file dist/release.txt
'''
}
}示例使用 disableConcurrentBuilds(),归档本次压缩包与版本标记。替换构建命令、管理节点地址、租户/凭据 ID、资源名、集合目录、引擎 ID 和业务 URL;单引擎删除第二项,更多引擎逐项添加 --engine-id。示例 npm ci && npm run build 假设客户项目的输出目录是 dist。
同租户同一集合或资源只允许一个发布任务写入。多个 Job 共用资源时需共享锁;disableConcurrentBuilds() 只约束当前 Job。流水线不自动 retry 重放变更。
仅发布配置的任务保留同步命令和业务检查;仅更新静态内容保留 upload → verify。两类操作不是跨资源事务:静态内容可能已经切换而配置同步失败,必须停止并核对当前状态。
凭据注入和 Pipeline 写法见 Jenkinsfile 官方说明 与 Pipeline 语法。
四、目录映射型静态资源
目录映射由客户通过 SSH、制品分发工具或部署系统把文件直接部署到引擎宿主机,平台仅配置映射路径。
管理员确认每台承载引擎的静态资源根目录及客户部署账号权限。根目录可不同,避免修改共享根目录影响其他业务。
Jenkins 将同一构建部署到所有承载引擎的新版本目录,如根目录下
tenant7/portal/releases/r42/,逐台检查文件清单、SHA256和可读权限;全部完成前不切换映射。更新配置集合资源路径,再运行带
--tenant-id的同步命令:yaml"/slb/static_resource/": - name: "customer-portal-mapped" map_dir: "/tenant7/portal/releases/r42"当前集合接口要求
map_dir字段以/开头,但实际仍拼接在引擎静态资源根目录下。例如根目录/data/www,实际访问/data/www/tenant7/portal/releases/r42。控制台输入方式见 目录映射说明。在所有承载路径验证
release.txt和业务,保留上一版本目录。上述verify也可核对映射资源的引擎状态和入口内容;upload仅操作上传包。
SSH 地址、账号、根目录由客户环境决定。上传包示例 Jenkinsfile 不包含文件分发步骤;目录映射需将“上传/替换包”替换为客户已有的全引擎部署与校验阶段。
失败处理与回退
| 现象 | 处理 |
|---|---|
| 租户不匹配 | 检查凭据和固定期望 ID,尚未发生写入 |
| 配置文件上传失败 | 不同步,此前上传的文件可能待同步,核对后续作 |
| 配置同步失败或请求超时 | 检查集合消息、待执行状态及引擎;超时不代表服务器未受理,也不会自动取消后台操作 |
| 静态上传失败或验收超时 | 保持单写者,检查节点及当前业务标记;先重新 verify,再决定是否上传 |
| 上传包回退 | 当前操作结束后,以同名资源上传上一成功制品,再用旧标记 verify |
| 映射目录回退 | 确认旧目录在全部引擎完整,再切回旧 map_dir、同步和验收 |
| 配置回退 | 恢复旧配置,明确处理本次新增远端文件后同步;仅恢复本地旧目录不会删除远端新文件 |
保留制品、版本标记、配置版本、租户 ID 和发布日志。回退也验收业务;脚本非零不表示所有资源自动恢复。
