当前位置:

首页 > 系统应用 > Linux环境下部署Gitlab Runner配合k8s实现自动发布(CI/CD)

Linux环境下部署Gitlab Runner配合k8s实现自动发布(CI/CD)

Gitlab Runner注册失败主因是ServiceAccount权限不足或网络不通;CI中kubectl失败因缺少二进制或kubeconfig;DinD误用致Job Pending;发布后CrashLoopBackOff因CI不校验Pod就绪状态。 在Kubernetes上搭建GitLab CI

Gitlab Runner注册失败主因是ServiceAccount权限不足或网络不通;CI中kubectl失败因缺少二进制或kubeconfig;DinD误用致Job Pending;发布后CrashLoopBackOff因CI不校验Pod就绪状态。

linux环境下部署gitlab runner配合k8s实现自动发布(ci/cd)

在Kubernetes上搭建GitLab CI/CD流水线,听起来很美好,但实际落地时,几个“坑”总是反复出现。Runner注册不上、流水线里的命令执行失败、Job一直卡着、或者明明CI显示成功了,应用却起不来。这些问题看似分散,其实背后都指向几个关键配置环节。下面就来逐一拆解这些高频故障点。

Gitlab Runner注册到Kubernetes集群失败的常见原因

当你执行gitlab-runner register命令后,如果注册失败,先别急着怀疑Runner安装有问题。十有八九,问题出在ServiceAccount的权限或者网络连通性上。

道理很简单:GitLab Runner在K8s里是以Pod形式运行的。这个Pod需要能跟API Server“对话”,地址就是https://kubernetes.default.svc。同时,它绑定的serviceaccount必须拥有足够的权限,去创建和管理后续CI Job所需的Pod、ConfigMap、Secret等资源。

所以,排查可以遵循以下路径:

首先,验证基础连通性。可以进入Runner Pod(如果它能起来的话),执行curl -k https://kubernetes.default.svc。如果返回403(Forbidden),那说明网络是通的,只是权限不够;如果出现timeout或connection refused,那就是网络层面的问题,需要检查集群内DNS和服务发现。

其次,聚焦权限。检查gitlab-runner这个ServiceAccount绑定的ClusterRole。很多人图省事直接绑view角色,这只能看,不能创建Pod,肯定不行。生产环境建议使用edit角色,或者根据最小权限原则自定义一个角色。

再者,注意命名空间的一致性。注册命令里--kubernetes-namespace参数指定的命名空间,必须和Runner实际部署的命名空间一致,并且确保该命名空间下已经创建了对应的ServiceAccount。张冠李戴是注册失败的常见原因。

最后,留意镜像拉取。如果注册时使用了--kubernetes-image指向私有仓库的镜像,却忘了在Pod Spec中配置对应的imagePullSecrets,那么Runner Pod自身就会卡在ImagePullBackOff状态,自然无法完成注册。

CI流水线中before_script里kubectl命令执行失败

流水线配置好了,第一个Job也触发了,结果在before_script阶段执行kubectl get pods就报错。这通常是因为环境不对。

默认情况下,GitLab Runner容器里跑的用户是gitlab-runner,这个用户环境里很可能根本没有安装kubectl这个命令行工具。即便你从宿主机把/root/.kube/config配置文件挂载进去了,也常常会因为文件权限(非root用户无法读取)或者上下文(Context)不对而失败。

解决思路很直接:

第一,显式安装kubectl。不要依赖任何预设环境。在.gitlab-ci.yml文件的before_script里,根据基础镜像类型安装。比如Alpine镜像用apk add --no-cache kubectl,Debian/Ubuntu系镜像用apt-get update && apt-get install -y kubectl。

第二,明确指定kubeconfig。使用kubectl --kubeconfig /path/to/config或者--context=your-context-name来明确告诉kubectl使用哪个配置,避免它去默认路径($HOME/.kube)寻找。

第三,更推荐的方式:使用ServiceAccount认证。这是K8s集群内Pod访问API的标准方式。你需要在定义Job时,通过Runner的Kubernetes Executor配置指定service_account。例如:

job_name:
  kubernetes:
    namespace: my-namespace
    image: alpine:latest
    service_account: gitlab-runner-sa

这样,Pod启动后会自动挂载Token和CA证书到/var/run/secrets/kubernetes.io/serviceaccount/目录下,kubectl会自动使用这些凭证,无需手动管理config文件。当然,前提是你得提前创建好这个gitlab-runner-sa并绑定好RBAC权限。如果这个ServiceAccount在default命名空间不存在,那么kubectl get pods自然会返回Forbidden错误。

image字段写docker:stable-git但Job一直Pending

这个场景非常典型,属于Docker-in-Docker(DinD)的经典误用。很多人在CI Job里想构建Docker镜像,就顺手把image指定为docker:stable-git,结果Job一直处于Pending状态。

