使用Nexus3 + Nginx搭建Jenkins插件代理仓库

使用Nexus3 + Nginx搭建Jenkins插件代理仓库

前言

​ 因为公司内部环境无法上网,搭建Jenkins环境后,存在如下情况:

  1. ​ 默认插件仓库偶尔会出现网络连接异常,无法下载的问题
  2. ​ 因为是内网环境,只能在申请搭建环境的这几天有权限连外网(在一个单独隔离的环境中),无法一次性将以后可能需要的所有插件都更新

环境说明

Sonatype Nexus : OSS 3.30.0-01

Jenkins: 2.286

Nginx: 1.19.9

操作系统: Windows 10 (因先自行尝试,所以使用Windows、Linux环境原理其实一样)

问题一、解决方案

  1. 使用 Jenkins 中文社区 的 更新中心镜像: https://updates.jenkins-zh.cn/update-center.json

    PS: 具体说明可查看 中文社区官网: https://jenkins-zh.cn/

    今天(2021-04-02)尝试用这个的时候报错(应该是资源问题,待他们修复即可):

    检查更新中心: IOException: Server returned HTTP response code: 403 for URL: https://cdn.jsdelivr.net/gh/jenkins-zh/update-center-mirror/tsinghua/dynamic-2.283/update-center.json 时发生错误
    

在这里插入图片描述

问题二、解决方案(包括问题一)

为了解决以上问题,想到可以将 Jenkins 插件仓库用Nexus代理并缓存(就像Maven仓库一样),了解到Nexus3 添加支持 RAW类型仓库,于是做了如下尝试:

1、Nexus 添加代理仓库,代理国内清华镜像源

清华镜像源地址: https://mirrors.tuna.tsinghua.edu.cn/jenkins/

1-1、Nexus 添加 Jenkins Raw Proxy仓库:

在这里插入图片描述

1-2、尝试请求文件,验证 Nexus 是否代理成功

请求链接: http://localhost:8081/repository/jenkins/TIME

文件可正常下载,表示代理配置成功:

在这里插入图片描述

Nexus3 上文件亦存在:
在这里插入图片描述

