从0到1搭建 K8s+Docker+Gitlab-CI+SpringCloud 之 Gitlab-CI
本文将介绍在 K8s+Docker+Gitlab-CI+SpringCloud 架构体系中的 Gitlab-CI 环节准备工作一台服务器(我采用的是一台阿里云ECS),我们将该该台服务器姑且命名为 serverA。在 serverA 上安装 Docker(注:如何安装 Docker 不是本文的重点,所以不做介绍)。在 serverA 上安装 Gitlab(注:如何安装 Gitlab 不是...
本文将介绍在 K8s+Docker+Gitlab-CI+SpringCloud 架构体系中的 Gitlab-CI 环节
准备工作
- 一台服务器(我采用的是一台阿里云ECS),我们将该该台服务器姑且命名为 serverA。
- 在 serverA 上安装 Docker(注:如何安装 Docker 不是本文的重点,所以不做介绍)。
- 在 serverA 上安装 Gitlab(注:如何安装 Gitlab 不是本文的重点,所以不做介绍)。
- 在 gitlab 中创建一个 project,例如:annoroad-alpha。
开始搭建
1、安装、运行 Gitlab Runner
由于公共镜像仓库中有Gitlab Runner相关镜像,所以我采用镜像的方式安装、运行 TA。首先登录 serverA(已安装 Docker),在 serverA 的命令行里敲入如下命令:
docker run -d --name gitlab-runner --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner
“gitlab-runner” 为 Gitlab Runner 容器的名称。
2、在 Gitlab Runner 中注册一个共享的 Runner
在【步骤1】中启动的 gitlab-runner 容器中执行 register 操作,注册一个 Runner,这个 Runner 可以是共享的,我们也可以为每个 Gitlab 上的项目(例如:annoroad-alpha)注册一个专属的 Runner,这里我采用的是共享 Runner,在 serverA 的命令行里敲入如下命令:
docker exec -it gitlab-runner gitlab-runner register -n --url http://192.168.10.28/ --registration-token 5aWJqSzmMSbUDx9Kzz95 --executor docker --description "annoroad-ms-runner" --tag-list "annoroad-ms-runner" --docker-image "docker:latest" --docker-volumes /var/run/docker.sock:/var/run/docker.sock
参数说明:
-
url、registration-token
这两个参数需要从 Gitlab 的页面上来获得,如下图:
-
description
该 Runner 的描述信息 -
tag-list
在 gitlab-ci.yml 文件中需要用到该参数,下图为 annoroad-alpha 的 gitlab-ci.yml 片段:
-
executor
说明在 Runner 中完成的构建任务,将会采用 Docker 容器的方式运行。 -
docker-image
结合上边的 executor 参数,在这里可以指定 Docker 镜像的版本 -
docker-volumes
由于采用的是 Docker 的方式完成构建任务,所以整个构建任务本身是在一个容器内完成的,而此时需要在容器中使用 docker 相关命令(将 jar 打包成 image 且推送到 register 上),这就会涉及到了「docker in docker」,也就是常见的「dind」 。针对这种在容器中执行 docker 命令的场景,可参考 这篇文章 中所说的几种方式。
这里我采用了文中提到的第三种方式「Use Docker socket binding」方式,将 docker-volumes 参数设置为 /var/run/docker.sock,也就是将 /var/run/docker.sock 绑定装载到容器中,我的理解就是将宿主机上的 Docker 与容器绑定,这样在该容器内就可以使用 docker 命令了。
需要注意的是:由于使用的都是宿主机上的 Docker 守护进程,所以 docker 命令产生的任何容器都将是 Gitlab Runner 的兄弟,而不是所运行程序的子进程。
通过以上的方式,我们就已经在 gitlab runner 中注册了一个名为 annoroad-ms-runner 的 runner。同时在 gitlab runner 的配置文件(/srv/gitlab-runner/config/config.toml)中会生成一段儿与该 runner 相关的配置信息,如下:
[root@gitlab-server cache]# vim /srv/gitlab-runner/config/config.toml
concurrent = 5 # 指定gitlab runner 能同时执行几个 project,默认是 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "annoroad-ms-runner"
url = "http://192.168.10.28/"
token = "2f89baa82a022a02b9e499db060563"
executor = "docker"
[runners.custom_build_dir]
[runners.docker]
tls_verify = false
image = "docker:latest"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache", "/root/.m2:/root/.m2"]
pull_policy = "if-not-present" # 镜像拉取策略,如果当前镜像不存在才去拉取
shm_size = 0
这里需要注意的是 gitlab runner 默认同一时刻只允许存在一个执行的 Pipeline(其他 Pipeline 只能等上一个执行完了才能执行),通过设置 concurrent,我们可以同时运行多个Pipeline。
还有一个要说清楚的是 config.toml 中的 token 是什么,如下图:
3、在 Gitlab 中为 project 配置 Runner
通过在 Gitlab 页面上进行相应的配置,把 annoroad-alpha 与共享 Runner 关联起来,如下图:
-
进入 Admin Area > Runners,找到注册的共享 Runner
-
进入共享 Runner 编辑页面,找到 annoroad-alpha,并且将 TA 设置为 Enable
-
完成
此时,annoraod-alpha 就已经和共享 Runner 关联上了(PS:其他 project 如果也使用共享 Runner,重复该步骤即可),我们再来看一下此时的 annoraod-alpha 是个什么状态 ??
- 进入 annoroad-alpha 项目,打开 CI/CD
- 展开后的效果
- 进入 annoroad-alpha 项目,打开 CI/CD
4、设置 Variables
下边设置的这些值将会在下边介绍的 .gitlab-ci.yml 中用到!!!!!
5、执行 Pipeline
- 进入 annoroad-alpha 项目,打开 CI/CD
- 选择发布分支(master),执行 Pipeline
这里需要大家注意以下两点:
1、执行 Pipeline 的分支必须都是保护分支,如果是您自己创建了一个 hotfix 分支,且该分支没被设置为保护分支,则在执行 Pipeline 的过程中会报错!!!
2、在 Variables 中设置的 PROFILE,在下边介绍的 .gitlab-ci.yml 中会用到!!!!
6、如何将分支设置为保护分支 ?!
我们可以通过如下步骤,来将指定分支设置为保护分支,如下:
- 步骤一
- 步骤二
gitlab-ci.yml 文件说明
为了实现 gitlab-ci,需要在 Gitlab 的 project(例如:annoroad-alpha) 中创建一个 gitlab-ci.yml文件,内如如下:
# 本次构建的阶段:package、build、deploy
stages:
- package
- build
- deploy
# define job variables at job level
variables:
DOCKER_DRIVER: overlay2
# $CI_PROJECT_NAME 是 Gitlab 的变量,表示当前正在构建的项目名称(事实上是项目文件夹名称)
# K8S_DEPLOYMENT_NAME 是当前 project 在 k8s 中 deployment 的名称
K8S_DEPLOYMENT_NAME: $CI_PROJECT_NAME
PROJECT_NAME: $CI_PROJECT_NAME-api
# 该镜像为 stage:build 阶段的基础镜像,在该阶段用执行 kubectl 命令更新 deployment
# annoroad-kubectl:2.0.0 镜像是基于 lachlanevenson/k8s-kubectl:v1.11.0 镜像
ANNOROAD_KUBECTL_IMAGE: registry.cn-beijing.aliyuncs.com/annoroad-cloud/annoroad-kubectl:2.0.0
# 源码打包阶段
package:
image: maven:3.5.4
stage: package
tags:
# 本文中创建的 Runner
- annoroad-ms-runner
only:
# 指定该阶段只能通过页面手动触发
- web
script:
- echo "=============== 开始 源码打包 ==============="
# 这里的 $PROFILE 是通过每次在 Gitlab 上执行 Pipeline 的时候需要指定变量值
# 用 TA 来说明要发布的环境(例如:开发、测试、生产等等),在下边的 stage:deploy 阶段也需要用到 TA
# 通过设置 -P$PROFILE 来告诉 maven 打包的时候取哪个环境的配置信息
- mvn clean install -Dmaven.test.skip=true -P$PROFILE -U
# 将打完的 jar 包保存3分钟,以供后续的stage:build 阶段使用
# 如果不设置 artifacts,则 jar 包不会被保存,在下一个阶段要使用该jar包则会报错
artifacts:
# ${CI_JOB_NAME} 是 Gitlab 的变量,表示 gitlab-ci.yml 中定义的 job 的名称
# ${CI_COMMIT_REF_NAME} 是 Gitlab 的变量,表示用于构建项目的分支或 tag 名称
name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}"
paths:
- ./$PROJECT_NAME/target/$PROJECT_NAME.jar
expire_in: 3 mins
# 镜像构建和打包推送阶段
build:
stage: build
tags:
# 本文中创建的 Runner
- annoroad-ms-runner
only:
# 指定该阶段只能通过页面手动触发
- web
script:
- echo "=============== 开始 镜像构建和打包推送 ==============="
- chmod 755 gitlab-ci-dockerbuild.sh
# 稍后再单独介绍 gitlab-ci-dockerbuild.sh 脚本
# 这里要特别说明的是:
# $ANNOROAD_REGISTRY
# 对应 annoroad-alpha 在 Gitlab 中 Settings -> CI/CD -> Variables 中设置的 ANNOROAD_REGISTRY
# $ANNOROAD_REGISTRY_USERNAME
# 对应 annoroad-alpha 在 Gitlab 中 Settings -> CI/CD -> Variables 中设置的 ANNOROAD_REGISTRY_USERNAME
# $ANNOROAD_REGISTRY_PASSWORD
# 对应 annoroad-alpha 在 Gitlab 中 Settings -> CI/CD -> Variables 中设置的 ANNOROAD_REGISTRY_PASSWORD
# $TEST_PORT
# 对应 annoroad-alpha 在 Gitlab 中 Settings -> CI/CD -> Variables 中设置的 TEST_PORT
# $PRODUCT_PORT
# 对应 annoroad-alpha 在 Gitlab 中 Settings -> CI/CD -> Variables 中设置的 PRODUCT_PORT
# $PROFILE
# 该参数是通过在 Gitlab 上运行 Pipeline 的时候指定设置的,通过该参数用来指定发布的环境(开发、测试、生产等等)
- ./gitlab-ci-dockerbuild.sh $PROJECT_NAME $ANNOROAD_REGISTRY $ANNOROAD_REGISTRY_USERNAME $ANNOROAD_REGISTRY_PASSWORD $TEST_PORT $PRODUCT_PORT $PROFILE
# 应用部署阶段
deploy:
stage: deploy
image:
name: $ANNOROAD_KUBECTL_IMAGE
# 覆盖原镜像的entrypoint,要不然会直接退出
entrypoint: [""]
tags:
# 本文中创建的 Runner
- annoroad-ms-runner
only:
# 指定该阶段只能通过页面手动触发
- web
script:
- echo "=============== 开始 应用部署 ==============="
# 修改 $K8S_DEPLOYMENT_NAME 中的 ENV 的 DEPLOY_TAG 属性,使 k8s 重新发布 $K8S_DEPLOYMENT_NAME
# $PROFILE 就是 stage:package 阶段中的 $PROFILE,用来指向 project 发布到哪个环境里
- kubectl set env deploy/$K8S_DEPLOYMENT_NAME DEPLOY_TAG="$(date)" -n $PROFILE
在 stage:build 阶段执行了一个 shell 脚本(gitlab-ci-dockerbuild.sh),该脚本与 gitlab-ci.yml 同在 project(annoroad-alpha) 的根目录下,内容如下:
#!/bin/sh
server_name=$1
annoroad_registry=$2
annoroad_registry_username=$3
annoroad_registry_password=$4
test_port=$5
product_port=$6
env=$7
if [ $env = "product" ];then
# 生产环境
server_port=$product_port;
elif [ "$env" = "test" ];then
# 测试环境
server_port=$test_port;
elif [ "$env" = "" ];then
echo "ERROR: PROFILE is empty !!!!!!!";
return 1;
else
echo "ERROR: invalid PROFILE($env) !!!!!!!";
return 1;
fi
image_name=$annoroad_registry/annoroad-cloud/$server_name
# 将 gitlba-ci.yml 中 stage:package 阶段生成的 jar 包 cp 到指定目录,创建 project(annoroad-alpha)的 image
cp ./$server_name/target/$server_name.jar ./$server_name/src/main/docker
cd ./$server_name/src/main/docker
# 镜像构建
docker build --build-arg server_name=$server_name --build-arg server_port=$server_port -t $server_name .
docker tag $server_name $image_name
# 登录私有 registry
docker login --username=$annoroad_registry_username --password=$annoroad_registry_password $annoroad_registry
# 推送 image
docker push $image_name
# 删除本地镜像
docker rmi $server_name
docker rmi $image_name
更多推荐
所有评论(0)