原因在于:GitLab Runner的Kubernetes Executor只是提供了一个Pod运行环境,它本身并不提供Docker守护进程(dockerd)。docker:stable-git这个镜像只包含了Docker客户端(CLI),没有服务端。它试图在容器内启动一个Docker守护进程,这在没有特权模式且未挂载Docker Socket的普通Pod里是不可能成功的。

那么,正确的做法是什么?

首选方案是使用Kaniko。这是一个专门用于在Kubernetes或容器化环境中构建镜像的工具,它不需要Docker守护进程,也不需要特权模式。在.gitlab-ci.yml中可以这样配置:

build:
  image: gcr.io/kaniko-project/executor:v1.22.0
  script:
    - /kaniko/executor
      --context $CI_PROJECT_DIR
      --dockerfile $CI_PROJECT_DIR/Dockerfile
      --destination $YOUR_REGISTRY/your-image:tag

如果因特殊原因必须使用Docker CLI(例如某些本地测试场景),则必须确保Runner的配置允许特权模式,并在Pod模板中挂载宿主机的Docker Socket:

[[runners.kubernetes.pod_security_context]]
  privileged = true
[[runners.kubernetes.volumes]]
  name = "docker-sock"
  mount_path = "/var/run/docker.sock"
  host_path = "/var/run/docker.sock"

需要注意的是,出于安全考虑,绝大多数生产环境的K8s集群会禁止这种特权挂载。

另外两个小贴士:一是docker:stable-git镜像本身不包含git命令,如果你的script里有git clone操作,需要先apk add git。二是国内环境可能遇到镜像拉取超时,可以在Runner的ConfigMap中配置镜像仓库地址,并确保配置了正确的image_pull_secrets。

发布后Pod始终CrashLoopBackOff,但CI显示Success

这是最让人困惑的情况之一:GitLab CI流水线一片绿色,显示部署成功,但跑到K8s集群里一看,新发布的Pod却在不断重启(CrashLoopBackOff)。

问题根源在于:CI/CD流水线里的部署任务(比如kubectl apply -f deploy.yaml)只负责把资源声明提交给K8s API Server。一旦提交成功,这个CI Job就认为任务完成,标记为Success。它不会去等待Pod真正启动完成,更不会去检查Pod内部容器的健康状态。后续的镜像拉取失败、应用启动报错、配置错误等,都和CI流水线“无关”了。

要解决这个问题,必须把健康检查的环节纳入CI流程:

第一,在CI脚本末尾增加主动等待和探测。在kubectl apply之后,加上一条等待命令:

kubectl wait --for=condition=ready pod -l app=myapp --timeout=120s -n my-namespace

这条命令会阻塞,直到指定标签的Pod状态变为Ready,或者超时。如果超时或失败,整个CI Job就会失败,从而在流水线上给出明确的红色错误信号。

第二,确保Deployment配置了完善的探针。在应用的deploy.yaml里,必须设置livenessProbe(存活探针)和readinessProbe(就绪探针)。没有这些探针,Kubernetes就无法判断你的应用何时才算真正启动成功、何时健康。

第三,注意镜像标签策略。如果CI构建的镜像标签是latest,而集群节点上已经存在同名的latest镜像,K8s可能会因为imagePullPolicy设置为IfNotPresent而跳过拉取,导致运行的还是旧版本代码。建议使用$CI_COMMIT_TAG或$CI_PIPELINE_ID这类唯一标识作为镜像标签。

当出现CrashLoopBackOff时,最快的排查方法是:

kubectl describe pod -n my-namespace 

重点看输出末尾的Events字段。这里通常会直接告诉你根本原因,比如“镜像拉取失败”、“OOMKilled(内存不足)”、“找不到ConfigMap”等,这比直接看容器日志(kubectl logs)更高效。

说到底,CI流水线的绿色只是一个开始。真正的考验在于K8s集群内部的细节:RBAC权限是否精细、镜像仓库的认证方式是否正确、探针的配置是否与应用的实际启动时间匹配……如果不把这些环节放到真实的Pod生命周期里去验证,那么CI流水线的一片绿色,反而可能掩盖了部署的失败。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
系统应用 git gitlab
相关文章 更多
git创建分支bip的命令及完整操作步骤
git创建分支bip的命令及完整操作步骤

想知道如何用Git创建名为bip的分支?本文提供清晰的命令行操作步骤,包括本地创建、切换分支以及推送到远程仓库的方法,适合初学者快速上手。

GitLab配置SSH免密登录步骤详解
GitLab配置SSH免密登录步骤详解

通过本教程学习如何在Windows、Mac或Linux系统中生成SSH密钥,并将公钥安全添加到GitLab平台,实现Git操作的免密认证,简化日常代码管理流程。

GitLab新手创建项目并推送第一次提交的操作指南
GitLab新手创建项目并推送第一次提交的操作指南

本文指导GitLab新手完成创建项目并推送第一次提交的最小闭环。涵盖远程项目创建、本地仓库初始化、添加远程地址及执行git push。重点说明HTTPS与SSH认证差异、分支名(master/main)核对及提交验证标准,确保远程仓库真正建立。

