Skip to main content

Command Palette

Search for a command to run...

Jenkins:乘着 Kubernetes 的翅膀

Updated
2 min read

前言

Kubernetes + Docker 是一对有意思的组合,为微服务架构的落地,扫清了最后一公里的障碍,在符合企业 IT 治理需求的前提之下,为传统企业应用的平滑过渡提供了有效条件和方法。

作为软件生产环节中重要组成部分的持续构建和发布过程,自然也要随势而动,这方面的老将 Jenkins 不但提供了用于构建、推送 Docker 镜像的插件,更提供了利用 Kubernetes 运行构建集群的能力。本文将利用一个简单的 Hello world 项目,来展示 Jenkins 的这一特性。

准备工作

Kubernetes 集群安装

要在 Kubernetes 集群完成下面所有的工作,因此首先进行集群的安装和配置,这方面可以参考 官方入门文档,如果英语不灵但动手排错能力强的话,也可以参考已经过时的拙作

集群安装后,应该具有以下能力:

  1. 集群具有受 DNS 支持的服务寻址能力;
  2. 能够利用 Kubectl 或者其他方法发布容器应用的能力;
  3. 私有镜像库,或者到 Docker Hub 的网络连接;
  4. Pause 镜像也自然是 Kubernetes 中运行应用的必须条件。

Jenkins 镜像

本文例子采用自制的一个集成镜像为基础工具,该镜像集成了众多常用的 CI/CD 工具,另外同时还包含了 Jenkins 的 Master 和 Slave 两种模式,镜像托管在 Docker Hub,源码可在 Github 浏览和下载。

如果具有直接连接 Docker Hub 的网络连接,则可无需理会;否则就需要下载镜像,并上传至私库。为行文方便,这里假设采用私库方式,镜像地址为 10.211.55.5:5000/jenkins:2.7.4.5

共享存储

因容器在集群中的运行状况未知,一般来说是需要为容器化应用提供共享存储服务的,本文中采用最简单的 NFS 方式,当然也可以使用官方支持的其他方式,例如 GlusterFS、Flocker 以及 Ceph 等等,具体支持能力可以参看官方说明,当然,如果只是学习测试,使用缺省的 Empty 格式亦可,或者偷懒使用 HostPath 方式结合限定 Node 运行的方式也能够完成任务。

本文中的卷挂载方式很是粗糙,目前推荐的共享存储方式是持久卷(PV & PVC)方式,以提供更好的管控能力,中文可参考:Kubernetes 中的 Persistent Volumes

Jenkins Master

YAML

首先要为我们的 Jenkins 镜像编写一个 Yaml ,用于提交到集群中运行:

kind: ReplicationController
apiVersion: v1
metadata:
  name: jenkins
  labels:
    name: jenkins
spec:
  replicas: 1
  selector:
    name: jenkins
  template:
    metadata:
      labels:
        name: jenkins
    spec:
      containers:
      - name: jenkins
        image: 10.211.55.5:5000/jenkins:2.7.4.5
        ports:
        - containerPort: 8080
          protocol: TCP
        - containerPort: 8081
          protocol: TCP
        volumeMounts:
          - name: jenkins
            mountPath: /data/jenkins
      volumes:
      - name: jenkins
        nfs:
          server: 10.211.55.5
          path: /var/data/nfs/ci/jenkins
          readOnly: false
---
kind: Service
apiVersion: v1
metadata:
  name: jenkins
  labels:
    name: jenkins
spec:
  type: NodePort
  ports:
  - protocol: TCP
    nodePort: 32502
    targetPort: 8080
    port: 8080
    name: web
  - protocol: TCP
    targetPort: 8081
    port: 8081
    name: service
  selector:
    name: jenkins

