Z.S.K.'s Records

Gitlab学习(CI中的变量)

在使用gitlab做ci/cd发布时,变量是无法避免的话题,这次来聊一聊gitlab中各类级别的变量

首先, 变量大致可以分为以下几大类,优先级从高到低:

变量无非就是一种作用域跟优先级的问题,优先级高的会自动覆盖同名优先级的变量

我觉得最常用的有Project-level、Group-level、global、job

group/project

这类的变量直接作用于整个组, 在gitlab的这个组下的所有project,都可以使用, 一般源代码管理都是以某一业务组区分,因此group级别的变量多用于整个组内共享

project-level同理

设置方法

group --> setting --> ci/cd --> variables

project --> setting --> ci/cd --> variables

这里以project变量为例:

protected

gitlab的原文如下:

Variables can be protected. Whenever a variable is protected, it would only be securely passed to pipelines running on the protected branches or protected tags. The other pipelines would not get any protected variables.

翻译一下: 如果把变量选中为protected的话,那么这个就是只会在protected branches or protected tags上安全的传递,其它的情况将不会获取改变量.

但是从我测试的情况来看, 提交的分支为master, 没有设置protected tag, 发现:

  1. 如果某个变量被选中为protected, commit触发pipeline时都可以获取该变量
  2. 但是如果commit时带上tag, 则该变量时为空,当取消protected状态时, 执行正常

乍一看是不是感觉跟原文说的有点出路, 其实出现这种情况是正常的, gitlab默认情况下, master分支是受保护的,

protected branches

可以通过项目 Setting-->Repository --> CI/CD --> Protected Branchers中查看,如下图

所以第1种情况能够正确获取protected的变量是正常的,关于protected branch官方说明在protected branch

第2种情况无法获取的原因是因为带上了tag, 而protected的变量需要存在protected tag配置才能使用

默认情况下是不设置的, 因此无法获取

protected tags

设置protected tag也非常简单,官方说明protected tag

项目 Setting-->Repository --> CI/CD --> Protected Tags

protected branchprotected tags都是为了防止对源代码误操作的两种方式

Masked

而变量的masked则是为了保护变量不回显

protected相当于对权限做了一次验证,但是它无法完全的把变量保护起来, 如果在CI中开启CI_DEBUG_TRACE: 'true'还是能够看到变量的值的,而masked则完全在log中不打印变量, 一般用于比较敏感的信息

K8s_SECRET

K8S_SECRET_开头的变量都会转换成kubernetes的secret

​ 如定义了一个变量叫: K8S_SECRET_RAILS_MASTER_KEY

​ 最终会在k8s中的形态,在部署应用容器里会最终又被转换成环境变量,可直接通过$RAILS_MASTER_KEY:

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
data:
RAILS_MASTER_KEY: MTIzNC10ZXN0
kind: Secret
metadata:
creationTimestamp: 2018-12-20T01:48:26Z
name: production-secret
namespace: minimal-ruby-app-54
resourceVersion: "429422"
selfLink: /api/v1/namespaces/minimal-ruby-app-54/secrets/production-secret
uid: 57ac2bfd-03f9-11e9-b812-42010a9400e4
type: Opaque

当然,在运行前pipeline时也可在UI指定环境变量,这些变量只对应某个project. 且只有这次有效

job

job级别的变量限定在只在某一具体的job内, 这也是用的最多的一种变量

1
2
3
4
5
justupdateconfig:
stage: test
dependencies: []
variables:
CI_DEBUG_TRACE: 'true // job-level

global

这里说到的global指的是在整个pipeline期间,该类变量都是可以使用的

.gitlab-ci.yml中定义全局变量

1
2
3
4
5
variables:
KUBERNETES_NS: 'stage'
APP: 'p-expoter'
PUSH_REPO: 'test'
CONFIGPATH: 'config/config.yml'

在pipeline执行期间都是可以直接引用的,$CONFIGPATH

predefined

同时, gitlab在执行时runner也会暴露出很多的自带的变量, 这些变量在做一些逻辑判断的时候非常有用, 比如判断是不是master分支, 当前路径等等

判断是否commit是否存在tag.

1
2
3
4
5
if [ "$CI_COMMIT_TAG" = "" ]; then
COMMIT_TAG="$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"
else
COMMIT_TAG="$CI_COMMIT_TAG-$CI_COMMIT_SHORT_SHA"
fi

变量列表在predefined_variables

gitlab还支持将变量直接注入到部署的业务容器中, 这个还没有用到过, 有需要的同学可以参考官文.

常用变量

1
2
3
4
5
6
7
8
9
10
CI_COMMIT_TAG  # commit tag
CI_DEBUG_TRACE # 开启debug
CI_MERGE_REQUEST_ID
CI_JOB_TRIGGERED #是否由api触发
CI_COMMIT_SHA #git commit产生的id 长格式
CI_COMMIT_SHORT_SHA # 同上, 短格式
CI_COMMIT_BRANCH # 提交分支
CI_PROJECT_DIR # 当前路径
CI_MERGE_REQUEST_SOURCE_BRANCH_NAME # mege request的源分支
CI_MERGE_REQUEST_TARGET_BRANCH_NAME # merge request的目标分支

参考文章:

转载请注明出处https://izsk.me

Z.S.K. wechat
Scan Me To Read on Phone
I know you won't do this,but what if you did?