Kubernetes 上稳定运行 Jenkins 的五大核心实践

1. 为什么 Kubernetes 上跑 Jenkins 不是“装个插件就完事”——从一次部署失败说起

我第一次在 Kubernetes 集群里部署 Jenkins,是在一个刚用 KubeKey 搭好的 Ubuntu 22.04 环境上。当时照着网上“Jenkins 安装配置”“Kubernetes 菜鸟教程”这类标题点进去,三步走:helm install jenkins、kubectl port-forward、浏览器打开。结果页面加载到一半卡住,控制台报错 Failed to resolve host name mirrors.tuna.tsinghua.edu.cn ,紧接着 Pipeline v608 plugin failed to load ,整个 UI 进不去。折腾六小时,重装三次,最后发现根本不是网络或插件问题——而是 Jenkins 的 Pod 启动时,容器内 /var/jenkins_home 目录权限被 Kubernetes 的 SecurityContext 默认设为 root-only,而 Jenkins 官方镜像(尤其是高版本)默认以非 root 用户 jenkins (UID 1001)运行,一启动就因无法写入 home 目录直接 crash。

这件事让我彻底意识到: 在 Kubernetes 上跑 Jenkins,本质不是“把 Jenkins 搬上云”,而是重构它的生命周期管理逻辑 。你面对的不再是单机上的 Java 进程,而是一个受 Deployment 控制、由 StatefulSet 管理存储、通过 Service 暴露、依赖 ConfigMap 注入配置、靠 Secret 管理凭证的完整应用拓扑。CI/CD Pipeline 在这里不再是一串 Groovy 脚本,它成了 Kubernetes 原生资源的一部分——Job 对象触发构建,Pod 模板定义执行环境,PersistentVolumeClaim 保障构建缓存不丢失,NetworkPolicy 控制它能访问哪些 Git 或 Harbor 服务。

所以这篇内容,不讲“Jenkins 怎么配置前端项目配置”这种零散操作,也不复述“Jenkins 安装部署”的通用流程。我们聚焦一个真实起点: Create Your First CI/CD Pipeline on Kubernetes With Jenkins 。这意味着你要亲手完成:一个可稳定运行的 Jenkins 主节点(Master)、一套能动态拉起构建 Agent 的 Kubernetes Pod 模板、一个从 GitLab 拉代码 → 编译 Vue 项目 → 构建 Docker 镜像 → 推送至 Harbor → 部署到同一集群的完整流水线。所有步骤都基于生产级实践验证,参数有依据、配置有解释、坑有定位路径。如果你正卡在 jenkins.initreactorrunner$1.ontaskfailed failed loading plugin pipeline 这类错误上,或者刚学完“kubernetes详解”却不知如何让 CI/CD 真正落地,那接下来的内容,就是你缺的那一块拼图。

2. Master 节点不是“装好就行”,而是 Kubernetes 原生应用的起点

2.1 为什么不能直接用 helm chart 默认值?三个致命陷阱

Helm 社区最常用的 jenkinsci/kubernetes-operator stable/jenkins (已归档)chart,表面看一键部署,实则埋了三条暗线:

  • 陷阱一:StorageClass 绑定失效
    默认 chart 使用 persistence.enabled=true + persistence.storageClass="" ,这会导致 PVC 处于 Pending 状态。原因很简单:Kubernetes 1.20+ 已弃用 default StorageClass 的隐式绑定逻辑,且多数生产集群(尤其用 KubeKey 或 RKE2 搭建的)不会自动创建名为 default 的 StorageClass。我见过太多人 kubectl get pvc 一直显示 Pending ,却去查 Jenkins 日志,完全跑偏。正确做法是显式指定集群中真实存在的 StorageClass 名称,比如 local-path (Rancher 环境)或 openebs-hostpath (OpenEBS 环境)。命令行部署时必须加:

    helm install jenkins jenkinsci/jenkins \
      --set persistence.storageClass="local-path" \
      --set persistence.size="10Gi"
    
  • 陷阱二:SecurityContext 权限冲突(就是开头那个坑)
    Jenkins 官方镜像( jenkins/jenkins:lts-jdk11 及更新版)固定以 UID 1001 运行,但 Kubernetes 默认 Pod 的 securityContext.runAsUser 是 0(root),且 fsGroup 未设置。结果容器启动时, /var/jenkins_home 目录属主是 root,而 Jenkins 进程想以 UID 1001 写入,直接 Permission Denied。解决方案不是降权运行 Jenkins(安全风险),而是让 Kubernetes 自动修正目录权限:

    securityContext:
      runAsUser: 1001
      runAsGroup: 1001
      fsGroup: 1001  # 关键!让 kubelet 自动 chown /var/jenkins_home 所有文件
    

    这个 fsGroup 字段是 Kubernetes 原生能力,不是 Jenkins 插件,必须写进 Deployment 的 Pod 模板里。

  • 陷阱三:Service 类型选错导致外部不可达
    很多人用 service.type=LoadBalancer ,但在私有云或本地 K8s(如 MicroK8s、K3s)中,没有云厂商的 LB 组件,Service 会永远卡在 <pending> 。更稳妥的方案是 service.type=NodePort ,并指定一个固定端口(如 30080),再通过 kubectl get nodes -o wide 查到任一节点 IP,用 http://<NODE_IP>:30080 访问。如果集群有 Ingress 控制器(如 Nginx Ingress),则应禁用 NodePort,改用 Ingress 资源,这样能支持 HTTPS 和域名路由。

提示: jenkins.failed to resolve host name mirrors.tuna.tsinghua.edu.cn 这类 DNS 错误,90% 源于 Jenkins Pod 的 dnsPolicy 被设为 Default ,导致它继承了宿主机的 DNS 配置(可能指向内网 DNS 服务器,而该服务器无法解析公网镜像源)。正确做法是显式设置 dnsPolicy: ClusterFirstWithHostNet 或直接在 Pod 中注入 DNS:

dnsConfig:
  nameservers:
    - 114.114.114.114
    - 8.8.8.8

2.2 初始化配置必须绕过 Web UI,用 JCasC(Jenkins Configuration as Code)

很多人部署完 Jenkins,第一反应是打开浏览器,点“系统配置”填 Git 凭证、配 Maven、装插件……这是最危险的操作。因为一旦 Jenkins Pod 重启(比如节点故障、升级),所有 Web 界面配置全丢。真正的 Kubernetes 做法是: 所有配置即代码,全部通过 ConfigMap 注入

JCasC(Jenkins Configuration as Code)插件是官方推荐方案。但它不能等 Jenkins 启动后再装——得在 Jenkins 镜像启动前就准备好配置。标准做法是:

  1. 创建 jenkins-config.yaml ,定义全局工具、凭据、插件列表;
  2. 将其打包进自定义 Jenkins 镜像,或通过 volumeMount 挂载到 /var/jenkins_home/casc_configs/
  3. 在 Jenkins 启动参数中指定 -Dcasc.jenkins.config=/var/jenkins_home/casc_configs/jenkins-config.yaml

一个最小可用的 jenkins-config.yaml 示例(含 GitLab 凭据和 Maven 配置):

jenkins:
  systemMessage: "Jenkins on Kubernetes - Managed by JCasC"
  numExecutors: 0  # 关键!禁用内置 executor,所有构建交给 Kubernetes Agent
  securityRealm:
    local:
      allowsSignup: false
      enableCaptcha: false
  authorizationStrategy:
    loggedI
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值