gitlab-ci的使用教程

Gitlab CI

本篇博客首先介绍了如何使用gitlab的ci功能

本篇博客主要介绍如何使用gitlab的ci功能,并且搭配aliyun docker hub功能,实现特定分支有更新的时候,可以进行打镜像,并且推送到aliyun的docker hub,后续可能还会再加上基于docker hub中的镜像实现部署的部分

这篇博客的由来

  • 最近公司打算放弃使用企业版的Github,转向使用Gitlab。刚好最近事情不太多,就尝试了一下gitlab的ci/cd功能
  • 并且实现了自动推送镜像到aliyun的docker hub(薅羊毛啊)
  • 顺道说一句,经过最近这一段时间使用gitlab的经历,我觉得它没有github好用(OvO)
  • 下面部分👇有错误、不好的地方,欢迎大家指正

我做了什么

  • 为了学习使用gitlab的ci/cd功能,我专门写了一个demo,主要就是一个最简单的golang http server,搭配写了一个Dockerfile,用于构造镜像
  • 然后在gitlab的ci/cd中我会使用这个Dockerfile构造出镜像,来推送到 aliyun docker hub,以供后续的部署使用(目前暂时没有部署部分)
  • 这样就模拟了一个项目从开发到线上部署的整个流程,基本全自动化,这样以后可以直接拿来用啦。
  • demo地址为:https://gitlab.com/qinhan-shu/dep-demo
  • 欢迎大家的 fork,issue,star 😄

Aliyun Docker Hub

  • Docker 在如今的web领域的地位、重要性我就不多说了,大家都懂,超级方便好用的容器技术,特别是搭配使用k8s的话
  • 官方的 Docker Hub 超级慢,而且还是公开的。我选择使用 aliyun 免费 & 快速的 Docker Hub 😂
  • 怎么申请呢,首先注册账号,然后进入控制台,搜索 “容器镜像服务”,然后开通,设置密码,这个密码是后续你推送镜像到 aliyun Docker Hub的密码,好好保存着,然后点击 ”创建镜像仓库“,按照他的指示一步一步来就可以来。(哦对,在创建镜像仓库的时候,应该会让你先创建一个命名空间)
  • 创建完成之后点击进入仓库,基本信息中有教你如何使用仓库的教程:
    docker

Gitlab使用CI

  • 想要使用gitlab的ci,那么你必须要有两个东西:Runner、放置于项目根目录的 .gitlab-ci.yml 文件
  • 每当你提交代码的时候,会根据你 .gitlab-ci.yml 配置文件中的规则在 Runner 中运行。这个大概就是 gitlab ci 的实现原理。

Runner

  • 所谓的Runner,就是ci的执行者。gitlab上有共享runner,但是我没有用,我是在自己的ecs上运行了gitlab runner,如果没有的话,使用共享的runner应该也是可以的(我没有试过,欢迎大家分享宝贵的踩坑心得)。

如何搭建自己的Runner

  • 首先进入项目,然后依次进入:settings -> CI/CD,然后展开Runner项,可以看到如下所示的一项:
    runner

  • 它标注了为这个项目构建runner时候所使用的url和令牌。接下来就来在ecs上搭建自己的runner吧。

  • 我推荐使用docker进行搭建,这样不需要在你的ecs上安装任何其他的东西,比较干净。当然官网也提供了单独安装runner的教程,如果大家想去直接安装runner的话也可以,教程地址:https://docs.gitlab.com/runner/install/

    Docker搭建自己的Runner

  • docker安装runner的话,第一步是安装docker:

    1
    curl -sSL https://get.docker.com/ | sh
  • 然后,启动runner

    • 需要将配置卷安装到gitlab-runner容器中以用于配置和其他资源:
      1
      2
      3
      4
      docker run -d --name gitlab-runner --restart always \
      -v /srv/gitlab-runner/config:/etc/gitlab-runner \
      -v /var/run/docker.sock:/var/run/docker.sock \
      gitlab/gitlab-runner:latest
  • 第三步就是注册,将上面图片中的url和令牌注册到Runner中,使其成为项目的Runner

    1
    docker run --rm -t -i -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
  • 接下来会依次让你输入一些东西(包括上面提到的 url和令牌 )

  • 输入url

    1
    2
    Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
    https://gitlab.com
  • 输入令牌

    1
    2
    Please enter the gitlab-ci token for this runner
    xxx
  • 输入Runner的描述(可以在GitLab的UI中更改)

    1
    2
    Please enter the gitlab-ci description for this runner
    [hostname] my-runner
  • 输入与Runner关联的tag(可以在GitLab的UI中更改)

    1
    2
    Please enter the gitlab-ci tags for this runner (comma separated):
    my-tag,another-tag
  • 输入Runner执行程序(推荐使用docker,因为其他的我也没用过,不敢瞎推荐)

    1
    2
    Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
    docker
  • 上述步骤选择Docker作为执行程序,则会要求将默认image,用于未在 .gitlab-ci.yml 中定义镜像的项目( 推荐使用alpine,因为小😂 )

    1
    2
    Please enter the Docker image (eg. ruby:2.1):
    alpine:latest
  • 完成了上述步骤之后,在返回到gitlab的项目的 settings -> CI/CD,然后展开Runner项,就可以看到你刚刚注册的Runner:
    active-runner

  • 到此,Runner就注册完成了

