跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

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

Gitlab Runner注册失败主因是ServiceAccount权限不足或网络不通;CI中kubectl失败因缺少二进制或kubeconfig;DinD误用致Job Pending;发布后CrashLoopBackOff因CI不校验Pod就绪状态。 Gitlab Runner注册到Kubernetes集群失败的常见原因 注册不成功,大概率不是Runner没装好,而是ServiceAccount权限或网络连通性问题。Gitlab Runner作为Pod运行时,必须能通过
https://kubernetes.default.svc
访问API Server,且绑定的
serviceaccount
需有
pod
、
configmap
、
secret
等资源的操作权限。 实操建议: 确认Runner Pod内能
curl -k https://kubernetes.default.svc
返回403(有连通性)而非timeout或connection refused; 检查
gitlab-runner
使用的
serviceaccount
是否绑定了
clusterrole
(如
edit
或自定义最小权限角色),仅
view
角色无法创建Pod; 注册命令中
--kubernetes-namespace
必须指定为Runner实际运行的命名空间,且该命名空间下需存在对应
serviceaccount
; 避免使用
--kubernetes-image
指向私有仓库镜像却未配置
imagePullSecrets
,会导致Pod卡在
ImagePullBackOff
。 CI流水线中
before_script
里kubectl命令执行失败 Runner默认以
gitlab-runner
用户运行容器,该用户通常没有
kubectl
二进制,也无权读取
/root/.kube/config
。即便挂载了config文件,权限和上下文切换也常被忽略。 实操建议: 不要依赖宿主机或Runner节点的
kubectl
,应在
.gitlab-ci.yml
中显式安装:
before_script: - apk add --no-cache kubectl
(Alpine基础镜像)或
- apt-get update && apt-get install -y kubectl
(Debian系); 用
kubectl --context=xxx
或
--kubeconfig
明确指定配置路径,避免依赖
$HOME
; 若使用ServiceAccount方式认证(推荐),需在Job Pod中挂载Token和CA证书:
kubernetes: { namespace: myns, image: alpine:latest, service_account: gitlab-runner-sa }
,此时
kubectl
会自动读取
/var/run/secrets/kubernetes.io/serviceaccount/
下的凭证; 注意
default
命名空间下没有
gitlab-runner-sa
时,
kubectl get pods
会报
Forbidden
,务必提前部署RBAC。
image
字段写
docker:stable-git
但Job一直Pending 这是典型的Docker-in-Docker(DinD)误用场景。Gitlab Runner的Kubernetes Executor本身不提供Docker守护进程,
docker:stable-git
镜像只有CLI,没有
dockerd
,也无法直接调用宿主机Docker Socket(安全限制+权限问题)。 Trae linux Trae Linux 官方版本现已全面上线,开发者可直接访问 Trae 官网(trae.cn 国内版或 trae.ai 国际版)获取专属安装包。该版本完美适配主流 Linux 发行版,提供 .deb(适配 Ubuntu/Debian)、.rpm(适配 RHEL/Fedora)以及通用 .tar.gz 格式,并全面支持 x64 与 ARM64 架构。 下载 实操建议: 构建镜像请改用
kaniko
:在
.gitlab-ci.yml
中设
image: gcr.io/kaniko-project/executor:v1.22.0
,并用
--context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $IMAGE_URL
参数; 若坚持用Docker CLI(如做本地测试),确保Runner配置启用了
privileged: true
,且Pod模板中挂载了
/var/run/docker.sock:/var/run/docker.sock
——但这在多数生产k8s集群中被禁用; 注意
docker:stable-git
镜像不含
git
命令,若
script
里有
git clone
,需额外
apk add git
; 镜像拉取超时常见于国内环境,可在Runner ConfigMap中添加
DOCKER_REGISTRY: https://registry.cn-hangzhou.aliyuncs.com
并配置
image_pull_secrets
。 发布后Pod始终
CrashLoopBackOff
,但CI显示Success CI阶段只负责触发部署(如
kubectl apply -f deploy.yaml
),并不等待Pod就绪或验证健康状态。部署完成即算Job成功,后续容器启动失败完全不会反馈回GitLab界面。 实操建议: 在
script
末尾加主动探测:
kubectl wait --for=condition=ready pod -l app=myapp --timeout=120s -n myns
,失败则整个Job报错; 确保Deployment中设置了
livenessProbe
和
readinessProbe
,否则Kubernetes无法判断服务是否真正可用; 检查
imagePullPolicy
:CI中构建的镜像tag若为
latest
,而集群已有同名镜像,可能跳过拉取,导致运行旧版本;建议用
$CI_COMMIT_TAG
或
$CI_PIPELINE_ID
作唯一tag; 日志排查优先看
kubectl describe pod -n myns
里的Events字段,比
logs
更能暴露镜像拉取失败、OOMKilled、ConfigMap缺失等根本原因。 真正卡住的地方往往不在CI配置,而在k8s侧的RBAC粒度、镜像仓库鉴权方式、以及Probe配置是否与应用启动时长匹配——这些细节不验证到真实Pod生命周期里,光看CI流水线绿色毫无意义。

相关文章