基于gitlab ci构建devops平台

2,102 阅读6分钟

devops介绍

DevOps 是一个完整的面向IT运维的工作流,以 IT 自动化以及持续集成(CI)、持续部署(CD)为基础,来优化程式开发、测试、系统运维等所有环节

devops的概念很多,理解也很多。我的理解,它属于软件工程范畴。它定义了一种理念,基于这种理念,能够快速的开发,交付软件及成果物。各个团队直接在这个体系中,高效的沟通,协作等。

这种理念,首先以持续集成(CI)和持续交付(CD)为蓝本进行构建。在这篇文章中,对devops的理论内容不做展开,主要介绍怎么快速的构建一套devops 基础体系,主要适用于初创团队,没有历史包袱的项目。

方案架构图

devops架构图

体系组成

代码版本管理

企业开发中常使用gitlab搭建代码版本库,可以将其看作devops体系中的起始点。

在构建CI流程时,需要对代码分支管理做一定规范。因为后边的构建过程就是基于该分支展开的。

在此简单的展开一种管理模式,将gitlab划分三个分支,dev,test,master。将三种分支分属开发,测试,运维三个角色进行管理。

  • 开发 开发人员将功能分支代码合并到dev分支后,触发构建过程,代码打包,镜像构建等,完成构建后,通过容器管理平台将新构建的镜像进行发布。
  • 测试 当开发人员将代码交付测试部门时,测试人员,将代码merge到test分支中,此时触发测试分支的构建的流程,完成构建后,通过管理平台进行测试环境的发布。
  • 运维 测试验收通过后,交付运维团队进行上线升级,将代码合并到master分支中,构建release版本信息,构建完成后,发布应用。

以上就是基于gitlab的分支管理,所做的三种构建分支,当然,实际操作环境下,绝非这么简单,不能的项目可以会涉及到不同的问题。如,环境配置信息的切换,回滚等,以及配置文件的管理,数据库sql的管理等等。

持续构建

持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。

这个定义有些学术化,看起来让人很懵逼,通俗的说,就是用机器自动化代替以前的新代码运行靠人工去集成,管理,发布,升级的这一过程。按照一定规范,我们将这一过程实现自动化。

实现这样过程的工具有很多,其中的佼佼者要数jenkins,但jenkins是java写的,部署时需要安装JDK8.0以上,功能也过于复杂。在此选用一种简单的持续集成工具gitlab ci进行介绍。

在gitlab8.0以后的版本默认集成了gitlab ci工具。

在使用gitlab ci时,需要借助一个叫作gitlab runner的工具来完成这一流程。关系图如下:

gitlab ci就像一个业务调度器,将需要工作的业务分发到runner中去执行。在构建中,需要一个 .gitlab-ci.yml 编写构建任务。它定义了Pipeline的工作流程。

  • Pipeline

在gitlab中定义的三个流程分支,在其代码发生变化时,通过钩子程序触发pipeline流程。

  • Stages
  • job

来一个.gitlab-ci.yml的基本模版

# 定义 stages
stages:
  - build
  - test
# 定义 job
job1:
  stage: test
  script:
    - echo "I am job1"
    - echo "I am in test stage"
# 定义 job
job2:
  stage: build
  script:
    - echo "I am job2"
    - echo "I am in build stage"

基于以上的构建流程,这里提供一个pipline的模版

variables:
  REPOSITORY: "xxxx/xxxxxx"

stages:
   - deploy

build:
  stage: deploy
  only:
    - master
  script:
    - docker build -t $REPOSITORY:prod .
    - docker tag $REPOSITORY:prod "私有镜像库地址"/$REPOSITORY:prod
    - docker push "私有镜像库地址"/$REPOSITORY:prod
  tags:
    - lable

test:
  stage: deploy
  only:
    - test
  script:
    - docker build -t $REPOSITORY:testing .
    - docker tag $REPOSITORY:testing "私有镜像库地址"/$REPOSITORY:testing
    - docker push "私有镜像库地址"/$REPOSITORY:testing
  tags:
    - lable

dev:
  stage: deploy
  only:
    - dev
  script:
    - docker build -t $REPOSITORY:dev .
    - docker tag $REPOSITORY:testing "私有镜像库地址"/$REPOSITORY:dev
    - docker push "私有镜像库地址"/$REPOSITORY:dev
  tags:
    - lable

