1 Star 1 Fork 0

xhal / jenkins-mirror

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

使用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 时发生错误

    1-0

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

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

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

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

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

1-1

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

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

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

1-2

Nexus3 上文件亦存在:

1-2-2

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'' 时发生错误

2-1

原来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

执行完成后,文件如下图所示:

2-2

修改 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 时发生错误

2-4-1

​ 于是又各种查资料,发现是因为生成的证书没有被信任的问题,试着将 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

2-5

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

2-6

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

2-7

至此, 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

3-0

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

3-1

如下图所示, Jenkins 可正常下载新插件:

3-2

参考资料

  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
MIT License Copyright (c) 2021 xhal Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

使用Nexus3 + Nginx搭建Jenkins插件代理仓库 展开 收起
Python
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/xhal/jenkins-mirror.git
git@gitee.com:xhal/jenkins-mirror.git
xhal
jenkins-mirror
jenkins-mirror
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891