Fuhui

Jenkins分布式实现


思路

查看jenkins源代码,把jenkins依赖单机的代码内容,修改为依赖分布式机器的内容; 这样做到应用本身无存储状态,容器化后可以做到随便创建和删除。参阅jenkins's blog

jenkins开发相关知识Extend Jenkins开发者文档

  1. jenkins本身开发指导说明

    • java8
    • mavne>=3.5.3
    • OpenJDK
  2. jenkins插件开发指导说明

  3. 快速打包jenkins.war,The WAR file will be created in war/target/jenkins.war

  4. jenkins启动

  5. intellij idea远程调试jenkins

  6. Becoming a Jenkins contributor: Newbie-friendly tickets

  7. docker打包jenkins

    mvn clean package -pl war -am -DskipTests -Dfindbugs.skip 目前来看主要涉及jobs/workspace内容等

jenkins相关知识点

  1. Blue Ocean重新定义jenkins的用户体验,侧重pipeline:https://jenkins.io/zh/doc/book/blueocean/
  2. 把jenkins的slave/agent的内容存储到其他存储系统,从而降低master和slave的通信压力:https://jenkins.io/zh/blog/2018/09/10/scaling-network-connections/
  3. jenkins的k8s使用:https://jenkins.io/zh/blog/2018/09/14/kubernetes-and-secret-agents/
  4. jenkins的python支持:https://jenkins.io/zh/solutions/python/
  5. hudson和jenkins的区别就是mysql和mariadb的区别,前者被oracle收购后,开发团队就开发了后者
  6. 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)
  7. Jenkins中文社区

分布式部署实现

  1. 关于Jenkins master共享JENKINS_HOME目录的实验验证了当前的jenkins在 分布式部署时的问题:通过共享强依赖的单机目录(k8s上实现多个容器挂载相同的目录,可以借助ceph分布式存储),无法实现
  2. 针对上面实验出现的问题,阅读jenkins源代码,看是否可以通过修改Jenkins应用的源代码解决
  3. 首先解决job相关的分布式实现,其次解决插件相关的分布式实现,还有Jenkins配置相关的分布式,或许通过配置本地化存储修改为远端数据库存储解决分布式问题

疑问

调试jenkins源代码

  1. 根据源代码生成jenkins.war包

  2. debug模式启动jenkins

     java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 -jar war/target/jenkins.war --httpPort=8081
    
  3. 使用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的步骤

  1. 先删除job下的config.xml文件
  2. 再递归删除其他文件和目录

实验结果

jenkins源码主要依赖包说明

  1. org.jenkins-ci:executable-war:1.45源码 执行main依赖

  2. org.jenkins-ci:winstone:5.3 源码只包含winstone部分,打包的时候,把org.eclipse.jettyjavax.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
    
  3. org.jenkins-ci:task-reactor:1.5 主要是执行各种任务:加载jobs/加载plugins/准备jenkins全局环境等

  4. org.jenkins-ci.main:remoting:3.33 主要是和远程slave通信,执行远程操作

  5. org.jenkins-ci:commons-jelly: 主要是jenkins前端展示相关

  6. org.jvnet.hudson:xstream: 主要是读写jenkins的job的config.xml配置相关

  7. org.kohsuke.stapler:stapler: 主要是处理jenkins的请求和响应相关

  8. 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