腾讯真题:容器化部署最佳实践
面试重要程度:⭐⭐⭐⭐⭐
真题来源:腾讯2024春招技术面试
考察重点:容器化部署、CI/CD流水线、生产环境运维、性能优化
预计阅读时间:40分钟
真题背景
面试官: "我们需要将一个Spring Boot微服务应用容器化部署到Kubernetes集群。请设计完整的容器化部署方案,包括镜像构建、CI/CD流水线、生产环境配置、监控告警等。要求支持多环境部署、灰度发布、自动扩缩容,并确保生产环境的高可用性。"
考察意图:
- 容器化部署的完整流程设计
- CI/CD流水线的工程实践能力
- Kubernetes生产环境运维经验
- 性能优化和故障排查能力
🎯 容器化部署架构设计
整体架构方案
/**
* 容器化部署架构设计
*/
public class ContainerDeploymentArchitecture {
/**
* 部署环境定义
*/
public enum DeploymentEnvironment {
DEVELOPMENT("dev", "开发环境", "单节点,资源限制较小"),
TESTING("test", "测试环境", "模拟生产,功能测试"),
STAGING("staging", "预发布环境", "生产数据,性能测试"),
PRODUCTION("prod", "生产环境", "高可用,多副本部署");
private final String name;
private final String description;
private final String characteristics;
}
/**
* 部署策略
*/
public enum DeploymentStrategy {
RECREATE("重建部署", "停止所有旧版本,再启动新版本"),
ROLLING_UPDATE("滚动更新", "逐步替换旧版本实例"),
BLUE_GREEN("蓝绿部署", "两套环境切换"),
CANARY("金丝雀部署", "小流量验证后逐步放量");
private final String name;
private final String description;
}
}
🏗️ 优化的Dockerfile设计
生产级Dockerfile
# 生产环境优化的Spring Boot Dockerfile
# ==================== 构建阶段 ====================
FROM maven:3.8.6-openjdk-17-slim AS builder
WORKDIR /app
# 先复制依赖文件,利用Docker层缓存
COPY pom.xml .
COPY src/main/resources/application.yml src/main/resources/
# 下载依赖(这一层会被缓存)
RUN mvn dependency:go-offline -B
# 复制源代码并构建
COPY src ./src
RUN mvn clean package -DskipTests -B
# ==================== 运行阶段 ====================
FROM openjdk:17-jre-slim
# 安装必要工具
RUN apt-get update && \
apt-get install -y --no-install-recommends curl dumb-init && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# 创建应用用户
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
# 复制应用文件
COPY --from=builder /app/target/*.jar app.jar
RUN chown appuser:appuser app.jar
USER appuser
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
EXPOSE 8080
# JVM优化参数
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
ENTRYPOINT ["dumb-init", "--"]
CMD ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
🚀 CI/CD流水线设计
GitLab CI/CD配置
# .gitlab-ci.yml
stages:
- validate
- test
- build
- deploy-dev
- deploy-test
- deploy-prod
variables:
DOCKER_REGISTRY: "registry.company.com"
IMAGE_NAME: "$DOCKER_REGISTRY/spring-boot-app"
# 验证阶段
validate:
stage: validate
image: maven:3.8.6-openjdk-17-slim
script:
- mvn validate
- mvn dependency:analyze
only:
- merge_requests
- main
# 测试阶段
unit-test:
stage: test
image: maven:3.8.6-openjdk-17-slim
services:
- postgres:13
- redis:6.2
script:
- mvn clean test
- mvn jacoco:report
coverage: '/Total.*?([0-9]{1,3})%/'
artifacts:
reports:
junit: target/surefire-reports/TEST-*.xml
coverage_report:
coverage_format: jacoco
path: target/site/jacoco/jacoco.xml
only:
- merge_requests
- main
# 构建镜像
build-image:
stage: build
image: docker:20.10.16
services:
- docker:20.10.16-dind
before_script:
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $DOCKER_REGISTRY
script:
- |
if [ "$CI_COMMIT_REF_NAME" = "main" ]; then
TAG="latest"
else
TAG="$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"
fi
docker build -t $IMAGE_NAME:$TAG .
docker push $IMAGE_NAME:$TAG
echo "IMAGE_TAG=$TAG" > build.env
artifacts:
reports:
dotenv: build.env
only:
- main
- develop
# 部署到开发环境
deploy-dev:
stage: deploy-dev
image: bitnami/kubectl:latest
script:
- kubectl apply -f k8s/dev/ -n development
- kubectl rollout status deployment/spring-boot-app -n development
environment:
name: development
url: https://api-dev.company.com
only:
- develop
# 部署到生产环境
deploy-prod:
stage: deploy-prod
image: bitnami/kubectl:latest
script:
- kubectl apply -f k8s/prod/ -n production
- kubectl rollout status deployment/spring-boot-app -n production
environment:
name: production
url: https://api.company.com
when: manual
only:
- main
📦 Kubernetes部署配置
生产环境部署清单
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-app
namespace: production
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: spring-boot-app
template:
metadata:
labels:
app: spring-boot-app
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
spec:
containers:
- name: app
image: registry.company.com/spring-boot-app:latest
ports:
- containerPort:
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java面试圣经 文章被收录于专栏
Java面试圣经,带你练透java圣经
