CI从入门到放弃


  • 持续集成
  • 自动化测试
  • 虚拟化

Introduce to GitLab CI

GitLab CI(Continuous Integration )从GitLab8.0开始就集成于GitLab中,后端的Runner使用.gitlab-ci.yml file 文件来描述对项目进行配置,.gitlab-ci.yml文件告诉GitLab运行器该做什么。 默认情况下,它运行一个包含三个stage的pipeline:构建,测试和部署。 你不需要使用所有三个stage; 没有job的stage会被忽略。

here's a growing trend to use continuous delivery and continuous deployment to automatically deploy tested code to staging and production environments.

运行一个CI需要有两步操作:

  1. 将.gitlab-ci.yml添加到存储库的根目录
  2. 配置一个Runner

Write a .gitlab-ci.yml

.gitlab-ci.yml文件是您配置CI对项目执行的操作的位置。 它位于存储库的根目录中。在任何推送到您的存储库时,GitLab将查找.gitlab-ci.yml文件,并根据该文件的内容在Runners上启动该提交的Job。

注意:.gitlab-ci.yml是一个YAML文件,所以你必须特别注意缩进。 始终使用空格,而不是制表符。

jobs

YAML文件定义了一组具有约束的job,说明应该何时运行它们。 您可以将job的顶级元素定义为任意名称,它们至少需要包含script子句。

job1:
  script: "execute-script-for-job1"

job2:
  script: "execute-script-for-job2"

job内的关键字

关键字 功能
script 由shell执行的脚本
stage job的stage,默认为test
variables job可见的环境变量
allow_failure 是否运行job失败
when 什么情况下执行job,可选on_success/on_failure/always/manual
only/except/tags 只在某些分支下执行job,指定执行job
artifacts job完成后把文件存在这个目录里
dependencies 依赖的job,可以用artifacts进行共享文件
coverage
before_script 覆盖在job之前执行的一组命令

stages

stages:
  - build
  - test
  - deploy

stages指定了各个stage的执行顺序

  1. 同一stage的job是并行运行的。
  2. 下一stage的job在上一stage的job成功完成后运行。

artifacts

artifacts指的是成功后应附加到job的文件和目录列表。job成功完成后,artifact将被发送到GitLab,并可在GitLab UI中下载

** artifacts:paths**:路径
**artifacts:expire_in ** 有效时间,默认为30天

dependencies

此功能应与artifact结合使用,并允许您定义要在不同job之间传递的artifact。请注意,默认情况下会传递所有先前阶段的artifact。

在CI中使用docker

Docker与GitLab CI一起使用时,使用.gitlab-ci.yml中设置的预定义镜像在单独且隔离的容器中运行每个job。

register a docker runner

使用sudo权限输入

sudo gitlab-runner register

接下来会提示输入gitlab仓库位置,tocken,以及使用的执行器,使用docker的话执行器就选择docker,然后选择镜像,这个配置以后可以通过修改配置文件进行修改,如果是通过root权限注册的,那么配置文件在/etc/gitlab-runner/config.toml文件中。

使用docker镜像的时候,默认是会从docker-hub下载镜像,如果镜像在本地,可以在config文件设置pull的policy:pull_policy = "if-not-present"或者pull_policy = "never"

[[runners]]
  name = ""
  url = ""
  token = ""
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "nb-node"
    privileged = false
    disable_cache = false
    volumes = ["/cache"]
+   pull_policy = "if-not-present"
  [runners.cache]

安装docker 和 nvidia-docker

ubuntu安装docker
Nvidia-Docker安装使用 -- 可使用GPU的Docker容器
具体安装方法参考官方github文档

值得注意的是上面的教程都是针对 nvidia-docker 1.0版本的,而最近我测试安装时不成功的,所以我安装了最新的nvidia-docker 2.0, nvidia-docker 2.0要求docker 版本为 18.06.0-ce,而这个版本的docker 使用apt-get 是无法安装的,所以我们从官网手动下载deb文件,进行安装。

