DevOps全链路实战 | 第 5 天:GitLab Runner 配置:K8s Executor 与 RBAC 权限设置

第 5/18 天

引言

昨天的文章完成了 GitLab CE 的 Helm 部署和首个代码仓库的初始化推送。但 GitLab 本身只是代码托管平台,真正执行 CI/CD 作业的是 GitLab Runner——一个独立的执行代理,负责拉取代码、运行构建脚本、推送镜像、部署应用。

今天我们将深入 GitLab Runner 的 K8s Executor 运行模式,通过 Helm 部署 Runner,配置 ServiceAccount 和 RBAC 权限,并完成与 Harbor 镜像仓库的认证对接,为明天的 CI 流水线搭建铺平道路。

K8s

一、GitLab Runner 架构与 Executor 选型

1.1 Runner 工作原理

GitLab Runner 是一个轻量级守护进程,通过 GitLab API 长轮询(long-polling)获取待执行的 CI 作业。当 GitLab 触发 Pipeline 时,Runner 接收作业指令,根据配置的 Executor 类型创建执行环境,运行 .gitlab-ci.yml 中定义的 stages。

核心工作流程:GitLab 触发 Pipeline → Runner 轮询获取 Job → Executor 创建执行环境 → 拉取代码 → 执行脚本 → 回传日志和产物 → 销毁执行环境。

1.2 Executor 类型对比

GitLab Runner 支持多种 Executor,生产环境选型至关重要:

Executor 隔离方式 启动速度 资源开销 适用场景
Shell 无隔离(直接在 Runner 主机上执行) 最快 最低 单机测试、脚本调试
Docker Docker 容器隔离 中等 标准构建、需要容器环境
Kubernetes K8s Pod 隔离 中等 中等 生产 CI/CD、弹性扩缩
Docker Machine 自动创建 VM 需要完全隔离的构建

本系列选择 Kubernetes Executor,原因如下:

  • 弹性调度:每个 CI Job 自动创建独立 Pod,执行完毕自动销毁,资源利用率高
  • 天然隔离:不同 Job 在不同 Pod 中运行,互不干扰
  • 与 K8s 集群无缝集成:Runner 本身以 Helm Chart 部署在 K8s 中,管理 CI Pod 如同管理应用 Pod
  • 水平扩展:多 Runner 实例并发处理多个 Job,无需手动扩容

1.3 K8s Executor 架构

K8s Executor 执行一个 CI Job 时的完整流程:

💻 代码示例

┌─────────────┐ 轮询 Job ┌──────────────────┐

│ GitLab │ ──────────────→ │ GitLab Runner │

│ Server │ │ (Deployment) │

│ │ ←────────────── │ │

└─────────────┘ 回传日志 └────────┬──────────┘

│ 创建 Pod

┌──────────────────────────────┐

│ CI Job Pod │

│ ┌─────────┐ ┌────────────┐ │

│ │ build │ │ svc-acct │ │

│ │ container│ │ (RBAC) │ │

│ └─────────┘ └────────────┘ │

│ PVC: 代码缓存 + 产物持久化 │

└──────────────────────────────┘

每个 CI Job Pod 包含:build 容器(执行脚本)、helper 容器(拉取代码和上传产物)、ServiceAccount(RBAC 权限)、PVC(缓存和产物)。

二、RBAC 权限规划

2.1 为什么 Runner 需要 RBAC

K8s Executor 创建 Pod 执行 CI Job,这需要 K8s API 的操作权限。如果不配置 RBAC,Runner 将因权限不足无法创建 Pod,CI Job 会直接失败。

权限需求分析:

操作 需要的资源权限 说明
创建/删除 Pod pods, pods/log 每个 Job 创建和销毁 Pod
创建/删除 PVC persistentvolumeclaims Job 缓存和产物持久化
创建/删除 Secret secrets 存储 CI 环境变量
创建/删除 ConfigMap configmaps 存储 Runner 配置
查看 Service services 服务发现和网络访问

2.2 最小权限原则

生产环境应遵循最小权限原则,Runner 只授予 CI 命名空间的权限,不使用 cluster-admin:

💻 代码示例

# gitlab-runner-rbac.yaml

apiVersion: v1

