## GBS Java 应用 Docker 镜像打包操作流程

### 目录结构

```
build-tools/
├── README.md           ← 本文档
├── Dockerfile          ← Dockerfile 模板（CentOS 7 + JDK 1.8.0_202）
├── build.sh            ← Shell 构建脚本（在 master 节点上执行）
├── build_push.py       ← Python 构建脚本（在本地 Windows 上执行，自动上传+构建+推送）
└── install_env.sh      ← 构建环境一键安装脚本（在 master 节点上执行）
```

### 环境信息

| 项目 | 信息 |
|------|------|
| Master 节点 | 192.168.20.100 (root / Zcloud@zcloud100) |
| OS | CentOS 7 (已 EOL，yum 源已切换阿里云 vault) |
| JDK | Oracle JDK 1.8.0_202，路径 `/opt/jdk1.8.0_202` |
| Maven | Apache Maven 3.8.8，路径 `/opt/maven`，阿里云镜像 |
| Docker | 26.1.4，cgroupdriver=systemd，storage=overlay2 |
| ACR 仓库 | `jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com` |
| ACR 命名空间 | `ali_img_ns` |
| K8s 命名空间 | `jjb-dragon` |

### 镜像命名规则

完整镜像地址格式：

```
{ACR仓库}/{命名空间}/prod-aly-{环境前缀}-dragon-{应用名}:{环境前缀}-{日期}-{序号}
```

示例：

```
jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1
```

各部分说明：

- `prod-aly` — 固定前缀（生产环境-阿里云）
- `ota` — 环境前缀，对应不同业务模块
- `dragon` — 项目代号
- `jjb-saas-safety-eval` — 应用名称
- `ota-20260626-1` — 标签：环境前缀-年月日-序号（同一天多次构建递增序号）

---

### 方式一：本地一键构建（推荐）

在本地 Windows 机器上执行 `build_push.py`，自动完成 JAR 上传 → Docker 构建 → ACR 推送。

**前置条件：** 本地已安装 Python 和 paramiko（`pip install paramiko`）

**执行命令：**

```bash
python build_push.py <JAR文件路径> <应用名> <环境前缀> [序号]
```

**示例：**

```bash
python build_push.py E:\projects\safety-eval-service\safety-eval-start\target\safety-eval-start-1.0-SNAPSHOT.jar jjb-saas-safety-eval ota 1
```

**输出：**

```
Image Address:
  jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1
```

---

### 方式二：在 Master 节点上构建

SSH 登录 master 节点后，使用 `build.sh` 脚本构建。

**Step 1 — 上传 JAR 到 master 节点**

在本地用 scp 或其他方式上传 JAR：

```bash
scp safety-eval-start-1.0-SNAPSHOT.jar root@192.168.20.100:/tmp/
```

**Step 2 — SSH 登录 master**

```bash
ssh root@192.168.20.100
# 密码: Zcloud@zcloud100
```

**Step 3 — 执行构建脚本**

```bash
source /etc/profile.d/java.sh
source /etc/profile.d/maven.sh
/opt/docker-templates/build.sh jjb-saas-safety-eval ota /tmp/safety-eval-start-1.0-SNAPSHOT.jar 1
```

脚本会自动完成：准备构建上下文 → 复制 JDK → Docker build → Docker login ACR → Docker push。

---

### 方式三：手动分步操作

如果需要手动控制每一步：

**Step 1 — 准备构建目录**

```bash
BUILD_DIR=/tmp/manual-build
rm -rf $BUILD_DIR && mkdir -p $BUILD_DIR/target
```

**Step 2 — 复制 JDK 和 JAR**

```bash
cp -r /opt/jdk1.8.0_202 $BUILD_DIR/
cp /path/to/your-app.jar $BUILD_DIR/target/
cp /opt/docker-templates/Dockerfile $BUILD_DIR/
```

**Step 3 — Docker Build**

```bash
docker build -t jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1 $BUILD_DIR
```

**Step 4 — 登录 ACR**

```bash
echo 'idurCT!rIq9EzISD' | docker login --username=10952138@qq.com --password-stdin jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com
```

**Step 5 — 推送镜像**

```bash
docker push jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1
```

**Step 6 — 清理**