2、修改Jenkins 更新中心镜像地址
尝试方案一(验证失败 PASS

​ 从Jenkins 更新中心镜像地址配置https://updates.jenkins.io/update-center.json,配置文件为Json。 因内部插件下载地址都是从此文件读取,所以第一个想法就是把这个文件地址改了不就成了。

​ 说做就做,先将此文件下载到本地,修改内容如下:

  • 因为后续不能连外网,所以检测连接的地址也改成Nexus服务地址 "connectionCheckUrl":"http://www.google.com/" 修改为 "connectionCheckUrl":"http://localhost:8081/"
  • 将所有带 .hpi 结尾的URL前缀 https://updates.jenkins.io/download/plugins/ 替换为 http://localhost:8081/repository/jenkins/plugins/ (共1805个)

因 Jenkins 升级站点,不支持本地文件路径,只好在 Nexus3上新建一个名为 jenkins-hosted 的 Raw-hosted 仓库,并上传修改后的 update-center.json, 新的站点URL为: http://localhost:8081/repository/jenkins-hosted/update-center.json

将Jenkins修改升级站点URL, 点击提交、立即获取,(Oh my God…报错了):

检查更新中心: SHA-512 digest mismatch: expected=cbf60c71f19642b29fd3a385cea599200ccc0884054a98398018cfa6f4b02246e5c761de5290dde7bf3659b556325c029b9a9bcba88f931092a484815e531627 in 'update site 'default'' 时发生错误

在这里插入图片描述

原来Jenkins 会校验站点证书,看来这方案不行。。。

尝试方案二 ( 验证成功)

​ 参考《Jenkins配置国内插件下载代理 https://blog.51cto.com/13812615/2505580》使用 Nginx 代理;在不修改原 update-center.json内容情况下,直接修改hosts文件将对应域名指定至本地。

​ 但之前都是 Http 协议,可以直接代理转发就行; 现在都是 https, 所以需要生成站点证书配置。

生成证书 (使用 openssl )

进入Nginx目录,新建 ssl 文件夹,执行以下命令:

### 生成 Key 文件,输入对应密码
openssl genrsa -des3 -out jenkins-io.key 1024
### 生成 csr 文件
openssl req -new -key .\jenkins-io.key -out .\jenkins-io.csr

#此步注意, 在 Common Name 时要填写, updates.jenkins.io, 否则在连接时证书验证会报 No name matching updates.jenkins.io found
Common Name (e.g. server FQDN or YOUR name) []:updates.jenkins.io


### 执行以下两步,去除密码(否则 Nginx 启动要求输入密码)
copy .\jenkins-io.key .\jenkins-io.key.org
openssl rsa -in .\jenkins-io.key.org -out .\jenkins-io.key

### 生成证书文件
openssl x509 -req -days 365 -in .\jenkins-io.csr -signkey .\jenkins-io.key -out .\jenkins-io.crt

执行完成后,文件如下图所示:
在这里插入图片描述

修改 hosts
127.0.0.1 www.google.com
127.0.0.1 updates.jenkins.io
配置 Nginx.conf 添加 https 域名代理
    # 默认的 www.google.com 验证网络连接,也代理至 Nexus3 服务
    server {
    	listen       80;
    	server_name  www.google.com;
    	
    	location / {
    		proxy_pass http://localhost:8081/;
    	}
    }
    
    server {
        listen       443 ssl;
        server_name  updates.jenkins.io;

        # ssl 证书配置
        ssl_certificate      D:/CI/nginx/nginx-1.19.9/ssl/jenkins-io.crt;
        ssl_certificate_key  D:/CI/nginx/nginx-1.19.9/ssl/jenkins-io.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location /download/ {
            proxy_pass http://localhost:8081/repository/jenkins/;
        }

		# 此处原update-center.json访问,使用本地路径(也可上传至 Nexus3 Raw仓库)
        location /update-center.json {
            root  D:/CI/Jenkins/;
        }
    }
验证 Jenkins 是否可正常连接下载插件

​ 将 Jenkins 升级站点URL 还原为 https://updates.jenkins.io/update-center.json ,点击提交、立即检查(…天啊,还是报错)

检查更新中心: SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 时发生错误

在这里插入图片描述

​ 于是又各种查资料,发现是因为生成的证书没有被信任的问题,试着将 jenkins-io.crt 导入系统,发现还是不行。忽然想到 Jenkins 是Java 程序,应该将证书导入 jre 才可以;于是执行以下命令:

PS D:\CI\nginx\nginx-1.19.9\ssl> keytool.exe -importcert -file .\jenkins-io.crt -keystore D:\Env\Java\corretto-1.8.0_275\jre\lib\security\cacerts -storepass changeit

在这里插入图片描述

添加后(重新启动Jenkins),再次验证 Jenkins , 已成功连接并可正常下载插件,如下图:
在这里插入图片描述

Nexus3 上 Jenkins 仓库也已有对应插件文件:

在这里插入图片描述

至此, Nexus3 代理 Jenkins 插件仓库的所有环境及配置已搭建完毕。

3、将插件仓库所有可用插件,都缓存至 Nexus3

​ nexus 仓库缓存的原理需要有URL请求去请求对应资源,才会将文件下载缓存至Nexus私服。

既然如此,于是想到个较简单也是比较笨的办法,挨个请求一遍。

python 脚本遍历请求

​ 既然所有插件的下载URL路径,都在update-center.json里,那就写个简单的 python 脚本,遍历的请求一遍就好了。

花了几分钟把脚本写好,等了大概半小时终于将所有插件都缓存到 Nexus私服了。

​ 以下为 python 脚本:

# coding=utf-8

import re, urllib.request, time, _thread

def requestUrl(idx, url, threadName):
    try:
        urllib.request.urlopen(url)
    except BaseException as e:
        print('Error: 待 18 秒后,继续尝试 ' + threadName + ' -- ' + str(idx) + ' -- ' + url + ': ' + str(e))
        time.sleep(18)
        requestUrl(idx, url, threadName)

def requestList(urlList, startIdx, step, threadName):
    for idx, url in enumerate(urlList):
        if idx < startIdx or (idx - startIdx) % step != 0:
            continue

        # Url 替换为 Nexus 的路径
        nurl = url.replace('https://updates.jenkins.io/download/', 'http://localhost:8081/repository/jenkins/')
        print(threadName + ' -- ' + str(idx) + ' -- ' + nurl)
        requestUrl(idx, nurl, threadName)
        time.sleep(1)

    print(threadName + '============= 执行完成!!!')

# 读取文件内容
file1 = open('../update-center.json', 'r', encoding='utf-8')
txt = file1.read()

# 正则匹配 URL
links = re.findall('"url":"(\S*.hpi)"', txt)

try:
    _thread.start_new_thread(requestList, (links, 0, 3, 'thread-1'))
    _thread.start_new_thread(requestList, (links, 1, 3, 'thread-2'))
    _thread.start_new_thread(requestList, (links, 2, 3, 'thread-3'))
except BaseException as e:
    print('线程启动异常', str(e))

while 1:
    pass

离线完毕,可见Nexus3 上已缓存文件大小: 5 GB

在这里插入图片描述

离线验证,Nexus 私服是否可用

在这里插入图片描述

如下图所示, Jenkins 可正常下载新插件:
在这里插入图片描述

以上代码工程,已上传Gitee.com: https://gitee.com/xhal/jenkins-mirror
有需要的小伙伴可以自行 clone 试试。

参考资料

  1. Sonatype Raw 仓库类型 https://help.sonatype.com/repomanager3/formats/raw-repositories
  2. Windows下Nginx配置SSL实现Https访问(包含证书生成) https://blog.csdn.net/qq_34924407/article/details/80544253
  3. Jenkins配置国内插件下载代理 https://blog.51cto.com/13812615/2505580
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值