核心是Kubernetes插件配置、ServiceAccount权限与PodTemplate中jnlp容器连通性三者必须精准匹配;任一出错即导致Pipeline卡在Waiting for agent或Failed to connect。

直接在 Kubernetes 上部署 Jenkins 并跑通流水线,核心不是“能不能”,而是“kubernetes 插件配不配得对、ServiceAccount 权限够不够、PodTemplate 里 jnlp 容器能不能连上 Jenkins Master”。配错任意一环,Pipeline 就卡在 Waiting for agent 或直接报 Failed to connect to Jenkins。
为什么 ServiceAccount 权限必须手动绑定 clusterrole
Kubernetes 默认不会给任意 ServiceAccount 访问 API Server 的权限。Jenkins Agent(即动态创建的 Pod)要调用 kubectl、拉镜像、创建 Job 等,必须有对应 RBAC 权限。仅靠 default SA 是无效的。
- 必须显式创建专用
ServiceAccount(比如叫jenkins-agent-sa) - 必须绑定
edit或自定义ClusterRole(不能只给view) - 若 Jenkins 运行在命名空间
devops,而你要部署应用到prod,则需跨命名空间授权,ClusterRoleBinding是唯一可靠方式 - 验证方法:
kubectl auth can-i --list --as=system:serviceaccount:devops:jenkins-agent-sa
kubernetes 插件中 cloud 配置的关键字段
Jenkins 后台「系统配置 → Clouds → Kubernetes」里的填空项,不是贴个 URL 就完事。最容易出错的是这三处:
-
Kubernetes URL:必须是集群内可解析的地址,如https://kubernetes.default.svc;填宿主机 IP 或外网域名大概率失败(DNS 不通 + TLS 验证失败) -
Credentials:必须用Secret text类型凭证,内容是ServiceAccount对应的 token(路径:/var/run/secrets/kubernetes.io/serviceaccount/token),不是 kubeconfig 文件 -
Namespace:填default以外的命名空间时,必须确保该命名空间已存在,且ServiceAccount在该命名空间下有对应权限(否则 Pod 创建失败,日志报Forbidden: unable to create pods in namespace xxx)
agent { kubernetes { yaml """...""" } } 中的硬约束
声明式 Pipeline 里写的 Pod 模板,有几个常被忽略但会直接导致 Agent 启动失败的点:
-
jnlp容器名必须为jnlp(大小写敏感),且image必须是 Jenkins 官方或兼容的 inbound-agent 镜像(如jenkins/inbound-agent:4.11-1),自定义镜像若没集成 JNLP 启动逻辑会静默退出 - 所有容器必须共用同一个
terminationGracePeriodSeconds,否则 Jenkins 可能无法正确回收 Pod -
defaultContainer值必须匹配yaml中某个container.name,否则sh步骤默认执行在jnlp容器里(它通常没装curl、git、python) - 若使用私有镜像仓库(如 Harbor),
imagePullSecrets必须在Pod级别声明,不能只在 container 里加imagePullPolicy
kubectl apply 在 Pipeline 里失败的典型原因
很多教程直接写 sh 'kubectl apply -f deployment.yaml',但实际几乎必挂,因为:
- Agent Pod 默认没有
kubectl二进制 —— 要么在容器镜像里预装,要么用sh 'curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && chmod +x kubectl'动态下载(注意架构和权限) - Pod 使用的
ServiceAccount没有deployments的create/update权限(RBAC 错误) -
deployment.yaml里写的namespace字段与当前上下文不一致,或未指定导致落到default,而你本意是部署到staging - 更稳妥做法:用
kubernetesDeploystep(来自Kubernetes Continuous Deploy Plugin),它自动注入 kubeconfig、支持 namespace 参数、失败时输出清晰错误
最常被跳过的细节是:Jenkins Master 和 Agent Pod 之间的网络连通性测试 —— 即便 RBAC 全开、证书无误,若 jnlp 容器 ping 不通 Jenkins Master 的 agent.jnlp 端口(默认 50000),整个流程就停在连接阶段,连日志都看不到有效报错。


















