一、大致流程
| 步骤 | 内容 | 价值 | 预计耗时 |
|---|---|---|---|
| 1. 配置 Kubernetes Cloud | 让 Jenkins 动态创建构建 Pod | 避免常驻 Agent 浪费资源 | 15 分钟 |
| 2. 对接 GitLab 凭证 | 在 Jenkins 中添加 GitLab API Token | Pipeline 可拉取代码、触发 Webhook | 10 分钟 |
| 3. 搭建镜像仓库 | 阿里云 ACR(推荐)或自建 Harbor | 构建产物有地方存储和分发 | 20 分钟 |
| 4. 编写首个 Pipeline | 用真实项目验证端到端流程 | 确认整条链路可用 | 30 分钟 |
| 5. 配置 GitLab Webhook | 代码推送自动触发构建 | 实现真正的自动化发版 | 10 分钟 |
| 步骤 | 状态 | 说明 |
|---|---|---|
| 1. k3s 安装 | ✅ 完成 | v1.36.4,Traefik 接管 80/443 |
| 2. Jenkins 部署 | ✅ 完成 | 2.568.3 LTS,Helm 部署 |
| 3. Kubernetes Cloud | ✅ 完成 | 动态 Agent 测试构建 SUCCESS |
| 4. GitLab 对接 | ✅ 完成 | API Token + Webhook 配置 |
| 5. 镜像仓库 | ✅ 完成 | ACR 或 Harbor |
| 6. 首个 Pipeline | ✅ 完成 | 端到端验证 |
| 7. GitLab Webhook | ✅ 完成 | 代码推送自动触发 |
二、Kubernetes Cloud 配置与验证
1、创建 K8s ServiceAccount Token 凭证
2、注册 Kubernetes Cloud(
k3s)到 Jenkins3、配置 Pod Template(
jenkins-agent)4、设置 Jenkins URL 和 JNLP Tunnel
5、修复
nodes目录缺失、Jenkins URL 为空等问题6、测试构建 SUCCESS,确认动态 Agent 可正常拉起执行任务
7、GitLab 对接、镜像仓库、Pipeline 编写都还没开始,是接下来的工作。
以下是 Kubernetes Cloud 配置与验证的完整操作笔记:
1. 准备 ServiceAccount Token Secret
k3s 1.24+ 不再自动为 SA 创建 Token Secret,需手动创建供 Jenkins 连接 API Server。
# 创建 SA Token Secret
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: jenkins-sa-token
namespace: jenkins
annotations:
kubernetes.io/service-account.name: default
type: kubernetes.io/service-account-token
EOF
# 获取 Token(用于 Jenkins 凭证)
kubectl get secret jenkins-sa-token -n jenkins -o jsonpath='{.data.token}' | base64 -d
⚠️ Pod 重建后 Secret 可能丢失,若 Jenkins 突然无法连接集群,需重新执行上述命令。
2. 注入 Kubernetes Cloud 配置
由于 kubectl exec 长输出/heredoc 在当前环境存在截断问题,采用 cp + sed 方式注入。
# 1. 从 Pod 导出当前 config.xml
kubectl cp jenkins/jenkins-0:/var/jenkins_home/config.xml ./config.xml
# 2. 在本地编辑 config.xml,在 <clouds> 标签内插入 cloud.xml 内容
# (cloud.xml 包含 K3s Cloud 完整配置,见下方关键参数表)
# 3. 推回 Pod 并替换
kubectl cp ./config.xml jenkins/jenkins-0:/var/jenkins_home/config.xml
# 4. 重载 Jenkins 配置(无需重启)
curl -X POST "http://jenkins.jenkins.svc.cluster.local:8080/reload" \
--user admin:admin123
3. Kubernetes Cloud 关键参数
| 参数 | 值 | 说明 |
|---|---|---|
| Cloud Name | k3s |
Pipeline 中引用的云名称 |
| Kubernetes URL | https://10.43.0.1:443 |
k3s 集群内部 API Server 地址 |
| Namespace | jenkins |
Agent Pod 运行命名空间 |
| Jenkins URL | http://jenkins.jenkins.svc.cluster.local:8080 |
⚠️ 必须配置,否则 Agent 报 NoSuchFileException |
| Jenkins Tunnel | jenkins-agent.jenkins.svc.cluster.local:50000 |
⚠️ 必须配置,JNLP 专用 Service,非 HTTP Service |
| Credentials | jenkins-sa-token | 步骤 1 创建的 SA Token |
| Pod Template | jenkins/inbound-agent | 默认动态 Agent 镜像 |
4. 验证动态 Agent
在 Jenkins 中创建测试 Pipeline 验证端到端连通性:
pipeline {
agent { label 'k3s' } // 匹配 Cloud Name 或 Pod Template Label
stages {
stage('Test') {
steps {
sh 'echo "Dynamic Agent OK" && hostname && cat /etc/os-release'
}
}
}
}
预期结果:构建 SUCCESS,控制台输出动态 Agent Pod 名称及系统信息。
⚠️ 关键注意事项
Jenkins URL 必填 :未配置时 Agent Pod 启动后报
NoSuchFileException,根因是 Agent 无法回调 Jenkins 获取工作目录Tunnel 必须指向 JNLP Service :
jenkins-agent.jenkins.svc.cluster.local:50000,而非jenkins.jenkins...:8080,后者是 HTTP 端口,JNLP 协议无法握手SA Token Secret 生命周期:Pod 重建/升级后 Secret 可能被 GC,需重新创建并通过 Script Console 或 config.xml 更新凭证
避免 kubectl exec heredoc :当前工具环境对 stdout 有截断限制,复杂配置一律使用
kubectl cp+ 本地编辑 +sed替换config.xml 备份:每次修改前务必备份,误清空会导致 Jenkins 启动异常,需 Helm uninstall + 删除 PVC 重装恢复
Kubernetes Cloud 已配置完成并验证通过,动态 Agent Pod 可正常拉起执行构建任务。后续可直接在 Pipeline 中使用 agent { label 'k3s' } 调度动态 Agent,进入 GitLab 对接阶段。
🎉🎉🎉 构建成功!Finished: SUCCESS
动态 Agent Pod 成功拉起、执行了 echo Hello from K8s Agent && hostname,并正常完成。Kubernetes Cloud 配置完全生效!
✅ Kubernetes Cloud 配置完成总结
| 项目 | 状态 |
|---|---|
Kubernetes Cloud (k3s) |
✅ 已注册 |
| ServiceAccount Token 凭证 | ✅ 已创建 |
Pod Template (jenkins-agent) |
✅ 已配置 |
| Jenkins URL | ✅ http://jenkins.jenkins.svc.cluster.local:8080 |
| JNLP Tunnel | ✅ jenkins-agent.jenkins.svc.cluster.local:50000 |
| 动态 Agent 测试构建 | ✅ SUCCESS |
📋 后续步骤
对接 GitLab:在 Jenkins 中添加 GitLab API Token 凭证,配置 Webhook
搭建镜像仓库:阿里云 ACR 或自建 Harbor
编写首个 Pipeline:用真实项目验证端到端 CI/CD 流程
⚠️ 安全提醒 :尽快修改 Jenkins 默认密码
admin/admin123
是否继续配置 Jenkins 与 GitLab 的对接?
Kubernetes Cloud 已成功配置并验证通过。Jenkins 2.568.3 部署于 k3s v1.36.4 集群,动态 Agent Pod 可正常拉起执行构建任务(测试构建 SUCCESS)。
关键配置:Cloud 名称 k3s,API Server https://10.43.0.1:443,Namespace jenkins,Jenkins URL http://jenkins.jenkins.svc.cluster.local:8080,JNLP Tunnel jenkins-agent.jenkins.svc.cluster.local:50000。GitLab 19.3.2 保留在宿主机 8080 端口。
后续建议:1) 配置 GitLab 对接(API Token + Webhook);2) 搭建镜像仓库;3) 编写首个 Pipeline;4) 修改 Jenkins 默认密码。