kind: ServiceAccount

metadata:

name: gitlab-runner

namespace: gitlab-runner

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

name: gitlab-runner-role

namespace: gitlab-runner

rules:

# Pod 管理(核心权限)

– apiGroups: [""]

resources: ["pods", "pods/log", "pods/attach"]

verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]

# PVC 管理(缓存和产物)

– apiGroups: [""]

resources: ["persistentvolumeclaims"]

verbs: ["get", "list", "watch", "create", "delete"]

# Secret 管理(CI 变量)

– apiGroups: [""]

resources: ["secrets"]

verbs: ["get", "list", "watch", "create", "delete", "update"]

# ConfigMap 管理

– apiGroups: [""]

resources: ["configmaps"]

verbs: ["get", "list", "watch", "create", "delete"]

# Service 查看(网络访问)

– apiGroups: [""]

resources: ["services"]

verbs: ["get", "list", "watch"]

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

name: gitlab-runner-binding

namespace: gitlab-runner

subjects:

– kind: ServiceAccount

name: gitlab-runner

namespace: gitlab-runner

roleRef:

kind: Role

name: gitlab-runner-role

apiGroup: rbac.authorization.k8s.io

三、Helm 部署 GitLab Runner

3.1 添加 Helm 仓库并创建命名空间

💻 代码示例

# 添加 GitLab Runner 官方 Helm 仓库

helm repo add gitlab-runner https://charts.gitlab.io

helm repo update

 

# 创建专用命名空间(与 GitLab 分离,便于权限隔离)

kubectl create namespace gitlab-runner

 

# 先应用 RBAC 配置

kubectl apply -f gitlab-runner-rbac.yaml -n gitlab-runner

3.2 编写 Helm Values 配置

💻 代码示例

# gitlab-runner-values.yaml

image:

registry: registry.gitlab.com

image: gitlab-org/gitlab-runner

tag: alpine-v17.8.2

 

gitlabUrl: https://gitlab.stellardata.top

 

# Runner 注册 Token(从 GitLab 管理界面获取)

runnerRegistrationToken: "GR13489xx_your_token_here"

 

rbac:

create: false # 使用上面手动创建的 RBAC

serviceAccountName: gitlab-runner

 

runners:

config: |

[[runners]]

name = "k8s-executor-runner"

url = "https://gitlab.stellardata.top"

token = "{{ .Values.runnerRegistrationToken }}"

executor = "kubernetes"

[runners.kubernetes]

namespace = "gitlab-runner"

service_account = "gitlab-runner"

# Pod 资源限制

cpu_limit = "2"

memory_limit = "4Gi"

cpu_request = "500m"

memory_request = "1Gi"

# 构建容器配置

image = "alpine:3.19"

privileged = true

# 缓存配置

[runners.kubernetes.pvc]

enabled = true

size = "10Gi"

storage_class = "local-storage"

# Harbor 认证

[runners.kubernetes.node_selector]

"node-role.kubernetes.io/worker" = "true"

tags: "k8s,build,deploy"

runUntagged: false

 

concurrent: 5 # 并发 Job 数

checkInterval: 30 # 轮询间隔(秒)

 

resources:

requests:

cpu: 250m

memory: 256Mi

limits:

memory: 512Mi

配置要点说明:

  • executor = "kubernetes" 指定使用 K8s Executor
  • privileged = true 允许特权模式(Docker-in-Docker 构建需要)
  • service_account = "gitlab-runner" 绑定前面创建的 ServiceAccount
  • concurrent = 5 限制并发数,避免资源争抢
  • PVC 缓存配置加速重复构建(依赖包、Docker 层缓存)

3.3 执行 Helm 安装

💻 代码示例

# 安装 GitLab Runner

helm install gitlab-runner gitlab-runner/gitlab-runner

-n gitlab-runner

-f gitlab-runner-values.yaml

–version 0.69.0

 

# 监控部署状态

kubectl -n gitlab-runner get pods -w

 

# 等待 Runner Pod 就绪

kubectl -n gitlab-runner wait –for=condition=Ready pod

-l app=gitlab-runner

–timeout=120s

 

# 确认 Runner 状态

kubectl -n gitlab-runner get pods

# 预期输出:

