jenkins-jnlp主从配置
3,私有仓库的落盘的pv/pvc配置。1、基础镜像的Dockerfile。2、jenkins的pipline。二、jenkins主从基本配置。5,jenkins插件参考截图。
·
一、k8s环境安装
二、jenkins主从基本配置
基于 Kubernetes v1.33.4 部署 Jenkins Master-Slave 架构-CSDN博客
三、详解配置
1、基础镜像的Dockerfile
镜像build和push工具选择buildah(介绍和原理自行搜索)
Dockerfile路径和内容
root@bocheng-System-Product-Name:~/1212121# ls
apache-maven-3.8.8 Dockerfile
root@bocheng-System-Product-Name:~/1212121# cat Dockerfile
# 基于官方 Jenkins Inbound Agent(JDK17)
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jenkins/inbound-agent:latest-jdk17
# 设置环境变量:Maven
ENV MAVEN_HOME=/opt/maven \
PATH=/opt/maven/bin:${PATH}
USER root
# 更新包列表并安装基础工具
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl \
gnupg \
uidmap \
&& \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# ✅ 使用二进制方式安装 buildah(推荐)
# 下载 buildah 二进制文件(使用 GitHub Release)
RUN set -eux && \
BUILDah_VERSION="1.34.0" && \
ARCH=$(dpkg --print-architecture) && \
case "${ARCH}" in \
amd64) ARCH="amd64" ;; \
arm64) ARCH="arm64" ;; \
*) echo "不支持的架构: ${ARCH}"; exit 1 ;; \
esac && \
curl -Lo /usr/bin/buildah "https://github.com/containers/buildah/releases/download/v${BUILDah_VERSION}/buildah-static-linux-${ARCH}" && \
chmod +x /usr/bin/buildah && \
ln -sf /usr/bin/buildah /usr/local/bin/buildah && \
buildah --version
# 安装 podman 和 skopeo(可选)
RUN apt-get update && \
apt-get install -y --no-install-recommends podman skopeo && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 创建 Maven 目录并复制
COPY apache-maven-3.8.8 /opt/apache-maven-3.8.8
# 创建符号链接
RUN ln -sf /opt/apache-maven-3.8.8 /opt/maven && \
ln -sf ${MAVEN_HOME} /maven
# 验证 Maven
RUN mvn -version
# 切回 jenkins 用户
USER jenkins
# 工作目录
WORKDIR /home/jenkins
如果安装不成功可以走docker run + docker commit的方式
因为kubectl -f是在pod里进行的
所以
1、在基础镜像里安装kubectl
2、拷贝.kube/config到基础镜像里边
总之确认可以连接到k8s机器,可以发布
2、jenkins的pipline
1,bc-gateway(项目任务)
pipeline {
agent { label 'jnlp-slave' }
environment {
registry = "swr.cn-east-3.myhuaweicloud.com"
project = "bocheng-test"
app_name = "${JOB_NAME}"
image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"
app_port = "8901"
git_address = "https://gitlab.dbblive.com/dbbjt/wanyan-test.git"
git_groups = "dbbjt"
rollback_image_name = "${registry}/${project}/${app_name}:${version}"
docker_registry_auth = "swr-secret"
git_auth = "5963249d-d581-46db-b227-89df9bafa8a8"
}
parameters {
gitParameter(
branch: '',
branchFilter: '.*',
defaultValue: 'master',
description: '选择发布的分支',
name: 'Branch',
quickFilterEnabled: false,
selectedValue: 'NONE',
sortMode: 'NONE',
tagFilter: '*',
type: 'PT_BRANCH_TAG'
)
choice(
choices: ['prod'],
description: '选择发布环境',
name: 'Namespace'
)
choice(
choices: ['deploy', 'rollback'],
description: 'deploy发布新代码,rollback回滚',
name: 'deploy_env'
)
string(
defaultValue: '0',
description: '输入要回滚的镜像版本号(即 BUILD_NUMBER)',
name: 'version',
trim: false
)
}
stages {
stage('拉取代码') {
steps {
echo "✅ 开始拉取应用代码: ${git_address}"
// 拉取 wanyan-test 应用代码
checkout([
$class: 'GitSCM',
branches: [[name: "${params.Branch}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [],
submoduleCfg: [],
userRemoteConfigs: [[
credentialsId: "${git_auth}",
url: "${git_address}"
]]
])
echo "✅ 开始拉取 K8s 部署配置: https://gitlab.dbblive.com/kubernetes/yyh-devops.git"
// 拉取 yyh-devops 仓库(包含 k8s 部署文件)
dir('yyh-devops-config') {
git branch: 'master',
url: 'https://gitlab.dbblive.com/kubernetes/yyh-devops.git',
credentialsId: "${git_auth}"
}
echo "✅ 代码拉取完成"
}
}
stage('代码编译和镜像打包上传') {
when {
environment name: 'deploy_env', value: 'deploy'
}
steps {
echo "✅ 开始编译并构建镜像"
sh """
mvn clean install -am -pl bc-gateway -Dmaven.test.skip=true -P test -T 4C
/usr/bin/buildah login -u cn-east-3@wanyanzhenjiang -p b39facac2c5dbffb4aa0defa8d4750ce3d148c81awanyanzhenjiangd184f755d0fff3f ${registry}
cd \${WORKSPACE}/bc-gateway
/usr/bin/buildah bud -t ${image_name} .
/usr/bin/buildah push ${image_name}
"""
echo "✅ 镜像构建并上传完成: ${image_name}"
}
}
stage('部署到K8S平台') {
when {
environment name: 'deploy_env', value: 'deploy'
}
steps {
echo "✅ 开始部署到 Kubernetes"
dir('yyh-devops-config/dbbjt/wanyan-test') {
sh '''
echo "🔍 当前路径: $(pwd)"
echo "📋 目录内容:"
ls -l
# 检查文件是否存在
if [ ! -f k8s-deployment.yaml ]; then
echo "❌ 错误: k8s-deployment.yaml 文件不存在!"
echo "请确认以下几点:"
echo "1. 仓库 https://gitlab.dbblive.com/kubernetes/yyh-devops.git"
echo " 包含路径 ddbjt/wanyan-test/k8s-deployment.yaml"
echo "2. 文件已提交并推送到远程 master 分支"
exit 1
fi
echo "🔄 开始替换变量..."
sed -i "s#{APP_NAME}#${JOB_NAME}#g" k8s-deployment.yaml
sed -i "s#{APP_PORT}#${app_port}#g" k8s-deployment.yaml
sed -i "s#{IMAGE_NAME}#${image_name}#g" k8s-deployment.yaml
sed -i "s#{NAME_SPACE}#${Namespace}#g" k8s-deployment.yaml
sed -i "s#{ADD_ENV_LABEL}#${Namespace}#g" k8s-deployment.yaml
echo "🚀 应用部署文件到 K8s..."
/usr/local/bin/kubectl apply -f k8s-deployment.yaml -n ${Namespace}
echo "✅ 部署完成"
'''
}
}
}
stage("服务启动检查") {
when {
environment name: 'deploy_env', value: 'deploy'
}
steps {
echo "⏳ 等待服务启动..."
sleep 63
timeout(time: 31, unit: 'SECONDS') {
waitUntil {
script {
def podstatus = sh(
returnStdout: true,
script: "kubectl get replicasets -n ${Namespace} | grep ${JOB_NAME} | awk '{if (\$2 >=1 && \$4 == 0) print \"podnotready\"}'"
).trim()
def notrun_podname = sh(
returnStdout: true,
script: "kubectl get pod -n ${Namespace} | grep ${JOB_NAME} | awk '{if (\$2 == \"0/1\") print \$1}'"
).trim()
if (podstatus == "podnotready" || notrun_podname) {
echo "🟡 服务尚未就绪,继续检查..."
sleep 10
return false
} else {
echo "🟢 ${JOB_NAME} 服务启动成功!"
return true
}
}
}
}
}
}
stage('回滚指定的镜像') {
when {
environment name: 'deploy_env', value: 'rollback'
}
steps {
echo "🔄 开始回滚 ${JOB_NAME} 到版本: ${version}"
dir('yyh-devops-config/dbbjt/wanyan-test') {
sh '''
echo "🔍 当前路径: $(pwd)"
ls -l
if [ ! -f k8s-deployment.yaml ]; then
echo "❌ 错误: k8s-deployment.yaml 不存在,无法回滚"
exit 1
fi
echo "🔄 替换回滚镜像..."
sed -i "s#{APP_NAME}#${JOB_NAME}#g" k8s-deployment.yaml
sed -i "s#{APP_PORT}#${app_port}#g" k8s-deployment.yaml
sed -i "s#{IMAGE_NAME}#${rollback_image_name}#g" k8s-deployment.yaml
sed -i "s#{NAME_SPACE}#${Namespace}#g" k8s-deployment.yaml
sed -i "s#{ADD_ENV_LABEL}#${Namespace}#g" k8s-deployment.yaml
echo "🚀 应用回滚配置..."
/usr/local/bin/kubectl apply -f k8s-deployment.yaml -n ${Namespace}
echo "✅ 回滚完成"
'''
}
}
}
}
post {
success {
echo "✅ 构建和部署成功"
}
failure {
echo "❌ 构建或部署失败"
}
always {
echo "📌 流水线执行结束"
}
}
}
2,依赖job (上述修改不依赖了)
yyh_devops
node('jnlp-slave') {
stage('Git Clone') {
git credentialsId: '5963249d-d581-46db-b227-89df9bafa8a8', url: 'https://gitlab.wanyanzhenjiang.com/kubernetes/caiwu/bc-gateway.git'
}
}
3,私有仓库的落盘的pv/pvc配置
root@k8s-master:/data/service/jenkins/mvn# cat local-pv-maven.yaml
# local-pv-maven.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-maven-local
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce # Local PV 不支持 ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /data/jenkins/maven-repo
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node1 # 替换为实际节点名
root@k8s-master:/data/service/jenkins/mvn# cat local-pvc-maven.yaml
# local-pvc-maven.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: maven-cache-pvc
namespace: prod
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: local-storage
volumeName: pv-maven-local
NFS的设置如下
root@k8s-master:/data/service/jenkins/nfs# cat nfs-pv.yaml
# nfs-pv-maven.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-php-nfs
namespace: prod
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany # 推荐!NFS 支持多节点读写
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-storage # 自定义类名
nfs:
server: 192.168.122.189
path: /opt/nfs/dbb-live-api/ # 建议子目录隔离用途(见下方说明)
root@k8s-master:/data/service/jenkins/nfs# cat nfs-pvc.yaml
# nfs-pvc-maven.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: php-cache-pvc
namespace: prod
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: nfs-storage
volumeName: pv-php-nfs
4,认证/凭据
1,k8s环境的
kubectl create secret docker-registry swr-secret --docker-server=swr.cn-east-3.myhuaweicloud.com --docker-username=cn-east-3@HPUAAL2AC4J1SRYWA1NW --docker-password=b39facac2c5dbffb4aa0defa8d4750ce3d148c81a0wanyanzhenjiang --docker-email=your-email@example.com --namespace=jenkins
2,jenkins的凭据
2.1 k8s的 Secret text (类型Kubernetes Service Account)
2.2 有权限的gitlab的认证的账号和密码
2.3 harbor仓库的认证的账号和密码
5,jenkins插件参考截图
Jenkins Kubernetes Cloud & Pod 配置所需核心插件列表
要实现 Jenkins + Kubernetes 云(Cloud)+ Pod Template 的完整功能,必须安装以下关键插件。以下是基于你提供的截图和配置需求的**必需插件清单**:
---
✅ 必须安装的核心插件(Core Plugins)
插件名称
版本
作用说明
Kubernetes Plugin
4358.vcfd9c5a_0a_f51
核心插件!提供与 Kubernetes 集群集成的能力,支持动态创建 Pod 作为 Jenkins Agent。
Kubernetes Credentials Plugin
203.v85b_9836a_f44b_
提供在 Jenkins 中管理 Kubernetes 凭据(如 Token、CA 证书)的功能。
Kubernetes Client API Plugin
7.3.1-256.v788a_0b_787114
提供对 Kubernetes API 的访问能力,是 Kubernetes Plugin 的依赖。
Kubernetes CLI Plugin
1.364.vadef8c88b823
允许 Jenkins 使用 kubectl 命令行工具操作 Kubernetes 集群。
🔥 这四个插件是实现“Jenkins → Kubernetes”连接的基础,缺一不可。
---
✅ 必须安装的辅助插件(Supporting Plugins)
插件名称
版本
作用说明
SSH Server Plugin
3.374.v19b_d59c6610
启用 Jenkins 的 SSH 服务,用于 JNLP 协议通信(Agent 与 Master 的连接)。
Pipeline Plugin
4.232-476.v5042c1c1ed7
支持 Pipeline 流水线语法,是现代 CI/CD 的基础。
Git Plugin
5.7.0
支持 Git 源码管理,配合 GitHub/GitLab 使用。
Git Parameter Plug-In
444.vca_b_84d3703c2
允许在构建时选择分支或标签。
GitHub Plugin
1.43.0
如果使用 GitHub,则需要此插件进行集成。
Git Push Plugin
34.vd474e0f7b_ec
支持构建后自动推送代码。
Credentials Binding Plugin
702.vfe613e537e88
将凭据绑定到环境变量中,用于构建脚本中。
SSH Credentials Plugin
361.vb_76760818e8c
存储和管理 SSH 密钥或密码,用于远程部署。
---
✅ 可选但推荐的插件(Recommended for Production)
插件名称
说明
Blue Ocean Plugin
提供现代化 UI 界面,更直观地查看流水线执行过程。
Pipeline: Declarative
支持声明式 Pipeline 语法,简化编写。
Pipeline: Groovy
支持脚本化 Pipeline,灵活性更高。
Localization: Chinese (Simplified)
中文语言包,方便中文用户操作。
Matrix Project Plugin
支持多维度构建矩阵(如不同 JDK 版本、操作系统等)。
Mailer Plugin
发送邮件通知构建结果。
---
🚫 不必要的插件(可忽略)
大部分其他插件(如 JSON Plugin, JUnit Plugin, HTML Publisher 等)属于特定用途,除非你有具体需求,否则无需特别关注。
---
✅ 总结:最小必要插件清单
1. Kubernetes Plugin
2. Kubernetes Credentials Plugin
3. Kubernetes Client API Plugin
4. Kubernetes CLI Plugin
5. SSH Server Plugin
6. Pipeline Plugin
7. Git Plugin
8. SSH Credentials Plugin
💡 **建议**:
在新安装的 Jenkins 中,优先安装以上 8 个插件即可满足 Kubernetes 动态 Agent + 构建 + 部署的基本需求。后续根据实际业务逐步扩展。
---
📌 验证方法
在 Jenkins 控制台中:
1. 进入 系统管理 > 插件管理
2. 搜索上述插件名称,确认其状态为“启用”
3. 访问 系统管理 > 云 > Kubernetes 页面,应能正常显示配置项
如果缺少任一核心插件,将无法完成 Kubernetes 云配置。

6,jenkins cloud的配置
概述
本配置文档详细描述了 Jenkins 中 Kubernetes 云(Cloud) 的配置项,用于在 Kubernetes 集群中动态创建和管理构建代理(Agent Pod),实现 CI/CD 流程的弹性扩展与资源隔离。
---
一、基本信息
- 配置路径: 系统管理 > Clouds > kubernetes > Configure
- 云名称: kubernetes
- 用途: 在 Kubernetes 集群中动态调度 Jenkins Agent Pod 执行构建任务。
- 状态: 已启用(通过“连接测试”按钮可验证)
---
二、核心配置详解
1. Kubernetes 地址
https://kubernetes.default.svc.cluster.local
- 说明:指向 Kubernetes API Server 的内部服务地址,通常用于集群内通信。
- 作用:Jenkins 通过该地址与 Kubernetes API 进行交互,创建、管理 Pod。
✅ 建议:使用内部 DNS 名称确保高可用性和网络稳定性。
---
2. 使用 Jenkins Proxy
- 选项: ❌ 未勾选
- 说明:不使用 Jenkins 的反向代理功能,直接连接 Kubernetes API。
---
3. Kubernetes 服务证书 key
- 字段为空
- 说明:未提供 CA 证书或客户端密钥。结合下一项设置,表明已禁用 HTTPS 证书检查。
---
4. 禁用 HTTPS 证书检查
- 选项: ✅ 已勾选
- 说明:跳过对 Kubernetes API Server 的 SSL/TLS 证书验证。
- ⚠️ **安全风险提示**:
- 生产环境应避免此设置,可能导致中间人攻击。
- 推荐方式:上传正确的 CA 证书并启用证书校验。
---
5. Kubernetes 命名空间
jenkins
- 说明:所有由 Jenkins 创建的 Agent Pod 将部署到 jenkins 命名空间中。
- 建议:为 Jenkins 独立划分命名空间,便于资源管理和权限控制。
---
6. Agent Docker Registry
- 字段为空
- 说明:未指定镜像仓库地址。若需从私有仓库拉取 agent 镜像,则需在此填写。
---
7. 注入受限 PSS 安全上下文
- 选项: ❌ 未勾选
- 说明:不强制注入 Pod Security Standard(PSS)限制策略,允许更灵活的安全配置。
---
8. 凭据(Credentials)
- 类型: Secret text
- 说明:用于认证 Jenkins 与 Kubernetes API 的通信。
- 可能是 ServiceAccount Token 或其他访问令牌。
- 实际值未显示,但必须存在且有效。
🔐 注意:凭据应在 Jenkins 的“凭据管理”中预先配置好。
---
9. WebSocket 和 Direct Connection
- WebSocket: ❌ 未勾选
- Direct Connection: ❌ 未勾选
- 说明:默认使用标准 TCP 连接方式通信,适用于大多数场景。
---
10. Jenkins 地址
http://jenkins.jenkins.svc.cluster.local:8080
- 说明:Jenkins 主控节点的内部服务地址。
- 作用:Agent Pod 启动后会连接此地址注册自身,并接收构建任务。
---
11. Jenkins 通道(Jenkins Channel)
jenkins.jenkins.svc.cluster.local:50000
- 说明:Jenkins Master 与 Agent 之间建立 JNLP(Java Network Launch Protocol)连接的端口。
- 作用:Agent 通过该端口与 Jenkins Master 建立双向通信通道。
---
12. 超时设置
参数
值
说明
Connection Timeout
5 秒
初始化连接超时时间
Read Timeout
15 秒
数据读取超时时间
Seconds to wait for pod to be running
600 秒(10分钟)
等待 Pod 处于 Running 状态的最大时间
Container Cleanup Timeout
5 秒
清理容器时的超时时间
⏱️ 建议:根据实际网络延迟适当调整 Seconds to wait for pod to be running,防止因启动慢导致失败。
---
13. 容器数量(Container Count)
10
- 说明:最多同时运行 10 个 Jenkins Agent Pod。
- 作用:限制并发构建任务数,防止资源耗尽。
---
14. Pod Labels(标签)
键
值
jenkins
jnlp
- 说明:为所有由 Jenkins 创建的 Agent Pod 添加标签 jenkins=jnlp。
- 作用:
- 便于后续通过 kubectl get pods -l jenkins=jnlp 查询 Jenkins Agent。
- 支持基于标签的资源调度策略(如 NodeSelector、Affinity)。
---
15. Pod Retention(Pod 保留策略)
- 选项: Never
- 说明:构建完成后立即删除 Pod,不保留任何历史 Pod。
- 优点:节省资源,保持集群整洁。
- 缺点:无法回溯旧 Pod 日志或调试信息。
💡 建议:生产环境中可考虑设置为 OnFailure 或 OnSuccess,以便排查问题。
---
16. 连接 Kubernetes API 的最大连接数
32
- 说明:Jenkins 与 Kubernetes API Server 之间的最大并发连接数。
- 作用:防止大量请求压垮 API Server。
---
17. 其他高级选项
选项
是否启用
说明
从 controller 传递给 agent 的环境变量
❌
不传递额外环境变量
Restrict pipeline support to authorized folders
❌
不限制流水线权限
Enable garbage collection
❌
不启用垃圾回收机制
默认提供的模板名称
空
未指定默认 Pod Template
---
三、工作流程图解
[触发构建任务]
↓
[Jenkins Controller 判断无空闲 Agent]
↓
[Jenkins 向 Kubernetes 发送请求创建新 Pod]
↓
[Kubernetes 根据配置创建 Pod 并分配资源]
↓
[Pod 启动并连接 Jenkins Master (JNLP)]
↓
[Agent 接收任务并执行构建]
↓
[构建完成 → Pod 自动销毁(Never 策略)]
---
四、注意事项与优化建议
✅ 当前优势
- 动态伸缩:按需创建 Agent,提升资源利用率。
- 隔离性:每个构建任务运行在独立 Pod 中,互不影响。
- 易维护:无需手动管理物理机或虚拟机。
⚠️ 存在问题与改进建议
问题
建议
禁用 HTTPS 证书检查
✅ 生产环境应上传 CA 证书并启用校验
缺少 Pod Template 配置
✅ 应配置至少一个 Pod Template,定义镜像、资源请求等
未启用日志收集
✅ 建议集成 Fluentd / EFK 收集 Agent 日志
无健康检查机制
✅ 可添加 Liveness/Readiness Probe 提升稳定性
无资源限制
✅ 建议设置 CPU/Memory 请求和限制,避免 OOM
---
五、附录:关键术语解释
术语
解释
JNLP
Java Network Launch Protocol,Jenkins 用于远程启动 Agent 的协议
Pod Template
定义 Agent Pod 的镜像、资源、卷、环境变量等模板
ServiceAccount
Kubernetes 中用于身份认证的服务账户,常用于 Jenkins 访问 API
ClusterRoleBinding
控制 Jenkins 对 Kubernetes 资源的操作权限
---
六、总结
该配置实现了 Jenkins 与 Kubernetes 的深度集成,支持:
- 动态创建构建代理
- 自动化任务分发
- 弹性扩容与缩容
- 安全隔离的构建环境
✅ **适合场景**:微服务架构下的 CI/CD 流水线,尤其是需要频繁构建和测试的项目。
🔧 **下一步建议**:
1. 添加 Pod Templates(例如:Java、Node.js、Go 等不同语言环境)
2. 配置 RBAC 权限控制
3. 启用日志与监控(Prometheus + Grafana)
4. 设置自动清理策略(如保留最近 5 个成功构建的 Pod)
---
📌 **保存建议**:点击 “Save” 保存配置,然后测试是否能正常创建 Pod 并执行构建任务。

7,kubernetes - Pod templates
Jenkins Pod Template 配置文档:jnlp-slave
概述
本配置文档详细解析了 Jenkins 中名为 jnlp-slave 的 Pod Template 设置,用于在 Kubernetes 集群中动态创建运行 Maven 构建任务的 Jenkins Agent Pod。该模板专为生产环境(prod 命名空间)设计,支持私有镜像仓库、Maven 缓存持久化和容器安全增强。
---
一、基本信息
- 配置路径: 系统管理 > Clouds > kubernetes > jnlp-slave
- 模板名称: jnlp-slave
- 命名空间: prod
- 标签列表: jnlp-slave
- 用途: 只允许绑定到指定 Job 的构建任务使用此模板
- 父级模板: 无(独立定义)
- Jenkins Agent 容器名: jnlp
---
二、核心配置详解
1. Container Template(容器模板)
字段
值
说明
名称
jnlp
容器名称,与 Pod 名称一致
Docker 镜像
swr.cn-east-3.myhuaweicloud.com/bocheng-test/jenkins-jnlp-maven:3.8.8-jdk17_v2
使用华为云 SWR 私有镜像仓库中的自定义 Maven 构建镜像
工作目录
/home/jenkins
Jenkins Agent 运行时的工作目录
运行命令
jenkins-agent
启动 Jenkins JNLP Agent 的默认命令
分配伪终端
✅ 已启用
允许交互式 shell,便于调试
注入 Jenkins Agent
❌ 未勾选
不在 agent container 内注入额外 agent(标准行为)
📌 **镜像说明**:该镜像基于 OpenJDK 17 + Maven 3.8.8,预装 Java、Maven 和必要工具,适合构建 Java 应用。
---
2. 环境变量(Environment Variables)
键
值
作用
CONTAINERD_ADDRESS
/run/containerd/containerd.sock
指向 containerd 的 Unix Socket,用于容器运行时通信
CONTAINERD_NAMESPACE
default
指定 containerd 的命名空间(通常为 default)
💡 **意义**:使 Pod 能够访问底层容器运行时,支持更高级的容器操作(如调试、日志采集等)。
---
3. 卷(Volumes)配置
(1) Host Path Volume - containerd socket
- 主机路径: /run/containerd/containerd.sock
- 挂载路径: /run/containerd/containerd.sock
- 只读: ❌
- 用途:让 Pod 能访问宿主机的 containerd 控制接口,实现容器级监控或调试。
(2) Host Path Volume - localtime
- 主机路径: /etc/localtime
- 挂载路径: /etc/localtime
- 只读: ❌
- 用途:同步宿主机时区,确保构建时间准确。
(3) Persistent Volume Claim (PVC)
- 申明值: maven-cache-pvc
- 挂载路径: /root/.m2/repository
- 只读: ❌
- 用途:将 Maven 本地仓库持久化存储,避免每次构建都重新下载依赖包,显著提升构建速度。
✅ **优势**:通过共享缓存减少网络 I/O,适用于频繁构建的项目。
(4) Persistent Volume Claim (PVC)
- 申明值: php-cache-pvc
- 挂载路径: /opt/nfs/dbb-live-api
- 只读: ❌
- 用途:将 Maven 本地仓库持久化存储,避免每次构建都重新下载依赖包,显著提升构建速度。
---
4. Raw YAML for the Pod(原始 YAML 配置)
spec:
containers:
- name: jnl
securityContext:
privileged: true
capabilities:
add:
- SYS_ADMIN
- SETCAP
allowPrivilegeEscalation: true
volumeMounts:
- name: containers-storage
mountPath: /var/lib/containers
- name: dev-mapper
mountPath: /dev/mapper
- name: containerd-socket
mountPath: /run/containerd/containerd.sock
- name: local-time
mountPath: /etc/localtime
- name: maven-cache
mountPath: /root/.m2/repository
volumes:
- name: containers-storage
emptyDir: {}
- name: dev-mapper
hostPath:
path: /dev/mapper
- name: containerd-socket
hostPath:
path: /run/containerd/containerd.sock
- name: local-time
hostPath:
path: /etc/localtime
- name: maven-cache
persistentVolumeClaim:
claimName: maven-cache-pvc
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
关键字段解析:
字段
说明
privileged: true
提升容器权限,允许执行特权操作(如访问设备文件)
capabilities.add
添加系统调用能力(SYS_ADMIN, SETCAP),用于容器内某些高级功能
allowPrivilegeEscalation: true
允许进程提升权限
volumeMounts
定义容器内部挂载点
tolerations
忽略节点污点,允许调度到 master 节点(仅限测试/开发环境)
⚠️ **注意**:privileged: true 和 tolerations 在生产环境中存在安全隐患,建议根据实际需求谨慎使用。
---
5. Image Pull Secret(镜像拉取凭证)
名称
swr-secret
说明
用于从华为云 SWR 私有镜像仓库拉取镜像的认证凭据
🔐 **前提条件**:必须在 Kubernetes 中预先创建名为 swr-secret 的 Secret,并关联到 jenkins-prod ServiceAccount。
---
6. Service Account
- 名称: jenkins-prod
- 作用:为 Pod 提供身份标识,用于访问 Kubernetes API 和执行相关操作。
- 关联:需配合 RBAC 角色绑定(RoleBinding)以授予必要权限。
---
7. 安全与运行参数
参数
值
说明
Run As User ID
0
以 root 用户身份运行容器(高权限)
Run As Group ID
未设置
默认继承
Supplemental Groups
未设置
无附加组
Host Network
❌
不启用主机网络模式
节点选择器
未设置
无节点调度限制
工作空间卷
Empty Dir Workspace Volume
使用临时卷作为工作目录,构建完成后自动清理
Size Limit
未设置
无大小限制
内存中
❌
不使用内存卷
---
8. 生命周期与保留策略
参数
值
说明
Pod Retention
Default
构建完成后按默认策略处理(通常为删除)
代理空闲存活时间
未设置
不限制空闲时间
Pod 寿命(秒)
未设置
不限制最大生命周期
连接超时(秒)
1000
Jenkins Master 与 Agent 的连接超时时间为 1000 秒(约 16 分钟)
---
三、工作流程图解
[触发构建任务]
↓
[Jenkins 根据标签匹配选择 jnlp-slave 模板]
↓
[Kubernetes 创建 Pod 并启动容器]
↓
[Pod 挂载 PVC(Maven 缓存)、HostPath(时间、containerd)]
↓
[容器以 root 权限运行,加载环境变量]
↓
[Jenkins Agent 启动并连接 Jenkins Master]
↓
[执行构建任务(如 mvn clean install)]
↓
[构建完成 → Pod 自动销毁(默认策略)]
---
四、优点与适用场景
✅ 优点
1. 高效构建:
- Maven 依赖缓存持久化 → 大幅缩短构建时间
2. 资源隔离:
- 每次构建都在独立 Pod 中运行,互不干扰
3. 灵活性强:
- 支持私有镜像仓库、自定义环境变量、卷挂载
4. 可扩展性好:
- 动态伸缩,按需创建 Agent
🎯 适用场景
- Java/Maven 项目的 CI/CD 流水线
- 需要长期缓存依赖的持续集成任务
- 生产环境部署前的自动化测试与打包
- 多环境构建(可通过不同模板区分)
---
五、注意事项与优化建议
⚠️ 安全风险提示
风险项
建议
privileged: true
❌ 生产环境应避免;若必须,建议最小化权限
Run As User ID=0
❌ 存在安全漏洞;考虑使用非 root 用户运行
tolerations 允许调度到 master
❌ 生产环境禁止,可能影响集群稳定性
✅ 优化建议
方向
措施
安全性
使用非 root 用户运行容器,移除不必要的 capabilities
性能
增加 concurrencyLimit 限制并发数,防止资源耗尽
可观测性
添加日志输出(如 fluentd)和指标采集(Prometheus)
可靠性
设置 Pod Disruption Budget 防止意外中断
维护性
将模板拆分为多个(如 java, nodejs, go)以提高复用性
---
六、附录:关键术语解释
术语
解释
Pod Template
Jenkins 用于定义 Kubernetes Pod 结构的模板
PVC (PersistentVolumeClaim)
请求持久化存储资源的对象
ServiceAccount
Kubernetes 中用于服务身份认证的账户
Image Pull Secret
用于从私有镜像仓库拉取镜像的凭证
Raw YAML
允许用户覆盖默认 Pod 配置,实现精细控制
---
七、总结
该 jnlp-slave Pod Template 是一个高度定制化的 Jenkins 构建环境,具备以下特性:
- ✅ 支持私有镜像仓库
- ✅ Maven 依赖缓存持久化
- ✅ 高权限容器运行(适合复杂构建)
- ✅ 支持容器运行时调试
- ✅ 与 Kubernetes 深度集成
🔧 **推荐做法**:
在生产环境中,建议对当前配置进行“去特权化”改造,例如:
securityContext:
privileged: false
runAsNonRoot: true
runAsUser: 1000
并结合 Pod Security Admission 策略进一步加固安全。
📌 **保存建议**:点击 “Save” 保存配置后,可在 Jenkins 的“Manage Nodes”中查看是否能成功创建 Pod 并执行任务。

Raw YAML for the Pod内容(让slave跑在root权限,为了编译推送镜像用)
spec:
containers:
- name: jnlp
securityContext:
privileged: true
capabilities:
add:
- SYS_ADMIN
- SETFCAP
allowPrivilegeEscalation: true
volumeMounts:
- name: containers-storage
mountPath: /var/lib/containers
- name: dev-mapper
mountPath: /dev/mapper
- name: containerd-socket
mountPath: /run/containerd/containerd.sock
- name: local-time
mountPath: /etc/localtime
- name: maven-cache
mountPath: /root/.m2/repository
volumes:
- name: containers-storage
emptyDir: {}
- name: dev-mapper
hostPath:
path: /dev/mapper
- name: containerd-socket
hostPath:
path: /run/containerd/containerd.sock
- name: local-time
hostPath:
path: /etc/localtime
- name: maven-cache
persistentVolumeClaim:
claimName: maven-cache-pvc
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
8,存储在gitlab里的k8s-deployment.yaml模版
~ git clone git@gitlab.dbblive.com:kubernetes/yyh-devops.git
~ cd yyh-devops/
~ mkdir dbbjt
~ git add dbbjt
~ git commit -m "add dbbjt file"
~ touch dbbjt/README.md
~ git add dbbjt
~ git commit -m "add dbbjt file"
~ git push -u origin master
~ cd dbbjt/
~ mkdir wanyan-test
~ cp /tmp/k8s-deployment.yaml wanyan-test/
~ git add wanyan-test/
~ git commit -m "add dbbjt file1"
~ git push -u origin master
---
apiVersion: v1
kind: Service
metadata:
name: {APP_NAME}
namespace: {NAME_SPACE}
labels:
app: {APP_NAME}
env: {ADD_ENV_LABEL}
spec:
ports:
- name: http
port: {APP_PORT}
protocol: TCP
targetPort: {APP_PORT}
selector:
app: {APP_NAME}
env: {ADD_ENV_LABEL}
sessionAffinity: None
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {APP_NAME}
namespace: {NAME_SPACE}
labels:
app: {APP_NAME}
env: {ADD_ENV_LABEL}
spec:
replicas: 1
selector:
matchLabels:
app: {APP_NAME}
env: {ADD_ENV_LABEL}
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: {APP_NAME}
env: {ADD_ENV_LABEL}
spec:
imagePullSecrets:
- name: swr-registry-secret
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- {APP_NAME}
topologyKey: kubernetes.io/hostname
weight: 100
containers:
- env:
- name: TZ
value: Asia/Shanghai
- name: LANG
value: en_US.UTF-8
image: {IMAGE_NAME}
imagePullPolicy: IfNotPresent
name: {APP_NAME}
ports:
- name: http
containerPort: {APP_PORT}
protocol: TCP
readinessProbe:
failureThreshold: 2
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: {APP_PORT}
timeoutSeconds: 2
livenessProbe:
failureThreshold: 2
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: {APP_PORT}
timeoutSeconds: 2
resources:
limits:
cpu: 1000m
memory: 1024Mi
requests:
cpu: 200m
memory: 256Mi
volumeMounts:
- mountPath: /data/logs
name: logs
- mountPath: /etc/localtime
name: localtime
readOnly: true
dnsPolicy: ClusterFirstWithHostNet
restartPolicy: Always
securityContext:
fsGroup: 2049
runAsGroup: 2049
runAsUser: 2049
volumes:
- emptyDir: {}
name: logs
- hostPath:
path: /etc/localtime
type: File
name: localtime

备注
镜像仓库用的华为的免费版
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)