git第三篇:CI/CD

我们可以利用gitlab自带的CI/CD来让代码在提交后自动编译部署。

按以下步骤实施即可:

1、在项目根目录中新建.gitlab-ci.yml文件,内容示例如下:

stages:
  - build
  - package
  - deploy

go-build:
  image: golang:1.23.1-bullseye
  stage: build
  before_script:
    - cat /etc/os-release
  script:
    - 'go env -w GOPROXY=https://goproxy.cn,direct'
    - 'git config --global --add url."git@github.com:".insteadOf "https://github.com/"'
    - 'git config --global --add url."git@gitlab.com:".insteadOf "https://gitlab.com/"'
    - 'go mod tidy'
    - 'go build -o $CI_PROJECT_NAME ./main.go'
  after_script:
    - ls -l
  artifacts:
    paths:
      - ./$CI_PROJECT_NAME

docker-package:
  image: docker:27.3.1-cli
  stage: package
  variables:
    DOCKER_IMAGE_NAME: $DOCKER_REGISTRY/koushr/$CI_PROJECT_NAME
    DOCKER_HOST: tcp://docker:2375
    DOCKER_TLS_CERTDIR: ""
    CI_DEBUG_SERVICES: "true"
  services:
    - name: docker:27.3.1-dind
  before_script:
    - cat /etc/os-release
    - export TAG=${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}
  script:
    - docker build -t "$DOCKER_IMAGE_NAME:$TAG" .
    - echo "$DOCKER_PWD" | docker login $DOCKER_REGISTRY -u $DOCKER_USER --password-stdin
    - docker push "$DOCKER_IMAGE_NAME:$TAG"
    - docker rmi "$DOCKER_IMAGE_NAME:$TAG"
  after_script:
    - docker logout

