基于Gitlab的CD流程实践
2017-05-11 10:02
465 查看
基于Gitlab的CD流程实践
DevOps(英文Development和Operations的组合)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运营工作必须紧密合作。— 百度百科
DevOps提出也已经有些年头了,本文不涉及相关概念,仅以基于Gitlab的CD(持续交付)流程为例子说明实践中工具的构成、配置及使用。
一提到CI(持续集成)就不得不提
Jenkins这一神器,但本流程没有使用它,原因如下:
Gitlab本身带了CI功能,集成度更好,更简单
Jenkins过于复杂了,不适合DevOps,或是说对开发人员不友好,一个工程的测试部署往往需要运维人员介入,而Gitlab
CI的CI流程开发人员可以自行操控
Jenkins没有天然的
pipeline功能,需要通过
blueocean插件实现
Note
以一个Spring
Boot工程(Java项目)为例,说明如何做源码管控、代码质量检查、编译与部署。
本文环境IP为
127.0.0.1,请自行修改。
使用Gitlab做版本控制
代码Push后:
调用SonarQube做质量检查
调用Gitlab CI做编译及单元测试(CI)
调用Gitlab CI做部署(CD)
环境准备
安装Docker.curl -sSL https://get.docker.com/ | sh
安装Gitlab By Docker.
docker run -d \ -p 1443:443 -p 180:80 -p 122:22 \ #开放的端口,注意这里开放的是180的Web端口 --name gitlab \ --env GITLAB_OMNIBUS_CONFIG="external_url 'http://127.0.0.1:180'; nginx['listen_port'] = 80;" \ # Web URL,请将`127.0.0.1`替换成真实的宿主机IP,此URL对应于GIT的地址,如`http://root@127.0.0.1:180/root/test.git`,特别注意的是需要指明Nginx端口为`80`(容器真实端口),否则Nginx也会改成`180`端口导致无法访问。 --restart always \ -v /data/gitlab/config:/etc/gitlab \ # 映射的配置文件目录 -v /data/gitlab/logs:/var/log/gitlab \ -v /data/gitlab/data:/var/opt/gitlab \ # 映射的数据文件目录 gitlab/gitlab-ce:latest
安装Gitlab-runner.
参考
https://docs.gitlab.com/runner/install/linux-repository.html
Tip
Gitlab
CE自带了CI功能,但只相当于一只有调度与监控功能,实际的执行能力需要由
Gitlab-runner提供,这带来的好处是Gitlab不会因为CI执行而影响性能,同时使用独立的
Gitlab-runner可以使用执行器更为自由地在不同主机上部署。
Tip
由于本文使用到
docker类型的
Executor所以直接安装到宿主机上更为方便。
修改权限.
默认gitlab-runner会创建
gitlab-runner用户,请将此用户加到
sudo组(免密码)中:
gitlab-runner ALL=(ALL) NOPASSWD: ALL
注册Runner.
本文件需要两个
runner:
[root[@host1](https://my.oschina.net/host1) target]# gitlab-ci-multi-runner register # 注册`runner` Running in system-mode. Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): http://127.0.0.1:180/ # gitlab的地址 Please enter the gitlab-ci token for this runner: yDNMAooQTxsrLrHgFf6C # token,见`http://<gitlab host>:180/admin/runners` Please enter the gitlab-ci description for this runner: [host1]: Please enter the gitlab-ci tags for this runner (comma separated): maven # 标签名,这里叫`maven` Whether to run untagged builds [true/false]: [false]: # 是否使用标签驱动,即满足这个标签时才使用此`runner` Whether to lock Runner to current project [true/false]: [false]: # 是否当前项目独占,上面的token是全局的,还一种token是关联项目的,如果使用关联某个项目的token且此处是true的时表示这个`runner`仅为这个项目使用 Registering runner... succeeded runner=yDNMAooQ Please enter the executor: kubernetes, docker, parallels, shell, ssh, docker-ssh+machine, docker-ssh, virtualbox, docker+machine: docker # 执行器类型,这里使用`docker` Please enter the default Docker image (e.g. ruby:2.1): maven:alpine # `docker`容器,这里使用maven容器 Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! [root[@host1](https://my.oschina.net/host1) target]# gitlab-ci-multi-runner register Running in system-mode. Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): http://127.0.0.1:180/ Please enter the gitlab-ci token for this runner: yDNMAooQTxsrLrHgFf6C Please enter the gitlab-ci description for this runner: [host1]: Please enter the gitlab-ci tags for this runner (comma separated): shell # 标签名,这里叫`shell` Whether to run untagged builds [true/false]: [false]: Whether to lock Runner to current project [true/false]: [false]: Registering runner... succeeded runner=yDNMAooA Please enter the executor: kubernetes, docker, parallels, shell, ssh, docker-ssh+machine, docker-ssh, virtualbox, docker+machine: shell # 执行器类型,这里使用`shell` Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
此时在gitlab中可以看到
runner已经生效了:
完成后生成的配置如下:
[root[@host1](https://my.oschina.net/host1) target]# cat /etc/gitlab-runner/config.toml concurrent = 1 check_interval = 0 [[runners]] name = "host1" url = "http://127.0.0.1:180/" token = "dfc2643e12d0be2168950490c46999" executor = "docker" [runners.docker] tls_verify = false image = "maven:alpine" privileged = false disable_cache = false volumes = ["/cache", "/root/m2:/root/.m2"] # 修改这个,将maven `.m2` 目录映射到本地 pull_policy = "if-not-present" # 添加这行,默认每次执行都要pull镜像,修改成仅不存在时pull shm_size = 0 [runners.cache] [[runners]] name = "host1" url = "http://127.0.0.1:180/" token = "f069825bc10401c71e064218ba3987" executor = "shell" [runners.cache]
Tip
https://docs.gitlab.com/runner/executors/README.html
安装SonarQube.
# 运行Sonarqube依赖的数据库 docker run --name sonar-db -d \ -e POSTGRES_USER=sonar \ -e POSTGRES_PASSWORD=sonar \ -e POSTGRES_DB=sonar \ -v /data/sonar-db:/var/lib/postgresql/data \ postgres:alpine # 运行Sonarquble docker run --name sonarqube -d \ -p 9000:9000 -p 9092:9092 \ -e SONARQUBE_JDBC_USERNAME=sonar \ -e SONARQUBE_JDBC_PASSWORD=sonar \ -e SONARQUBE_JDBC_URL=jdbc:postgresql://sonar-db/sonar?characterEncoding=utf8 \ -v /data/sonarqube/data:/opt/sonarqube/data \ -v /data/sonarqube/conf:/opt/sonarqube/conf \ -v /data/sonarqube/extensions:/opt/sonarqube/extensions \ # 映射插件目录 --link sonar-db:sonar-db \ sonarqube:alpine
在
/data/sonarqube/extensions下创建
plugins目录,将
https://github.com/gabrie-allaigre/sonar-gitlab-plugin/releases/download/2.0.1/sonar-gitlab-plugin-2.0.1.jar下载到此目录
打开
http://<host>:9000/updatecenter/available用户名/密码:`admin/admin`,下载
SonarJava或其它插件并重启
按
https://gitlab.talanlabs.com/gabriel-allaigre/sonar-gitlab-plugin#configuration配置几个参数
示例工程
/src/main/java/com/ecfront/test/devops/DevOpsApplication.java.
package com.ecfront.test.devops; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; @SpringBootApplication public class DevOpsApplication { public static void main(String[] args) { new SpringApplicationBuilder(DevOpsApplication.class).web(true).run(args); } }
Spring Boot示例,开始默认为8080端口的web服务
/src/main/resources/application.yml.
spring: application: name: DevOps
指定组件名称,可忽略
/.gitlab-ci.yml.
stages: # 定义三个阶段(pipeline) - verify - build - deploy maven-build: # job名称,可随意命名 image: maven:alpine # 使用maven容器运行,可以忽略 stage: build # 绑定这个job为`build`阶段 only: - master # 仅在master分支变更时才触发执行 tags: - maven # 使用标签名为`maven`的`runner`执行 script: "mvn package -B" # 执行脚本,此处为打包操作 artifacts: paths: - target/*.jar # 本阶段输出文件,此处输出打包后的fatjar docker-deploy: stage: deploy tags: - shell # 这个阶段使用标签名为`shell`的`runner`执行 script: # 这里的脚本逻辑是先把包含这个jar的文件编译成镜像,然后run it - sudo docker build -t ecfront/test:1.0 . - app="test" - if sudo docker ps | awk -v app="app" 'NR>1{ ($(NF) == app ) }'; then - sudo docker stop "$app" && sudo docker rm -f "$app" - fi - sudo docker run --name test -d -p 8080:8080 ecfront/test:1.0 sonarqube: # sonarqube的配置 stage: verify only: - master tags: - maven script: # 使用mvn运行sonarqube处理,$SONAR\_URL为sonarqube的url - mvn verify sonar:sonar -Dsonar.host.url=$SONAR_URL
Tip
在变量中添加SONAR_URL=<sonarqube url>
详见:https://docs.gitlab.com/ce/ci/variables/
Tip
https://docs.gitlab.com/ce/ci/yaml/README.html
/Dockerfile
FROM java:8-jdk-alpine VOLUME /tmp ADD /target/devops.jar devops.jar ENTRYPOINT ["java","-jar","/devops.jar"]
使用java容器运行
把上面打出的包加到镜像中
容器运行后运行对应的jar文件
/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> <groupId>com.ecfront.test</groupId> <artifactId>devops</artifactId> <packaging>jar</packaging> <version>1.0.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.sonarsource.scanner.maven</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>3.3.0.603</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <finalName>${project.artifactId}</finalName> </configuration> </plugin> </plugins> </build> </project>
提交测试
我们push这个工程到gitlab后就可以看执行pipelines了:
也可以查看job详细:
在Sonarqube中可以看到工程已经建立了:
查看
test容器可以发现我们的工程已经运行起来了:
相关文章推荐
- 基于 Docker 的 CI/CD 实践
- 自动化工具Ansible:基于Jenkins+Ansible+GitLab的部署实践
- 基于CC2430/31的Zigbee实践(2)--zmain函数流程 及分频问题等
- 基于Jenkins+Gitlab+Harbor+Rancher架构的CI/CD实现
- iHealth基于Docker的DevOps CI/CD实践
- 基于OpenStack+Docker设计与实现CI/CD——基于Docker技术的CI&CD实践
- 超长干货:基于Docker的DevOps CI/CD实践——来自iHealth的分享
- iHealth基于Docker的DevOps CI/CD实践
- 视频演讲: 基于Docker+CI/CD的DevOps实践经验分享
- 基于gitlab-ci runner的Docker stack实践
- 第2号顾问申请的解答(岗位描述+服务流程+收费标准)——CSDN外包实践(25)
- 『原创』DX图形显示基本流程(基于MESH静态模型绘制----托管代码)
- 基于构件技术的软件工程 - Small Team Practice小型团队项目实践标准
- Framework的设计与应用--基于Windows Forms的应用开发实践
- 调用Xvid编码器流程(基于xvid1.1.0)
- 关于基于流程的待办事项的实现
- 调用Xvid编码器流程(基于xvid1.1.0)
- 基于工作流的网络运维流程管理平台的建设和应用
- 项目代理工作手册II(工作流程+收益分析)——CSDN外包实践(40)
- 基于CSDN外包频道的研发型项目顾问服务——CSDN外包实践(49)