现在持续即成多结合容器技术一起使用,在这一步中,最终状态是将要部署的代码打包成一个镜像,发布到镜像库。

私有镜像库作为持续集成的一个重要平台,最终存储着构建好的镜像。

在这一平台构建中,现在多选择明星项目harbor作为私有镜像库。具体在此不做展开,后续会有专门针对该内容的文章进行展开。

持续交付/持续部署

在持续集成中,我们完成了从代码到镜像的制作。最终将生成的镜像交付到私有镜像库中。在持续交付持续部署中,要将完成的镜像发布到部署环境中。

部署也是devops环境中非常重要的一环。简单的说,这一步,要实现的一个目标就是docker run image。将静态的镜像文件变成动态的docker运行环境。

最简单的应用就是docker run 构建完成的镜像。但往往系统常由多个组件构成,如,redis,nginx,mysql,以及其它一些子系统集成在一起组成一个完成的项目。在这种情况下,就需要做容器编排。

编排的目的,使容器安装我们定义的规范来运行。

目前一统江湖的要数谷歌的kubernetes技术。如果,项目简单的话,也可以直接使用docker-compose进行编排。

这里来一个docker-compose的模版。就以harbor为例。

version: '2'
services:
  log:
    image: vmware/harbor-log:v1.1.2
    container_name: harbor-log 
    restart: always
    volumes:
      - /var/log/harbor/:/var/log/docker/:z
    ports:
      - 127.0.0.1:1514:514
    networks:
      - harbor
  registry:
    image: vmware/registry:2.6.1-photon
    container_name: registry
    restart: always
    volumes:
      - /data/registry:/storage:z
      - ./common/config/registry/:/etc/registry/:z
    networks:
      - harbor
    environment:
      - GODEBUG=netdns=cgo
    command:
      ["serve", "/etc/registry/config.yml"]
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "registry"
  mysql:
    image: vmware/harbor-db:v1.1.2
    container_name: harbor-db
    restart: always
    volumes:
      - /data/database:/var/lib/mysql:z
    networks:
      - harbor
    env_file:
      - ./common/config/db/env
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "mysql"
  adminserver:
    image: vmware/harbor-adminserver:v1.1.2
    container_name: harbor-adminserver
    env_file:
      - ./common/config/adminserver/env
    restart: always
    volumes:
      - /data/config/:/etc/adminserver/config/:z
      - /data/secretkey:/etc/adminserver/key:z
      - /data/:/data/:z
    networks:
      - harbor
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "adminserver"
  ui:
    image: vmware/harbor-ui:v1.1.2
    container_name: harbor-ui
    env_file:
      - ./common/config/ui/env
    restart: always
    volumes:
      - ./common/config/ui/app.conf:/etc/ui/app.conf:z
      - ./common/config/ui/private_key.pem:/etc/ui/private_key.pem:z
      - /data/secretkey:/etc/ui/key:z
      - /data/ca_download/:/etc/ui/ca/:z
    networks:
      - harbor
    depends_on:
      - log
      - adminserver
      - registry
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "ui"
  jobservice:
    image: vmware/harbor-jobservice:v1.1.2
    container_name: harbor-jobservice
    env_file:
      - ./common/config/jobservice/env
    restart: always
    volumes:
      - /data/job_logs:/var/log/jobs:z
      - ./common/config/jobservice/app.conf:/etc/jobservice/app.conf:z
      - /data/secretkey:/etc/jobservice/key:z
    networks:
      - harbor
    depends_on:
      - ui
      - adminserver
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "jobservice"
  proxy:
    image: vmware/nginx:1.11.5-patched
    container_name: nginx
    restart: always
    volumes:
      - ./common/config/nginx:/etc/nginx:z
    networks:
      - harbor
    ports:
      - 80:80
      - 443:443
      - 4443:4443
    depends_on:
      - mysql
      - registry
      - ui
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "proxy"
networks:
  harbor:
    external: false

对于k8s的内容,后续会有专题对该内容做展开。

总结

通过以上的内容,我们可以构建起一个简单的devops体系闭环,要达到一个完善的平台,还有很多事情要做。如,自动化测试,配置中心,发布流程,敏捷开发等等。在这个蓝本的基础上根据需求和痛点驱动逐步的完善。