基于Gitlab和Kubernetes的CI/CD
此套CI/CD流程仅依赖gitlab。runner等组件安装在kubernetes集群中,尽量减少其他依赖,便于维护。
依赖介绍
gitlab runner
gitlab runner用来运行我们的作业并将结果返回给gitlab。此处我们使用gitlab runner的kubernetes执行器,通过helm安装,无需特殊设置
gitlab agent
gitlab agent for kubernetes,一般称为gitlab agent。gitlab agent可以让我们将gitlab与kubernetes集群链接起来。通过这种方式我们可以在gitlab-ci.yml
文件中直接操作kubernetes集群
gitlab容器镜像库
这里我们将生成的镜像直接保存在gitlab上,这样就可以免除对harbor的依赖
gitlab 软件仓库
暂未实现,略
安装gitlab runner
rancher添加chart仓库
安装runner
gitlab获取runner token
修改values文件
rbac权限需要创建,否则runner执行会报错
指定gitlab的地址和runner token
gitlabUrl: https://gitlab.com/ runnerRegistrationToken: xxxxxx
runner安装完成
给runner添加一个标签,方便后续区分
安装gitlab agent for kubernetes
通过gitlab agent for kubernetes,我们可以把gitlab与kubernetes集群链接起来,以进行部署和管理等操作。
使用gitlab agent 可以避免暴露kubernetes api导致的不安全的问题。同时gitlab agent可以使gitlab与防火墙后的kubernetes集群连接,更加方便。
相关资料
rancher添加chart仓库
同上略
代码仓库中添加代理配置
项目根目录下添加.gitlab/agents/microserver
三级目录结构,第三级目录名称可以自定义(agnet的名称)
第三级目录下添加config.yaml
文件
ci_access: projects: # 这里的id为gitlab项目名称 - id: dtstack/gitlab-test
gitlab添加基础设施
需要代码仓库里面包含agent配置(上一步配置的内容),才可以选择到集群
点击注册后会显示相关的token,需要保存好,后续会用到
安装gitlab agnet
选择自定义helm选项
values文件中天降token,注意kas地址是否需要修改
config: kasAddress: wss://kas.gitlab.com token: xxx
安装完成后可以在gitlab上看到集群
gitlab-ci文件
经过上面的步骤,我们的基本配置就已经完成了,接下来需要编写gitlab-ci.yml
文件。整体内容如下
# To contribute improvements to CI/CD templates, please follow the Development guide at: # https://docs.gitlab.com/ee/development/cicd/templates.html # This specific template is located at: # https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Go.gitlab-ci.yml #runner使用的镜像 image: golang:1.18.3-bullseye variables: VERSION: $CI_COMMIT_TAG #在同一分支中共享缓存 cache: key: $CI_COMMIT_REF_SLUG paths: - mybinaries #定义阶段 stages: - test - build - release - images - deploy #格式化和测试代码 format&test: stage: test script: - go fmt $(go list ./... | grep -v /vendor/) - go vet $(go list ./... | grep -v /vendor/) - go test -race $(go list ./... | grep -v /vendor/) #构建代码 build_compile: stage: build script: - mkdir -p mybinaries - go build -o mybinaries/mybin-$VERSION ./... artifacts: paths: - mybinaries ##发布 #release: # stage: release # image: goreleaser/goreleaser:latest # rules: # - if: $CI_COMMIT_TAG # Run this job when a tag is created # variables: # # Disable shallow cloning so that goreleaser can diff between tags to # # generate a changelog. # GIT_DEPTH: 0 ## GITLAB_TOKEN: $GITLAB_TOKEN # script: # - echo "running release_job" # - goreleaser build --rm-dist # release: # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties # tag_name: '$CI_COMMIT_TAG' # description: '$CI_COMMIT_TAG' #推送镜像 build_images&push: stage: images image: name: registry.cn-hangzhou.aliyuncs.com/cefso/kaniko-project.executor:debug entrypoint: [""] script: - mkdir -p /kaniko/.docker - export IFS='' - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json - >- /kaniko/executor --context "${CI_PROJECT_DIR}" --build-arg "version=${VERSION}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:${VERSION}" --force #部署应用 deploy_staging: stage: deploy image: name: bitnami/kubectl:latest entrypoint: [''] environment: name: staging script: - echo "Deploy to staging server" - kubectl config get-contexts - kubectl config use-context ${CI_PROJECT_PATH}:microserver - kubectl get pods - kubectl set image deployment/gitlab-test-app gitlab-test-app=${CI_REGISTRY_IMAGE}:${VERSION} - kubectl rollout restart deployment/gitlab-test-app
基础配置
# runner使用的镜像 # 由于我们使用的是kubernetes执行器,所以此处需要先配置一个gitlab runner默认使用的镜像,后续可以进行覆盖 image: golang:1.18.3-bullseye # 这里定义了一个变量为VERSION,这个用来作为我们镜像的版本号 variables: VERSION: $CI_COMMIT_TAG # 在同一分支中共享缓存 # 通过缓存来减少构建时间(不确定是否生效了) cache: key: $CI_COMMIT_REF_SLUG paths: - mybinaries #定义阶段 stages: - test - build - release - images - deploy
测试阶段
#格式化和测试代码 # 对go的代码进行了格式化和测试,此处使用的是默认镜像 format&test: stage: test script: - go fmt $(go list ./... | grep -v /vendor/) - go vet $(go list ./... | grep -v /vendor/) - go test -race $(go list ./... | grep -v /vendor/)
构建阶段
# 构建代码 # 对go的代码进行打包编译 build_compile: stage: build script: - mkdir -p mybinaries - go build -o mybinaries/mybin-$VERSION ./... # 此处配置了产物,通过这个配置我们可以在gitlab的ui界面中下载我们构建好的二进制程序 artifacts: paths: - mybinaries
发布阶段
未实现,略
##发布 #release: # stage: release # image: goreleaser/goreleaser:latest # rules: # - if: $CI_COMMIT_TAG # Run this job when a tag is created # variables: # # Disable shallow cloning so that goreleaser can diff between tags to # # generate a changelog. # GIT_DEPTH: 0 ## GITLAB_TOKEN: $GITLAB_TOKEN # script: # - echo "running release_job" # - goreleaser build --rm-dist # release: # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties # tag_name: '$CI_COMMIT_TAG' # description: '$CI_COMMIT_TAG'
镜像阶段
这里我们在定义了一个新的镜像,用来替换在文件最开头使用的镜像,文件格式较为复杂,但是基本为固定用法,替换部分我们需要的内容即可。
#推送镜像 build_images&push: stage: images image: name: registry.cn-hangzhou.aliyuncs.com/cefso/kaniko-project.executor:debug entrypoint: [""] script: - mkdir -p /kaniko/.docker - export IFS='' - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json - >- /kaniko/executor --context "${CI_PROJECT_DIR}" --build-arg "version=${VERSION}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:${VERSION}" --force
kaniko
kaniko构建镜像的方式
部署阶段
由于gitlab自带的helm仓库暂时还未加入到free tier,所以此处先放弃使用helm来进行部署,仅仅简单的进行镜像替换。
此处再次替换了默认镜像为bitnami提供的kubectl镜像。通过gitlab agent来对kubernetes集群进行直接操作。
#部署应用 deploy_staging: stage: deploy image: # bitnami提供的kubectl镜像 name: bitnami/kubectl:latest entrypoint: [''] environment: name: staging script: - echo "Deploy to staging server" # 安装gitlab agent后可通过kubectl config命令来切换配置,从而自动获取对集群的操作全新啊 - kubectl config get-contexts - kubectl config use-context ${CI_PROJECT_PATH}:microserver - kubectl get pods # kubectl set命令来更新镜像 - kubectl set image deployment/gitlab-test-app gitlab-test-app=${CI_REGISTRY_IMAGE}:${VERSION} # 上一步中如果镜像的tag相同,会导致deployment不会自动重新部署,这里手动重新部署来防止这种情况 - kubectl rollout restart deployment/gitlab-test-app
通过tag来定义镜像版本
这里我们通过git的tag功能来确定镜像版本
当我们给分支时候,本次构建就会生产对应tag版本的镜像。如果没有带tag,会生成lasts版本的镜像