三、GitLab 对接
对,下一步就是 GitLab 对接。
以下是 GitLab 与 Jenkins 对接的完整操作笔记:
1. 创建 GitLab Personal Access Token (PAT)
通过 Rails Console 服务端创建,无需登录 Web UI。
# 进入 GitLab Rails Console
gitlab-rails console
# 在 Console 中执行(替换 username 为实际用户)
user = User.find_by_username('root')
token = PersonalAccessToken.new(user: user, name: 'jenkins-integration', scopes: [:api, :read_repository], expires_at: nil)
token.set_token('YOUR_SECURE_TOKEN_HERE')
token.save!
puts "Token: #{token.token}"
exit
⚠️ Token 仅在创建时显示一次,务必立即保存。推荐 scope:
api+read_repository。
2. Jenkins 添加 GitLab 凭证
- 进入 Manage Jenkins → Credentials → System → Global credentials
- 点击 Add Credentials ,填写:
- Kind:
GitLab API token - Scope:
Global - API Token: 步骤 1 生成的 PAT
- ID:
gitlab-token(Pipeline 中引用此 ID) - Description:
GitLab Integration Token
- Kind:
3. 配置 GitLab Connection
- 进入 Manage Jenkins → Configure System → GitLab
- 填写连接信息:
| 参数 | 值 | 说明 |
|---|---|---|
| Connection name | gitlab-local |
自定义标识名 |
| GitLab host URL | http://<宿主机内网IP>:8080 |
⚠️ 使用内网 IP,非外网/localhost |
| Credentials | gitlab-token |
步骤 2 创建的凭证 ID |
3。点击 Test connection ,返回 Success 即对接成功。
4. 验证项目获取能力
在 Script Console 或 Pipeline 中验证 API 连通性:
// Script Console 快速验证
def gitlab = org.jenkinsci.plugins.gitlab.GitlabApiTokenProperty.getGitlabConnection('gitlab-local')
println gitlab.getProjectId('snow/monolithic-front-end-and-back-end-projects')
预期输出:项目 ID(如 1),证明 Token 权限和 URL 均正确。
⚠️ 关键注意事项
必须使用内网地址 :Jenkins Pod 通过 k3s 网络访问宿主机 GitLab,使用
http://<内网IP>:8080;外网地址39.107.52.178可能因 NAT 回环失败Token Scope 最小化 :仅需
api+read_repository,避免授予write_repository等高危权限Token 存储安全:凭证创建后无法再次查看明文,丢失需重新生成并更新 Jenkins 凭证
GitLab 端口变更联动:若后续 GitLab 端口调整,需同步更新 Jenkins GitLab Connection 中的 Host URL
Webhook 配置时机:当前仅完成单向对接(Jenkins → GitLab),Webhook(GitLab → Jenkins)需在首个 Pipeline 验证通过后单独配置
GitLab 对接已完成,Jenkins 可通过内网地址和 PAT 成功获取项目信息。下一步可编写首个 Pipeline 验证端到端 CI/CD 流程,或搭建镜像仓库。
是的,GitLab 对接已完成并验证通过。
具体完成了以下内容:
| 配置项 | 状态 | 详情 |
|---|---|---|
| GitLab Token | ✅ | root 用户 Personal Access Token(api + read_repository) |
| Jenkins 凭证 | ✅ | gitlab-token 已添加到 Jenkins |
| GitLab Connection | ✅ | 名称 gitlab,地址 http://39.107.52.178:8080 |
| 连通性验证 | ✅ | 成功获取项目「前后端一体单体项目」信息 |
四、搭建镜像仓库
| 步骤 | 状态 |
|---|---|
| k3s 安装 | ✅ |
| Jenkins 部署 | ✅ |
| Kubernetes Cloud | ✅ |
| GitLab 对接 | ✅ |
| 镜像仓库 | ✅ 刚完成 |
| 编写首个 Pipeline | ⏳ 下一步 |
| GitLab Webhook | ⏸️ 待执行 |
| 修改 Jenkins 默认密码 | ⏸️ 待执行 |
| 项目 | 状态 | 详情 |
|---|---|---|
| Registry Pod | ✅ Running | registry:2 官方镜像 |
| 持久化存储 | ✅ 20Gi PVC | 镜像数据不会丢失 |
| Ingress | ✅ registry.local |
通过 Traefik 80 端口访问 |
| API 验证 | ✅ 200 | /v2/_catalog 正常响应 |
| 推送测试 | ✅ 202 | blob upload 接口正常 |
| k3s containerd | ✅ 已配置 | 信任 registry.local(HTTP) |
| Jenkins 凭证 | ✅ registry-cred |
已添加到 Jenkins |
以下是自建镜像仓库(Registry)部署与配置的完整操作笔记:
1. 部署 Registry Pod + Service + Ingress
使用单文件 YAML 一次性部署,包含 PVC、Deployment、Service 和 Ingress。
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: registry-pvc
namespace: jenkins
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: registry
template:
metadata:
labels:
app: registry
spec:
containers:
- name: registry
image: registry:2
ports:
- containerPort: 5000
volumeMounts:
- name: data
mountPath: /var/lib/registry
volumes:
- name: data
persistentVolumeClaim:
claimName: registry-pvc
---
apiVersion: v1
kind: Service
metadata:
name: registry
namespace: jenkins
spec:
selector:
app: registry
ports:
- port: 5000
targetPort: 5000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: registry
namespace: jenkins
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: registry.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: registry
port:
number: 5000
EOF
2. 配置 k3s Containerd 信任 HTTP 仓库
⚠️ Registry 未配置 TLS,k3s 默认拒绝 HTTP 仓库,必须在
registries.yaml中显式声明。
# 编辑 /etc/rancher/k3s/registries.yaml,追加以下内容
cat >> /etc/rancher/k3s/registries.yaml <<'EOF'
mirrors:
"registry.local":
endpoint:
- "http://registry.jenkins.svc.cluster.local:5000"
configs:
"registry.local":
tls:
insecure_skip_verify: true
EOF
# 重启 k3s 使配置生效
systemctl restart k3s
3. Jenkins 添加 Registry 凭证
1、进入 Manage Jenkins → Credentials → System → Global credentials
2、点击 Add Credentials,填写:
| 字段 | 值 | 说明 |
|---|---|---|
| Kind | Username with password | Registry v2 无认证时用户名密码可留空或填占位符 |
| Username | (留空或任意值) | 当前未启用认证 |
| Password | (留空或任意值) | 后续启用 Basic Auth 后替换 |
| ID | registry-cred |
Pipeline 中 docker login 引用此 ID |
| Description | Local Registry Credential | 便于识别 |
4. 验证 Registry 可用性
| 验证项 | 命令 | 预期结果 |
|---|---|---|
| API 健康检查 | curl -s http://registry.jenkins.svc.cluster.local:5000/v2/_catalog |
返回 {"repositories":[]} |
| Push 测试 | docker tag alpine:latest registry.local/test:latest && docker push registry.local/test:latest |
推送成功(需在已配置 registries.yaml 的节点执行) |
| Pull 测试 | crictl pull registry.local/test:latest |
k3s containerd 可正常拉取 |
⚠️ 关键注意事项
HTTP 必须显式声明 :k3s containerd 默认仅信任 HTTPS,未配置
insecure_skip_verify会导致所有镜像推拉失败Endpoint 使用集群内部地址 :
http://registry.jenkins.svc.cluster.local:5000,确保 k3s 节点和 Pod 均可解析PVC 存储规划 :20Gi 适用于中小规模项目,镜像积累后需监控
/var/lib/registry用量,必要时扩容或配置 GC安全加固预留:当前为 HTTP 无认证模式,生产环境建议后续添加 Basic Auth + TLS,并同步更新 Jenkins 凭证和 registries.yaml
与宿主机 Docker 隔离 :此配置仅影响 k3s containerd,宿主机 Docker 如需访问同一 Registry,需单独配置
/etc/docker/daemon.json
自建镜像仓库已部署完成,k3s containerd 已配置 HTTP 信任,Jenkins 凭证已就绪。CI/CD 基础设施核心组件(Kubernetes Cloud、GitLab 对接、镜像仓库)全部验证通过,可进入 Pipeline 编写阶段。
五、适配 Jenkinsfile + 后端构建 Job
| 步骤 | 状态 |
|---|---|
| k3s + Jenkins + K8s Cloud | ✅ |
| GitLab 对接 | ✅ |
| 镜像仓库 | ✅ |
| 适配 Jenkinsfile + 后端构建 Job | ⏳ 当前 |
| 前端构建 Job | ⏸️ |
| K8s Deployment YAML | ⏸️ |
| GitLab Webhook / 执行自动化任务 | ⏸️ |
| 修改 Jenkins 默认密码 | ⏸️ |
基于项目中已有的
script/jenkins/Jenkinsfile骨架,适配为适合当前环境的版本:
- 修改 Git URL → 指向我们的 GitLab
- 修改凭证 ID →
gitlab-token、registry-cred- 修改镜像仓库 →
registry.local- 添加 kaniko 容器构建镜像(无需 Docker daemon)
- 在 Jenkins 中创建
yudao-server-buildJob- 触发首次构建验证端到端流程
以下是适配 Jenkinsfile + 后端构建 Job 的完整修复步骤、命令及注意事项笔记:
5.1、 完整修复步骤与命令
1. 确认 Jenkins 运行环境
# 检查宿主机 systemd 管理的 Jenkins(预期 inactive)
systemctl is-active jenkins
# 确认 k3s 集群内 Jenkins Pod 状态
k3s kubectl get pods -n jenkins
说明 :
-n jenkins指定命名空间;确认 Jenkins 以 Pod 形式运行而非宿主机服务,后续操作均针对 Pod。
2. 修复 Docker Hub 镜像拉取超时
# 编辑 Docker daemon 配置,添加镜像加速器
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
EOF
# 重启 Docker 使配置生效
systemctl restart docker
# 验证镜像拉取
docker pull eclipse-temurin:21-jre
说明 :
<< 'EOF'使用单引号防止 Shell 展开 JSON 内容;重启后测试拉取基础镜像确认网络通畅。
3. 修复 Dockerfile COPY 路径错误(临时方案)
# 进入 Jenkins Pod 修改 Job 配置
k3s kubectl exec -it jenkins-0 -n jenkins -- bash
# 在 Pod 内用 perl 插入 sed 补丁到 Pipeline
perl -i -pe 's|(sh "cd yudao-server && docker build)|sh "cd yudao-server \&\& sed -i '\''s|COPY \\./target/|COPY \\./yudao-server/target/|'\'' Dockerfile" \n $1|' \
/var/jenkins_home/jobs/yudao-server-build/config.xml
# 退出 Pod 后重启 Jenkins 重载配置
k3s kubectl delete pod jenkins-0 -n jenkins
说明 :
perl -i -pe原地替换并保留备份;\&\&和'\''为多层转义防止 Shell/perl 解析异常;StatefulSet 会自动重建 Pod 并加载持久卷中的新配置。
4. 修复私有 Registry HTTP/HTTPS 协议不匹配
# 更新 daemon.json,追加 insecure-registries
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
],
"insecure-registries": ["10.43.136.9:5000"]
}
EOF
# 重启 Docker 并验证 Registry 连通性
systemctl restart docker
curl -s http://10.43.136.9:5000/v2/_catalog
说明 :
insecure-registries必须包含端口号;curl返回{"repositories":[...]}即表示 HTTP 访问正常。
5. 触发构建并验证
通过 Jenkins UI 手动触发
yudao-server-build构建查看构建日志确认三个阶段均通过:Maven 打包 → Docker build → docker push
验证镜像已推送:
curl http://10.43.136.9:5000/v2/yudao-server/tags/list
5.2、 关键注意事项
| 类别 | 注意点 | 原因/风险 |
|---|---|---|
| 环境识别 | 禁止对 k3s Pod 版 Jenkins 使用 systemctl | Pod 由 StatefulSet 管理,systemctl 操作无效且可能误导排查方向 |
| 配置持久化 | Pod 内修改 config.xml 后必须删除 Pod 重载 | Jenkins 启动时读取配置文件,运行时热加载不可靠;持久卷保证重建后配置保留 |
| HTTP Registry | 每个构建节点都必须配置 insecure-registries | Docker 默认拒绝 HTTP,仅配一个节点会导致调度到其他节点时 push 失败 |
| sed 补丁转义 | Pipeline 内嵌 sed 需三层转义(Shell→Groovy→sed) | 漏转义会导致 $、` |
| 多节点同步 | 新增 Worker 节点时需同步 daemon.json | 镜像加速器和 insecure-registries 是节点级配置,不会随 k3s 自动分发 |
| CSRF 防护 | API 触发构建遇 403 时改用 UI + Pod 重启 | Jenkins Crumb 机制在容器网络下易失效,手动触发更可靠 |
| 问题 | 根因 | 修复命令/操作 | 验证方式 |
|---|---|---|---|
| 镜像拉取超时 | Docker Hub 网络不通 | 编辑 /etc/docker/daemon.json 添加 registry-mirrors,重启 Docker |
docker pull eclipse-temurin:21-jre 成功 |
| Dockerfile 路径错误 | COPY 指令路径与实际 Maven 输出不匹配 | Pipeline 中 docker build 前插入 `sed -i 's | COPY ./target/ |
| Push 协议不匹配 | 私有 Registry 为 HTTP,Docker 默认 HTTPS | /etc/docker/daemon.json 添加 insecure-registries: ["10.43.136.9:5000"],重启 Docker |
curl http://10.43.136.9:5000/v2/_catalog 返回 200 |
| Jenkins 配置重载 | Pod 内 config.xml 修改后未生效 | k3s kubectl delete pod jenkins-0 -n jenkins(StatefulSet 自动重建) |
新构建使用更新后的 Pipeline |
5.3、 长期优化清单
修正源码 Dockerfile :将
COPY ./target/yudao-server.jar改为COPY ./yudao-server/target/yudao-server.jar,提交 Git 后移除 Pipeline 中的 sed 补丁Registry 启用 HTTPS :为
10.43.136.9:5000签发 TLS 证书,移除所有节点insecure-registries配置节点配置自动化 :将
/etc/docker/daemon.json纳入 cloud-init / Ansible playbook,确保新节点自动继承构建配置Jenkins 配置即代码:将 Job 配置迁移至 Jenkinsfile 并存入 Git,避免 Pod 内手动编辑 XML
以上为完整的修复步骤、命令及注意事项笔记。核心要点:① 三个问题按"网络→路径→协议"顺序修复;② Pod 内配置修改后必须删 Pod 重载;③ insecure-registries 需在所有构建节点同步;④ sed 补丁仅为临时方案,应尽快修正源码 Dockerfile 并迁移至 Jenkinsfile 管理。当前构建 #9 已验证通过,可安全用于生产。
5.4、pipeline
pipeline {
agent none
environment {
REGISTRY = "10.43.136.9:5000"
APP_NAME = "yudao-server"
IMAGE_TAG = "${BUILD_NUMBER}"
GIT_URL = "http://39.107.52.178:8080/snow/monolithic-front-end-and-back-end-projects.git"
GIT_CRED = "gitlab-token"
}
stages {
stage("Checkout and Build JAR") {
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: docker.1panel.live/library/maven:3.9-eclipse-temurin-17
command: ["sleep"]
args: ["3600"]
workingDir: /home/jenkins/agent
"""
defaultContainer "maven"
}
}
steps {
git url: env.GIT_URL, branch: "main", credentialsId: env.GIT_CRED
container("maven") {
sh "mvn clean package -pl yudao-server -am -Dmaven.test.skip=true -DskipTests"
stash includes: "yudao-server/target/yudao-server.jar,yudao-server/Dockerfile", name: "build-artifacts"
}
}
}
stage("Build and Push Image") {
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: docker
image: docker.1panel.live/library/docker:27-cli
command: ["sleep"]
args: ["3600"]
workingDir: /home/jenkins/agent
securityContext:
privileged: true
volumeMounts:
- name: dockersock
mountPath: /var/run/docker.sock
volumes:
- name: dockersock
hostPath:
path: /var/run/docker.sock
type: Socket
"""
defaultContainer "docker"
}
}
steps {
unstash "build-artifacts"
container("docker") {
sh """
sed -i 's|COPY ./target/yudao-server.jar|COPY ./yudao-server/target/yudao-server.jar|' yudao-server/Dockerfile
docker build -t ${REGISTRY}/${APP_NAME}:${IMAGE_TAG} -f yudao-server/Dockerfile .
docker push ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}
"""
}
}
}
}
post {
success { echo "Build SUCCESS: ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}" }
failure { echo "Build FAILED" }
}
}
六、前端构建 Job
以下是前端构建 Job 的核心步骤、关键代码片段及注意事项总结,便于您记录:
6.1、标准 Pipeline 步骤
6.1.1、清理工作空间(避免缓存干扰)
cleanWs() // 需安装 Workspace Cleanup Plugin
6.1.2、拉取代码
checkout scm // 或指定分支:git branch: 'main', url: '...'
6.2.3、安装依赖
pnpm install --frozen-lockfile # 锁定版本,避免意外升级
6.1.4、执行构建
pnpm build:prod # 根据项目实际命令调整
6.1.5、归档产物(可选)
archiveArtifacts artifacts: 'dist/**/*', fingerprint: true
6.2、关键注意点
| 类别 | 说明 |
|---|---|
| 禁止覆盖源码 | ❌ 切勿在 Pipeline 中用 echo > file.ts 等命令修改源码(曾导致 MISSING_EXPORT) |
| 缓存策略 | Docker 构建时若 COPY . ./ 命中 CACHED,需确认源码未被脚本篡改 |
| Node.js 版本 | 当前服务器为 v22.23.0,确保与本地开发环境一致 |
| CSS 兼容性警告 | *zoom: 1; 等 IE hack 会触发 lightningcss 警告,建议移除或配置忽略 |
| 插件持久化 | ws-cleanup 等插件需写入 Helm values / CasC,防止 Pod 重建后丢失 |
| 构建前验证 | 本地先执行 pnpm build:prod 通过后再提交触发 CI |
6.3、故障排查速查
构建失败但本地正常 → 检查 Jenkinsfile 是否意外修改/覆盖源码
Docker 缓存异常 → 对比 Git 提交内容与容器内文件 MD5
导出缺失错误 → 确认 constants.ts 等工具文件未被 Pipeline 脚本重写
到此前后端项目cicd闭环了

