Skip to content
实战部署:若依(RuoYi-Vue)

实战部署:若依(RuoYi-Vue)

将若依前后端分离项目完整部署到 K8s 集群的实操指南,涵盖 Redis、MySQL、后端应用、前端应用、私有镜像仓库和 Ingress。


1. 部署架构概览

┌───────────────────────────────────────────────────────────────┐
│                        K8s 集群                                │
│                                                                │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐                  │
│  │  Redis   │   │  MySQL   │   │ Registry │                  │
│  │ (Helm)   │   │ (Helm)   │   │ (Docker) │                  │
│  └──────────┘   └──────────┘   └──────────┘                  │
│       ▲              ▲                                         │
│       │              │                                         │
│  ┌────┴──────────────┴────┐                                   │
│  │      RuoYi-Admin       │                                   │
│  │      (Deployment)      │                                   │
│  └──────────┬─────────────┘                                   │
│             │                                                  │
│  ┌──────────┴─────────────┐     ┌──────────────┐             │
│  │      RuoYi-UI          │────▶│   Ingress    │──── 外部用户 │
│  │      (Deployment)      │     │ (Traefik/K3s)│             │
│  └────────────────────────┘     └──────────────┘             │
└───────────────────────────────────────────────────────────────┘

2. 安装 Redis

使用 Helm 部署单节点 Redis 用于开发/测试:

helm install redis \
  --set architecture=standalone \
  --set auth.password="123456" \
  --set master.persistence.enabled=false \
  --set master.persistence.medium=Memory \
  --set master.persistence.sizeLimit=1Gi \
  bitnami/redis \
  --kubeconfig=/etc/rancher/k3s/k3s.yaml

安装成功后注意记录 Redis 的 DNS 名称(输出中会显示),后续配置后端时需要,格式通常为 redis-masterredis.<namespace>.svc.cluster.local


3. 安装 MySQL

3.1 准备 SQL 初始化脚本

将若依项目的 SQL 文件(ry_2024xxxx.sqlquartz.sql)放到一个目录中:

mkdir -p /home/app/sql
cp ry_2024xxxx.sql quartz.sql /home/app/sql/

3.2 创建 ConfigMap

# 将整个 SQL 目录创建为 ConfigMap(Helm 会使用它初始化数据库)
kubectl create cm ruoyi-init-sql --from-file=/home/app/sql

3.3 编写 values.yaml

# ruoyi-mysql.yaml
auth:
  rootPassword: "123456"
  database: ry-vue

initdbScriptConfigMap: ruoyi-init-sql

primary:
  persistence:
    enabled: true
    size: 2Gi

secondary:
  persistence:
    enabled: true
    size: 2Gi
  replicaCount: 2

architecture: replication

3.4 安装

helm install db -f ruoyi-mysql.yaml bitnami/mysql --kubeconfig=/etc/rancher/k3s/k3s.yaml

# 记录主库 DNS
# 输出示例:db-mysql-primary.dev.svc.cluster.local

4. 构建后端镜像

4.1 Dockerfile(多阶段构建)

# 阶段 1:编译
FROM maven:3.8-openjdk-8 AS builder
WORKDIR /app/build
COPY . .
RUN mvn clean package

# 阶段 2:打包运行
FROM openjdk:8u342-jre
WORKDIR /app/ruoyi
COPY --from=builder /app/build/ruoyi-admin/target/ruoyi-admin.jar .
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "ruoyi-admin.jar"]

4.2 构建与推送

docker build -t ruoyi-admin:v3.8 .
docker tag ruoyi-admin:v3.8 <私有仓库>:5000/ruoyi-admin:v3.8
docker push <私有仓库>:5000/ruoyi-admin:v3.8

4.3 准备配置文件

application.yml 中数据库和 Redis 相关配置提取到 application-k8s.yaml

# /home/app/conf/application-k8s.yaml
spring:
  datasource:
    master:
      url: jdbc:mysql://db-mysql-primary:3306/ry-vue
      username: root
      password: "123456"
    slave:
      url: jdbc:mysql://db-mysql-secondary:3306/ry-vue
      username: root
      password: "123456"
  redis:
    host: redis-master
    password: "123456"
kubectl create cm ruoyi-admin-config --from-file=/home/app/conf/application-k8s.yaml

5. 构建前端镜像

5.1 Dockerfile(多阶段构建)

FROM node:14-alpine AS builder
WORKDIR /build/ruoyi-ui
COPY . .
RUN npm install --registry=https://registry.npmmirror.com && npm run build:prod

FROM nginx:1.22
WORKDIR /app/ruoyi-ui
COPY --from=builder /build/ruoyi-ui/dist .
EXPOSE 80
# 自动继承基础镜像的启动命令

🚨 注意

  1. 推荐使用 Node 14(最新版本可能报错)
  2. 使用 build:prod 打包(不要打包预发布环境,否则部署后报错)
  3. 强烈建议在容器中编译,避免本地环境差异

5.2 构建与推送

docker build -t ruoyi-ui:v3.8 .
docker tag ruoyi-ui:v3.8 <私有仓库>:5000/ruoyi-ui:v3.8
docker push <私有仓库>:5000/ruoyi-ui:v3.8

6. 部署后端应用

