在传统软件的开发中,代码的集成工做一般是在全部人都将工做完成后在项目即将结束进行时,而这每每会花费大量的时间和精力。而持续集成是一种将集成阶段放在软件开发阶段的作法,以便更加有规律地构建,测试和集成代码。html
“持续集成并不能消除 Bug,而是让它们很是容易发现和改正。”java
持续集成能够在开发人员提交了新代码后,马上进行构建、单元测试。从而咱们能够根据测试结果以肯定新的代码或者环境配置与原来的以及其余开发人员的代码或者环境配置可否正确地集成在一块儿。linux
持续交付(Continuous Delivery):频繁地将软件的新版本,交付给质量团队或者用户,以供评审。若是评审经过,代码就进入生产阶段。nginx
持续部署(Continuous Deployment):是持续交付的下一步,指的是代码评审之后,自动部署到生产环境。git
从 GitLab 8.0 开始,GitLab CI 就已经集成在 GitLab 中,咱们只须要在项目中添加一个 .gitlab-ci.yml
文件,而后添加一个 Runner
,便可进行持续集成。并且随着 GitLab 的升级,GitLab 也变得愈来愈强大。github
.gtilab-ci.yml
文件存放与项目于仓库的根目录,用以来定义 GitLab CI/CD 中的 Pipeline
。其实无非是一个配置文件,理解起来挺简单的,咱们主要是须要了解 Pipeline
的概念以及如何配置一个 .gitlab-ci.yml
web
一个 Pipeline 大概相对于一个构建任务,里面能够包含多个流程,如安装依赖、运行测试、编译、部署测试服务器、部署生产服务器等流程,Git 提交时会触发 Pipeline。而一个 Pipeline 中又能够包含一至多个 Stage
,即用来定义安装依赖、运行测试之类的流程的。而后,一个 Stage 中又包含了一至多个 Job
,Jobs 表示一个 Stage 中具体的构建工做,即某个 Stage 里面执行的工做。咱们能够在 Stages 里面定义这些 Job,它们之间的关系以下图所示:spring
注意:docker
.gitlab-ci.yml
中配置的顺序执行,当前面的 Stage 执行完毕后才会继续执行后面的 Stage,若是一个 Stage 失败,那么后面的 Stage 不会执行,该构建任务失败。stages: - build - test - deploy build: stage: build script: - "execute-script-for-build" - "do something..."" only: - master tags: - ruby - postage test: stage: test script: ......
上面配置将一次 pipeline 分红了三个阶段:build、test、deploy。下面介绍配置文件中的节点:shell
当咱们理解完上面的概念后,咱们还没了解最重要的东西——上面的任务由谁来构建呢?答案就是 Gitlab-runner 了!
为何不用 GitLab CI 来运行这些构建任务呢?
通常来讲,构建任务任务都会占用不少的系统资源(譬如编译代码),而 GitLab CI 又是 GitLab 的一部分,若是由 GitLab CI 来运行构建任务的话,在执行构建任务的时候, GitLab 的性能会大幅降低。
GitLab CI 最大的做用是管理各个项目的构建状态,所以,运行构建任务这种浪费资源的事情就交给 GitLab Runner 来作啦!
由于 GitLab Runner 能够安装到不一样的机器上,因此在构建任务运行期间并不会影响到 GitLab 的性能。
接下来介绍 GitLab 对 Spring Boot 程序的持续集成,固然 GitLab 不止支持 Java 应用服务,确定也支持其余编译语言,这里主要只是像演示一下过程,过程基本上是相通的。
这不是本次的重点,因此就简要介绍下咯。
利用 Docker 和 Docker Compose 快速搭建 GitLab 服务,docker-compose.yml 文件以下:
version: '3' services: web: image: 'twang2218/gitlab-ce-zh:10.5' restart: always hostname: '192.168.253.139' environment: TZ: 'Asia/Shanghai' GITLAB_OMNIBUS_CONFIG: | external_url 'http://192.168.253.139:8080' gitlab_rails['gitlab_shell_ssh_port'] = 2222 unicorn['port'] = 8888 nginx['listen_port'] = 8080 ports: - '8080:8080' - '8443:443' - '2222:22' volumes: - /usr/local/docker/gitlab/config:/etc/gitlab - /usr/local/docker/gitlab/data:/var/opt/gitlab - /usr/local/docker/gitlab/logs:/var/log/gitlab
启动完毕后,访问 http://ip:8080,初始化安装完成后效果以下:
设置初始化密码后刷新,就能够看见登陆界面了,登陆!
ssh-keygen -t rsa -P 'youname'
复制用户目录下的 .ssh 文件夹下的公钥,将其复制到 GitLab 的
/usr/lcoal/docker/runner
/usr/local/docker/runner/enviroment
jdk-8u152-linux-x64.tar.gz
并复制到 /usr/local/docker/runner/environment
在 usr/lcoal/docker/runner/environment
目录下建立 Dockerfile
FROM gitlab/gitlab-runner:v11.0.2 RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse' > /etc/apt/sources.list && \ echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse' >> /etc/apt/sources.list && \ echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse' >> /etc/apt/sources.list && \ echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list && \ apt-get update -y && \ apt-get clean RUN apt-get -y install apt-transport-https ca-certificates curl software-properties-common && \ curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add - && \ add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" && \ apt-get update -y && \ apt-get install -y docker-ce COPY daemon.json /etc/docker/daemon.json WORKDIR /usr/local/bin RUN wget https://raw.githubusercontent.com/topsale/resources/master/docker/docker-compose RUN chmod +x docker-compose RUN mkdir -p /usr/local/java WORKDIR /usr/local/java COPY jdk-8u152-linux-x64.tar.gz /usr/local/java RUN tar -zxvf jdk-8u152-linux-x64.tar.gz && \ rm -fr jdk-8u152-linux-x64.tar.gz RUN mkdir -p /usr/local/maven WORKDIR /usr/local/maven RUN wget https://raw.githubusercontent.com/topsale/resources/master/maven/apache-maven-3.5.3-bin.tar.gz RUN tar -zxvf apache-maven-3.5.3-bin.tar.gz && \ rm -fr apache-maven-3.5.3-bin.tar.gz ENV JAVA_HOME /usr/local/java/jdk1.8.0_152 ENV MAVEN_HOME /usr/local/maven/apache-maven-3.5.3 ENV PATH $PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin WORKDIR /
在 /usr/local/docker/runner/environment
目录下建立 daemon.json
,用于配置加速器和仓库地址
{ "registry-mirrors": [ "https://registry.docker-cn.com" ], "insecure-registries": [ "ip:port" ] }
新建一个 Git 项目,将其克隆到本地
docker exec -it gitlab-runner gitlab-runner register # 输入 GitLab 地址 Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): http://192.168.75.146:8080/ # 输入 GitLab Token Please enter the gitlab-ci token for this runner: 1Lxq_f1NRfCfeNbE5WRh # 输入 Runner 的说明 Please enter the gitlab-ci description for this runner: 能够为空 # 设置 Tag,能够用于指定在构建规定的 tag 时触发 ci Please enter the gitlab-ci tags for this runner (comma separated): 能够为空 # 选择 runner 执行器,这里咱们选择的是 shell Please enter the executor: virtualbox, docker+machine, parallels, shell, ssh, docker-ssh+machine, kubernetes, docker, docker-ssh: shell
以上交互中,GitLab 地址和 Token 令牌能够在 GitLab 的项目的设置中找到:
当上述步骤完成后,刷新当前页面,能够看见当前页面下多出来一个 runner:
在这里我只简单地作了个小 dome,大概这么简单:
项目中用到的 .gitlab-ci.yml
、Dockerfile
、docker-compose.yml
以下:
.gitlab-ci.yml
stages: - build - run - clean build: stage: build script: - /usr/local/maven/apache-maven-3.5.3/bin/mvn clean package - cp target/ci-test-project-1.0.0-SNAPSHOT.jar docker - cd docker - docker build -t ci-test-project . run: stage: run script: - cd docker - docker-compose down - docker-compose up -d clean: stage: clean script: - docker rmi $(docker images -q -f dangling=true)
Dockerfile
FROM openjdk:8-jre RUN mkdir /app COPY ci-test-project-1.0.0-SNAPSHOT.jar /app/app.jar ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar"] EXPOSE 8080
docker-compose.yml
version: '3.1' services: itoken-config: restart: always image: ci-test-project ports: - 8080:8080
完成 demo 的以后就将项目提交到 GitLab 上,push 完成以后,点击项目的 CI/CD 能够看见一下页面
再点击进入就能够看见具体的做业了,自行体会
当项目出现全部 jobs 所有经过时,也就是持续集成初步完善了,这时咱们能够打开浏览器访问 ip:8080
能够看见浏览器上显示
Hello GitLab
此时咱们能够尝试修改项目中的代码再提交,好比简单地将 retuen "Hello GitLab"
改为 return "Hello World"
再提交一遍代码,等 jobs 经过后,再刷新浏览器,咱们能够看见
Hello World
至此,这个小 Demo 也就完成了。