Docker镜像构建与CI/CD自动化部署全流程实战指南

Docker镜像构建与CI/CD自动化部署全流程实战指南
云原生技术已经成为现代应用开发和部署的核心基础设施今天我们来完整梳理从Docker镜像构建到CI/CD流水线再到自动化部署的全流程。这套技术栈能够显著提升开发效率实现环境标准化是每个后端开发和运维人员都需要掌握的核心技能。1. 核心能力速览能力项说明技术栈Docker Kubernetes CI/CD工具链主要功能镜像构建、持续集成、自动化部署环境要求Linux/Windows/macOSDocker环境部署方式本地部署、云平台集成适合场景微服务架构、多环境部署、团队协作开发2. 适用场景与使用边界这套技术组合特别适合以下场景微服务架构项目的标准化部署需要多环境开发、测试、生产隔离的项目团队协作开发需要统一的构建和部署流程追求快速迭代和自动化运维的互联网项目不适用场景单体小项目部署频率低的传统应用对容器化技术栈不熟悉的团队资源受限无法承担容器编排系统开销的环境3. 环境准备与前置条件在开始之前确保你的系统满足以下基本要求操作系统要求Linux: Ubuntu 16.04, CentOS 7, 或其他主流发行版Windows: Windows 10 专业版/企业版/教育版版本1903macOS: macOS 10.13软件依赖Docker Engine 20.10Docker Compose 1.29可选Git 2.0至少4GB可用磁盘空间网络要求稳定的互联网连接用于下载镜像和依赖如果使用云服务需要相应的云平台账号4. Docker镜像构建实战4.1 Dockerfile编写规范一个标准的Dockerfile应该包含以下关键部分# 基础镜像选择 FROM openjdk:8-jre-slim # 维护者信息 LABEL maintainerdev-teamcompany.com # 设置工作目录 WORKDIR /app # 复制应用文件 COPY target/myapp.jar app.jar COPY config/application.properties config/ # 暴露端口 EXPOSE 8080 # 设置环境变量 ENV JAVA_OPTS-Xmx512m -Xms256m ENV PROFILEprod # 健康检查 HEALTHCHECK --interval30s --timeout3s \ CMD curl -f http://localhost:8080/health || exit 1 # 启动命令 ENTRYPOINT [sh, -c, java $JAVA_OPTS -jar app.jar --spring.profiles.active$PROFILE]4.2 多阶段构建优化对于需要编译的项目推荐使用多阶段构建来减小镜像体积# 构建阶段 FROM maven:3.8.4-openjdk-11 as builder WORKDIR /build COPY pom.xml . RUN mvn dependency:go-offline COPY src/ src/ RUN mvn package -DskipTests # 运行阶段 FROM openjdk:11-jre-slim WORKDIR /app COPY --frombuilder /build/target/app.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]4.3 镜像构建命令# 基础构建 docker build -t myapp:1.0.0 . # 多标签构建 docker build -t myapp:1.0.0 -t myapp:latest . # 指定Dockerfile路径 docker build -f Dockerfile.prod -t myapp:prod . # 构建参数传递 docker build --build-arg VERSION1.0.0 -t myapp:1.0.0 .5. 本地镜像测试验证构建完成后必须进行本地测试# 运行容器测试 docker run -d -p 8080:8080 --name myapp-test myapp:1.0.0 # 检查容器状态 docker ps docker logs myapp-test # 健康检查验证 curl http://localhost:8080/health # 停止测试容器 docker stop myapp-test docker rm myapp-test6. CI/CD流水线搭建6.1 流水线设计原则一个完整的CI/CD流水线应该包含以下阶段代码检出 → 2. 依赖安装 → 3. 单元测试 → 4. 构建镜像 → 5. 镜像推送 → 6. 部署测试 → 7. 人工审核 → 8. 生产部署6.2 Jenkins流水线配置示例pipeline { agent any environment { REGISTRY registry.example.com IMAGE_NAME myapp VERSION ${env.BUILD_NAG}-${env.GIT_COMMIT} } stages { stage(代码检出) { steps { git branch: main, url: https://github.com/company/myapp.git } } stage(单元测试) { steps { sh mvn test } post { always { junit target/surefire-reports/*.xml } } } stage(构建镜像) { steps { script { docker.build(${IMAGE_NAME}:${VERSION}) } } } stage(推送镜像) { steps { script { docker.withRegistry(https://${REGISTRY}, registry-credentials) { docker.image(${IMAGE_NAME}:${VERSION}).push() } } } } stage(部署测试环境) { steps { sh kubectl set image deployment/myapp myapp${REGISTRY}/${IMAGE_NAME}:${VERSION} -n test kubectl rollout status deployment/myapp -n test } } stage(人工审核) { steps { input message: 是否部署到生产环境, ok: 确认部署 } } stage(生产部署) { steps { sh kubectl set image deployment/myapp myapp${REGISTRY}/${IMAGE_NAME}:${VERSION} -n prod kubectl rollout status deployment/myapp -n prod } } } post { always { cleanWs() } success { slackSend channel: #deployments, message: 部署成功: ${IMAGE_NAME}:${VERSION} } failure { slackSend channel: #deployments, message: 部署失败: ${IMAGE_NAME}:${VERSION} } } }6.3 GitLab CI配置示例image: docker:latest services: - docker:dind variables: DOCKER_HOST: tcp://docker:2375 DOCKER_DRIVER: overlay2 stages: - test - build - deploy before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY unit-test: stage: test script: - docker run --rm -v $(pwd):/app -w /app maven:3.8.4-openjdk-11 mvn test build-image: stage: build script: - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA . - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA deploy-to-test: stage: deploy script: - apk add --no-cache kubectl - kubectl config use-context test-cluster - kubectl set image deployment/myapp myapp$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n test - kubectl rollout status deployment/myapp -n test only: - main deploy-to-prod: stage: deploy script: - apk add --no-cache kubectl - kubectl config use-context prod-cluster - kubectl set image deployment/myapp myapp$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n prod - kubectl rollout status deployment/myapp -n prod when: manual only: - main7. Kubernetes部署配置7.1 Deployment配置apiVersion: apps/v1 kind: Deployment metadata: name: myapp namespace: prod labels: app: myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: registry.example.com/myapp:1.0.0 ports: - containerPort: 8080 env: - name: SPRING_PROFILES_ACTIVE value: prod resources: requests: memory: 512Mi cpu: 250m limits: memory: 1Gi cpu: 500m livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 57.2 Service配置apiVersion: v1 kind: Service metadata: name: myapp-service namespace: prod spec: selector: app: myapp ports: - port: 80 targetPort: 8080 type: ClusterIP7.3 Ingress配置apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myapp-ingress namespace: prod annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: myapp-service port: number: 808. 自动化部署策略8.1 蓝绿部署apiVersion: v1 kind: Service metadata: name: myapp-service spec: selector: app: myapp version: v1.0.0 # 通过版本标签控制流量 ports: - port: 80 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: myapp-v2 spec: replicas: 3 selector: matchLabels: app: myapp version: v2.0.0 template: metadata: labels: app: myapp version: v2.0.0 spec: containers: - name: myapp image: registry.example.com/myapp:v2.0.08.2 金丝雀发布# 先部署少量实例进行测试 kubectl scale deployment myapp-v2 --replicas1 # 将部分流量导入新版本 kubectl patch service myapp-service -p { spec: { selector: { app: myapp, version: v2.0.0 } } } # 监控新版本运行状况 kubectl get pods -l appmyapp,versionv2.0.0 kubectl logs -l appmyapp,versionv2.0.09. 监控与日志收集9.1 应用监控配置apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config data: prometheus.yml: | global: scrape_interval: 15s scrape_configs: - job_name: myapp static_configs: - targets: [myapp-service:8080]9.2 日志收集配置apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd spec: selector: matchLabels: name: fluentd template: metadata: labels: name: fluentd spec: containers: - name: fluentd image: fluent/fluentd-kubernetes-daemonset:v1.16-debian-elasticsearch8-1 env: - name: FLUENT_ELASTICSEARCH_HOST value: elasticsearch-logging - name: FLUENT_ELASTICSEARCH_PORT value: 920010. 常见问题与排查方法10.1 Docker构建问题问题1构建上下文过大# 解决方案使用.dockerignore文件 echo node_modules/ .dockerignore echo .git/ .dockerignore echo *.log .dockerignore问题2镜像层缓存失效# 优化Dockerfile将不经常变动的层放在前面 # 使用--cache-from参数利用缓存 docker build --cache-frommyapp:latest -t myapp:new .10.2 Kubernetes部署问题问题1镜像拉取失败# 检查镜像仓库认证 kubectl create secret docker-registry regcred \ --docker-serverregistry.example.com \ --docker-usernameusername \ --docker-passwordpassword # 在Deployment中引用secret spec: template: spec: imagePullSecrets: - name: regcred问题2资源不足# 检查节点资源 kubectl describe nodes # 检查Pod资源请求和限制 kubectl describe pod myapp-pod # 调整资源配置 kubectl set resources deployment/myapp --limitsmemory1Gi,cpu500m10.3 网络连接问题问题1服务无法访问# 检查服务端点 kubectl get endpoints myapp-service # 检查网络策略 kubectl get networkpolicies # 测试服务连通性 kubectl run test --imagebusybox --rm -it -- wget -O- myapp-service:8011. 最佳实践与优化建议11.1 镜像优化使用Alpine或Distroless基础镜像减小体积多阶段构建分离构建环境和运行环境合并RUN指令减少镜像层数定期清理无用的镜像和容器11.2 安全实践使用非root用户运行容器定期更新基础镜像安全补丁扫描镜像中的安全漏洞限制容器权限和资源访问11.3 性能优化合理设置资源请求和限制使用就绪性和存活性探针配置HPA自动扩缩容优化应用启动时间这套云原生技术栈虽然学习曲线较陡但一旦掌握就能显著提升开发部署效率。建议从简单的单应用开始实践逐步扩展到微服务架构最终实现全自动化的CI/CD流水线。