与 Kubernetes 集成
Jenkins 与 Kubernetes 的集成有两个方向:用 K8s 做动态构建 Agent(按需起 Pod 跑构建)和把 Jenkins 本身部署到 K8s(Helm)。本篇以动态 Agent 为主。
本篇目标:能配置 Kubernetes 云并让流水线用动态 Pod 构建,理解镜像拉取、PVC、污点容忍和 RBAC 权限。
1. 为什么用 K8s 动态 Agent
| 对比 | 固定 Agent | K8s 动态 Agent |
|---|---|---|
| 资源利用 | 常驻占用 | 按需创建/销毁 |
| 环境隔离 | 共享,易污染 | 每个构建独立 Pod |
| 弹性 | 需要预先规划机器 | 自动扩容到集群剩余资源 |
| 维护 | 每台机器要打补丁 | 只需维护镜像 |
工作流程:
构建请求 → Jenkins Master 调 K8s API
→ 按 Pod Template 创建 Pod(含多个容器)
→ Agent 容器连接 Master 领取任务
→ 构建完成 → Pod 自动销毁
2. 配置 Kubernetes Cloud
安装 Kubernetes 插件,然后:
Manage Jenkins → Manage Nodes and Clouds → Clouds → New cloud → Kubernetes
Kubernetes URL: https://kubernetes.default.svc (Jenkins 在集群内时)
或集群 API Server 地址
Kubernetes namespace: jenkins-agents
Credentials: kubeconfig 或 service account token(见第 4 篇 Secret file)
Jenkins URL: http://jenkins:8080 (Pod 内 Agent 回连地址)
2.1 所需的 RBAC 权限
动态 Agent 需要让 Jenkins 在目标 Namespace 创建/删除 Pod。给 Jenkins 的 ServiceAccount 授权:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins-agent
namespace: jenkins-agents
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "secrets", "services", "configmaps", "persistentvolumeclaims"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins-agent
namespace: jenkins-agents
subjects:
- kind: ServiceAccount
name: jenkins
namespace: jenkins
roleRef:
kind: Role
name: jenkins-agent
apiGroup: rbac.authorization.k8s.io
3. Pod Template
流水线里用 agent { kubernetes { ... } } 定义动态 Pod:
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.9-eclipse-temurin-17
command: ['cat']
tty: true
- name: docker
image: docker:24.0
command: ['cat']
tty: true
volumeMounts:
- mountPath: /var/run/docker.sock
name: docker-sock
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
'''
}
}
stages {
stage('编译') {
steps {
container('maven') { sh 'mvn clean package' }
}
}
stage('打镜像') {
steps {
container('docker') { sh 'docker build -t $IMAGE .' }
}
}
}
}
关键点:
command: ['cat']+tty: true:容器保持存活,等待流水线步骤;container('name'):指定在 Pod 内哪个容器执行步骤;- PVC 挂载:构建缓存等持久数据挂
persistentVolumeClaim卷,避免每次重建拉依赖。
3.1 用 PVC 缓存 Maven 依赖
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.9-eclipse-temurin-17
command: ['cat']
tty: true
volumeMounts:
- mountPath: /root/.m2
name: m2-cache
volumes:
- name: m2-cache
persistentVolumeClaim:
claimName: maven-cache
'''
}
}
4. 部署 Jenkins 到 K8s(Helm)
如果要在 K8s 上运行 Jenkins 本身:
helm repo add jenkinsci https://charts.jenkins.io
helm upgrade --install jenkins jenkinsci/jenkins -f values.yaml
# values.yaml 关键配置
controller:
serviceType: ClusterIP # 外部用 Ingress 暴露
adminUser: admin
adminPassword: <generated>
persistence:
existingClaim: jenkins-home # 持久化 $JENKINS_HOME 的 PVC
nodeSelector:
node-role.kubernetes.io/worker: ""
tolerations: [] # 如需调度到特定节点池
podSecurityContext:
fsGroup: 1000
containerEnv:
- name: TZ
value: Asia/Shanghai
K8s 上的 Jenkins 持久化
默认 Helm Chart 会用 PVC 存 $JENKINS_HOME。PVC 的 reclaimPolicy 和备份责任在你这儿(见第 14 篇)。另外 Jenkins 以非 root 运行,PVC 要支持 fsGroup 授权。
5. 常见问题
| 现象 | 原因与处理 |
|---|---|
| Agent Pod 一直 Pending | 集群资源不足、污点未容忍、PVC 无法绑定 |
Failed to connect to Jenkins | Pod 内回连的 Jenkins URL 不可达(域名/端口) |
image pull failed | 私有镜像需 imagePullSecrets |
| 容器启动即退出 | 缺 command: ['cat'] + tty: true |
| 权限不足创建 Pod | RBAC Role/Binding 未配好 |
# 私有镜像仓库的 imagePullSecrets
spec:
imagePullSecrets:
- name: registry-secret
6. 练习与验收
练习 A
- 在有 K8s 集群的环境安装 Kubernetes 插件并配置 Cloud
- 配置 RBAC,让 Jenkins 能在
jenkins-agents命名空间创建 Pod - 用上面的 Pod Template 跑通一次动态构建,观察 Pod 自动创建/销毁
练习 B
- 给动态 Agent 挂一个 PVC 缓存 Maven 依赖,对比两次构建的拉取速度
- (可选)用 Helm 把 Jenkins 部署到集群,配置 Ingress 访问
- 在 Agent Pod 里用
imagePullSecrets拉私有镜像仓库的构建镜像
验收清单
- 理解 K8s 动态 Agent 的原理和优势
- 会配置 Kubernetes Cloud 和 Pod Template
- 知道
command: ['cat']+tty: true保持容器存活 - 会用 PVC 缓存构建依赖
- 知道 RBAC、污点、imagePullSecrets 的配置
- 了解用 Helm 在 K8s 上部署 Jenkins 的方式
下一篇:制品与部署交付。