.gitlab-ci.yml

  • 说完了Runner,接下来说说 .gitlab-ci.yml
  • 官网的教程地址:https://docs.gitlab.com/ee/user/project/pages/getting_started_part_four.html
  • 上面的配置文件详解我就不说了,说说Demo(https://gitlab.com/qinhan-shu/dep-demo)中的配置文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    # 首先是镜像的设置
    # 如果不设置镜像的话,则会使用之前注册runner时候最后选择的镜像
    # 在后续每个job中也可以单独设置镜像,如果没有设置的话,则使用这个默认的全局镜像
    image: golang:latest

    # services 是依赖的服务,因为我有一个名为 push_image 的job,这个job需要用到docker命令,将编译好的镜像推送到 aliyun docker hub
    # 因此启动 docker:dind 服务,就是一个 docker daemon,如果没有这个服务,push_image job就会报错了
    services:
    - docker:dind

    # 一些全局变量
    variables:
    # docker 镜像的驱动,选择overlay2来提速,默认驱动较慢
    DOCKER_DRIVER: overlay2
    # 项目名称
    REPO_NAME: gitlab.com/qinhan-shu/dep-demo

    # 顾名思义,就是在 job 执行之前所执行的脚本
    before_script:
    - mkdir -p $GOPATH/src/$(dirname $REPO_NAME)
    - ln -svf $CI_PROJECT_DIR $GOPATH/src/$REPO_NAME
    - cd $GOPATH/src/$REPO_NAME

    # 这个是比较重要的一个配置项目 -- 阶段
    # 各个阶段依次执行,只有前面一个阶段执行完成之后才可以执行后续的阶段
    # 而每一个阶段可以有多个job,job就是ci执行的最小单位
    # 例如改配置就会分成三个阶段:
    # test:测试代码正确性阶段,包括了四个job(gofmt,govet,gotest,coverage)分别从四个不同的侧重点测试代码的正确性;
    # build:编译阶段,包括两个阶段(compile,push_image),第一个job 执行go build,第二个推送镜像到阿里云(我设置成了手动点击执行);
    # deploy:部署,暂时还没有写 😂;
    stages:
    - test
    - build
    - deploy

    # gofmt job,后面的几个job都类似,就不一一详细叙述了,可以直接跳到最后一个job - push_image
    gofmt:
    # 标明属于哪个stage
    stage: test
    # 执行条件,即满足下面条件才会执行。
    # 除去refs,还有其他的条件,见官方文档:https://docs.gitlab.com/ee/ci/yaml/README.html#onlyexcept-basic
    only:
    # 执行分支
    refs:
    - master
    # 具体这个job的执行脚本,借助了Makefile,可以参考看看项目中的 Makefile
    script:
    - make gofmt

    govet:
    stage: test
    only:
    refs:
    - master
    script:
    - make govet

    gotest:
    stage: test
    only:
    refs:
    - master
    script:
    - make gotest

    coverage:
    stage: test
    only:
    refs:
    - master
    script:
    - make coverage

    compile:
    stage: build
    only:
    refs:
    - master
    script:
    - make server

    # push_image job:推送镜像到 aliyun docker hub
    push_image:
    stage: build
    # 本job的镜像,因为需要使用到 docker 指令
    image: docker:stable
    # 只有prod分支才执行
    only:
    refs:
    - prod
    # 默认跳过,手动执行,在项目中的流水线中手动点击执行(考虑到不是每一次都打镜像)。
    when: manual
    # 具体执行的脚本,首先 build, 然后push
    # 这儿一些敏感的账号密码之类放到了 CI/CD 的环境变量中去了
    # 可以在 项目 -> settings -> CI/CD -> Variables 中设置
    script:
    # - COMMIT=$(git rev-parse --short HEAD)
    - IMAGE_NAME=registry.cn-shanghai.aliyuncs.com/qinhan-shu/dep-demo:latest
    - docker build -t $IMAGE_NAME -f docker/Dockerfile .
    - echo ${DOCKER_PASSWORD} | docker login --username ${DOCKER_USER} --password-stdin ${DOCKER_REG}
    - docker push $IMAGE_NAME

总结

  • 后续补充上部署的部分