一场 Chat 学会基于 Docker 的 CI/CD 实战

本 Chat 将分享作者近期接触到的一个项目,以实例分析的方式,讲解如何应用 Docker 对开发流程持续优化,提升开发效率和产品迭代速度,实现 CICD。

通过本 Chat 你将学到:

  1. 什么是 Docker?
  2. 开发中如何应用 Docker?
  3. 怎么实现 CICD,通过打通开发、测试、上线发布的自动化,提升整体研发效率和开发敏捷度?

背景

前一阵子,由于偶然的原因,接触到一个 WEB 项目,需求方期望能通过架构重构,大幅提升整体性能、稳定性和可维护性。

项目原始架构

enter image description here

这是一个典型的 LAMP 架构,部署在单机上面,一开始系统运行的很好,但随着用户量的上升,众多问题开始涌现出来。

由于项目本身年代久远,开发换了一波又一波,基本上已经没有人了解整个项目的全部,很多模块大家都是靠猜。整个系统长时间部署在同一台机器上,没人敢动这台机器。出了问题非常难定位,没人愿意维护这套东西。

改造后项目架构

enter image description here

主要将各子模块分离,Apache 做服务器,Memcache 做缓存,MySQL 做数据库,另外将附件等资源放置在 CDN 以提升用户的访问体验。

同时将各模块容器化, 并引入 CI/CD,以提升系统整体的可维护性和稳定性,由于系统的所有部分(包括环境)全部通过代码固化,就防止了后续由于开发人员变更导致的系统渐渐腐化的问题。

接下来将重点描述该项目如何实现 CI/CD,及 CI/CD 在该项目中起到的作用。

通过 CI/CD 提升效率

如何实现 CI/CD?

这里主要用到两个工具:Docker 和 Gitlab。

Docker 是一套轻量级的虚拟化技术,非常适合与开发集成,固化开发环境,提升开发效率,不必多说,大家应该都比较熟了。

Gitlab 是一个可以部署在私有云环境下的 Git 代码仓库管理系统,通过 Gitlab 自带的流水线功能,可以轻松实现 CI/CD。

通过 Docker 和 Gitlab 我们能轻松打通整个开发流程。

先看一下最终的效果:

在 Gitlab 上的效果:

enter image description here

整个流程包括:

构建 -> 推送 -> 部署到测试环境 -> 部署到生产环境

当然中途还会包含在测试环境的测试等步骤,我们可以看到整个过程都是持续和可视的,开发者只需要关注代码即可,代码一提交,后续过程都会自动化执行。

运行环境效果:

enter image description here

具体代码分析

下面贴一段 gitlab-ci 代码,通过代码我们可以轻松地知道上面过程是如何实现的。

这段代码包含了四个 stage,分别表示上图中的四个阶段,每个阶段会执行一些命令,来运行系统的各个组件。

variables:
    TEST_IMAGE: "20.20.10.100:5000/test/test:latest"
    TEST_URL: test.com
    TEST_IP:  20.20.10.100
    IMAGE_NAME: "20.20.10.100:5000/test/test:${CI_COMMIT_REF_SLUG}_${CI_COMMIT_SHA}"
    PRODUCT_IP: 12.16.0.23
    PRODUCT_URL: http://product.com
    SvrDbIP: 12.16.0.5

# stage 定义运行的阶段
stages:
    #  构建阶段
    - build
    # 发布阶段
    - push
    # 部署到测试环境
    - deploy_test
    # 部署到开发环境
    - deploy_product

# 定义job(作业)
build:
    # 必须指定该job运行的阶段
    stage: build
    # 要运行的shell命令
    #image: docker:latest
    script:
        - echo "build"
        - make
        - docker build -t ${IMAGE_NAME}  .
    only:
    - master
    - test

push:
    stage: push
    script:
        - docker push ${IMAGE_NAME}
    only:
    - master
    - test

deploy_test:
    stage: deploy_test
    script:
      - echo "Deploy to test server"
      - ssh root@${TEST_IP} "docker kill ci;
        docker rm -f ci;
        docker run -d --cap-add=SYS_TIME --net=host --name=ci              --restart=always 
            -p 80:80 -p 8889:8889 -e SvrDbIP=${TEST_IP} -e ${IMAGE_NAME} /start.sh
    environment:
      name: test
      url: http://${TEST_IP}
    only:
    - master
    - test

deploy_product:
    stage: deploy_product
    variables:
        PRODUCT_IMAGE_NAME: "${PRODUCT_IP}:5000/product:${CI_COMMIT_REF_SLUG}_${CI_COMMIT_SHA}"
        PRODUCTLOCAL_IMAGE_NAME: "localhost:5000/product:${CI_COMMIT_REF_SLUG}_${CI_COMMIT_SHA}"
    script:
        docker pull ${PRODUCTLOCAL_IMAGE_NAME}
        docker commit ci ci:autobak-job${CI_JOB_ID}-$(date +%y%m%d%H%M%S)
        docker rm -f cidel
        docker rename ci cidel
        docker kill cidel
        docker run -d --cap-add=SYS_TIME --net=host --name=ci --restart=always -p 80:80 -p 8889:8889  -e SvrDbIP=${SvrDbIP} ${PRODUCTLOCAL_IMAGE_NAME} /start.sh

    environment:
      name: production
      url: http://${PRODUCT_URL}
    when: manual
    only:
    - master
    - test

总结

项目通过上述方法重构后, 顺利地解决了性能、稳定性、可维护性等问题,并且通过 CI/CD 极大地降低了项目开发对人的依赖。后面的版本开发中,基本可以做的随便一个普通开发者都能快速上手。生产环境发现 Bug 也能快速回滚,从而减少整体影响。由于篇幅有限,就讲到这里,如果读者有兴趣可以留言或私聊。

猜你喜欢

转载自blog.csdn.net/c880420/article/details/81236845
今日推荐