在云原生时代,将传统的单体或微服务应用进行容器化并部署到 Kubernetes 集群已成为标准实践。本文将以一个典型的 SpringBoot 应用为例,详细讲解从构建 Docker 镜像到通过 Kubernetes 进行编排部署,并最终集成 Jenkins 实现持续集成与持续交付(CI/CD)的全流程。
1. SpringBoot 应用容器化
首先,我们需要为 SpringBoot 应用创建一个 Dockerfile,这是构建镜像的蓝图。
# 使用官方 OpenJDK 运行时作为基础镜像
FROM openjdk:11-jre-slim
# 设置工作目录
WORKDIR /app
# 将构建好的 Jar 包复制到容器中
COPY target/my-springboot-app-1.0.0.jar app.jar
# 暴露应用端口
EXPOSE 8080
# 定义容器启动时执行的命令
ENTRYPOINT ["java", "-jar", "app.jar"]
使用以下命令在项目根目录(pom.xml 同级)构建 Docker 镜像:
docker build -t my-springboot-app:latest .
这会将我们的 Java 应用打包成一个可移植的容器镜像。
2. 编写 Kubernetes 部署文件
接下来,我们需要定义 Kubernetes 资源清单来部署和管理这个容器。通常包含 Deployment 和 Service 两个主要部分。
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-app-deployment
labels:
app: springboot-app
spec:
replicas: 2 # 指定Pod副本数量
selector:
matchLabels:
app: springboot-app
template:
metadata:
labels:
app: springboot-app
spec:
containers:
- name: springboot-app
image: my-springboot-app:latest # 使用上一步构建的镜像
ports:
- containerPort: 8080
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe: # 存活探针
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
service.yaml
apiVersion: v1
kind: Service
metadata:
name: springboot-app-service
spec:
selector:
app: springboot-app
ports:
- protocol: TCP
port: 80 # Service对外端口
targetPort: 8080 # 容器内端口
type: LoadBalancer # 根据云服务商创建外部负载均衡器
使用 kubectl 命令应用配置:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
3. 集成 Jenkins 实现 CI/CD 流水线
自动化是云原生实践的关键。我们可以在 Jenkins 中创建一个 Pipeline 任务,自动化整个构建、推送镜像和部署流程。
在项目根目录创建 Jenkinsfile:
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'your-registry.com/your-namespace'
K8S_NAMESPACE = 'default'
}
stages {
stage('代码检出') {
steps {
checkout scm
}
}
stage('Maven 构建') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('构建与推送 Docker 镜像') {
steps {
script {
docker.build("${DOCKER_REGISTRY}/my-springboot-app:${env.BUILD_ID}")
docker.withRegistry('https://your-registry.com', 'docker-credentials-id') {
docker.image("${DOCKER_REGISTRY}/my-springboot-app:${env.BUILD_ID}").push()
}
}
}
}
stage('更新 K8s 部署') {
steps {
script {
// 使用 sed 或 yq 工具动态更新 deployment.yaml 中的镜像标签
sh """
sed -i 's|image:.*|image: ${DOCKER_REGISTRY}/my-springboot-app:${env.BUILD_ID}|' k8s/deployment.yaml
"""
sh "kubectl apply -f k8s/deployment.yaml --namespace=${K8S_NAMESPACE}"
}
}
}
stage('健康检查') {
steps {
script {
// 等待并检查新Pod是否就绪
sh "kubectl rollout status deployment/springboot-app-deployment --namespace=${K8S_NAMESPACE} --timeout=300s"
}
}
}
}
post {
success {
echo 'Pipeline 执行成功!应用已部署。'
}
failure {
echo 'Pipeline 执行失败。'
// 可以在这里添加回滚逻辑
}
}
}
此流水线定义了从代码变更到生产部署的完整自动化流程,极大地提升了运维/DevOps效率。
总结
通过以上步骤,我们完成了 SpringBoot 应用的容器化、Kubernetes 部署以及 CI/CD 流水线的搭建。这套组合拳不仅提升了应用的可移植性和伸缩性,还通过自动化降低了人工操作的风险和成本,是构建现代云原生应用的坚实基础。在实际项目中,你可能还需要考虑配置管理、服务网格、监控告警等更多环节。