# app/svc-ruoyi-admin.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ruoyi-admin
  labels:
    app: ruoyi-admin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ruoyi-admin
  template:
    metadata:
      labels:
        app: ruoyi-admin
    spec:
      containers:
        - name: ruoyi-admin
          image: <私有仓库>:5000/ruoyi-admin:v3.8
          ports:
            - containerPort: 8080
          volumeMounts:
            - mountPath: /app/ruoyi/config
              name: config
          args: ["--spring.profiles.active=k8s"]
      volumes:
        - name: config
          configMap:
            name: ruoyi-admin-config
---
apiVersion: v1
kind: Service
metadata:
  name: ruoyi-admin
spec:
  type: ClusterIP
  selector:
    app: ruoyi-admin
  ports:
    - port: 8080
      targetPort: 8080

💡 说明:Spring Boot 会自动在 jar 包所在目录的 config/ 子目录中查找配置文件。ConfigMap 挂载到 /app/ruoyi/config,配合 --spring.profiles.active=k8s 启动参数,Spring Boot 会加载 application-k8s.yaml


7. 部署前端应用

7.1 Nginx 配置

# /home/app/conf/nginx.conf
server {
    listen       80;
    server_name  localhost;

    location / {
        root   /app/ruoyi-ui;
        try_files $uri $uri/ /index.html;
        index  index.html index.htm;
    }

    location /prod-api/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://ruoyi-admin:8080/;
    }

    # 避免 actuator 暴露
    if ($uri ~ "/actuator") {
        return 403;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}
kubectl create cm ruoyi-ui-config --from-file=/home/app/conf/nginx.conf

7.2 Deployment 和 Service

# app/svc-ruoyi-ui.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ruoyi-ui
  labels:
    app: ruoyi-ui
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ruoyi-ui
  template:
    metadata:
      labels:
        app: ruoyi-ui
    spec:
      initContainers:                      # 等待后端启动
        - name: wait-for-ruoyi-admin
          image: nginx:1.22
          command:
            - sh
            - -c
            - |
              until curl -m 3 ruoyi-admin:8080; do
                echo "Waiting for ruoyi-admin...";
                sleep 5;
              done
      containers:
        - name: ruoyi-ui
          image: <私有仓库>:5000/ruoyi-ui:v3.8
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /etc/nginx/conf.d
              name: config
      volumes:
        - name: config
          configMap:
            name: ruoyi-ui-config
            items:
              - key: nginx.conf
                path: default.conf
---
apiVersion: v1
kind: Service
metadata:
  name: ruoyi-ui
spec:
  type: NodePort
  selector:
    app: ruoyi-ui
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080

8. 配置 Ingress

K3s 内置 Traefik Ingress 控制器,直接创建 Ingress 资源即可:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ruoyi-ingress
  annotations:
    traefik.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: ruoyi-ui
                port:
                  number: 80
kubectl apply -f ruoyi-ingress.yaml
kubectl get ingress

9. 启动顺序控制

背景:当服务重启时,若 ruoyi-admin 在 MySQL 或 Redis 之前启动,会因数据库连接失败而报错终止。

9.1 使用 Init Container 控制顺序

spec:
  initContainers:
    - name: wait-for-mysql
      image: busybox:1.36
      command:
        - sh
        - -c
        - |
          until nslookup db-mysql-primary; do
            echo "Waiting for MySQL...";
            sleep 5;
          done
    - name: wait-for-redis
      image: busybox:1.36
      command:
        - sh
        - -c
        - |
          until nslookup redis-master; do
            echo "Waiting for Redis...";
            sleep 3;
          done
  containers:
    - name: ruoyi-admin
      # ...

💡 最佳实践:在 Init Container 中增加重试上限和超时,避免无限等待。超过阈值后以失败退出,让 Pod 重启重试:

for i in $(seq 1 30); do
  nslookup db-mysql-primary && exit 0
  echo "Attempt $i/30: Waiting for MySQL..."
  sleep 5
done
exit 1

10. 部署验证清单

检查项 命令
Redis 状态 kubectl get pod -l app.kubernetes.io/name=redis
MySQL 状态 kubectl get pod -l app.kubernetes.io/name=mysql
后端状态 kubectl get pod -l app=ruoyi-admin
前端状态 kubectl get pod -l app=ruoyi-ui
后端日志 kubectl logs -f deploy/ruoyi-admin
前端日志 kubectl logs -f deploy/ruoyi-ui
Service kubectl get svc
Ingress kubectl get ingress
访问测试 curl http://<NodeIP>:30080 或通过 Ingress

11. 私有镜像仓库配置

11.1 启动简单 Registry

docker run -d -p 5000:5000 --restart always --name registry registry:2

11.2 配置 insecure registry

Docker 侧/etc/docker/daemon.json):

{
  "insecure-registries": ["<私有仓库IP>:5000"]
}

K3s 侧/etc/rancher/k3s/registries.yaml):

mirrors:
  "<私有仓库IP>:5000":
    endpoint:
      - "http://<私有仓库IP>:5000"

重启 K3s:sudo systemctl restart k3s

🚨 多节点集群:每个节点都需要配置。

11.3 在 K8s 中使用私有镜像

# 拉取验证
sudo k3s crictl pull <私有仓库IP>:5000/ruoyi-admin:v3.8