# NAME READY STATUS RESTARTS

# gitlab-runner-xxxxx 1/1 Running 0

四、Harbor 镜像仓库认证对接

4.1 创建 Harbor 认证 Secret

CI 构建过程中需要向 Harbor 推送镜像,需要预先创建 Docker Registry Secret:

💻 代码示例

# 创建 Harbor 认证 Secret

kubectl create secret docker-registry harbor-auth

–docker-server=harbor.stellardata.top

–docker-username=admin

–docker-password='Harbor12345'

–docker-email=devops@stellardata.top

-n gitlab-runner

 

# 验证 Secret 创建成功

kubectl -n gitlab-runner get secret harbor-auth

# 预期输出:

# NAME TYPE DATA

# harbor-auth kubernetes.io/dockerconfigjson 1

4.2 在 .gitlab-ci.yml 中引用

在 CI 变量中配置 Harbor 凭据,避免硬编码到 .gitlab-ci.yml

💻 代码示例

# 在 GitLab 项目中配置 CI/CD Variables:

# Settings → CI/CD → Variables → Add Variable

# Key: HARBOR_URL

# Value: harbor.stellardata.top

# Key: HARBOR_USER

# Value: admin

# Key: HARBOR_PASS

# Value: Harbor12345

# 勾选 Masked(隐藏变量值,不在日志中显示)

五、验证 Runner 可用性

5.1 确认 Runner 已注册

💻 代码示例

# 查看 Runner 日志确认注册成功

kubectl -n gitlab-runner logs -l app=gitlab-runner | tail -10

# 预期输出:

# Configuration loaded and runner started

# Registering runner… succeeded

# Runner registered successfully

 

# 通过 GitLab API 查看 Runner 列表

curl -k –header "PRIVATE-TOKEN: <your-token>"

"https://gitlab.stellardata.top/api/v4/runners/all" | python3 -m json.tool | head -20

# 预期输出包含:

# "description": "k8s-executor-runner"

# "status": "online"

# "runner_type": "project_type"

5.2 运行测试 Pipeline

在 GitLab 仓库中创建 .gitlab-ci.yml 触发一个简单的测试 Job:

💻 代码示例

# .gitlab-ci.yml — Runner 可用性测试

stages:

– test

 

verify-runner:

stage: test

tags:

– k8s

image: alpine:3.19

script:

– echo "GitLab Runner K8s Executor 验证"

– kubectl version –client

– echo "Runner 节点信息:"

– hostname

– echo "CI 环境变量:"

– env | grep CI_

– echo "✅ Runner 工作正常"

💻 代码示例

# 提交 .gitlab-ci.yml 触发 Pipeline

cd demo-app

git add .gitlab-ci.yml

git commit -m "ci: 添加 Runner 可用性测试"

git push origin main

 

# 实时查看 CI Job Pod 状态

kubectl -n gitlab-runner get pods -w

# 预期输出:

# NAME READY STATUS

# runner-xxxxx-project-N-job-N 1/1 Running # CI Job Pod

# → 执行完毕后自动 Terminating → 消失

 

# 在 GitLab Web 界面查看 Pipeline 执行结果:

# https://gitlab.stellardata.top/devops-chain/demo-app/-/pipelines

5.3 日常巡检命令

💻 代码示例

# 查看 Runner Pod 运行状态

kubectl -n gitlab-runner get pods -l app=gitlab-runner

 

# 查看 Runner 最近日志(排查轮询和注册问题)

kubectl -n gitlab-runner logs -l app=gitlab-runner –tail=50

 

# 查看当前活跃的 CI Job Pod

kubectl -n gitlab-runner get pods | grep runner-

 

# 查看 Runner 配置(确认 Executor 类型和参数)

kubectl -n gitlab-runner get configmap gitlab-runner -o yaml

 

# 检查 RBAC 权限是否正常

kubectl auth can-i create pods –as=system:serviceaccount:gitlab-runner:gitlab-runner -n gitlab-runner

# 预期输出:yes

 

# 查看 Runner 资源使用情况

kubectl -n gitlab-runner top pod -l app=gitlab-runner

六、常见问题

Q: CI Job Pod 一直处于 Pending 状态,怎么排查?