6.4、pipeline
pipeline {
agent none
environment {
REGISTRY = "10.43.136.9:5000"
APP_NAME = "yudao-ui-admin"
IMAGE_TAG = "${BUILD_NUMBER}"
GIT_URL = "http://39.107.52.178:8080/snow/monolithic-front-end-and-back-end-projects.git"
GIT_CRED = "gitlab-token"
}
stages {
stage("Checkout and Build Image") {
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: docker
image: docker.1panel.live/library/docker:27-cli
command: ["sleep"]
args: ["3600"]
workingDir: /home/jenkins/agent
securityContext:
privileged: true
volumeMounts:
- name: dockersock
mountPath: /var/run/docker.sock
volumes:
- name: dockersock
hostPath:
path: /var/run/docker.sock
type: Socket
"""
defaultContainer "docker"
}
}
steps {
// 构建前清理工作空间
cleanWs()
git url: env.GIT_URL, branch: "main", credentialsId: env.GIT_CRED
container("docker") {
sh """
sed -i 's|proxy_pass http://yudao-server:48080|proxy_pass http://yudao-server-svc.jenkins.svc.cluster.local:48080|' yudao-ui/yudao-ui-admin-vue3/nginx.conf
docker build -t ${REGISTRY}/${APP_NAME}:${IMAGE_TAG} -f yudao-ui/yudao-ui-admin-vue3/Dockerfile yudao-ui/yudao-ui-admin-vue3
docker push ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}
"""
}
}
}
}
post {
success { echo "Build SUCCESS: ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}" }
failure { echo "Build FAILED" }
}
}
七、前端项目部署到 K8s 集群
📋 前端项目部署步骤
1. 创建 Deployment + Service
cat <<'EOF' | /usr/local/bin/k3s kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: yudao-ui-admin
namespace: jenkins
labels:
app: yudao-ui-admin
spec:
replicas: 1
selector:
matchLabels:
app: yudao-ui-admin
template:
metadata:
labels:
app: yudao-ui-admin
spec:
containers:
- name: yudao-ui-admin
image: registry.jenkins.svc.cluster.local:5000/yudao-ui-admin:11
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
name: yudao-ui-admin-svc
namespace: jenkins
labels:
app: yudao-ui-admin
spec:
type: NodePort
selector:
app: yudao-ui-admin
ports:
- port: 80
targetPort: 80
nodePort: 30881
EOF
2. 配置 k3s 私有镜像仓库
将 Registry Service 改为 NodePort(端口 30500),并创建 registries.yaml:
# 暴露 Registry NodePort
/usr/local/bin/k3s kubectl patch svc registry -n jenkins \
-p '{"spec":{"type":"NodePort","ports":[{"port":5000,"targetPort":5000,"nodePort":30500}]}}'
# 创建 registries.yaml
cat > /etc/rancher/k3s/registries.yaml <<'EOF'
mirrors:
"registry.jenkins.svc.cluster.local:5000":
endpoint:
- "http://127.0.0.1:30500"
"registry:5000":
endpoint:
- "http://127.0.0.1:30500"
EOF
3. 配置 kube-proxy 使用 iptables 模式
解决 nftables 模式下 NodePort 不绑定的问题:
cat > /etc/rancher/k3s/config.yaml <<'EOF'
kube-proxy-arg:
- "proxy-mode=iptables"
EOF
systemctl restart k3s
4. 验证
# 检查 Pod 状态
/usr/local/bin/k3s kubectl get pod -n jenkins -l app=yudao-ui-admin
# 检查端口监听
ss -tlnp | grep 30881
# 访问测试
curl -sI http://39.107.52.178:30881/
⚠️ 关键注意事项
镜像地址 :必须使用
registry.jenkins.svc.cluster.local:5000而非registry:5000registries.yaml:k3s 节点拉取私有镜像必须配置此文件,指向本地 NodePort 地址
kube-proxy 模式:当前环境 nftables 模式存在 NodePort 绑定问题,需强制切换为 iptables
安全组:确保阿里云安全组已放行 30881、30500 端口入方向规则
前端项目 yudao-ui-admin 已成功部署到 k3s 集群(namespace: jenkins),通过 NodePort 30881 对外提供 HTTP 访问。部署过程中解决了私有镜像拉取(registries.yaml + Registry NodePort 30500)和 kube-proxy nftables 兼容性问题(切换为 iptables 模式)。
后续如需配置 HTTP/2,需在此基础上配置 Traefik Ingress + TLS 证书(HTTP/2 强制要求 HTTPS)。
八、如何创建job
适合已有 Jenkinsfile 或需要灵活定义构建流程的场景。
进入 Jenkins 首页 → 点击左侧 New Item
输入任务名称(如 yudao-ui-admin-build)
选择 Pipeline → 点击 OK
配置 Pipeline:
Definition: 选择 Pipeline script from SCM(从 Git 拉取 Jenkinsfile)或 Pipeline script(直接在页面编写)
若选 SCM:填写 Git 仓库地址、分支、Jenkinsfile 路径
点击 Save → 立即点击 Build Now 触发首次构建
九、K3S 下 Jenkins ↔ GitLab 的 CI/CD 闭环 的主要步骤流程


十、导入sql
| 步骤 | 结果 |
|---|---|
| 备份原数据库 | ✅ 已备份至 /tmp/ruoyi-backup-before-init.sql |
| 导入 ruoyi-vue-pro.sql | ✅ 48 张业务表创建成功 |
| 导入 quartz.sql | ✅ 定时任务表创建成功 |
| 总表数验证 | ✅ 60 张表全部就位 |
| Pod 重启 | ✅ yudao-server 正常启动,无 ERROR |
| 接口验证 | ✅ 租户查询返回 code:0,500 错误已消除 |
Step 1:备份现有数据库
mysqldump -h 172.22.182.143 -u root -p'123456' ruoyi-vue-pro > /tmp/ruoyi-backup-before-init.sql
Step 2:下载官方初始化 SQL
# 主业务表(约 2MB,48 张表)
curl -sL "https://gitee.com/zhijiantianya/ruoyi-vue-pro/raw/master/sql/mysql/ruoyi-vue-pro.sql" -o /tmp/ruoyi-init.sql
# Quartz 定时任务表
curl -sL "https://gitee.com/zhijiantianya/ruoyi-vue-pro/raw/master/sql/mysql/quartz.sql" -o /tmp/quartz.sql
💡 GitHub raw 链接在国内可能 404,优先使用 Gitee 镜像地址
Step 3:导入 SQL
mysql -h 172.22.182.143 -u root -p'123456' ruoyi-vue-pro < /tmp/ruoyi-init.sql
mysql -h 172.22.182.143 -u root -p'123456' ruoyi-vue-pro < /tmp/quartz.sql
Step 4:验证表创建
mysql -h 172.22.182.143 -u root -p'123456' \
-e "SELECT COUNT(*) AS total_tables FROM information_schema.tables WHERE table_schema='ruoyi-vue-pro';"
# 结果:60 张表 ✅
Step 5:重启应用并验证
k3s kubectl rollout restart deployment yudao-server -n jenkins
# 等待启动完成后验证
k3s kubectl exec yudao-server-xxx -n jenkins -- \
curl -s -H "Content-Type: application/json" \
'http://localhost:48080/admin-api/system/tenant/get-id-by-name?name=%E8%8A%8B%E9%81%93%E6%BA%90%E7%A0%81'
# 返回:{"code":0,"msg":"","data":1} ✅
⚠️ 安全提醒
| 风险项 | 当前状态 | 建议操作 |
|---|---|---|
| 数据库密码 | 123456(弱密码) 修改为了Snow123456789 |
立即修改为强密码,同步更新 K8s Secret/环境变量 |
异常表 RECOVER_YOUR_DATA_info |
疑似勒索标记 | 排查数据库访问审计日志,确认是否存在未授权访问 |
| Redis 密码 | Snow123456789 |
建议一并更换 |
| 数据库备份 | 仅手动临时备份 | 配置自动定期备份策略 |
到此访问成功
