本篇目录
- 1. 客户需求
- 2. 需求调研
- 3. 实践
- 3.1 方案一:环境变量的方式
- 3.2 方案二:k8s 自身的spec注入机制
- 4. 效果
该实践来自于客户的一个真实需求
1. 客户需求
客户的某些流水线需要使用GPU资源,但是对于GPU服务器而言,会有多张GPU显卡,而客户只需要将runner的资源调度在其中的一张或者多张显卡,而不是占用整个GPU服务器的显卡资源。
2. 需求调研
- 通过查看runner的相关文档,对于runner使用GPU资源而言,本身runner是不需要做任何配置的,详见说明 [GPU]
(https://docs.gitlab.com/runner/configuration/gpus.html)。 - 关于GPU(主要针对的英伟达),可以通过 NVIDIA_VISIBLE_DEVICES 环境变量来控制,进行制定数量GPU显卡资源的调度。
- 针对runner的执行器为 kubernetes 类型而言,可以通过spec的配置注入机制来实现将部分配置聚合在runner 拉起的pod中,从而实现资源的控制,该技术本身是基于k8s的原理来实现的。
3. 实践
3.1 方案一:环境变量的方式
gitlab runner的配置文件调整如下:
config: |
[[runners]]
environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true","NVIDIA_VISIBLE_DEVICES=0"]
说明:
- 对于多张显卡而言,总是从
0..n
,因此这里的 0 指的是第一张显卡,也就是说runner的作业拉起pod后,会占用第一张显卡。 - 如果要使用多张显卡,可以参考NVIDIA_VISIBLE_DEVICES 的详细配置。
3.2 方案二:k8s 自身的spec注入机制
相比于方案一,方案二要更灵活一下,但是需要开启 FF_USE_ADVANCED_POD_SPEC_CONFIGURATION
flag。具体的配置调整如下:
config: |
[[runners]]
environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true"]
[runners.kubernetes]
namespace = "{{.Release.Namespace}}"
image = "alpine"
pull_policy = ["if-not-present"]
[runners.kubernetes.node_selector]
"nvidia.com/gpu.present" = "true"
[[runners.kubernetes.pod_spec]]
name = "cpu limit"
patch = '''
containers:
- name: build
resources:
limits:
nvidia.com/gpu: 1
'''
patch_type = "strategic"
patch_type说明:
- strategic:Kubernetes 的 战略合并 Patch,可以在不破坏原始 YAML 结构的前提下进行合并和修改(推荐)。
- json:使用 JSON Patch 格式来修改资源。
- merge:简单的合并 Patch。
4. 效果
调整前
调整后