第十九篇:《Docker 在生产环境中的 CI/CD 实践》

第十九篇:《Docker 在生产环境中的 CI/CD 实践》 将 Docker 集成到 CI/CD 流水线中可以实现从代码提交到镜像构建、测试、部署的全自动化。本文介绍如何使用 Jenkins、GitLab CI 和 GitHub Actions 构建镜像、推送到私有仓库并通过滚动更新部署到 Swarm 或 Kubernetes 集群。同时涵盖镜像缓存、安全扫描、蓝绿部署等生产级实践。一、CI/CD 中的 Docker 典型流程text代码提交 → 触发构建 → 运行单元测试 → 构建镜像 → 推送镜像 → 部署到测试环境 → 集成测试 → 部署到生产环境每个阶段都可以在容器中执行确保环境一致性。二、使用 Jenkins Pipeline 构建 Docker 镜像2.1 环境准备Jenkins 安装 Docker Pipeline 插件。Jenkins 节点上安装 Docker并将 Jenkins 用户加入 docker 组或使用 Docker outside of Docker 方式。2.2 Jenkinsfile 示例groovypipeline {agent anyenvironment {DOCKER_REGISTRY ‘myregistry.com:5000’DOCKER_IMAGE “DOCKERREGISTRY/myapp:{DOCKER_REGISTRY}/myapp:DOCKERR​EGISTRY/myapp:{BUILD_NUMBER}”}stages {stage(‘Checkout’) {steps { git ‘https://github.com/your/app.git’ }}stage(‘Unit Test’) {steps {sh ‘docker run --rm -v $(pwd):/app -w /app node:18 npm test’}}stage(‘Build Image’) {steps {sh “docker build -t ${DOCKER_IMAGE} .”}}stage(‘Push Image’) {steps {withCredentials([string(credentialsId: ‘registry_password’, variable: ‘REG_PASS’)]) {sh ‘’’echo ${REG_PASS} | docker login -u youruser --password-stdin ${DOCKER_REGISTRY}docker push ${DOCKER_IMAGE}‘’’}}}stage(‘Deploy to Test’) {steps {sh “docker stack deploy -c docker-compose.test.yml myapp --with-registry-auth”}}stage(‘Integration Test’) {steps {sh ‘./integration-tests.sh’}}stage(‘Deploy to Production’) {input { message “Deploy to production?” }steps {sh “docker stack deploy -c docker-compose.prod.yml myapp --with-registry-auth”}}}post {always {cleanWs() // 清理工作空间}}}2.3 使用 Docker 缓存加速构建在构建阶段可以挂载宿主机的 Docker 缓存目录避免重复下载基础镜像层groovysh ‘’’docker build --cache-from ${DOCKER_IMAGE} -t ${DOCKER_IMAGE} .‘’’或在 docker build 中使用 --build-arg BUILDKIT_INLINE_CACHE1 配合 registry 缓存。三、GitLab CI 集成.gitlab-ci.yml 示例stages:-test-build-deployvariables:DOCKER_REGISTRY:myregistry.com:5000IMAGE_TAG:$CI_COMMIT_SHORT_SHAbefore_script:-docker login-u $CI_REGISTRY_USER-p $CI_REGISTRY_PASSWORD $DOCKER_REGISTRYunit-test:stage:testscript:-docker run--rm-v $(pwd):/app-w /app node:18 npm testbuild:stage:buildscript:-docker build-t $DOCKER_REGISTRY/myapp:$IMAGE_TAG .-docker push $DOCKER_REGISTRY/myapp:$IMAGE_TAGdeploy-test:stage:deployscript:-docker stack deploy-c docker-compose.test.yml myapp--with-registry-authenvironment:testdeploy-prod:stage:deployscript:-docker stack deploy-c docker-compose.prod.yml myapp--with-registry-authenvironment:productiononly:-main四、GitHub Actions 集成.github/workflows/docker-ci.ymlname:Docker CI/CDon:push:branches:[main]pull_request:branches:[main]jobs:test:runs-on:ubuntu-lateststeps:-uses:actions/checkoutv3-name:Run unit testsrun:docker run--rm-v ${{github.workspace}}:/app-w /app node:18 npm testbuild-and-push:needs:testruns-on:ubuntu-latestif:github.event_name pushgithub.ref refs/heads/mainsteps:-uses:actions/checkoutv3-name:Login to Registryuses:docker/login-actionv2with:registry:myregistry.com:5000username:${{secrets.REG_USER}}password:${{secrets.REG_PASS}}-name:Build and pushuses:docker/build-push-actionv4with:context:.push:truetags:myregistry.com:5000/myapp:${{github.sha}}-name:Deploy to Swarmuses:appleboy/ssh-actionv0.1.5with:host:${{secrets.SWARM_MANAGER}}username:${{secrets.SSH_USER}}key:${{secrets.SSH_KEY}}script:|docker login -u ${{ secrets.REG_USER }} -p ${{ secrets.REG_PASS }} myregistry.com:5000 docker stack deploy -c /path/to/docker-compose.prod.yml myapp --with-registry-auth五、镜像安全扫描在 CI 中集成漏洞扫描可阻断含高危漏洞的镜像。5.1 使用 Trivydockerrun--rm-v/var/run/docker.sock:/var/run/docker.sock aquasec/trivy image--severityHIGH,CRITICAL myapp:latest在 Jenkins 中若扫描失败则终止流水线。5.2 使用 Docker Scout官方dockerscout quickview myapp:latest六、部署策略6.1 滚动更新SwarmSwarm 服务支持滚动更新只需在 stack 文件中配置更新策略deploy:replicas:5update_config:parallelism:2delay:10sfailure_action:rollback6.2 蓝绿部署手动实现使用两个环境标签blue / green通过负载均衡切换。# 部署新版本 greendockerserviceupdate --label-addenvgreen myapp# 切换负载均衡器路由到 green# 验证成功后移除 bluedockerservicermmyapp_blue6.3 金丝雀发布Istio Kubernetes更复杂的金丝雀发布需要服务网格不在 Docker Swarm 原生支持范围内可考虑迁移到 K8s。七、构建缓存优化使用 BuildKitDOCKER_BUILDKIT1 docker build支持并行构建和跳过未使用的阶段。缓存外部依赖将 package.json / go.mod 先复制安装依赖再复制源码。使用 registry 作为缓存源–cache-from 参数。示例优化版 Dockerfile 已在前文提及。八、清理 CI 环境避免 CI 节点磁盘被大量旧镜像占满。定期执行dockersystem prune-f--filteruntil24h或在 GitLab Runner 配置中设置 cleanup 脚本。九、小结将 Docker 融入 CI/CD 流水线可以显著提升交付速度和可靠性。核心要点每个阶段使用容器保证一致。镜像缓存和分层构建加速构建。安全扫描嵌入流水线。选择合适的部署策略滚动更新、蓝绿。