2025-05-03 10:42:14 +08:00
2025-05-03 10:42:14 +08:00
2025-05-03 10:42:14 +08:00
2025-05-03 10:42:14 +08:00
2025-05-03 10:42:14 +08:00
2025-05-03 10:42:14 +08:00
2025-05-03 10:42:14 +08:00
2025-05-03 10:42:14 +08:00

Kubernetes GitLab Runner 智能调度器

该项目实现了一个 Kubernetes MutatingWebhook用于优化 GitLab Runner 在 Kubernetes 中的调度策略。它能够使 CI/CD 任务优先调度到上次执行任务的节点上,从而利用节点上已存在的缓存目录,显著提高构建速度。

背景

在 Kubernetes 中运行 GitLab Runner 时,默认的调度策略是将 Pod 分散到集群的不同节点上。但在 CI/CD 流程中,每个任务都需要下载依赖、构建代码等,这些操作可以通过缓存来加速。如果能够将任务调度到之前执行过相同任务的节点上,可以命中缓存,大幅缩短构建时间。

工作原理

  1. 当 GitLab Runner 创建新的 Pod 时MutatingWebhook 会拦截该请求
  2. 检查该 Pod 是否包含缓存卷(通过卷名前缀 runner-cache 识别)
  3. 查询该 Runner ID 上次被调度到的节点(存储在 ConfigMap 中)
  4. 向 Pod 添加节点亲和性NodeAffinity使其优先调度到上次执行过的节点
  5. Pod 调度后,通过 Pod 监控组件记录新的调度结果,以供下次任务使用

部署指南

前提条件

  • Kubernetes 集群1.16+
  • kubectl 命令行工具
  • Docker用于构建镜像
  • OpenSSL用于生成证书

构建镜像

# 克隆仓库
git clone https://git.treesir.pub/DevOps/k8s-hookrunner-scheduling.git
cd k8s-hookrunner-scheduling

# 构建 Docker 镜像
docker build -t your-registry/gitlab-runner-webhook:latest -f deploy/Dockerfile .
docker push your-registry/gitlab-runner-webhook:latest

部署到集群

  1. 修改镜像地址
# 修改 deploy/webhook-deployment.yaml 中的镜像地址
sed -i 's|gitlab-runner-webhook:latest|your-registry/gitlab-runner-webhook:latest|g' deploy/webhook-deployment.yaml
  1. 生成 TLS 证书并部署 Webhook
# 进入 deploy 目录
cd deploy

# 生成证书并创建 Secret
./generate-certs.sh

# 部署服务
kubectl apply -f webhook-deployment.yaml
  1. 验证部署
# 检查 Pod 是否运行正常
kubectl get pods -n kube-system -l app=gitlab-runner-webhook

# 检查服务是否正常
kubectl get service -n kube-system gitlab-runner-webhook

# 检查 WebhookConfiguration 是否存在
kubectl get mutatingwebhookconfigurations gitlab-runner-webhook

配置 GitLab Runner

确保 GitLab Runner 配置中 Pod 包含 Runner ID 标签。在 Runner 的 values.yaml 中,确保有以下配置:

runners:
  config: |
    [[runners]]
      [runners.kubernetes]
        [runners.kubernetes.pod_labels]
          "gitlab.com/runner-id" = "{{ .RunnerID }}"

工作原理详解

  1. Pod 调度记录:系统通过 Pod Informer 持续监控集群中的 Pod 调度情况,对于每个被调度的 GitLab Runner Pod记录其 Runner ID 和被调度的节点名称。

  2. 历史记录存储:调度历史存储在 Kubernetes ConfigMap 中,以 Runner ID 为键,节点名为值。

  3. 亲和性注入:对于新建的 Pod系统查询其 Runner ID 上次调度的节点并添加节点亲和性preferredDuringSchedulingIgnoredDuringExecution权重为 100使 Kubernetes 调度器优先将 Pod 调度到该节点上。

  4. 系统组成

    • WebHook 服务器:拦截 Pod 创建请求并注入节点亲和性
    • 调度记录器:记录和存储 Pod 调度历史
    • Pod 监控器:监控 Pod 调度事件,及时更新调度历史

定制开发

修改标签识别规则

如果你的 GitLab Runner 使用的不是默认标签,可以修改 pkg/webhook/mutate.go 中的常量定义:

// 修改为你的标签
const GitlabRunnerLabel = "your-custom-label"

修改缓存卷识别规则

如果你的缓存卷名称前缀不是 runner-cache,可以修改以下常量:

// 修改为你的缓存卷名称前缀
const CacheVolumePrefixes = "your-cache-prefix"

贡献指南

欢迎提交 Pull Request 或提出 Issue 来帮助改进项目。

Description
No description provided
Readme 51 MiB
Languages
Go 90.2%
Shell 8.5%
Dockerfile 1.3%