上面的 YML 文件有几点需要注意

  1. 挂载:Jenkins 的所有插件、配置和工作文件都处于环境变量 JENKINS_HOME 所示的路径中,因此我们这里利用 NFS 把位于 10.211.55.5 上的 /var/data/nfs/ci/jenkins 目录映射到容器的 /data/jenkins 之中,让 Jenkins 获得持久化存储。
  2. 端口:Jenkins 缺省运行需要 8080 端口对外提供 Web 界面。这里我们另外声明了一个 8081 端口,为集群内新建的 Slave 提供通信能力,可以看到,下面的 Service 定义中,仅仅使用 NodePort 方式暴露了一个 Web 端口
  3. 时区:镜像提供了 TIMEZONE 环境变量,这一变量将会在运行时影响容器操作系统以及 Jenkins 的 JVM 的时区设置。这一变量缺省使用 Asia/Shanghai
  4. JENKINS_MODE:用于指示 Jenkins 的运行模式,可选值为 MASTER 或者 SLAVE,缺省运行在 MASTER 模式下。

运行和配置

接下来就可以使用 kubectl create -f jenkins.yaml 来运行镜像了。执行之后可以刷 kubectl get pods 来查看启动情况。

这一 RC 的启动需要加载 NFS 卷,因此如果启动时间过长,可以使用 kubectl get events 命令查看是否加载出了问题。

Pod 变为 Running 状态之后,就可以尝试采用上面 YAML 中定义的 Node Port 来访问 Jenkins 界面了,经过一段时间的 "Jenkins正在启动,请稍后.....",系统要求输入 /data/jenkins/secrets/initialAdminPassword 文件中保存的初始密码,假设前面 get pods 命令得到的 Pod 名称是 jenkins-7nmka,这里就可以使用 kubectl exec jenkins-7nmka cat /data/jenkins/secrets/initialAdminPassword 来查看,获取结果后即可复制黏贴到录入框中继续安装。

接下来的插件安装,为节省时间直接 Select None。接下来设置管理员用户名密码,保存后,安装结束。

安装和配置 Kubernetes 插件

安装

接下来就是进入 pluginManager/available 页面安装插件。

如果网络需要代理,可以进入网址 /pluginManager/advanced,设置代理服务器。 如果可选插件页面为空,可以在 /pluginManager/advanced 页面里面点击 "立即获取" 按钮进行刷新。

过滤框中输入 "kubernetes" 会看到列表中的 "Kubernetes plugin",选择安装。

配置 Jenkins

安装成功后,进入配置页面(/configure)。

首先为了测试方便,我们把 “执行者数量” 设置为 0,也就是说只使用 Jenkins Slave 进行构建。

配置 Kubernetes

可以看到,页面下方有一个按钮 “新增一个云”,点击后出现 Kubernetes 配置项目。

这里我们用无认证的 http 方式进行连接,Kubernetes URL 中填入 API Server 的 http 地址,例如:http://10.211.55.5:8080

Jenkins URL 中,这里要注意我们不应该使用浏览器地址栏中的 Node 地址,而是应该使用集群内部的服务地址,根据上文中 Service 的定义,这里使用 http://jenkins:8080

最后是 ”Add Pod Template“ 按钮,来定义 Slave 的 Pod 模板:

  • 这里的 "Docker Image" 项目跟上面使用的是同一个地址,也就是 10.211.55.5:5000/jenkins:2.7.4.5
  • 根据前文说道的环境变量,这里我们新增一个环境变量:JENKINS_MODE=SLAVE,
  • "Jenkins slave root directory" 这一项填写 /data/jenkins
  • "Command to run slave agent " 这里填写镜像中的启动命令 /usr/local/bin/run.sh

填写完成后,保存。

配置端口

最后需要到安全配置页面(/configureSecurity),TCP port for JNLP agents 一项填写固定端口 8081。

Hello world

创建

新建一个 Free Style 项目。构建步骤中新增 "Execute shell script" 环节,并保存,内容为

echo "Hello World"

构建

点击该任务的 “立即构建” 按钮,即可触发构建动作。

因为前面我们设置 Master 不执行构建工作,所以在构建启动之后,会在构建执行状态中看到有节点被动态新建,来执行我们的构建过程。这一过程中如果使用 kubectl get events 或者 kubectl get pods 命令,能看到 Jenkins Slave Pod 的创建、执行和销毁过程。