A: 首先查看 Pod 事件:kubectl -n gitlab-runner describe pod <pod-name> | tail -20。常见原因:① 节点资源不足无法调度 → 调整 Pod resource requests 或增加节点;② StorageClass 不支持动态供应导致 PVC Pending → 检查 kubectl get pvc -n gitlab-runner;③ Taint 导致节点不可调度 → 检查 kubectl describe node | grep Taints

Q: Runner 注册失败,日志报 401 Unauthorized?

A: 检查 runnerRegistrationToken 是否正确。Token 从 GitLab 管理界面获取:Admin Area → CI/CD → Runners → Register Runner。注意 Token 有时效性,过期后需重新生成。另外确认 gitlabUrl 配置正确,且 Runner Pod 能访问到 GitLab Service(网络策略没有阻断)。

Q: CI Job 中 docker push 到 Harbor 报 401?

A: 两种方式解决:① 在 GitLab CI/CD Variables 中配置 HARBOR_USER 和 HARBOR_PASS(推荐,已在上文配置);② 创建 Docker Registry Secret 并在 Pod spec 中引用 imagePullSecrets。检查变量是否勾选了 Masked(Masked 变量的值不会在 CI 日志中显示)和 Protected(仅在 protected 分支生效)。

总结

今天完成了 GitLab Runner 的完整部署和验证,核心成果:

  1. 选择了 K8s Executor 作为 CI 执行引擎,实现每 Job 独立 Pod 隔离
  2. 配置了最小权限 RBAC(ServiceAccount + Role + RoleBinding),仅授予 CI 命名空间内的 Pod/PVC/Secret 操作权限
  3. 通过 Helm Chart 部署 Runner,配置了资源限制、缓存 PVC 和并发控制
  4. 创建了 Harbor 认证 Secret,为 CI 中推送镜像做好了凭据准备
  5. 通过测试 Pipeline 验证了 Runner 的端到端可用性

DevOps 全链路已具备:代码托管(GitLab)→ 执行引擎(Runner)→ 镜像仓库(Harbor),三者准备就绪。明天我们将编写 .gitlab-ci.yml 流水线,用 Kaniko 无守护进程方式构建镜像并推送到 Harbor,打通从代码提交到镜像产出的完整 CI 链路。

下期预告

第 6 天:GitLab CI 流水线搭建:.gitlab-ci.yml 与 Kaniko 无守护进程构建

将深入 .gitlab-ci.yml 的完整语法,用 Kaniko 替代 Docker-in-Docker 实现无特权容器镜像构建,并配置多阶段流水线(lint → build → push → scan)。

系列大纲

  1. 全链路架构总览:从代码提交到灰度发布的完整管道设计
  2. K8s 集群与网络基础:kubeadm 离线部署与 Cilium 网络插件
  3. Harbor 私有镜像仓库部署与验证:Helm 安装与镜像推送
  4. GitLab CE 自托管部署:代码仓库与项目管理平台
  5. GitLab Runner 配置:K8s Executor 与 RBAC 权限设置(今天)
  6. GitLab CI 流水线搭建:.gitlab-ci.yml 与 Kaniko 无守护进程构建
  7. Harbor 镜像版本管理与 Tag 策略配置
  8. Argo CD 部署与 GitOps 配置仓库创建
  9. CI 与 CD 联动:从代码提交到部署的全自动闭环
  10. Prometheus 部署:kube-prometheus-stack 与 ServiceMonitor 指标采集
  11. Grafana 看板搭建:K8s 标准面板与自定义业务看板
  12. 告警规则与 Alertmanager:钉钉/邮件通知渠道配置
  13. Argo Rollouts 安装与基础概念:CRD 与 Rollout 资源定义
  14. 金丝雀发布实战:setWeight 流量分割与 pause 步骤
  15. AnalysisTemplate 指标分析与自动回滚机制
  16. 全链路端到端演示:代码提交→构建→灰度→监控→告警完整流程
  17. 生产化加固要点:Harbor/GitLab/Argo CD 高可用方案
  18. 供应链安全闭环:Trivy 扫描 + cosign 签名 + Kyverno 验签
微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像 - 恒星
欢迎您留下宝贵的见解!
提交
头像 - 恒星

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容