基于K8s部署Jenkins Slave Pod:如何避免依赖包重复下载
如何在Kubernetes Jenkins Slave Pod中缓存依赖包避免重复下载
针对你当前的场景(Jenkins部署在K8s,用Slave Pod执行任务,OpenEBS本地PV共享存储),可以通过以下几种方式实现依赖包的缓存,避免每次启动Slave Pod都重复下载。
一、修复并优化现有脚本的缓存逻辑
你的现有脚本存在变量未定义的问题(${W_PATH}未声明,应该替换为${PVC_PATH}),同时可以优化缓存检查逻辑,确保依赖包和解压后的文件都被正确缓存。
修正后的完整Pipeline代码
#!/usr/bin/env groovy // groovy公共变量 def PROJECT = "CI-code" def WORKDIR_PATH = "/opt/status" def DOWNLOAD_KUBE_DOWNLOAD_URL = "xxx/kube-1.19.0-v2.2.0-amd64.tar.gz" def PVC_PATH = "/var/openebs/local/pvc-8e8f9830-9bdc-494d-ac45-19310cbda035/cloudybase" // 定义缓存目录和标记文件路径 def CACHE_DIR = "${PVC_PATH}/cache" def KUBE_CACHE_MARK = "${CACHE_DIR}/kube_download_completed" def KUBE_TARGET_DIR = "/home/jenkins/agent/workspace/deploywork/Middleware-choreography/kubeQ/kubeQ/" pipeline { agent { kubernetes { yaml """ apiVersion: v1 kind: Pod metadata: name: jenkins-slave namespace: devops-tools spec: containers: - name: jnlp image: "xxx/google_containers/jenkins-slave-jdk11-wget:latest" imagePullPolicy: Always securityContext: privileged: true runAsUser: 0 volumeMounts: - name: docker-cmd mountPath: /usr/bin/docker - name: docker-sock mountPath: /var/run/docker.sock - name: code mountPath: /home/jenkins/agent/workspace/${PROJECT} # 额外挂载缓存目录到Slave Pod内,方便直接使用缓存文件 - name: cache mountPath: ${CACHE_DIR} volumes: - name: docker-cmd hostPath: path: /usr/bin/docker - name: docker-sock hostPath: path: /var/run/docker.sock - name: code hostPath: path: ${PVC_PATH} # 复用同一个PVC路径作为缓存卷 - name: cache hostPath: path: ${CACHE_DIR} """ } } stages { stage('拉取代码') { steps { git branch: 'release-2.2.0', credentialsId: 'e17ba069-aa8b-4bfd-9c9e-3f3956914f09', url: 'xxx/deployworker.git' } } stage('下载依赖包到组件包对应目录') { steps { sh """ logging() { echo -e "\033[32m $(/bin/date)\033[0m" - \$@ } main () { logging "检查Kube安装包缓存状态..." # 检查缓存标记和目标目录是否存在内容 if [ ! -f "${KUBE_CACHE_MARK}" ] || [ ! "$(ls -A ${KUBE_TARGET_DIR})" ]; then download_and_extract_kube else logging "Kube安装包已缓存,跳过下载和解压步骤" fi } download_and_extract_kube () { DOWNLOAD_KUBE_NAME=\$(echo ${DOWNLOAD_KUBE_DOWNLOAD_URL} | /bin/sed 's|.*/||') # 创建缓存目录 mkdir -p ${CACHE_DIR} cd ${CACHE_DIR} && { /bin/curl -O ${DOWNLOAD_KUBE_DOWNLOAD_URL} ; cd -; } if [ "\$?" -ne "0" ]; then logging "下载Kube安装包失败" exit 1 fi # 创建目标目录 mkdir -p ${KUBE_TARGET_DIR} tar xf ${CACHE_DIR}/\${DOWNLOAD_KUBE_NAME} -C ${KUBE_TARGET_DIR} if [ "\$?" -ne "0" ]; then logging "解压Kube安装包失败" exit 1 fi # 写入缓存完成标记 echo 'true' > ${KUBE_CACHE_MARK} logging "Kube安装包下载和解压完成,已缓存" } # 执行主逻辑 main """ } } } }
关键优化点
- 修复变量错误:将未定义的
${W_PATH}替换为已声明的${PVC_PATH} - 独立缓存目录:在PVC路径下创建专门的
cache目录,统一管理缓存文件,避免和代码目录混淆 - 双重缓存检查:同时检查缓存标记文件和目标目录的内容,确保缓存有效(避免标记文件存在但解压文件丢失的情况)
- 挂载缓存目录:将缓存目录直接挂载到Slave Pod内,不需要从PVC根目录复制,提升效率
二、进阶优化方案
1. 自定义Jenkins Slave镜像
如果依赖包版本相对稳定,可以将常用的依赖包提前打包到Jenkins Slave镜像中,这样Slave Pod启动时直接就能使用,无需任何下载步骤:
- 基于现有
jenkins-slave-jdk11-wget镜像,编写Dockerfile:
FROM xxx/google_containers/jenkins-slave-jdk11-wget:latest # 下载并解压Kube安装包到指定目录 RUN DOWNLOAD_URL="xxx/kube-1.19.0-v2.2.0-amd64.tar.gz" && \ DOWNLOAD_NAME=$(echo $DOWNLOAD_URL | sed 's|.*/||') && \ curl -O $DOWNLOAD_URL && \ mkdir -p /home/jenkins/agent/workspace/deploywork/Middleware-choreography/kubeQ/kubeQ/ && \ tar xf $DOWNLOAD_NAME -C /home/jenkins/agent/workspace/deploywork/Middleware-choreography/kubeQ/kubeQ/ && \ rm -f $DOWNLOAD_NAME
- 构建并推送镜像到私有仓库,然后在Pipeline的Slave Pod YAML中使用自定义镜像,删除下载依赖的Stage即可。
2. 使用专用缓存PVC
如果需要扩展到多个Slave Pod(同一节点),可以创建一个专门的OpenEBS本地PV用于缓存,在Slave Pod中挂载该PVC到固定的缓存路径,实现多个Slave共享缓存。
3. 利用Jenkins缓存插件
使用Pipeline Cache Plugin,可以更灵活地管理缓存,支持根据文件哈希自动更新缓存,无需手动维护标记文件。只需在Pipeline中添加缓存步骤:
stage('下载依赖包') { steps { cache(path: KUBE_TARGET_DIR, key: "kube-cache-${DOWNLOAD_KUBE_DOWNLOAD_URL}") { sh "curl -O ${DOWNLOAD_KUBE_DOWNLOAD_URL} && tar xf ..." } } }
注意:需要确保插件配置的缓存存储路径指向挂载的PVC目录,否则缓存会随着Slave Pod销毁而丢失。
内容的提问来源于stack exchange,提问作者zccharts
相关产品推荐
相关产品推荐

