题目
设计一个GitLab CI/CD流水线实现Spring Boot应用的容器化构建与Kubernetes部署
信息
- 类型:问答
- 难度:⭐⭐
考点
GitLab CI流水线设计,Docker镜像构建优化,Kubernetes部署配置,环境变量管理
快速回答
该流水线设计包含以下核心阶段:
- 构建阶段:使用Maven构建Spring Boot应用
- Docker构建阶段:创建优化的Docker镜像(多阶段构建)
- 测试阶段:执行容器化单元/集成测试
- 部署阶段:分环境(staging/prod)部署到Kubernetes集群
关键配置要点:
- 使用GitLab CI变量管理敏感信息(Docker凭证/K8s配置)
- 利用缓存加速依赖下载
- 为生产环境部署设置手动审批流程
- 使用Kubernetes Deployment滚动更新策略
1. 整体流水线设计
完整的.gitlab-ci.yml示例:
stages:
- build
- docker-build
- test
- deploy
variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
IMAGE_NAME: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
# 1. 构建阶段
build:
stage: build
image: maven:3.8.6-openjdk-17
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .m2/repository/
script:
- mvn package -DskipTests
artifacts:
paths:
- target/*.jar
# 2. Docker镜像构建(多阶段优化)
docker-build:
stage: docker-build
image: docker:20.10.16
services:
- docker:20.10.16-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_NAME .
- docker push $IMAGE_NAME
# 3. 容器化测试
test:
stage: test
image: $IMAGE_NAME
script:
- mvn test
- ./run-integration-tests.sh # 自定义集成测试脚本
# 4. 分环境部署
deploy-staging:
stage: deploy
image: bitnami/kubectl:latest
environment:
name: staging
url: https://staging.example.com
script:
- echo $KUBE_CONFIG | base64 -d > kubeconfig
- kubectl --kubeconfig=kubeconfig set image deployment/myapp myapp=$IMAGE_NAME -n staging
only:
- main
# 生产环境需要手动触发
deploy-prod:
stage: deploy
image: bitnami/kubectl:latest
environment:
name: production
url: https://prod.example.com
script:
- echo $KUBE_CONFIG_PROD | base64 -d > kubeconfig
- kubectl --kubeconfig=kubeconfig apply -f k8s/prod-deployment.yaml
when: manual
only:
- tags2. 核心组件解析
Dockerfile多阶段构建示例
# 构建阶段
FROM maven:3.8.6-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
# 运行时镜像
FROM openjdk:17-jre-slim
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]优化点:
- 分离构建和运行时镜像,减小最终镜像体积(~300MB → ~150MB)
- 提前复制pom.xml下载依赖,利用Docker层缓存
Kubernetes部署配置(k8s/prod-deployment.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: ${IMAGE_NAME}
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: app-config
resources:
limits:
memory: "512Mi"
cpu: "500m"3. 最佳实践
- 安全凭证管理:
- 使用GitLab CI的
Masked Variables存储Docker登录凭证 - Kubernetes kubeconfig文件用Base64编码后存入变量
- 使用GitLab CI的
- 构建优化:
- Maven/Gradle依赖缓存减少构建时间
- 使用
docker build --cache-from复用镜像层
- 部署策略:
- Staging环境自动部署,Production环境手动审批
- Kubernetes滚动更新保证零停机部署
- 通过
environment.url在GitLab中直接访问服务
4. 常见错误
- Docker-in-Docker(dind)配置错误:
- 未正确配置
services导致docker命令失败 - 解决方案:确保使用
docker:20.10.16-dind服务
- 未正确配置
- 镜像标签冲突:
- 使用
latest标签导致版本混乱 - 正确做法:
${CI_COMMIT_SHORT_SHA}保证唯一性
- 使用
- Kubernetes配置泄漏:
- 在代码库中存储明文kubeconfig文件
- 正确做法:通过CI变量注入Base64编码配置
5. 扩展知识
- Helm集成:使用
helm upgrade替代原生kubectl实现更复杂的部署 - GitLab Auto DevOps:利用GitLab内置模板快速生成流水线
- 安全扫描:添加容器漏洞扫描阶段(Trivy/Clair)
- HPA配置:在Deployment中配置Horizontal Pod Autoscaler