Jenkins分布式实现
思路
查看jenkins源代码,把jenkins依赖单机的代码内容,修改为依赖分布式机器的内容; 这样做到应用本身无存储状态,容器化后可以做到随便创建和删除。参阅jenkins's blog
jenkins开发相关知识Extend Jenkins、开发者文档
-
- java8
- mavne>=3.5.3
- OpenJDK
-
- step 1: Preparing for Plugin Development
- step 2: Create a Plugin
- step 3: Build and Run the Plugin
- step 4: Extend the Plugin
- Plugin tutorial
- Plugin Cookbook
- Create a new Plugin with a custom build Step
- Plugin Structure
- Making your plugin behave in distributed Jenkins
- IntelliJ IDEA plugin for Stapler方便在idea里开发jenkins的插件
- Exposing data to the remote API
- Manage global settings and tools installations
- Debugging native Maven jobs
- Remote debugging a Java application
-
快速打包jenkins.war,The WAR file will be created in war/target/jenkins.war
-
mvn clean package -pl war -am -DskipTests -Dfindbugs.skip 目前来看主要涉及jobs/workspace内容等
jenkins相关知识点
- Blue Ocean重新定义jenkins的用户体验,侧重pipeline:https://jenkins.io/zh/doc/book/blueocean/
- 把jenkins的slave/agent的内容存储到其他存储系统,从而降低master和slave的通信压力:https://jenkins.io/zh/blog/2018/09/10/scaling-network-connections/
- jenkins的k8s使用:https://jenkins.io/zh/blog/2018/09/14/kubernetes-and-secret-agents/
- jenkins的python支持:https://jenkins.io/zh/solutions/python/
- hudson和jenkins的区别就是mysql和mariadb的区别,前者被oracle收购后,开发团队就开发了后者
- jenkins api介绍 里面介绍了推荐的python和java封装好的api;同时jenkins信息的获取是通过xpath获取的,比如通过http://127.0.0.1:8080/api/json?depth=1 或者http://127.0.0.1:8080/api/xml?depth=1可以获取一些较少的关键信息,通过http://127.0.0.1:8080/api/json?tree=jobs[name]{0,12} 或者http://127.0.0.1:8080/api/xml?tree=jobs[name]{0,12}可以获取前12个job的信息(这里tree=jobs[name]使用了xpath过滤);每项任务的操作,在web界面上可以 看到链接;授权采用的是基本授权(Basic Auth)
- Jenkins中文社区
分布式部署实现
- 关于Jenkins master共享JENKINS_HOME目录的实验验证了当前的jenkins在 分布式部署时的问题:通过共享强依赖的单机目录(k8s上实现多个容器挂载相同的目录,可以借助ceph分布式存储),无法实现
- 针对上面实验出现的问题,阅读jenkins源代码,看是否可以通过修改Jenkins应用的源代码解决
- 首先解决job相关的分布式实现,其次解决插件相关的分布式实现,还有Jenkins配置相关的分布式,或许通过配置本地化存储修改为远端数据库存储解决分布式问题
疑问
- jenkins是不是把job等信息全部存入内存?因为jenkins不使用数据库,内容全部落磁盘,把磁盘的部分或者全部信息落入内存,无疑可以加快速度
调试jenkins源代码
-
根据源代码生成jenkins.war包
-
debug模式启动jenkins
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 -jar war/target/jenkins.war --httpPort=8081
-
使用idea开启远程调试
1. 第一句日志目前不知道从哪儿打印的? Listening for transport dt_socket at address: 8000 2. 接下来的日志是 [org.jenkins-ci:executable-war:1.45](https://github.com/jenkinsci/extras-executable-war) 的 `Main.java` 的 `main` 函数输出的,既可以认为这是程序的入口 3. 接着会调用org.jenkins-ci:winstone:5.3到Launcher.java启动jetty服务 4. 接着调用jenkins/core/src/main/java/hudson/WebAppMain.java,主要是Creates the sole instance of {@link jenkins.model.Jenkins} and register it to the {@link ServletContext}. 5.
删除job的步骤
- 先删除job下的config.xml文件
- 再递归删除其他文件和目录
实验结果
-
job的日志是每次从磁盘加载的,不存内存,根据project名字,去磁盘里检索
检索路径格式:项目名字/builds/构建号/log 举例:demo/builds/1/log
-
job的日志是每次从磁盘加载的,不存内存
jenkins源码主要依赖包说明
-
org.jenkins-ci:executable-war:1.45
源码 执行main依赖 -
org.jenkins-ci:winstone:5.3
源码只包含winstone部分,打包的时候,把org.eclipse.jetty
和javax.servlet
也打包进去Winstone is a command line interface around Jetty 9.4, which implements servlet 3.1, WebSocket/JSR-356, and HTTP/2 support. It is used as the default embedded servlet container in Jenkins (via executable-war module) and can be used by any other web applications that wants to be self-contained
-
org.jenkins-ci:task-reactor:1.5
主要是执行各种任务:加载jobs/加载plugins/准备jenkins全局环境等 -
org.jenkins-ci.main:remoting:3.33
主要是和远程slave通信,执行远程操作 -
org.jenkins-ci:commons-jelly:
主要是jenkins前端展示相关 -
org.jvnet.hudson:xstream:
主要是读写jenkins的job的config.xml配置相关 -
org.kohsuke.stapler:stapler:
主要是处理jenkins的请求和响应相关 -
org.kohsuke.stapler:stapler-jelly:
主要是jenkins前端展示相关的补充
参与jenkins建设
注册jenkins的wiki和jira账号,为同一个账号 https://wiki.jenkins.io/#all-updates https://issues.jenkins-ci.org/browse/JENKINS-58948?filter=-4