21 KiB
safety-eval-service 本地 JAR 打包发布到 100 服务器 K8s 完整流程
本文档记录了将本地 Windows 开发机上的
safety-eval-serviceJAR 包发布到 GBS K8s 集群(主节点192.168.20.100)的全链路操作步骤,包括所用工具、命令、账号密码和注意事项。
1. 环境总览
1.1 网络与服务器
| 角色 | IP | 说明 |
|---|---|---|
| K8s Master | 192.168.20.100 |
控制面,Docker/Maven/Nexus/NFS |
| K8s Worker01 | 192.168.20.110 |
Pod 运行节点 |
| K8s Worker02 | 192.168.20.120 |
Pod 运行节点 |
| Nexus 私服 | 192.168.20.100:8578 |
Maven snapshots/releases 仓库 |
| MySQL | 192.168.20.100:33080 |
GBS 共享数据库 |
| Nacos | prod-nacos:8848(集群内)/ 192.168.20.100:30290(NodePort) |
配置中心 + 注册中心 |
| Gateway | 192.168.20.100:30140(NodePort) |
SCG 统一入口 |
K8s 版本 v1.27.6,命名空间 jjb-dragon。
1.2 本地开发机
- OS:Windows(Git Bash / cmd / PowerShell 均可)
- 项目路径:
E:\works\projects\safety-eval-service - 模块:Maven 多模块(DDD 六层),启动模块为
safety-eval-start - 本地 JDK:1.8.x
- 构建产物:
safety-eval-start/target/safety-eval-start-1.0-SNAPSHOT.jar
1.3 容器镜像仓库
| 仓库 | 地址 | 用途 | 用户名 | 密码 |
|---|---|---|---|---|
| 杭州 ACR(默认发布仓) | jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com |
主镜像仓,K8s image-pull-secret 指向此处 |
10952138@qq.com |
idurCT!rIq9EzISD |
| 张家口 ACR(备用/本地构建仓) | registry.cn-zhangjiakou.aliyuncs.com / VPC: registry-vpc.cn-zhangjiakou.aliyuncs.com |
另一台阿里云服务器本地构建用 | kilaa |
Kilaa@6666 |
| 张家口 ACR AK | — | — | LTAI5tF8GbtKizLAowJbAYmT |
G0ZYeaZtnpxhp0bO1rPp4HPrq57LaT |
镜像命名规范:
- 杭州 ACR:
{ACR}/ali_img_ns/prod-aly-{env}-dragon-{app}:{env}-YYYYMMDD-{N}- 示例:
jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260703-1
- 示例:
- 张家口 ACR:
registry.cn-zhangjiakou.aliyuncs.com/kilaa/zcloud-gbs-operation:jjb-saas-safety-eval-ota-YYYYMMDD-{N}
1.4 SSH / 系统账号
| 目标 | 用户 | 密码 |
|---|---|---|
192.168.20.100(master)SSH |
root |
Zcloud@zcloud100 |
1.5 K8s 拉取凭据
- Secret 名:
image-pull-secret(底座镜像)/image-pull-secret1(应用镜像) - 类型:
kubernetes.io/dockerconfigjson - 当前只配置了杭州 ACR 的 auth,因此 K8s 部署必须使用杭州 ACR 地址
1.6 数据库
| 项 | 值 |
|---|---|
| Host | 192.168.20.100:33080 |
| 用户 | root |
| 密码 | Mysql@zcloud33080 |
2. 本服务基础信息
| 配置项 | 值 |
|---|---|
| app.name | jjb-saas-cq-anquan |
| gateway 路由名 | cqanquan |
| server.port(本地 / K8s 容器内) | 8095 |
| context-path | /safety-eval |
| Dubbo 端口 | 20895 |
| Nacos 服务名 | safety-eval-service |
| Spring Boot 版本 | 2.7.18 |
| 架构 | DDD 六层(adapter / app / client / domain / infrastructure / start) |
端口说明:本服务在 K8s 容器内仍监听
8095,与本地一致;Service 通过port: 80 / targetPort: 8095对外暴露 80 端口。GBS 其他部分服务会在 Nacos prod 配置中将server.port覆盖为 80,本服务暂未做此覆盖,部署时务必确认实际监听端口再填写containerPort与targetPort。
K8s 资源:
- Deployment:
jjb-saas-safety-eval-deploy - Pod Label:
app=jjb-saas-safety-eval-pod - Service:
jjb-saas-safety-eval(ClusterIP,80→8095,20895→20895)
3. 完整发布流程
发布流程分为 5 个阶段:本地编译 → 上传 JAR → 构建镜像 → 推送 ACR → K8s 部署。
阶段 1:本地 Maven 编译
在 Windows 本地打包:
cd E:\works\projects\safety-eval-service
mvn clean package -DskipTests
产物路径:safety-eval-start/target/safety-eval-start-1.0-SNAPSHOT.jar(约 226 MB)。
也可将源码上传到 master 节点用
/opt/maven(Maven 3.8.8,阿里云镜像)远程编译,避免本地环境差异。
阶段 2:上传 JAR 到 master 节点
使用 SFTP 或 SCP 将 JAR 上传到 192.168.20.100:
# 方式 A:scp(需要 sshpass 或在 Git Bash 中交互式输密码)
scp safety-eval-start/target/safety-eval-start-1.0-SNAPSHOT.jar root@192.168.20.100:/tmp/safety-eval.jar
# 方式 B:Python paramiko 脚本(推荐,见 docs/build-tools/build_push.py)
python docs/build-tools/build_push.py ^
E:\works\projects\safety-eval-service\safety-eval-start\target\safety-eval-start-1.0-SNAPSHOT.jar ^
jjb-saas-safety-eval ota 1
阶段 3:构建 Docker 镜像
方式 A:使用 build.sh(推荐,在 master 上执行)
docs/build-tools/build.sh 会在 master 上自动:
- 将 JAR + JDK + Dockerfile 组装为 build context
docker build生成镜像docker push推到杭州 ACR
ssh root@192.168.20.100
cd /path/to/build-tools
./build.sh jjb-saas-safety-eval ota /tmp/safety-eval.jar 1
生成镜像:jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-YYYYMMDD-1
方式 B:使用根目录 Dockerfile
项目根 Dockerfile 基于 jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/pub/jdk:1.8.0_202(镜像已含 JDK),构建更轻量:
# 在 master 上
mkdir -p /tmp/build-safety-eval/start/target
cp /tmp/safety-eval.jar /tmp/build-safety-eval/start/target/start.jar
cp Dockerfile /tmp/build-safety-eval/
cd /tmp/build-safety-eval
docker build -t jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-YYYYMMDD-1 .
方式 C:复用 master 上已有的张家口 ACR 镜像(最快)
如果张家口 ACR 已有当天构建的镜像(如 jjb-saas-safety-eval-ota-YYYYMMDD-N),直接 retag + push 到杭州 ACR,免去重新构建:
# 在 master 上
SRC=registry.cn-zhangjiakou.aliyuncs.com/kilaa/zcloud-gbs-operation:jjb-saas-safety-eval-ota-YYYYMMDD-N
DST=jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-YYYYMMDD-1
docker pull $SRC
docker tag $SRC $DST
echo 'idurCT!rIq9EzISD' | docker login --username=10952138@qq.com --password-stdin jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com
docker push $DST
阶段 4:部署到 K8s
首次部署(create)
# 在 master 上
/usr/bin/kubectl apply -f deployment.yaml -n jjb-dragon
/usr/bin/kubectl apply -f service.yaml -n jjb-dragon
deployment.yaml 参考(见 docs/deploy/safety-eval-deploy.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
deployLabel: jjb-saas-safety-eval-deploy
name: jjb-saas-safety-eval-deploy
namespace: jjb-dragon
spec:
replicas: 1
selector:
matchLabels:
app: jjb-saas-safety-eval-pod
template:
metadata:
labels:
app: jjb-saas-safety-eval-pod
namespace: jjb-dragon
spec:
containers:
- name: jjb-saas-safety-eval-app
image: jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-YYYYMMDD-N
imagePullPolicy: Always
command: ["/opt/jdk1.8.0_202/bin/java"]
args:
- -Dnacos.namespace=jjb-dragon
- -Dnacos.url=prod-nacos:8848
- -Dspring.profiles.active=prod
- -Dmysql.password=Mysql@zcloud33080
- -Dmysql.host=192.168.20.100
- -Dmysql.port=33080
- -Dmysql.username=root
- -jar
- /opt/app.jar
env:
- name: TZ
value: Asia/Shanghai
ports:
- containerPort: 8095
name: http
- containerPort: 20895
name: dubbo
resources:
limits:
cpu: "1"
memory: 2048M
requests:
cpu: 500m
memory: 512M
imagePullSecrets:
- name: image-pull-secret
service.yaml 参考(见 docs/deploy/safety-eval-svc.yaml):
apiVersion: v1
kind: Service
metadata:
name: jjb-saas-safety-eval
namespace: jjb-dragon
spec:
type: ClusterIP
selector:
app: jjb-saas-safety-eval-pod
ports:
- name: http
port: 80
targetPort: 80
- name: dubbo
port: 20895
targetPort: 20895
更新部署(已存在 deploy)
只替换镜像 tag:
/usr/bin/kubectl set image deployment/jjb-saas-safety-eval-deploy \
jjb-saas-safety-eval-app=jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-YYYYMMDD-N \
-n jjb-dragon
# 强制滚动(不修改镜像时触发重启)
/usr/bin/kubectl rollout restart deployment/jjb-saas-safety-eval-deploy -n jjb-dragon
阶段 5:验证
# Pod 状态
/usr/bin/kubectl get pods -n jjb-dragon | grep safety-eval
# 启动日志
/usr/bin/kubectl logs -f deployment/jjb-saas-safety-eval-deploy -n jjb-dragon --tail=100
# Nacos 注册检查(通过 NodePort)
curl -s "http://192.168.20.100:30290/nacos/v1/ns/instance/list?serviceName=safety-eval-service&namespaceId=jjb-dragon"
# Endpoints
/usr/bin/kubectl get endpoints jjb-saas-safety-eval -n jjb-dragon
正常日志标志:
Tomcat started on port(s): 8095 (http) with context path ''
Nacos registry, DEFAULT_GROUP safety-eval-service 10.x.x.x:8095 register finished
4. 工具清单
| 工具 | 版本 | 位置 | 用途 |
|---|---|---|---|
| Maven | 3.8.8 | 本地 / master /opt/maven |
JAR 编译打包 |
| JDK | 1.8.0_202 | 本地 / master /opt/jdk1.8.0_202 |
Java 运行环境 |
| Docker | 26.1.4 | master /usr/bin/docker |
镜像构建推送 |
| kubectl | v1.27.6 | master /usr/bin/kubectl |
K8s 资源管理 |
| scp / sftp | — | 本地 → master | JAR 文件上传 |
| paramiko | 5.0.0 | 本地 Python 3.11 | SSH 自动化(推荐) |
| ssh | OpenSSH | 本地 Git Bash / cmd | 远程登录 master |
| curl | — | master / 本地 | Nacos/HTTP 验证 |
| build.sh | 自研 | docs/build-tools/build.sh |
一键构建推送(Shell 版) |
| build_push.py | 自研 | docs/build-tools/build_push.py |
本地 Windows 一键构建推送(Python 版) |
5. 常用命令速查
# 登录 master
ssh root@192.168.20.100 # 密码:Zcloud@zcloud100
# 登录杭州 ACR
echo 'idurCT!rIq9EzISD' | docker login --username=10952138@qq.com --password-stdin jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com
# 登录张家口 ACR
echo 'Kilaa@6666' | docker login --username=kilaa --password-stdin registry.cn-zhangjiakou.aliyuncs.com
# 查看 deploy
/usr/bin/kubectl get deploy,pods,svc -n jjb-dragon | grep safety-eval
# 查看日志
/usr/bin/kubectl logs -f deployment/jjb-saas-safety-eval-deploy -n jjb-dragon
# 重启(不改镜像)
/usr/bin/kubectl rollout restart deployment/jjb-saas-safety-eval-deploy -n jjb-dragon
# 进入 Pod
/usr/bin/kubectl exec -it deployment/jjb-saas-safety-eval-deploy -n jjb-dragon -- /bin/bash
# Nacos 控制台
http://192.168.20.100:30290/nacos # nacos/nacos
# Nexus 私服
http://192.168.20.100:8578 # admin/admin123
6. 注意事项与踩坑
-
端口差异排查:本服务本地与容器内均为
8095,Service 用port: 80 / targetPort: 8095。但 GBS 部分老服务会被 Nacosxxx-prod.yml覆盖为80,因此新服务上线前必须用kubectl get endpoints -n jjb-dragon或 Pod 启动日志确认实际监听端口,再填写containerPort与targetPort。Dubbo 端口20895不受影响。 -
镜像仓库选择:K8s
image-pull-secret只配了杭州 ACR。如果从张家口 ACR 拉镜像,Pod 会报ImagePullBackOff。解决方案:- 方案 A:在 master 上 retag + push 到杭州 ACR(推荐)
- 方案 B:给
image-pull-secret追加张家口 ACR 的 auth
-
lb:// URI scheme:SCG 网关路由中若有
lb://协议,不会在 K8s 中被解析,需改为http://{svc-name}直连 K8s DNS,并设filterGatewaName=NULL。 -
Dubbo 注册 namespace:Dubbo provider 注册到 Nacos 的命名空间是
jjb-dragon-facade(带-facade后缀),consumer 必须配置dubbo.registry.parameters.namespace=jjb-dragon-facade。 -
Nacos 不可达导致启动失败:Dubbo 3.2.x 无显式
config-center时会自动从 registry 推导,需同时检查 config-center 配置。 -
镜像 tag 冲突:每天多次发布时,version-suffix(
ota-YYYYMMDD-N的N)需递增,否则ImagePullPolicy: Always拉到的可能是缓存的旧镜像。 -
主节点构建依赖:master 上的
/opt/jdk1.8.0_202是从 Docker 镜像提取的,/opt/maven配置了阿里云镜像。/opt/docker-templates/下有 Dockerfile 模板。
7. 附:账号密码汇总
| 用途 | 地址 | 账号 | 密码/Token |
|---|---|---|---|
| Master SSH | 192.168.20.100:22 |
root |
Zcloud@zcloud100 |
| 杭州 ACR | jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com |
10952138@qq.com |
idurCT!rIq9EzISD |
| 张家口 ACR | registry.cn-zhangjiakou.aliyuncs.com |
kilaa |
Kilaa@6666 |
| 张家口 ACR AK | — | LTAI5tF8GbtKizLAowJbAYmT |
G0ZYeaZtnpxhp0bO1rPp4HPrq57LaT |
| MySQL | 192.168.20.100:33080 |
root |
Mysql@zcloud33080 |
| Nacos | http://192.168.20.100:30290/nacos |
nacos |
nacos |
| Nexus | http://192.168.20.100:8578 |
admin |
admin123 |
8. 文件索引
docs/
├── build-tools/
│ ├── build.sh # Shell 一键构建推送(在 master 上执行)
│ ├── build_push.py # Python 一键构建推送(Windows 本地执行)
│ ├── Dockerfile # CentOS7+JDK 版 Dockerfile 模板
│ ├── README.md # build-tools 使用说明
│ └── install_env.sh # master 环境初始化脚本
├── deploy/
│ ├── safety-eval-deploy.yaml # K8s Deployment
│ └── safety-eval-svc.yaml # K8s Service
└── 本地JAR打包发布到100服务器完整流程.md # 本文档
Dockerfile # 项目根 Dockerfile(基于 pub/jdk:1.8.0_202)
9. 服务启动验证(多种确认方式)
部署完成后需要多维度确认服务已真正可用。下面按"由浅入深"列出 8 种验证方式,建议至少跑完 1~4 步。
所有命令默认在 master 节点(
192.168.20.100)上执行,已登录 root。
9.1 K8s 资源状态检查
# Pod / Deployment 是否 READY 1/1、Running
/usr/bin/kubectl get deploy,pods,svc -n jjb-dragon | grep safety-eval
# 滚动升级是否完成(无旧 ReplicaSet 残留)
/usr/bin/kubectl rollout status deployment/jjb-saas-safety-eval-deploy -n jjb-dragon --timeout=180s
# Endpoints 是否绑到 Pod IP(空说明 Service 没选到 Pod)
/usr/bin/kubectl get endpoints jjb-saas-safety-eval -n jjb-dragon
# 最近事件(ImagePullBackOff、CrashLoopBackOff、OOMKilled 等都能在这里看到)
/usr/bin/kubectl get events -n jjb-dragon --sort-by=.metadata.creationTimestamp \
| grep -i safety-eval | tail -20
# Pod 详情(重点看 Conditions、ContainerStatus、LastState)
/usr/bin/kubectl describe pod -n jjb-dragon -l app=jjb-saas-safety-eval-pod
判断标准:
| 项 | 健康值 |
|---|---|
| Deployment READY | 1/1 |
| Pod STATUS | Running |
| RESTARTS | 0(或长期稳定的小数字) |
| Endpoints | 非空,且包含 Pod IP + 8095,20895 |
9.2 启动日志
# 实时跟踪日志
/usr/bin/kubectl logs -f deployment/jjb-saas-safety-eval-deploy -n jjb-dragon --tail=200
# 只看最后 50 行
/usr/bin/kubectl logs deployment/jjb-saas-safety-eval-deploy -n jjb-dragon --tail=50
关键日志标志:
Tomcat started on port(s): 8095 (http) with context path ''
Nacos registry, DEFAULT_GROUP safety-eval-service 10.244.x.x:8095 register finished
失败标志(出现任一则服务不可用):
APPLICATION FAILED TO STARTBeanCreationException/UnsatisfiedDependencyExceptionConnection refused到 MySQL / Nacos / RedisUnable to acquire JDBC ConnectionAddress already in useKilled(OOM,需调大resources.limits.memory)
9.3 Nacos 服务注册(控制台 + API)
控制台:浏览器打开 http://192.168.20.100:30290/nacos,账号 nacos/nacos。
- 左上角切换命名空间到
jjb-dragon - 菜单 → 服务管理 → 服务列表 → 搜索
safety-eval-service - 点进去查看实例列表,健康状态应为绿色
健康
API 方式(适合脚本化):
# 列出 jjb-dragon 命名空间下所有服务
curl -s "http://192.168.20.100:30290/nacos/v1/ns/service/list?pageNo=1&pageSize=200&namespaceId=jjb-dragon" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print([s for s in d['doms'] if 'safety' in s])"
# 查看 safety-eval-service 的实例健康状态
curl -s "http://192.168.20.100:30290/nacos/v1/ns/instance/list?serviceName=safety-eval-service&namespaceId=jjb-dragon" \
| python3 -m json.tool
判断标准:hosts[].healthy=true、enabled=true、port=8095,且至少有一条实例 IP 是当前 Pod IP。
9.4 Dubbo Provider 注册
Dubbo 服务注册在独立的命名空间 jjb-dragon-facade:
# 列出 Dubbo 服务
curl -s "http://192.168.20.100:30290/nacos/v1/ns/service/list?pageNo=1&pageSize=500&namespaceId=jjb-dragon-facade" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print([s for s in d['doms'] if 'safety' in s.lower() or 'Cqanquan' in s or 'cqanquan' in s])"
# 查看某个 Dubbo 接口的实例
curl -s "http://192.168.20.100:30290/nacos/v1/ns/instance/list?serviceName=providers:com.xxx.XxxService::&namespaceId=jjb-dragon-facade"
判断标准:providers:com.xxx.XxxService::jjb-dragon 形式的条目存在且健康。
9.5 Spring Boot Actuator
如果 application.yml 开启了 actuator,可直接访问健康/信息端点。
# 从 Pod 内部访问
/usr/bin/kubectl exec -it deployment/jjb-saas-safety-eval-deploy -n jjb-dragon -- \
curl -s http://localhost:8095/actuator/health
# 从 master 经 Pod IP 访问
POD_IP=$(/usr/bin/kubectl get pod -n jjb-dragon -l app=jjb-saas-safety-eval-pod \
-o jsonpath='{.items[0].status.podIP}')
curl -s "http://${POD_IP}:8095/actuator/health"
curl -s "http://${POD_IP}:8095/actuator/info"
判断标准:{"status":"UP"} 且各 component(db、nacos、dubbo 等)无 DOWN。
9.6 集群内直连(Pod → Pod)
进入一个同集群的 Pod,直接 curl 目标服务的 HTTP 接口:
# 进入 safety-eval 自己的 Pod 测试
/usr/bin/kubectl exec -it deployment/jjb-saas-safety-eval-deploy -n jjb-dragon -- /bin/bash
# 在 Pod 内
curl -s http://localhost:8095/safety-eval/ # context-path
curl -s http://localhost:8095/actuator/health
# 从另一个 Pod(如 jjb-saas-base)测试跨服务调用
/usr/bin/kubectl exec -it deployment/jjb-saas-base-deploy -n jjb-dragon -- \
curl -s http://jjb-saas-safety-eval/safety-eval/
判断标准:HTTP 200 或返回业务 JSON,而非 Connection refused / 502。
9.7 通过网关访问(NodePort)
网关 NodePort 30140,路由通过 MySQL jjb-saas-gateway.route 表配置。本服务的 gateway=cqanquan,需携带 filterGatewaName 请求头:
# 从 master / 任意能访问 100 的机器
curl -i "http://192.168.20.100:30140/safety-eval/" \
-H "filterGatewaName: cqanquan"
# 带 Token 的业务请求示例
curl "http://192.168.20.100:30140/safety-eval/api/xxx" \
-H "filterGatewaName: cqanquan" \
-H "Authorization: Bearer <token>"
判断标准:
200/401/404等业务状态码 → 服务已通502 Bad Gateway/503 Service Unavailable→ 服务未注册或端口不对404但网关日志有路由 → 路由正常,接口路径不对
9.8 本地开发机 port-forward(调试用)
把 K8s Service 映射到本地,浏览器或 Postman 直接访问:
# 本地 Windows PowerShell / Git Bash
ssh -L 8095:jjb-saas-safety-eval:80 root@192.168.20.100
# 或
kubectl port-forward svc/jjb-saas-safety-eval 8095:80 -n jjb-dragon
然后本地访问 http://localhost:8095/safety-eval/ 即可。
验证清单(推荐顺序)
| # | 检查项 | 命令 / 工具 | 预期 |
|---|---|---|---|
| 1 | Pod Running + Endpoints 有值 | kubectl get pods,endpoints |
1/1 Running、IP:8095,20895 |
| 2 | 启动日志无报错 | kubectl logs --tail=200 |
出现 Tomcat started on port(s): 8095 |
| 3 | Nacos 注册成功 | Nacos 控制台 / API | safety-eval-service healthy=true |
| 4 | Dubbo Provider 注册 | Nacos API(jjb-dragon-facade) | providers:xxx::jjb-dragon 存在 |
| 5 | Actuator 健康 | curl /actuator/health |
{"status":"UP"} |
| 6 | Pod 内 HTTP 可达 | curl localhost:8095/safety-eval/ |
200 或业务 JSON |
| 7 | 网关路由可达 | curl :30140/safety-eval/ -H filterGatewaName:cqanquan |
非 502/503 |
| 8 | 业务接口冒烟 | Postman 或 curl 调用真实接口 | 业务返回正常 |