本文档以构建一个 Java 软件项目并部署到 阿里云容器服务的Kubernetes集群 为例说明如何使用 GitLab CI在阿里云Kubernetes服务上运行GitLab-Runner、配置kubernetes类型的executor并执行Pipeline。
1. 创建GitLab源码项目并上传示例代码
1.1 创建GitLab源码项目
本示例中创建的GitLab源码项目地址为:
http://xx.xx.xx.xx/demo/gitlab-java-demo.git
1.2 获取示例代码并上传至GitLab
$ git clone https://code.aliyun.com/CodePipeline/gitlabci-java-demo.git
$ git remote add gitlab http://xx.xx.xx.xx/demo/gitlab-java-demo.git
$ git push gitlab master
2. 在Kubernetes集群中安装GitLab-Runner
2.1 获取GitLab Runner的注册信息
2.1.1 项目专用Runner
Project --> Settings --> CI/CD --> Runners, 获取URL和registration token信息,如图:
2.1.2 Group Runners
Group --> Settings --> CI/CD --> Runners, 获取URL和registration token信息,如图:
2.1.3 Shared Runners
只能管理员创建, 进入admin/runners 页面获取url和token
2.2 获取并修改GitLab Runner的Helm Chart
$ git clone https://github.com/haoshuwei/ack-gitlab-runner.git
修改values.yaml文件, 示例如下:
## GitLab Runner Image
##
image: gitlab/gitlab-runner:alpine-v12.1.0
## Specify a imagePullPolicy
##
imagePullPolicy: IfNotPresent
## Default container image to use for initcontainer
init:
image: busybox
tag: latest
## The GitLab Server URL (with protocol) that want to register the runner against
##
gitlabUrl: http://xx.xx.xx.xx/
## The Registration Token for adding new Runners to the GitLab Server. This must
## be retreived from your GitLab Instance.
##
runnerRegistrationToken: "AMvEWrBTBu-d8czEYyfY"
## Unregister all runners before termination
##
unregisterRunners: true
## Configure the maximum number of concurrent jobs
##
concurrent: 10
## Defines in seconds how often to check GitLab for a new builds
##
checkInterval: 30
## For RBAC support:
##
rbac:
create: true
clusterWideAccess: false
## Configure integrated Prometheus metrics exporter
##
metrics:
enabled: true
## Configuration for the Pods that that the runner launches for each new job
##
runners:
## Default container image to use for builds when none is specified
##
image: ubuntu:16.04
## Specify the tags associated with the runner. Comma-separated list of tags.
##
tags: "k8s-runner"
## Run all containers with the privileged flag enabled
## This will allow the docker:dind image to run if you need to run Docker
## commands. Please read the docs before turning this on:
##
privileged: true
## Namespace to run Kubernetes jobs in (defaults to the same namespace of this release)
##
namespace: gitlab
cachePath: "/opt/cache"
cache: {}
builds: {}
services: {}
helpers: {}
resources: {}
2.3 安装GitLab Runner
$ helm package .
Successfully packaged chart and saved it to: /root/ack-gitlab-runner/ack-gitlab-runner-0.1.37.tgz
$ helm install --namespace gitlab --name gitlab-runner *.tgz
查看相关的deployment/pod启动是否成功,若成功启动, 则在GitLab上可以看到注册成功的GitLab Runner, 如图:
3. 缓存cache的配置
GitLab Runner中对缓存方案的支持有限,所以我们使用挂载volume的方式做缓存。在上面的示例中, 我们在安装GitLab Runner时默认使用/opt/cache目录作为缓存空间(可以修改values.yaml文件中的runners.cachePath字段)
比如建立maven缓存, 可以在variables下添加MAVEN_OPTS变量并指定本地缓存目录:
variables:
KUBECONFIG: /etc/deploy/config
MAVEN_OPTS: "-Dmaven.repo.local=/opt/cache/.m2/repository"
如果需要挂载新的volume, 则可以修改templates/configmap.yaml文件中的如下字段:
cat >>/home/gitlab-runner/.gitlab-runner/config.toml <<EOF
[[runners.kubernetes.volumes.pvc]]
name = "gitlab-runner-cache"
mount_path = "{{ .Values.runners.cachePath }}"
EOF
即在GitLab Runner进行register之后, 在run之前, 修改config.toml的配置。
4. 全局变量的设置
Project --> Settings --> CI/CD --> Variables, 添加GitLab Runner可用的环境变量,本示例添加3个变量如下:
- REGISTRY_USERNAME 镜像仓库用户名
- REGISTRY_PASSWORD 镜像仓库密码
- kube_config kubeconfig的编码字符串
kubeconfig的编码字符串的生成:
echo $(cat ~/.kube/config | base64) | tr -d " "
5. 编写.gitlab-ci.yml
编写.gitlab-ci.yml文件完成java demo源码项目的编译构建、镜像推送和应用部署。(可参考gitlabci-java-demo源码项目中的.gitlab-ci.yml.example)
.gitlab-ci.yml示例:
image: docker:stable
stages:
- package
- docker_build
- deploy_k8s
variables:
KUBECONFIG: /etc/deploy/config
mvn_build_job:
image: registry.cn-beijing.aliyuncs.com/codepipeline/public-blueocean-codepipeline-slave-java:0.1-63b99a20
stage: package
tags:
- k8s-runner
script:
- mvn package -B -DskipTests
- cp target/demo.war /opt/cache
docker_build_job:
image: registry.cn-beijing.aliyuncs.com/codepipeline/public-blueocean-codepipeline-slave-java:0.1-63b99a20
stage: docker_build
tags:
- k8s-runner
script:
- docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD registry.cn-beijing.aliyuncs.com
- mkdir target
- cp /opt/cache/demo.war target/demo.war
- docker build -t registry.cn-beijing.aliyuncs.com/gitlab-demo/java-demo:$CI_PIPELINE_ID .
- docker push registry.cn-beijing.aliyuncs.com/gitlab-demo/java-demo:$CI_PIPELINE_ID
deploy_k8s_job:
image: registry.cn-beijing.aliyuncs.com/codepipeline/public-blueocean-codepipeline-slave-java:0.1-63b99a20
stage: deploy_k8s
tags:
- k8s-runner
script:
- mkdir -p /etc/deploy
- echo $kube_config |base64 -d > $KUBECONFIG
- sed -i "s/IMAGE_TAG/$CI_PIPELINE_ID/g" deployment.yaml
- cat deployment.yaml
- kubectl apply -f deployment.yaml
.gitlab-ci.yml定义了一个Pipeline, 分三个阶段步骤执行:
image: docker:stable # Pipeline中各个步骤阶段的构建镜像没有指定时, 默认使用docker:stable镜像
stages:
- package # 源码打包阶段
- docker_build # 镜像构建和打包阶段
- deploy_k8s # 应用部署阶段
variables:
KUBECONFIG: /etc/deploy/config # 定义全局变量KUBECONFIG
maven源码打包阶段:
mvn_build_job: # job名称
image: registry.cn-beijing.aliyuncs.com/codepipeline/public-blueocean-codepipeline-slave-java:0.1-63b99a20 # 本阶段构建使用的构建镜像
stage: package # 关联的阶段名称
tags: # GitLab Runner的tag
- k8s-runner
script:
- mvn package -B -DskipTests # 执行构建脚本
- cp target/demo.war /opt/cache # 构建物保存至缓存区
镜像构建和发布阶段:
docker_build_job: # job名称, 已挂载docker.sock
image: registry.cn-beijing.aliyuncs.com/codepipeline/public-blueocean-codepipeline-slave-java:0.1-63b99a20 # 本阶段构建使用的构建镜像
tags: # GitLab Runner的tag
- k8s-runner
script:
- docker login -u REGISTRY_USERNAME -p $REGISTRY_PASSWORD registry.cn-beijing.aliyuncs.com # 登录镜像仓库
- mkdir target
- cp /opt/cache/demo.war target/demo.war
- docker build -t registry.cn-beijing.aliyuncs.com/gitlab-demo/java-demo:$CI_PIPELINE_ID . # 打包docker镜像,使用的tag为本次pipeline的id
- docker push registry.cn-beijing.aliyuncs.com/gitlab-demo/java-demo:$CI_PIPELINE_ID # 推送docker镜像
应用部署阶段:
deploy_k8s_job: # job名称
image: registry.cn-beijing.aliyuncs.com/codepipeline/public-blueocean-codepipeline-slave-java:0.1-63b99a20 # 本阶段构建使用的构建镜像
stage: deploy_k8s # 关联的阶段名称
tags: # GitLab Runner的tag
- k8s-runner
script:
- mkdir -p /etc/deploy
- echo $kube_config |base64 -d > $KUBECONFIG # 配置连接Kubernetes集群的config文件
- sed -i "s/IMAGE_TAG/$CI_PIPELINE_ID/g" deployment.yaml # 动态替换部署文件中的镜像tag
- kubectl apply -f deployment.yaml
6. 执行pipeline
提交.gitlab-ci.yml文件后,Project gitlab-java-demo会自动检测到这个文件并自行pipeline, 如图:
7. 访问服务
如果部署文件中没有指定namespace, 则默认会部署到gitlab命名空间下:
$ kubectl -n gitlab get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
java-demo LoadBalancer 172.19.9.252 xx.xx.xx.xx 80:32349/TCP 1m
浏览器访问 xx.xx.xx.xx/demo 进行验证
了解更多阿里云容器服务内容,请访问 https://www.aliyun.com/product/containerservice
了解更多GitLab CI的内容,请访问 https://docs.gitlab.com/runner/