JENKINS服务部署与插件反向代理加速下载方案
不建议说明:
本方法已失效;本篇博文中的内容,仅供兴趣研究使用。
前言:
关键字:Jenkins、Nginx、自动化运维、镜像加速;
Jenkins是一款目前比较热门的由Java编写的开源的持续集成工具,基于其开源的性质以及强大的插件库,国内IT公司在部署DveOps系统时,经常会选用Jenkins作为系统的CI[持续集成]部分。对Jenkins服务,在服务部署上实际并没有什么可以说,基本就是JAVA环境的搭建,再加上使用"java"命令运行一个基于JAVA的"war"应用包,Jenkins服务就已经搭建成功了。另外,基于JAVA的特性,使用这种方式部署的服务,基于上不会产生错误的可能,无论你的服务器上的CPU的指令是基于ARM还是X86架构。
总体上来说,Jenkins是非常友好的,但很多时候,这种友好只能适用于非国内Jenkins的用户身上。国内用户使用Jenkins服务的痛点,永远在于插件的安装与更新上,尽管有清华开源镜像源这样强大的公众服务器,但基于Jenkins对插件下载与安装的安全保证措施,很多时候,即使我们在Jenkins上设定了插件安装/更新的服务器地址为清华的镜像源,也依然无法从清华的镜像源中下载插件[实际上还是从国外网站下载插件]。关于产生上述情形的原因,网上已有很多解释的文章了,本处也就不重复论述了。
于是,博主在寻求一种稳定的更新插件的方法,这是本文的重点~是的,博主也从网上搜索了大量的关于插件加速下载的文章,而让人无语的是,网上永远不缺那些错误的博文,一个无实质作用的插件加速方法,竟然在无数次转发后占满的搜索引擎的索引页面。博主不得感叹,不知道在什么时候时起,复制粘贴别人的文章进行发布成为了技术提升的手段,而非实际的操作与测试。还好,这个世界上还是存在真正的高手的,博主在通过不同的关键字,从搜索引擎中搜索了数天,终于找到了一个插件加速在国内可用的真正方案,也再次感叹,在这一个浮燥的网络时代中,网络上,真正的高手总被那些夸夸其谈的所谓技术人员所湮没……
另注:本文所提供的下载文件 --> jenkins_nginx.tar.gz
一、硬件与软件环境
本教程在以下环境下搭建测试通过!
-
主硬件 :精英 LIVA X [X86架构,你可以用任何PC代替]
-
主机环境 :Docker [19.03.12]
-
操作系统 :Debian 10
-
Jenkins版本 :2.235.3
-
测试日期:2020年07月30日
二、Jenkins部署
关于Jenkins服务的部署,对于传统的安装方法,请参阅官方文档,本处简单说明一下传统的安装方法:1、在服务品上部署好JAVA环境;2、下载名为"jenkins.war"的JAVA应用包;3、执行"java -jar jenkins.war"命令即可部署到一个完整的Jenkins服务;
传统的Jenkins服务的部署方式不是博主的使用方法,因为博主只是在做这些服务的前期测试,而并非用于生产环境[博主也不可能有这么多服务器],所以博主更倾向于使用DOCKER。不过,实际上也有另外一个原因,那就是插件下载的加速方案需要用到Nginx去作反向代理。对于这种多服务的组合应用,很多时候需要多次测试配置才可以产生一个稳定的可使用状态,在调整配置那些配置文件时,经常需要重启以及文件创建,博客可不想把自己的系统搞得乱七八糟,即使博主已经做了系统备份。当然,你也可以不使用DOCKER环境去部署这些服务而直接部署在本地主机上,这完全是没问题的,这种方式下想实现快速部署,那么你可能需要使用到Ansible,这是题外话了……
以下为DOCKER环境下,选用Jenkins官方镜像部署Jenkins服务的方法;关于DOCKER的安装我写过了,DOCKER使用国内镜像源加速下载的方法也写过了[应该写过吧],本处也就不再次重复了;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
docker pull jenkins/jenkins:2.235.3-lts-alpine # 下载“jenkins/jenkins:2.235.3-lts-alpine”镜像; # 你可以至DOCKER-HUB去查找你希望使用的镜像; # 注意:Jenkins官方提供了非常多的镜像,那些较新的版本是用于测试的, # 不兼容当前的很多插件,建议下载“2.235.x-lts”的版本, # 这是官方当前最新长期支持的稳定版本; sudo mkdir /var/jenkins_local && sudo chown 0:0 /var/jenkins_local # 创建一个用于存放数据的目录; docker run -itd -v /var/jenkins_local:/var/jenkins_home -p 8080:8080 -p 50000:50000 --name jenkins_local jenkins/jenkins:2.235.3-lts-alpine # 运行镜像并创建Jenkins服务; # -itd :等同"-i"、"-t"、"-d"; # -d :守护进程方式运行; # -v :本地目录/文件挂载至DOCKER容器内的对应目录/文件; # -p :端口影射关系; # --name :指定容器名称; docker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:2.235.3-lts-alpine # 之前的方法指定了一些参数,这基本是部署一个准备长期使用时所使用的方法; # 但如果你不明白这一系列参数/选项的意义,也可以使用这个官方说明中最基本的启用方案; |
以上介绍了在Docker环境下,Jenkins服务的部署方法,当然,这些东西毫无意义~我们真正在意的是插件下载的的稳定加速方法~
三、利用NGINX实现插件加速下载[镜像篇]
插件加速下载最简单的方法是使用国际代理,仅需要在Jenkins服务的配置页面设定一下代理服务器的地址与端口即可。但显然,并不是所有人都能拥有或搭建一个速度尚可的国际代理服务器,使用国内Jenkins插件镜像源实现插件的下载与更新,对大部分人来说,可能是更实在的选择。本示例将介绍如何建立自己的镜像文件,并使用Jenkins的清华镜像源,实现Jenkins插件在国内的加速下载。
本处介绍一下原理,首先,在Jenkins服务的WEB配置页面中指定插件的下载/更新地址为清华的镜像源["https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json"],再利用NGINX服务的反向代理功能,在插件真正下载时,修改了插件的实际下载地址[下载地址指向清华的镜像源],实现插件下载加速,用黑客一点的话来说,就是域名劫持~也许你有疑问,为什么要使用NGINX?为什么网上大部分关于JENKINS插件下载的加速方案均有修改下载/更新地址为清华镜像源,而这一种方式就无法实现插件下载的加速?关于这些问题,见本博文最后的参考文章链接。
要利用NGINX实现插件加速下载,首先要存在NGINX服务,Jenkins官方提供的"jenkins/jenkins:2.235.3-lts-alpine"镜像默认只部署了Jenkins服务,所以在考虑我们的真正需求后,我们就必需对"jenkins/jenkins:2.235.3-lts-alpine"进行一些修改操作,修改的内容大概为:为镜像安装NGINX服务、设定NGINX配置文件、修改镜像启动脚本[加入NGINX服务的启动]、修改"hosts"文件用于域名劫持[需要配合NGINX服务实现];以上的四个操作,本示例会利用一个DockerFile文件完成镜像的构建,所以第一步,我们需要先写好NGINX的配置文件[这份文件需要复制至镜像内,所以需要先设定好];
1、创建并配置NGINX配置文件[ 参考命令:touch nginx.conf && nano nginx.conf ],以下为"nginx.conf"文件的配置内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
user root; worker_processes auto; pcre_jit on; error_log /dev/null; include /etc/nginx/modules/*.conf; #daemon off; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; server_tokens off; client_max_body_size 0; keepalive_timeout 65; sendfile on; tcp_nodelay on; #tcp_nopush on; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:2m; #ssl_dhparam /etc/ssl/nginx/dh2048.pem; gzip on; gzip_vary on; #gzip_static on; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log off; include /etc/nginx/conf.d/*.conf; # 关键就是这一部分的内容了,本处将"mirrors.jenkins-ci.org" # 代理到了"https://mirrors.tuna.tsinghua.edu.cn/jenkins/"; # 当然,要实现域名支持,本处还需要"hosts"文件的帮助, # 需要将"mirrors.jenkins-ci.org"的DNS解释定义至本地主机, # 即向"hosts"文件添加"127.0.0.1 mirrors.jenkins-ci.org"的内容; server { listen 80; server_name mirrors.jenkins-ci.org; location / { proxy_redirect off; proxy_pass https://mirrors.tuna.tsinghua.edu.cn/jenkins/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Accept-Encoding ""; #proxy_set_header User-Agent "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.49 Safari/537.36"; proxy_set_header Accept-Language "zh-CN"; } index index.html index.htm index.php; #error_page 404 /404.html; location ~ /\. { deny all; } } } |
以上"nginx.conf"文件的配置,基本和默认生成的"/etc/nginx/nginx.conf"文件相同,但还是应所使用的基础镜像文件的实际情况[jenkins/jenkins:2.235.3-lts-alpine],进行了一些配置项的修改,大概为:修改了NGINX服务的运行用户、禁用了NGINX的日志功能、解除的文件上传大小的限制、启用了GZIP压缩功能;当然,当中最重要的修改就是加入了"server"块,见上面代码中的关于"server"块的说明;
2、编写DockerFile文件,[ 参考命令:touch jenkins_nginx.df && nano jenkins_nginx.df ],以下为"jenkins_nginx.df"文件的配置内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# escape = \ (backslash) FROM jenkins/jenkins:2.235.3-lts-alpine # 指定所使用的基础镜像 USER root # 指定执行RUN的用户 RUN sed -i 's#dl-cdn.alpinelinux.org#mirrors.aliyun.com#g' /etc/apk/repositories \ # 修改APK的软件源为国内 && apk update && apk add --no-cache nginx && mkdir /run/nginx \ # 更新软件源、安装NGINX并创建必要的目录 && sed -i 's#exec java#nginx \&\& exec java#g' /usr/local/bin/jenkins.sh \ # 向默认的启动脚本中增加NGINX的启动项 && sed -i "1 i 127.0.0.1 mirrors.jenkins-ci.org" /etc/hosts # "hosts"文件修改以配合域名劫持 COPY --chown=0:0 ./nginx.conf /etc/nginx/nginx.conf # 复制之前配置好的"nginx.conf"文件至容器内 HEALTHCHECK --interval=5m --timeout=3s CMD curl --fail -s http://127.0.0.1:8080/login || exit 1 # 错误修正:2020.08.08 # 错误位置:第 7 行 # 原文:&& echo "127.0.0.1 mirrors.jenkins-ci.org" >> /etc/hosts # 修正:&& sed -i "1 i 127.0.0.1 mirrors.jenkins-ci.org" /etc/hosts # 修正说明:此前未注意Dockerfile的"RUN"指令在使用重定向符[">>"]时,应使用某种的特定语法, # 遗漏"sed"命令的"-i"参数[2021.08.13] # 因语法错误,造成本处的域名解释未正确写入"/etc/hosts"文件,造成域名劫持加速失效, # 本博文所提供的下载文件未更新对应代码!!!! |
以上DockerFile文件的编写,到底做了什么,这不在本示例的说明范围内,毕竟这不是篇关Docker的文章,但博主也尽可能的作了一些简单说明。以上DockerFile文件中,比较可能需要产生变化的是"RUN"部分,毕竟这是对镜像内的文件进行了一系列的操作;而更更可能产生变化的是第六行[即向默认的启动脚本中增加NGINX服务的启动项],这是对镜像的默认启动脚本的修改,日后若官方对镜像中脚本进行了修改,那么本处的修改将可能引发不可预期的错误,若日后官方的镜像真的修改了此启动脚本造成了本项修改无效/错误,请依据自己的SHELL知识修改此行的命令;
3、当以上两份文件创建完成后,我们就可以生成自己的镜像文件了,并利用新生成的镜像去部署Jenkins服务的容器了,相关命令如下:
1 2 3 4 5 6 7 8 9 10 |
docker build -f jenkins_nginx.df -t lemonsys/jenkins_nginx:v1.0 . # 利用"jenkins_nginx.df"文件创建名为"lemonsys/jenkins_nginx:v1.0"的镜像; # 注意:别忘记了最后那个"."; docker run -p 8080:8080 -p 50000:50000 lemonsys/jenkins_nginx:v1.0 # 利用新创建的镜像去运行Jenkins容器[最基本的方式]; # 本处命令仅供参考,真正的使用见下一节“使用篇” # 其它参考命令:镜像删除 # docker rmi lemonsys/jenkins_nginx:v1.0 |
注意:以上代码并没有任何错误,但严重不建议以复制粘贴的方式创建相关文件,建议下载本文所提供的文件然后进行修改;下载链接 --> jenkins_nginx.tar.gz
1 2 3 4 5 6 7 8 |
Edward@FionaEye:~ $ tar -zxf jenkins_nginx.tar.gz -C ./ Edward@FionaEye:~ $ tree jenkins_nginx jenkins_nginx ├── jenkins_nginx.df └── nginx.conf 0 directories, 2 files Edward@FionaEye:~ $ |
原因:使用复制粘贴的方式复制配置至文件内,所有空格的前面将可能存在不可见的字符"M-BM-",造成文件不可用,这是字符编码的问题~若必需使用复制粘贴方式,请务必手动替换掉配置项中的所有空格!!!或使用以下命令过滤掉所有"M-BM-"字符~
1 2 3 4 |
sed 's/\xc2\xa0/ /g' -i [文件名称] # LINUX下可使用以下命令查看不可见字符的情况 cat -A [文件名称] |
四、利用NGINX实现插件加速下载[使用篇]
为什么有使用篇,原因是:即使本处已经利用了本文中的方法,安装了NGINX服务并修改了一些相应的文件实现了对"mirrors.jenkins-ci.org"域名进行了劫持[劫持到"https://mirrors.tuna.tsinghua.edu.cn/jenkins/"],但Jenkins的默认"jenkins.war"应用包中默认的插件安装/更新源是"https://updates.jenkins.io/update-center.json",所以当我们初次部署Jenkins服务时,是没办法使用插件加速下载的,所以正确的使用方法如下[包含了一些常用的额外操作]:
1、利用新建的镜像创建并部署Jenkins服务;
1 2 3 4 5 |
sudo mkdir /var/jenkins_local # 创建"jenkins_local"目录用于保存相关数据; sudo docker run -itd -v /var/jenkins_local:/var/jenkins_home -p 8080:8080 -p 50000:50000 --name jenkins_server lemonsys/jenkins_nginx:v1.0 # 利用新创建的镜像去运行Jenkins容器; |
2、在浏览器上通过"http://192.168.100.250:8080"访问JENKINS服务[IP地址按自己实际情况填写];注意:JENKINS服务创建初始的服务程序文件可能需要较长时间,请耐心等待;
3、JENKINS服务相关文件创建完成时,需要输入初始化密码以进行JENKINS服务的配置[见下图];
4、通过以下命令获取初始化密码并从WEB界面填入,之后进入插件配置界面;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
sudo docker logs jenkins_server # 用此方法获取初始化密码一般情况下是可以的,也是建议的, # 但毕竟此方法是使用DOCKER对容器的日志记录功能获取初始化密码, # 此方法存在的问题是,若长时间启动了JENKINS容器,随着容器的日志的 # 增加,初始化密码可能变得不再可见; sudo docker exec -it jenkins_server cat /var/jenkins_home/secrets/initialAdminPassword # 此方法为读取容器内的对应的初始化密码文件来获取密码; # 但不建议使用,原因是在容器内使用命令,将会产生命令操作记录, # 这将会对镜像内的文件产生变更,这会让DOCKER服务生成一个额外的卷, # 以记录这样变更,这也是上面NGINX服务,博主关闭其日志功能的原因; sudo cat /var/jenkins_local/secrets/initialAdminPassword # 如果JENKINS容器的创建过程中使用了"-v"指定了数据的存放位置, # 如本示例,强烈建议使用本方法获取初始化 |
5、插件安装选项选择"选择插件来安装"[不要选择"安装推荐的插件",此时并不能加速插件的下载],并点击"无"表示不安装任何插件,确认末选择任何插件的情况下,然后点击"安装"进入下一步;
6、配置管理员用户的用户名与密码;本示例指定了用户名与密码均为:admin;选择"保存并完成"进入下一步;
7、配置JENKINS服务的URL地址,保持默认值即可,点击"保存并完成"进入下一步后,选择"开始使用Jenkins";
8、以管理员登录JENKINS服务并配置插件的更新源为清华的插件源;默认值为"https://updates.jenkins.io/update-center.json",替换为"https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json";
9、在进行完上述操作后,已经可以通过域名劫持的方法来进行插件的下载/安装了,而且,镜像是通用的[当然还是区分ARM与X86架构的],当需要在其它服务器上部署JENKINS服务时,只需要利用这个镜像重复上述使用操作即可;
10、附图:为JENKINS默认建议安装的插件列表;
五、参考文章
参考文章:《jenkins 插件下载加速最终方案》
六、结语
无~END~
JENKINS服务部署与插件反向代理加速下载方案:等您坐沙发呢!