GitLab持续集成在商用项目中的应用实践

两年前在开始一个新的商业项目时我花了两个星期时间在项目开发流程中应用上了持续集成,随后一年又随着项目的发展和商用化作了不少改进。因此掌握了GitLab 持续集成这套方案在商业软件中完整的落地实践经验。文章最先发布在其余平台,当时引发了很多关注,内容虽然是对一个PHP项目持续集成的设置,可是整个持续集成是彻底容器化的,这套方法论能够很方便的应用于任何编程语言的项目。php

关注文章下方公众号,关键字回复CI能够获取完整的持续集成方案的编排文件和容器的Dockerfile 源码。html

CI

GitLab CI/CD

Gitlab持续集成是Gitlab提供的一整套持续集成、持续交付解决方案。Gitlab自9.0版本开始增长了CI和CD功能,因此若是你的公司里的Gitlab上在Settings里找不到关于CI/CD的配置项那么大家确实该对公司的GitLab进行升级了。前端

咱们公司以前项目部署一直在用一个叫瓦力的工具,虽然也能实现交付项目的功能可是也有很多弊端,好比:java

  1. 前置任务和后置任务功能不够强大,须要专门写shell脚原本完成复杂的任务。
  2. build环境永远是一套,公司里有的php项目用的版本有5.六、7.0、7.1 ,java项目依赖的jdk版本不一样,这些版本都会相互排斥,一旦一个版本的项目构建成功后一定会影响其余版本的项目。
  3. 构建过程和构建结果不够可视化。

后来公司有的项目陆陆续续开始使用GitLab CI,由于当时对这套解决方案研究不深不知道该如何在CI上进行代码回滚,如何管控生产环境的部署上线(好比只有权限高的人才能部署测试环境、构建完成后想手动部署生产环境而不是push后自动部署)因此只用来作构建和部署测试环境的代码。与此同时执行CI Jobs的机器仍然是一台物理机,上面须要全局安装了这些构建工具来完成项目构建工做,这仍然会遇到上面第二点项目代码版本依赖的冲突。node

因为我本身如今在公司一个重点项目里作架构师,在项目开始之初就有打算将持续集成和持续交付这里好好梳理一下,解决上面这些比较突出的问题。最近因为这些问题爆发的愈来愈严重以为有义务拿出一套比较好的解决方案来解决这些问题因此一直在研究解决这些问题的方案。mysql

随着对Gitlab CI 这套方案理解的加深慢慢制定了以下的策略:laravel

  1. 使用Docker来做为git runner 的executor(执行器),这样在每一个Job完成后都会清理build环境。
  2. 应用不一样的docker镜像来解决构建代码版本依赖的问题(php7的项目用php7的镜像起的容器来执行构建工做,5.6的就用php5.6 镜像起的容器去执行构建工做)
  3. 控制Git工做流,针对不一样功能的代码分支分别写CI Job去执行构建、测试和部署的工做。而且master只接受合并请求不容许任何人push, 这样就可以控制发布正式环境的时间点了,并且部署操做除了push自动触发外也能够配置成在GitLab项目页面里手动点击按钮来部署。

我基本上是将CI分红build , test, deploy三个阶段,build里主要就是完成项目代码依赖包的安装(composer 和 npm install 之类的工做, 咱们先后端是两个项目,前端项目事先须要针对不一样环境配置不一样的打包命令)。git

build:
  stage: build
  image: kevinyan001/git-runner:php7.1-node10
  script:
    - /usr/local/bin/composer install
  only:
    - develop
    - uat
  tags:
    - your-runner-tag

test阶段会去执行项目中编写的测试用例:sql

test-dev:
  stage: test
  image: kevinyan001/git-runner:php7.1-node10
  script:
    - php artisan migrate --force
    - ./vendor/bin/phpunit
  only:
    - develop
  tags:
    - your-runner-tag

deploy阶段完成项目最后的部署和一些服务器reload操做最终将项目交付上线。docker

deploy-testing:
  stage: deploy
  script:
    - rsync -az --delete --exclude=.git --exclude=.gitignore --exclude=.gitlab-ci.yml ./ $SERVER_TOKEN_TEST:$WEB_ROOT_TEST
    - ssh $SERVER_TOKEN_TEST -t "chown -R www:www ${WEB_ROOT_TEST}"
  environment:
    name: test
    url: http://test.example.com
  only:
    - develop
  tags:
    - your-runner-tag

说明:

  • 任务中的$SERVER_TOKEN_TEST这些是提早在GitLab项目的Settings --> CI/CD Pilelines里定义的变量,执行任务时容器会在BASH SHELL中读入这些预先定义的变量。
  • $SERVER_TOKEN_TEST里设置的内容是user@server_ip, ${WEB_ROOT_TEST}里设置的是项目在服务端的路径。
  • 我在容器的镜像里安装了ansible, 发布正式环境时使用ansible将项目部署到正式环境对应的多个主机上。

git runner会在每一个Job的开始阶段经过镜像kevinyan001/git-runner:php7.1-node10 跑一个容器,在容器中执行这些操做,等Job执行完后容器会被中止并清理掉,这就须要咱们在每次容器起来的时候在容器里执行一些预备工做,好比与目标服务器创建信任关系这些基础的工做,我是经过将SSH PRIVATE KEY注入到容器中,目标服务器事先放上对应的公钥来创建容器与目标主机的信任关系的:

before_script:
  - mkdir -p ~/.ssh
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r'  > /root/.ssh/id_rsa
  - chmod -R 600 ~/.ssh
  - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
  - chmod 644 ~/.ssh/known_hosts
  - mkdir -p /etc/ansible
  - echo 'xx.xx.xxx.xxx db_master' >> /etc/hosts #make container can connect to mysql server
  - echo 'xx.xx.xxx.xxx db_slave' >> /etc/hosts

具体能够参考gitlab ci关于这一块的说明文档:https://docs.gitlab.com/ee/ci...

因为GitLab CI的功能很是多,可配置像也不少因此具体某个配置的做用我就不细说了,贴几个我认为比较有用的说明文档出来节省你们的搜索时间。
https://docs.gitlab.com/runne...
https://docs.gitlab.com/ee/ci/
https://docs.gitlab.com/ee/ci...
https://docs.gitlab.com/ee/ci...
https://docs.gitlab.com/ee/ci...

kevinyan001/git-runner:php7.1-node10是我作的一个专门用来跑CI任务的容器的镜像,已经上传到了 Docker 官方的镜像源中能够直接使用。你能够针对你的需求制做其余的镜像。关注下面公众号回复CI能够得到源版的Dockerfile。

Conclusion

GitLab CI/CD提供了一套通用的解决方案让你从最初的Coding开始到最后代码交付上线都能在它提供的工具集合中轻松完成,经过Git Runner的Executor执行不一样阶段定制的任务进行代码build、集成测试、和部署上线。除此以外还能够帮咱们完成API文档生成、代码检查、Wiki文档构建等工做,只要在Linux Bash Shell中能实现的任务它都能帮你实现。它支持用不少不一样类型的Executor来执行CI Jobs,其中我最推荐使用的类型是Docker Executor,这样咱们的build环境就不依赖于Git Runner宿主机上的环境,从而可以应用不一样容器完成各类不一样项目的构建工做。

WX20191117-152623@2x.png

相关文章
相关标签/搜索