```bash
rm -rf $BUILD_DIR
```

---

### 从源码构建（Maven 打包 + Docker 构建）

如果拿到的是 Java 源码而不是编译好的 JAR：

```bash
source /etc/profile.d/java.sh
source /etc/profile.d/maven.sh

# Maven 编译打包
cd /path/to/project
mvn clean package -DskipTests

# 然后用编译好的 JAR 走上面的构建流程
/opt/docker-templates/build.sh <app-name> <env-prefix> target/xxx.jar 1
```

Maven 已配置阿里云镜像（`maven.aliyun.com/repository/public`），依赖下载速度约 200-400 KB/s。

---

### K8s 部署命令

**创建新 Deployment：**

```bash
/usr/bin/kubectl create deployment jjb-saas-safety-eval \
  --image=jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1 \
  -n jjb-dragon --replicas=1
```

**更新已有 Deployment 的镜像：**

```bash
/usr/bin/kubectl set image deployment/jjb-saas-safety-eval \
  jjb-saas-safety-eval=jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1 \
  -n jjb-dragon
```

**查看 Pod 状态：**

```bash
/usr/bin/kubectl get pods -n jjb-dragon | grep safety-eval
```

**查看日志：**

```bash
/usr/bin/kubectl logs -f deployment/jjb-saas-safety-eval -n jjb-dragon
```

**查看 Deployment 详情：**

```bash
/usr/bin/kubectl describe deployment jjb-saas-safety-eval -n jjb-dragon
```

---

### 常用查询命令

**查看本地镜像：**

```bash
docker images | grep jjb-saas-safety-eval
```

**查看镜像详情：**

```bash
docker inspect jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1
```

**查看镜像构建历史：**

```bash
docker history jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1
```

**本地测试运行：**

```bash
docker run --rm -it --name safety-eval-test \
  -p 8080:8080 \
  jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com/ali_img_ns/prod-aly-ota-dragon-jjb-saas-safety-eval:ota-20260626-1
```

**列出 ACR 上所有已有镜像：**

```bash
docker images --format '{{.Repository}}:{{.Tag}}' | grep 'ali_img_ns'
```

---

### 构建环境安装

首次使用新机器时，运行 `install_env.sh` 一键安装全部构建依赖：

```bash
ssh root@192.168.20.100
bash install_env.sh
```

该脚本会安装并配置：JDK 1.8.0_202、Maven 3.8.8（阿里云镜像）、Dockerfile 模板、yum vault 源、ACR 登录。

---

### Dockerfile 结构说明

镜像内部结构（从已有运行镜像逆向分析得出）：

```
/
├── opt/
│   ├── jdk1.8.0_202/     ← Oracle JDK 1.8.0_202
│   ├── app.jar           ← 应用 JAR 包
│   └── logs/             ← 日志目录
```

容器启动命令（ENTRYPOINT）：

```
/opt/jdk1.8.0_202/bin/java
  -Dnacos.namespace=jjb-dragon
  -Dnacos.url=prod-nacos:8848
  -Dspring.profiles.active=prod
  -Dmysql.password=***
  -Dmysql.host=192.168.20.100
  -Dmysql.port=33080
  -Dmysql.username=root
  -jar /opt/app.jar
```

运行时可通过 K8s deployment 的 `args` 或 `env` 字段覆盖以上参数。

---

### 故障排查

**问题：`yum install` 报错 404**
CentOS 7 已 EOL，确认 `/etc/yum.repos.d/CentOS-Base.repo` 使用 `centos-vault` 源（install_env.sh 会自动处理）。

**问题：Maven 下载依赖慢**
检查 `/root/.m2/settings.xml` 是否配置了阿里云镜像，mirrorOf 应为 `central`。

**问题：`docker push` 报 unauthorized**
重新登录 ACR：`echo 'idurCT!rIq9EzISD' | docker login --username=10952138@qq.com --password-stdin jjb-registry-registry.cn-hangzhou.cr.aliyuncs.com`

**问题：K8s 拉取镜像失败 (ImagePullBackOff)**
确认 `jjb-dragon` namespace 下有 `image-pull-secret` 或 `image-pull-secret1`：
```bash
/usr/bin/kubectl get secret -n jjb-dragon | grep image-pull
```
