0%

gitlab-ci配合docker实现CICD

CI/CD

之前一直不是很了解什么是CI/CD只是有一个模糊的印象,毕竟直译就是持续集成/持续部署,然后实际上接触之后就很有体会,所谓的cicd简单理解就是一种可以帮助你自动化构建项目部署的自动化工具流程,比如说go项目在编写完代码commit之后,cicd就可以根据你提交的最新的代码进行build成二进制,并且通过流水线的概念帮你完成一个又一个部署或者构建项目。

正好碰到了一个实际的需求,记录一下在gitlab下配合ci/cd的流程(以go项目为例)

gitlab runner+docker CI/CD流程

其实工程上业务需求一般的分为两种;

  1. 自动构建二进制文件,然后打成docker镜像上传私有docker仓库
  2. 拉docker私有仓库已经存在的镜像,运行

这篇文章写的很详细,不过用的是手动上传包到harbor(docker私有仓库的开源实现)的。

  • 手动构建docker包上传harbor ,使用gitlab CI从harbor拉取镜像

https://blog.k8s.li/gitlab-ci-harbor.html

1
2
docker login [harbor_host]
docker push docker镜像至harbor

而刚刚说的第一种业务场景模拟构建实现:

流水线1:构建二进制脚本-打包成docker镜像上传harbor

.gitlab-ci.yml

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
#构建golang的包并且做成docker镜像上传至harbor私库
stages:
- build
- docker

build:
stage: build
image: golang:alpine
before_script:
- go env -w GO111MODULE=on
- go env -w GOPROXY=https://goproxy.cn
script:
# go build -o binaryFile sourcecCodeFile
- go build -o build/helloworld main.go
tags:
- dev

docker:
stage: docker
image: docker:latest
variables:
# 大写的作为变量用$符号引用
DOCKER_TLS_CERTDIR: ''
GIT_STRATEGY: none
#这里需要新建一个hello-world项目在harbor中
REPO: hello-world/hello-world
services:
- name: docker:dind
command: ["--registry-mirror", "https://xxxx.com", "--insecure-registry", "xxx.xxx.xxx.xxx:xxxx"]
before_script:
# dollar 符号开头的是系统环境变量
- echo $docker_password | docker login -u $docker_username --password-stdin $docker_addr
script:
# docker build -t image:tag Dockerfile所在位置(构建docker镜像)
- docker build -t $docker_addr/$REPO:latest .
# 将docker push到harbor对应仓库
- docker push $docker_addr/$REPO:latest
tags:
- dev

main.go

1
2
3
4
5
6
7
8
package main

import "fmt"

func main() {
fmt.Println("hello world")
}

run.sh

1
2
#!/bin/sh
/main

Dockerfile

1
2
3
4
5
6
7
8
FROM alpine
COPY build/helloworld /main
COPY run.sh /run.sh

# RUN apk add --no-cache bash
RUN chmod +x /main \
&& chmod +x /run.sh
ENTRYPOINT ["sh","/run.sh"]

流水线2:拉docker私有仓库已经存在的镜像,运行

其实上一个已经包含了这个,build go的那个就是,只是需要指定一下环境变量然后来访问私库,在before_script中指定一下就好