linux-deploy:
  image: debian:bullseye
  stage: deploy
  before_script:
    - cat /etc/os-release
    - sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
    - apt-get update && apt-get install -y openssh-client sshpass
    - mkdir -pv ~/.ssh
    - ssh-keyscan $LINUX_DEPLOY_HOST >> ~/.ssh/known_hosts
    - cat ~/.ssh/known_hosts
    - sshpass -e scp ./sh/*.sh root@$LINUX_DEPLOY_HOST:/root/$CI_PROJECT_NAME
    - sshpass -e ssh root@$LINUX_DEPLOY_HOST "cd /root/$CI_PROJECT_NAME && chmod 777 *.sh"
    - export TAG=${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}
  script:
    - sshpass -e ssh root@$LINUX_DEPLOY_HOST "export DOCKER_PWD=$DOCKER_PWD && export DOCKER_REGISTRY=$DOCKER_REGISTRY && export DOCKER_USER=$DOCKER_USER && export CI_PROJECT_NAME=$CI_PROJECT_NAME && export TAG=$TAG && cd /root/$CI_PROJECT_NAME && sh start.sh"
  after_script:
    - cat /etc/os-release

上面的git.private.com代表私有代码仓库地址,192.168.1.108代表私有代码仓库的内网ip地址,hub.private.com代表私有镜像仓库地址。

项目有了.gitlab-ci.yml文件,每次提交后,gitlab就会找可用的runner去执行流水线了。

如果是把代码上传到了公有的gitlab,那么这个时候在项目主页->Build->Pipelines可以看到有流水线在执行了。如https://gitlab.com/koushr/registration/-/pipelines

如果是私有化的gitlab,我们在项目主页->CI/CD->Pipelines可以看到流水线处于Pending状态,点第一个job进去,会看到This job is stuck, because the project doesn't have any runners online assigned to it。这是说gitlab还没有关联runner,接下来需要我们安装runner。

gitlab-ci.yml详解:

每个stage都可以指定一个image,代表这个stage的job会在这个image创建的容器中执行。

高版本的docker-dind默认启用tls,如果我们在gitlab-runner register(见下文)时不指定证书的位置,在gitlab-ci.yml中不设置DOCKER_TLS_CERTDIR为空字符串的话,job会报Cannot connect to the Docker daemon at tcp://xxx:xxx. Is the docker daemon running?

2、安装runner

runner可以安装在任何地方,只要gitlab服务器、runner服务器能够相互访问就行。

我们可以直接在服务器上安装,也可以以docker方式安装,二选一即可。注意安装的runner的版本要尽量和gitlab的版本对应。在浏览器中访问私有仓库地址,在链接后面加/help,可以看到gitlab的版本。

a、在服务器上安装runner:

跟着https://docs.gitlab.com/runner/install/linux-repository.html走就行。

查看runner的日志:journalctl -u gitlab-runner -f。在runner工作不正常时也可以查看此日志来定位问题,比如runner离线。

b、在服务器上以docker方式安装runner

跟着https://docs.gitlab.com/runner/install/docker.html走就行。

docker run --name gitlab-runner -e TZ=Asia/Shanghai -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/config.toml:/etc/gitlab-runner/config.toml --restart always -d gitlab/gitlab-runner:alpine-v11.0.0
config.toml是gitlab-runner的配置文件,可有可无。建议有。如果没有,容器启动后会在/etc/gitlab-runner目录中自动生成。在里面可以定义gitlab-runner的并发度,默认为1。
示例:
concurrent = 100
check_interval = 3
log_level = "warning"

concurrent值为100,表示最多可以同时运行100个job,这样pipeline就可以并行执行了。

3、注册runner

跟着https://docs.gitlab.com/runner/register/走就行。

执行gitlab-runner register命令。如果runner是直接安装在服务器上,则在服务器上执行。如果runner是以docker方式安装,则要在容器中执行。命令示例如下:

gitlab-runner register --non-interactive --url "https://gitlab.com" --token xxx --executor "docker" --docker-image docker:latest --docker-pull-policy if-not-present --docker-privileged --docker-volumes /root/.ssh:/root/.ssh --docker-volumes /var/run/docker.sock:/var/run/docker.sock --docker-volumes /go/pkg/mod:/go/pkg/mod --name "docker-executor-runner"
上例中,url和token的值需要从项目主页->Settings->CI/CD->Runners settings,点击右侧的Expand,Setup a specific Runner manually处获取。不同的版本,支持的参数可能不一样,可以执行gitlab-runner register --help查看具体支持哪些参数。
docker-image用于指定默认镜像,如果.gitlab-ci.yml文件中各stage指定了自己的image,那么各stage运行环境就是其自定义镜像生成的容器。如果某个stage没有指定image,那么这个stage的运行环境就是用默认镜像生成的容器。建议.gitlab-ci.yml文件中各stage都指定自己的image。
docker-pull-policy指定为if-not-present,流水线只会在第一次执行的时候拉取镜像,之后再执行就不会拉了,默认是每次都拉,设为if-not-present可以节省时间。
把/root/.ssh目录映射进容器是用于拉取项目中引用的私有仓库的其他项目,如果用不到可以去掉。容器的/go/pkg/mod目录存放的是编译时拉下来的依赖,最好映射出来,这样下次编译就不用重复拉取了,会节省时间。
把服务器的/var/run/docker.sock映射进去是为了让容器可以使用宿主机的docker daemon,这样在容器中就可以使用docker命令了,否则会报错。其实最好使用dind的方式,但是自己一直没有成功(自己单独dind,可以,但是使用流水线部署dind,不行),以后有时间需要再研究一下。如果我们的流水线没有构建镜像的需求,则这里可以去掉。
/go/pkg/mod目录是针对golang项目的(如果.gitlab-ci.yml文件中用于编译的镜像不是golang:1.23.1-bullseye,依赖也可能放其他目录,要根据实际情况调整),如果是其他语言项目,目录要根据实际情况调整。
/path/to/skywalking-go是用于编译skywalking-go的,如果用不到可以去掉。
上例中,executor的值为docker,此时.gitlab-ci.yml文件中script的运行环境就是.gitlab-ci.yml文件中各stage指定的image生成的容器。如果我们是golang项目,编译阶段image就要指定为含有相应版本golang的镜像,如果我们是java项目,则要指定为含有相应版本jdk的镜像。executor的值,除docker,还支持shell,示例如下:
gitlab-runner register --non-interactive --url "http://xxx.xxx.xxx.xxx/" --registration-token "xxxxxxx" --executor "shell" --description "shell-runner" --tag-list "shell" --run-untagged="true" --locked="false"
如果使用shell,那么.gitlab-ci.yml文件中script的运行环境和runner的安装方式有关。如果runner是直接安装在服务器上的,那么.gitlab-ci.yml文件中script就是直接在此服务器上运行,如果runner是以docker方式安装的,那么.gitlab-ci.yml文件中script是在runner容器中执行的。而runner容器一般只带了gitlab-runner命令,没有各语言的编译环境,所以当runner是以docker方式安装时,register不建议使用shell的executor。
最佳实践:runner直接安装在服务器上,register的executor值为docker。
注册完后,会自动生成config.toml文件(如果已经有config.toml已经存在,则会往此文件中追加内容)。如果runner是直接安装在服务器上,则生成的config.toml在服务器的/etc/gitlab-runner/目录中。如果是以docker方式部署的,则最好在docker run时就映射进去。
注册完后,可以去项目主页->Settings->CI/CD,找到Runners settings,点击右侧的Expand,去Runners activated for this project查看runner。如果runner左侧有感叹号图标,把鼠标放上去后提示New runner. Has not connected yet,则需要在执行register的地方再执行gitlab-runner verify。刷新浏览器页面,再次查看runner,runner左侧图标会变为一个绿色圆点,把鼠标放上去后会提示Runner is online。

至此,runner就可以用了。接下来我们就可以享受流水线带来的便利了。

错误提示1:

ERROR: Preparation failed: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

需要查看runner所在服务器能否pull镜像。如果不能pull,即使开启了docker服务,也会报上面这个错。

 

posted on 2016-10-23 18:49  koushr  阅读(3940)  评论(0)    收藏  举报

导航