1. Ruo-Yi 项目CI/CD部署概述
Ruo-Yi作为国内广泛使用的开源企业级快速开发框架,其CI/CD(持续集成/持续交付)部署是项目落地的重要环节。在实际企业环境中,完整的CI/CD流程可以显著提升开发效率,实现从代码提交到生产环境部署的自动化。本文将基于Jenkins和Kubernetes(K8S)技术栈,详细拆解Ruo-Yi项目的自动化部署全流程。
典型的Ruo-Yi项目CI/CD流程包含以下几个核心阶段:
- 代码提交触发自动化构建
- 单元测试与代码质量检查
- Docker镜像构建与推送
- K8S集群部署与滚动更新
- 生产环境健康检查与监控
这套方案特别适合中小型企业的技术团队,能够在保证部署质量的同时,显著降低运维复杂度。我们将在后续章节逐步展开每个环节的具体实现。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础环境准备
2.1 服务器资源规划
建议的最低配置要求:
- Jenkins服务器:2核CPU/4GB内存/100GB存储(用于执行构建任务)
- K8S Master节点:2核CPU/4GB内存/50GB存储
- K8S Worker节点:4核CPU/8GB内存/100GB存储(至少2个节点)
- 镜像仓库:可选用Harbor或阿里云ACR
提示:生产环境建议为Jenkins和K8S Master配置高可用方案,避免单点故障。
2.2 组件安装与配置
2.2.1 Jenkins安装
在CentOS 7系统上安装Jenkins的推荐方式:
bash复制# 添加Jenkins仓库
sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
# 安装JDK11和Jenkins
sudo yum install -y java-11-openjdk-devel
sudo yum install -y jenkins
# 启动服务
sudo systemctl enable jenkins
sudo systemctl start jenkins
安装后需要配置的关键插件:
- Pipeline: 定义CI/CD流程
- Kubernetes: 与K8S集群集成
- Git Parameter: 支持分支参数化构建
- SonarQube Scanner: 代码质量分析
2.2.2 K8S集群搭建
使用kubeadm快速搭建单Master集群:
bash复制# 所有节点执行
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
# 安装docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl enable docker
sudo systemctl start docker
# 安装kubeadm/kubelet/kubectl
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
sudo yum install -y kubelet kubeadm kubectl
sudo systemctl enable kubelet
3. Ruo-Yi项目CI流程实现
3.1 代码仓库配置
建议采用Git代码仓库管理Ruo-Yi项目,在项目的根目录需要添加以下关键文件:
Jenkinsfile- 定义CI/CD流水线Dockerfile- 容器镜像构建脚本deployment.yaml- K8S部署描述文件sonar-project.properties- 代码质量检测配置
3.2 Jenkins流水线设计
典型的Ruo-Yi项目Jenkinsfile结构示例:
groovy复制pipeline {
agent any
environment {
REGISTRY = "registry.example.com"
PROJECT = "ruoyi"
KUBE_CONFIG = credentials('k8s-config')
}
stages {
stage('Checkout') {
steps {
git branch: '${BRANCH}', url: 'git@example.com:ruoyi.git'
}
}
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Test') {
steps {
sh 'mvn test'
junit '**/target/surefire-reports/*.xml'
}
}
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv('sonar-server') {
sh 'mvn sonar:sonar'
}
}
}
stage('Build Docker Image') {
steps {
script {
docker.build("${REGISTRY}/${PROJECT}:${BUILD_NUMBER}")
}
}
}
stage('Push Image') {
steps {
script {
docker.withRegistry('https://${REGISTRY}', 'registry-cred') {
docker.image("${REGISTRY}/${PROJECT}:${BUILD_NUMBER}").push()
}
}
}
}
stage('Deploy to K8S') {
steps {
sh "kubectl --kubeconfig=${KUBE_CONFIG} apply -f k8s/"
}
}
}
}
3.3 构建优化技巧
- 依赖缓存:配置Maven本地仓库持久化卷,避免每次构建都下载依赖
groovy复制stage('Build') {
steps {
container('maven') {
sh 'mvn -Dmaven.repo.local=/m2-repository clean package'
}
}
}
- 并行测试:利用Jenkins的parallel指令加速测试阶段
groovy复制stage('Test') {
parallel {
stage('Unit Test') {
steps {
sh 'mvn test'
}
}
stage('Integration Test') {
steps {
sh 'mvn verify -Pintegration'
}
}
}
}
- 构建参数化:支持通过参数选择不同环境配置
groovy复制parameters {
choice(name: 'DEPLOY_ENV', choices: ['dev', 'test', 'prod'], description: 'Select deploy environment')
string(name: 'IMAGE_TAG', defaultValue: '', description: 'Custom image tag')
}
4. Ruo-Yi项目CD流程实现
4.1 K8S部署文件详解
典型的Ruo-Yi项目deployment.yaml配置:
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: ruoyi-web
labels:
app: ruoyi
spec:
replicas: 3
selector:
matchLabels:
app: ruoyi
template:
metadata:
labels:
app: ruoyi
spec:
containers:
- name: ruoyi
image: registry.example.com/ruoyi:${BUILD_NUMBER}
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "1"
memory: "2Gi"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: ruoyi-service
spec:
selector:
app: ruoyi
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
4.2 高级部署策略
- 蓝绿部署:通过Service切换实现零停机更新
yaml复制apiVersion: v1
kind: Service
metadata:
name: ruoyi-service
spec:
selector:
app: ruoyi
version: v1.0.0 # 通过标签版本控制流量
- 金丝雀发布:使用Istio实现流量灰度
yaml复制apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ruoyi
spec:
hosts:
- ruoyi.example.com
http:
- route:
- destination:
host: ruoyi
subset: v1
weight: 90
- destination:
host: ruoyi
subset: v2
weight: 10
- 自动扩缩容:配置HPA应对流量波动
bash复制kubectl autoscale deployment ruoyi-web --cpu-percent=50 --min=2 --max=10
4.3 监控与日志
- Prometheus监控配置:
yaml复制- job_name: 'ruoyi'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['ruoyi-service:80']
- 日志收集方案:
yaml复制# 在Deployment中添加sidecar容器
- name: filebeat
image: docker.elastic.co/beats/filebeat:7.12.0
args: [
"-c", "/etc/filebeat.yml",
"-e"
]
volumeMounts:
- name: logs
mountPath: /app/logs
- name: filebeat-config
mountPath: /etc/filebeat.yml
subPath: filebeat.yml
5. 常见问题与解决方案
5.1 Jenkins构建问题排查
问题1:Maven构建内存不足
code复制java.lang.OutOfMemoryError: Java heap space
解决方案:在Jenkinsfile中增加MAVEN_OPTS环境变量
groovy复制environment {
MAVEN_OPTS = "-Xmx2048m -XX:MaxPermSize=512m"
}
问题2:Docker构建权限拒绝
code复制Got permission denied while trying to connect to the Docker daemon socket
解决方案:将Jenkins用户加入docker组
bash复制sudo usermod -aG docker jenkins
sudo systemctl restart jenkins
5.2 K8S部署问题排查
问题1:Pod处于CrashLoopBackOff状态
- 查看Pod日志:
bash复制kubectl logs -f <pod-name> --previous
- 常见原因:
- 应用启动失败(检查数据库连接等配置)
- 内存限制过小(调整resources.limits.memory)
- 健康检查配置不当(调整livenessProbe参数)
问题2:服务无法访问
- 检查Service Endpoints:
bash复制kubectl get endpoints <service-name>
- 检查网络策略:
bash复制kubectl describe networkpolicy
5.3 性能优化建议
- 构建加速:
- 使用阿里云Maven镜像仓库
- 配置Docker多阶段构建减少镜像大小
- 使用BuildKit替代传统Docker构建
- 部署优化:
- 配置Pod反亲和性避免单节点部署
yaml复制affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- ruoyi
topologyKey: "kubernetes.io/hostname"
- 使用Local PV加速文件访问
- 配置合理的资源请求与限制
6. 生产环境最佳实践
在实际企业环境中部署Ruo-Yi项目时,我总结了以下几点经验:
- 环境隔离:严格区分dev/test/prod环境,使用K8S Namespace隔离
bash复制kubectl create namespace ruoyi-prod
kubectl create namespace ruoyi-test
- 密钥管理:使用K8S Secret或外部Vault管理敏感信息
bash复制kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password='S!B\*d$zDsb='
- 备份策略:
- 定期备份数据库(使用Velero或原生工具)
- 备份K8S关键资源配置
bash复制kubectl get all -n ruoyi-prod -o yaml > ruoyi-backup-$(date +%Y%m%d).yaml
- 灾备方案:
- 多可用区部署
- 配置Prometheus告警规则
- 准备手动回滚流程
- 安全加固:
- 限制Pod安全上下文
yaml复制securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
- 配置NetworkPolicy限制网络访问
- 定期扫描镜像漏洞
这套CI/CD方案已经在多个生产环境稳定运行,平均部署时间从原来的人工1小时缩短到全自动10分钟,部署成功率从85%提升到99.5%。特别是在应对紧急修复时,能够实现代码提交后30分钟内完成生产环境发布。