docker 各版本下载位置

卸载老版本的docker

apt-get remove docker-ce

下载安装新版本的docker

wget https://download.docker.com/linux/ubuntu/dists/trusty/pool/stable/amd64/docker-ce_18.06.0~ce~3-0~ubuntu_amd64.deb 
dpkg -i docker-ce_18.06.0~ce~3-0~ubuntu_amd64.deb  
rm docker-ce_18.06.0~ce~3-0~ubuntu_amd64.deb  

然后安装nvidia-docker的github的方式安装nvidia-docker-2.

docker自定义远端仓库位置

docker切换默认镜像源
默认安装的 docker 镜像源是在国外,pull 镜像的时候奇慢无比,需要自己手动切换成国内的镜像源。
docker 默认的配置文件是 /etc/default/docker,如果此目录下不存在 docker 文件,可以自己手动创建一个,将文件中添加内容:

 DOCKER_OPTS=" --registry-mirror=https://【xxxxx】.mirror.aliyuncs.com" 

上述代码中的地址替换成自己想要更换的镜像源的地址即可,然后使用 service docker restart命令重启服务。
自定义的仓库可能需要通过 docker login 进行登录。

可以参考define-an-image-from-a-private-container-registry

如果要将私有docker仓库用作构建的镜像源,可以在DOCKER_AUTH_CONFIG秘密变量中设置授权配置。 它可以在项目的GitLab变量部分(网页端)和config.toml文件中设置。

2018-07-18-10-34-34.jpg

在CI中定义镜像和服务

before_script:
  - bundle install

test:2.1:
  image: ruby:2.1
  services:
  - postgres:9.3
  script:
  - bundle exec rake spec

test:2.2:
  image: ruby:2.2
  services:
  - postgres:9.4
  script:
  - bundle exec rake spec

gitlabCI runner的结合使用例子

CI 手动调docker回传artifact 的一个例子

#image: cicuda8

build_arti:
  stage: build
  tags:
    - manual_docker
  script: 
    - hostname
    - mkdir build && cd build
    - touch tmp
    - echo "cd hostbuild && echo hello-world > tmp2" > tmp
  artifacts:
    expire_in: 1 day
    paths:
    - build/

test_arti:
  stage: test
  tags:
    - manual_docker
  script: 
    - sudo docker run --name test_manual_docker -i \
      -v $(pwd)/build:/hostbuild cicuda8 sh /hostbuild/tmp
    - sudo docker rm test_manual_docker
  dependencies:
    - build_arti
  artifacts:
    expire_in: 1 day
    paths:
    - build/
    
deploy_arti:
  stage: deploy
  tags:
    - manual_docker
  script:
    - cd build
    - cat tmp2
    - echo "end4"
  dependencies:
    - test_arti

CI通过SSH连接来调docker的例子

#image: cicuda8

build_arti:
  stage: build
  tags:
    - manual_docker
  script: 
    - hostname
    - mkdir build && cd build
    - touch tmp
    - echo "cd hostbuild && echo hello-world > tmp2" > tmp
  artifacts:
    expire_in: 1 day
    paths:
    - build/

test_arti:
  stage: test
  tags:
    - manual_docker
  script: 
    - cp /usr/share/expect_login.sh expect_login.sh
    - echo "send \"sudo docker run --name test_manual_docker -i -v $(pwd)/build:/hostbuild cicuda8 sh /hostbuild/tmp\r\"" >> expect_login.sh
    - echo "expect $*" >> expect_login.sh
    - echo "send \"sudo docker rm test_manual_docker\r\"" >> expect_login.sh
    - echo "expect $*" >> expect_login.sh
    - cat expect_login.sh
    - expect expect_login.sh 10.10.36.34
    #- sudo docker run --name test_manual_docker -i -v $(pwd)/build:/hostbuild cicuda8 sh /hostbuild/tmp
    #- sudo docker rm test_manual_docker
  dependencies:
    - build_arti
  artifacts:
    expire_in: 1 day
    paths:
    - build/
    