尾声

上面只是一个最为基础的构建过程,甚至都无法称为是一个完整过程,Kubernetes 插件还提供了很多其他选项,结合自定义的 Slave 镜像,能够完成更多更复杂的任务,用于配合实际的生产过程。

More from this blog

龙虾恐慌:AIOps 又要改名了?

ChatGPT 开始,把 AI 拉近到普罗大众的面前,让无数人感受到 AI 的亲民魅力。而龙虾,则把大模型驱动的自动化能力,突然间变得水灵灵、活泼泼地走进千家万户。它不只是“风口上的猪”,而是风口本身。热度高到让 Mac mini 一度断货,不知道这在不在库克的预料之内。 每代人都有每代人的鸡蛋,春节期间,我就领了我的鸡蛋。翻出古老的 MacBook Air M1,充值各种大模型。当然了,这个工具

Mar 9, 20261 min read

再见 2025

我猜不少人以为这个号废了吧?并没有,只是今年变化有点大,一直有种抄起键盘,无从说起的感觉,所以一直偷懒到今天,2025 的最后一天。 今年是我的第四个本命年,去年末一期播客里,大内说本命年不是灾年,是变化年,有危也有机。可是讲真啊,只看到危,没看到机。 各种因缘际会,从鹅厂跳槽到前东家,已经接近四年,第一个合同期已经进入尾声。除了前两年还在云原生领域嗷嗷叫,后两年基本都是些鸡零狗碎的东西了,用老东家的术语说是——偏离主航道,可谓是前景暗淡了。 一旦确定要滚蛋,反倒心思轻松起来,每天骑着我的小红车...

Jan 5, 20261 min read

辅助编程?dora 说:我知道你很急可是请你别急

从 OpenGPT 把大模型的火烧旺了之后,这三年来,相信很多组织或摩拳擦掌、或躬身入局,希望借助聪明能干的大模型,或想偿还技术宅,或想降本增效,或想弯道超车。一时间,沉寂许久的 AIxx 又活过来了,LLM Ops、Vibe Coding、中医大模型、GPT 算命等等,全都老树发新芽,焕发了勃勃生机。那么视角拉回从业者最关注的饭碗相关的领域之一——AI 辅助开发,产生了什么触动,应该如何拥抱呢? DORA 的年度报告中给出了很有意思的结论——强者恒强。 执行摘要部分总结了几个有趣的点: 问题...

Oct 6, 20251 min read

[译]dora:ai 辅助软件开发状态报告

执行摘要 在 2025 年,科技领导者面临的核心问题已不再是“是否要采用 AI”,而是“如何实现其价值”。 DORA 的研究基于超过 100 小时的定性访谈和来自全球近 5,000 名技术专业人士的问卷调查。研究揭示了一个关键事实:AI 在软件开发中的主要角色是“放大器”。它会放大高效能组织的优势,也会凸显组织的缺陷。 关键结论:AI 是放大器 AI 投资的最大回报并非来自工具本身,而是来自组织底层系统的战略性建设: 高质量的内部平台 清晰的工作流 团队的协同能力 缺少这些基础,AI ...

Oct 2, 202514 min read

僭越了,有人在用 Rust 写 Kubernetes

一个新语言问世,最爱做的事情之一,就是重写存量软件了。 云原生喝酒 SIG 重点扶持项目——rk8s(https://github.com/rk8s-dev/rk8s) 也可以归在这个范畴里,只不过这个项目重写的东西比较大,是 Kubernetes。 从 2025 年 1 月第一个 Commit 开始,到现在有了 200 多次 Commit,十几万行代码。当然距离 Kubernetes 的几百万行代码还差得远——老马就是喜欢整这种大无畏项目。 另外该项目也是国内第一个脱离 Cargo 转向使用 ...

Sep 27, 20253 min read

【伪】架构师

342 posts