背景
- 在过往企业开发中,大部分企业从开发到测试,到部署目前还是手工进行
- 在一些某些中大型企业中,目前构建及部署还是直接使用二进制包部署,或直接单机运行
- 在某些场合下,仓库中代码的编译需要硬件支持,致使本地无法编辑及运行
- 在某些场合下,我们希望根据不同的用户需求部署到不同集群环境中,以实现资源的合理分配
- 在某些时候,用户编译及部署是一项枯燥的工作,我们希望能实现开发工程师无感知的配置代码仓库中的配置文件即可
愿景
- 简化开发上线流程
- 提供基于细粒度的镜像版本构建,做到业务的滚动升级,无覆盖
- 提供上线前自动化测试用户验证
- 提供k8s集群化部署方案或轻量级集群部署(多集群管理,GPU集群,普通CPU集群)
- 提供CICD流程化日志查询
- 提供CICD简单化配置即可自动运行
- 提供CICD消息通知(Webhook, 邮件通知)
目标
- 简单配置
- 自动触发CI
- 自动测试
- 自动构建镜像
- 自动部署
- 自动消息通知
组件介绍
Rancher
- k8s集群管理工具,提供多集群管理工具,内置商店可以实现多场景应用部署
GitLab
- 代码仓库,用户记录代码历史,jeckins将根据代码仓库的commit变化,进行Pipeline 流程
GitLab-Runner
- 为Pipeline流水线提供运行Runner
- 在实际环境中可以分类,例如Cpu-runner,Gpu-runner
Harbor
- 镜像仓库,主要用户镜像存储
K8s
- docker容器化编排技术,实现多节点管理与部署
k3s
- 同上,但是以轻量方式,单进程服务跑完所有k8s依赖的组件,功能与k8s一样
环境准备
- 本次测试以最小化部署来实现,简化流程,所以集群会有两个
- k3s部署的最小化单节点集群(可多节点)
- k8s部署的8节点集群
- Gitlab自行构建
- Harbor镜像仓库自行构建
获取Gitlab Runner注册令牌
- 获取图片中api地址,后面会用到
- 获取图片中api另外,后面会用到
安装Gitlab-Runner
- docker-compose 配置文件
version: "3"
services:
runner:
image: gitlab/gitlab-runner:latest
container_name: gitlab-runner
restart: always
volumes:
- /srv/gitlab-runner/config:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock
- /root/.kube/config:/root/.kube/config
- /etc/docker/daemon.json:/etc/docker/daemon.json
- /usr/bin/docker:/usr/bin/docker
- 运行runner,并注册runner到Gitlab中
command=$1
#
url="http://git.enflame.cn/"
token="aaaaaaaaaaaaaaaaaaaa"
# 修改下面两项
tag="global-runner,ALP,ARD,CPU"
description="ARD-ALP-Normal-runner"
if [ "$command" = "register" ]; then
echo "注册服务中..."
docker run --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \
--non-interactive \
--executor "docker" \
--docker-image alpine:latest \
--url $url \
--registration-token $token \
--description $description \
--tag-list $tag \
--run-untagged="true" \
--locked="false" \
--access-level="not_protected"
fi
- 编辑挂载目录下的/srv/gitlab-runner/config/config.toml文件
concurrent = 1
check_interval = 0
shutdown_timeout = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "ARD-ALP-Normal-runner" # Runner名称
url = "http://git.enflame.cn/" # Gitlab Api地址
id = 2389 # runner id 由register生成
token = "aaaaaaaaaaaaaaaaaa" # Gitlab Api令牌
token_obtained_at = 2022-12-26T15:21:24Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "docker" # 执行器docker
[runners.custom_build_dir]
[runners.cache]
MaxUploadedArchiveSize = 0
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false # 是否进行ssl认证
image = "docker:latest" # 默认使用的镜像
privileged = false # 是否特权启动
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false # volumes 数据挂载,将宿主机docker配置信息,k8s配置信息一起挂载进去,保证执行CICD过程无需在仓库暴露认证信息
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock","/usr/bin/docker:/usr/bin/docker","/root/.docker/config.json:/root/.docker/config.json","/root/.kube/config:/root/.kube/config"]
shm_size = 0
- 查看runner
Demo
- 在项目中构建如何下文件.gitlab.ci.yml
项目中请自行准备Dockerfile与k8s deployment.yaml
variables: # 定义全局可以使用的变量
image_name: harbor.uat.enflame.cc/library/enflame.cn/topsmodel-db
stages: # 定义三个阶段
- Build
- Test
- Deploy
Image Build: # 构建阶段-镜像打包
stage: Build
script:
- docker build -t $image_name:$CI_COMMIT_SHA . # 无需关心harbor,因为密钥已挂载到容器中,可以拉取
Image Push: # 构建阶段-推送仓库
stage: Build
script:
- docker push $image_name:$CI_COMMIT_SHA # 无需关心harbor,因为密钥已挂载到容器中,可以推送
Deploy K8s: # 构建阶段-k8s部署
stage: Deploy
image: roffe/kubectl # 使用kubectl镜像,因为附带了client工具,注意kube/config文件已挂载进容器
when: manual # 表示手动执行
script:
- sed -i "s#{CICD_IMAGE}#$image_name:$CI_COMMIT_SHA#g" ./deployment.yaml # 全局修改配置文件,进行替换
- echo ./deployment.yaml
- kubectl apply -f deployment.yaml # 更新到集群中
- 提交仓库并查询仓库变化
Gitlab-CICD可以使用的系统环境变量
变量 | 描述 |
---|---|
CI | 指定作业在CI环境中完成。 |
CI_COMMIT_REF_NAME | 为项目构建定义分支或标记名称。 |
CI_COMMIT_REF_SLUG | 它使用小写的 |
CI_COMMIT_SHA | 指定构建项目的提交修订 |
CI_COMMIT_TAG | 它提交标签名称 |
CI_CONFIG_PATH | 指定CI配置文件的路径 |
CI_DEBUG_TRACE | 它启用调试跟踪。 |
CI_ENVIRONMENT_NAME | 定义作业的环境名称。 |
CI_ENVIRONMENT_SLUG | 它是一个环境名称,适用于DNS,URL,Kubernetes标签等。 |
CI_ENVIRONMENT_URL | 定义作业的环境URL。 |
CI_JOB_ID | 表示GitLab |
CI_JOB_MANUAL | 它指定作业已经手动启动。 |
CI_JOB_NAME | 作业名称在 |
CI_JOB_STAGE | stage名称在 |
CI_JOB_TOKEN | 该标记用于在涉及触发器时用GitLab |
CI_REPOSITORY_URL | 它指定了克隆Git存储库的URL |
CI_RUNNER_DESCRIPTION | 它指定runner的描述。 |
CI_RUNNER_ID | 它为正在使用的runner提供了唯一的身份证。 |
CI_RUNNER_TAGS | 它定义了 |
CI_RUNNER_VERSION | 它指定当前作业的GitLab |
CI_RUNNER_REVISION | 它指定了当前作业的GitLab修订版本。 |
CI_PIPELINE_ID | 它提供了当前管道的唯一ID。 |
CI_PIPELINE_SOURCE | 它通过使用push,web,trigger,schedule,api,pipeline等选项来指定流水线的触发方式。 |
CI_PIPELINE_TRIGGERED | 它指定作业已被触发。 |
CI_PIPELINE_SOURCE | 它指定了诸如push,web,trigger,schedule,api,external之类的管道源。 |
CI_PROJECT_DIR | 它定义了克隆存储库的完整路径,作业运行的地方。 |
CI_PROJECT_ID | 它提供了当前项目的唯一ID。 |
CI_PROJECT_NAME | 它提供当前项目的名称。 |
CI_PROJECT_PATH | 它提供了项目名称以及命名空间。 |
CI_PROJECT_URL | 它提供了http地址来检索项目。 |
CI_PROJECT_VISIBILITY | 它规定了项目的可见性,无论是内部的,私人的还是公共的。 |
CI_REGISTRY | 0 |
CI_REGISTRY_IMAGE | 它只有在启用容器注册表的情况下才返回与特定项目绑定的GitLab |
CI_REGISTRY_PASSWORD | 密码可用于将容器推送到GitLab容器注册表。 |
CI_REGISTRY_USER | 用户名可以用来将容器推送到GitLab容器注册表。 |
CI_SERVER | 它指定作业在CI环境中执行。 |
CI_SERVER_NAME | 它提供CI服务器名称来协调作业。 |
CI_SERVER_REVISION | 它用于通过使用GitLab修订来安排作业。 |
CI_SERVER_VERSION | 它用于通过使用GitLab版本来安排作业。 |
CI_SHARED_ENVIRONMENT | 它表明作业在共享环境中执行,并且如果环境共享,则它被设置为true。 |
ARTIFACT_DOWNLOAD_ATTEMPTS | 它指定尝试下载运行作业的工件的次数。 |
GET_SOURCES_ATTEMPTS | 它指定了获取源运行作业的尝试次数。 |
GITLAB_CI | all |
GITLAB_USER_ID | 它指定正在运行作业的GitLab用户的ID。 |
GITLAB_USER_EMAIL | 它指定正在运行作业的GitLab用户的电子邮件。 |
GITLAB_USER_LOGIN | 它指定正在运行作业的GitLab用户的登录用户名。 |
GITLAB_USER_NAME | 它指定了正在运行作业的GitLab用户的真实姓名。 |
GITLAB_FEATURES | 它提供了GitLab实例和计划的许可功能列表。 |
RESTORE_CACHE_ATTEMPTS | 它定义了恢复执行作业的缓存尝试次数。 |
CI_DISPOSABLE_ENVIRONMENT | 它表明工作是在一次性环境中执行的,如果环境是一次性的,则它被设置为true。 |