deploy_arti:
  stage: deploy
  tags:
    - manual_docker
  script:
    - cd build
    - cat tmp2
    - echo "end6"
  dependencies:
    - test_arti

这里使用了expect脚本:expect_login.sh

#!/usr/bin/expect
set timeout 30
set ip [lindex $argv 0]
spawn ssh -l maxiaolong 10.0.8.241
expect "password:"
send "mxl@lt.776688\r"
expect "Ip:*"
send "$ip\r"
expect "$*"
send "hostname\r"
expect $*
send ifconfig\r
expect "$*"
#interact

第二个例子 本地执行docker

stages:
  - build-default2
  - lint
  - test-default
  - build-more
  - test-more
  - build-python-full
  - test-python-full

build-default2:
  stage: build-default2
  variables:
    CC: "/usr/bin/gcc-4.8"
    CXX: "/usr/bin/g++-4.8"
    GTEST_ROOT: "/usr/local/gtest/gtest-4.8"
  tags:
    - manual_docker
  script:
    - mkdir temp && cd temp && touch scripts.sh mylog.log
    - git clone $CI_REPOSITORY_URL
    - echo "cd /temp && export CC=/usr/bin/gcc-4.8 && export CXX=/usr/bin/g++-4.8 && export GTEST_ROOT=/usr/local/gtest/gtest-4.8 " >> scripts.sh
    - echo "cd $CI_PROJECT_NAME " >> scripts.sh
    - echo "git checkout $CI_COMMIT_REF_NAME" >> scripts.sh
    - echo "mkdir build && cd build/ && cmake ..  && make -j8 " >> scripts.sh
    - echo "cd ../python && make -j8 " >> scripts.sh
    - cat scripts.sh
    - cd -
    - sudo nvidia-docker run -i --rm  -v $(pwd)/temp:/temp  cicuda8:parrots2 sh /temp/scripts.sh
    - cat temp/mylog.log

第三个例子 上海集群执行docker


stages:
  - build-default
  - lint
  - test-default
  - build-more
  - test-more
  - build-python-full
  - test-python-full

build-default:
  stage: build-default
  variables:
    CC: "/usr/bin/gcc-4.8"
    CXX: "/usr/bin/g++-4.8"
    GTEST_ROOT: "/usr/local/gtest/gtest-4.8"
  tags:
    - ssh_docker
  script:
    - hostname
    - who -m
    - mkdir temp && cd temp && touch scripts.sh
    - echo "cd /$CI_PROJECT_NAME && export CC=/usr/bin/gcc-4.8 && export CXX=/usr/bin/g++-4.8 && export GTEST_ROOT=/usr/local/gtest/gtest-4.8 " >> scripts.sh
    - echo "cd $CI_PROJECT_NAME && hostname && pwd " >> scripts.sh
    - echo "mkdir build && cd build/ && cmake ..  && make -j8 " >> scripts.sh
    - echo "cd ../python && make -j8 " >> scripts.sh
    - cat scripts.sh
    - cd -
    - nvidia-docker run -i --rm  -v $(pwd):/$CI_PROJECT_NAME  registry.sensetime.com/platform/cicuda8:parrots2 sh /$CI_PROJECT_NAME/temp/scripts.sh

Configure a Runner

在GitLab中,Runners运行您在.gitlab-ci.yml中定义的作业。 Runner可以是虚拟机,VPS,裸机,docker容器甚至是容器集群。
get more information at GitLab Runner.

reference

"error while loading shared libraries: xxx.so.x" 错误的原因和解决办法
the docker excutor
Using Docker images
Getting started with GitLab CI/CD
Configuration of your jobs with .gitlab-ci.yml

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容