在小说搜搜找不到想看的小说怎么办?小说搜搜换源功能使用详解【必学】
在小说搜搜找不到想看的小说怎么办?小说搜搜换源功能使用详解【必学】

小说搜搜搜索不到结果?五种实用解决方法帮你搞定 在小说搜搜里搜不到想看的书?这事儿其实挺常见。问题多半出在书源上——要么是默认的书源还没来得及收录,要么是原先的源数据失效了,更新没跟上。别急,下面这五条解决路径,基本能覆盖绝大多数情况,操作起来也不复杂。 一、通过阅读页调出换源入口手动切换 这个方法

怎么看B站UP主直播的真实人数?在线观看人数换算教程
怎么看B站UP主直播的真实人数?在线观看人数换算教程

“实时人气”不等于真实在线人数,需通过区分标识、验证列表与弹幕、第三方工具比对及互动加权扣除四步估算 当你点开B站的某个直播间,屏幕上那个“实时人气:12.8万”的数字可能让你心头一震,觉得场面火热。然而细看之下,弹幕寥寥无几,互动屈指可数——这场景是不是有点眼熟?问题来了:那个醒目的“人气值”,真

chrome搜索免验证入口
chrome搜索免验证入口

Chrome官方免验证入口为https://www.google.cn/chrome/,提供全平台安装包、免登录即用、本地化安全机制及引擎级性能优化。 到底该去哪里找正版、免费且无需繁琐验证的Chrome浏览器入口?这个问题困扰了不少网友。今天,我们就来直通核心,为大家详细拆解Chrome引擎的官方

Mac导入Android项目指南
Mac导入Android项目指南

网上关于在mac上导入现有项目的android studio操作教程多种多样,以下是我在实际操作中成功导入项目所采用的具体步骤及关键注意事项,供各位开发者参考。 网上的教程确实五花八门,但核心流程其实万变不离其宗。根据多年经验,想要在Mac上把已有的Android项目顺利导入Android Stud

过程式编程、面向对象编程、函数式编程、泛型编程、元编程
过程式编程、面向对象编程、函数式编程、泛型编程、元编程

命令式编程关注执行步骤,声明式描述目标,函数式强调无副作用。回调函数作为参数传递,可导致回调地狱,后由Promise解决。仿函数重载`operator()`,lambda更轻量。元编程生成代码,如模板、装饰器、宏,提升抽象能力。

如何配置Python项目的.gitignore文件_排除环境相关冗余文件
如何配置Python项目的.gitignore文件_排除环境相关冗余文件

Python项目配置.gitignore应排除__pycache__、虚拟环境(venv/.venv等)、IDE生成文件(.idea/.vscode等)及缓存目录。误提交后需用`gitrm--cached`移除索引。建议复用GitHub官方模板并验证规则有效性。

怎么在VSCode中查看Git冲突记录-图形化合并分支操作实操
怎么在VSCode中查看Git冲突记录-图形化合并分支操作实操

VSCode不保存历史冲突记录,仅在合并时实时标记冲突文件。冲突文件位于源代码管理面板的MERGECHANGES分组,带红色感叹号和冲突数量。点击文件以三栏合并编辑器显示当前分支、传入分支和结果区,供用户编辑解决冲突。

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程
PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

Mac软件 更多
Postman macOS版
Postman macOS版
Mac

Postman是一套面向API全生命周期的开发与测试平台,可在Mac上发送和调试多种协议请求,管理集合、环境及认证信息,并完成脚本测试、模拟服务、监控、文档发布和团队协作。它适合开发、测试及运维人员使用,提供个人免费方案。

Docker Desktop macOS版
Docker Desktop macOS版
Mac

Docker Desktop 是 Docker 官方为 Mac 提供的容器开发环境,集成 Docker Engine、命令行工具、Compose、Build、Kubernetes 与图形化管理界面。

Android Studio macOS版
Android Studio macOS版
Mac

Android Studio 是 Google 面向安卓应用开发提供的官方集成开发环境,基于 IntelliJ IDEA 构建。它整合智能代码编辑、Gradle 构建、界面预览、设备模拟、性能分析、调试测试及 APK 分析等工具。

WINDOWS 更多
PixPix 网页版
PixPix 网页版
Windows

PixPix 是面向品牌、卖家和内容团队的在线 AI 图片视频创作平台,提供图视频 Agent、无限画布、图片生成、视频生成、自然语言编辑及商品套图、产品精修和带货视频等电商工具。

Postman Windows版
Postman Windows版
Windows

Postman 是面向 API 全生命周期的开发与协作平台。Windows 桌面版可用于构建和发送 HTTP、GraphQL、gRPC、WebSocket、MQTT 等请求,并提供环境变量、集合、脚本测试、模拟服务、监控、文档及团队工作区等

Docker Desktop Windows版
Docker Desktop Windows版
Windows

Docker Desktop 为 Windows 开发者提供集成式容器环境,内置 Docker Engine、命令行工具、Compose、Build 与 Kubernetes 等组件,可在本机完成镜像构建、容器运行、日志查看和资源管理。