分布式构建

Jenkins 分布式概述

  • Jenkins 可以部署在多个节点上 以实现分布式构建的效果;
  • 其节点可划分主节点(master)和 代理节点(agent)两种类型;

主节点

  • 主节点负责提供UI、处理HTTP请求及管理构建环境等

  • Jenkins的一个部署实例的核心控制系统,它能够完全访问所有Jenkins配置的选项和任务(job)列表,而且,若不存在其他代理节点,主节点也是默认的任务执行节点;

代理节点

  • 代理节点则主要负责执行构建任务

  • 在早先版本的Jenkins中,代理节点(agent)也被称为从节点(slave),它代表着所有的非主节点;

  • 这类节点由主节点管理,按需分配或指定执行特定的任务 ,例如不同的构建任务或测试任务等

  • 脚本式流水线中,节点特指一个运行代理节点的系统,而在声明式流水线中,它则是分配的一个来作为代理节点的特定节点

执行器(Executor)

  • 简单来说,Executor 只是节点或代理节点用于执行任务的一个槽位;
  • Executor 的数量定义了该节点可以执行的并发任务量,一个节点上可以有任务数量的槽位,但也允许管理员按节点资源定义合适的数量
  • 在主节点将任务分配给特定节点时,该节点上必须有可用的Executor来立即执行该任务,否则,只能等到有空闲槽位可用

节点标签

  • Jenkins中的标签(tag)指的是附加在节点之上的标识符,而后可由pipeline中的agent指令等进行过滤和选择;
  • agent节点较多时,出于便捷管理之需,通常应该给这些节点添加能够暴露其某种特性或功能的标签,以便于在构建任务中能基于标签过滤出符合条件的agent来;
    • 一个agent上可附加多个标签
    • 标签名称不允许使用空白字符,也不允许使用标签表达式中预留的关键字,例如!、&、|、<、>、) 和 ( 等;
  • 常用的标签纬度有如下几个:
    • 操作系统类型:linux、windows、macos等;
    • 系统位数:32bit、64bit;
    • 集成的工具链:jdk、go、python、nodejs等;

Master & Agent 的连接方式

为了能让 master 将一个主机识别为 agent,需要事先在各 agent 上运行特定的代理程序以使得其能够与master 之间建立双向通信,有多种方法实现 master 与 agent 之间的连接建立:

SSH连接器

  • 首选且最稳定的双向连接机制,它依赖于Jenkins内置的SSH客户端,并要求各agent要部署并启动了SSH服务;
  • 支持基于密钥及口令的两种认证方式,但认证信息要保存为master之上的凭证;
    • 基于密钥认证时,master主机上私钥凭证对应的公钥要存在于各agent主机之上;

Inbound连接器

  • 在agent上以手动或系统服务的方式经由JNLP协议触发双向连接的建立;

JNLP-HTTP连接器

  • 在agent上经由JNLP协议通过HTTP建立双向连接;

Jenkins 分布式实现

master 配置

Jenkins Dashboard –> 系统管理 –> 节点管理 –> 新建节点

  • **节点名称:**例如:jenkins-agent01.xiangzheng.com
    • 节点名称是正在添加的agent节点的标识,仅用于标识该agent ;
  • 固定节点 √
  • create

  • **Number of executors:**例如:2

    • 执行器数量,可以简单设置为小于等于节点上CPU核心数的整数值;
    • agent 节点必须至少拥有一个执行器(如需暂时阻止其执行构建,请使用其页面右上方的临时断开此节点按钮)
    • master 节点设置执行器的数目为零将会阻止构建在其上执行
  • **远程工作目录:**例如:/appdata/jenkins/work

    • 在 agent 节点上授权 Jenkins 使用的工作目录,建议使用绝对路径;
    • 该目录为 agent 上的 Jenkins 实例为响应 master 发来构建任务而专用的工作目录;
  • **标签:**例如:agent01

    • 节点标识
  • **用法:**例如:尽可能的使用这个节点

    • 控制Jenkins如何在这台机器上安排构建任务.

      • 尽可能的使用这个节点

        这是默认和常用的设置. 在这种模式下,Jenkins会尽可能的使用这个节点.任何时候如果一个构建能使用这个节点构建,那么Jenkins就会使用它.

      • 只允许运行绑定到这台机器的Job

        这种模式下,Jenkins只会构建哪些分配到这台机器的Job. 这允许一个节点专门保留给某种类型的Job.例如,在Jenkins上连续的执行测试,你可以设置执行者数量为1,那么同一时间就只会有一个构建, 一个实行者不会阻止其它构建,其它构建会在另外的节点运行.

  • **启动方式:**例如:Launch agents via SSH

    • master 识别该 agent 主机并与其建立双向连接的方式;
    • 选定连接方式后,需要给定该方式下的具体配置;
      • Launch agents via SSH:若 master 基于 ssh 连接器连接至目标 agent 之上,且基于 jenkins 节点的用户及密码进行认证,则需要在 master上添加相应的Credential,而后添加使用的凭据;
        • 类型:userame with password
        • 范围:全局
        • 用户名:例如:jenkins(此处为agent节点上ssh登录的用户名)
        • 密码:(agent节点ssh登录用户名对应的密码)
        • ID:例如:jenkins-agent01-ssh-connection
        • 描述:例如:jenkins-agent01-ssh-connection
  • **可用性:**例如:尽量保持代理在线

    • master 与 agent 间的连接保持机制;
  • **节点属性:**这里可以选择将master节点的工具等内容同步到agent节点

agent 配置

agent 节点安装完 Jenkins 后,假设 master 节点的启动方式选择为 Launch agents via SSH

准备工作目录

# mkdir -p /appdata/jenkins/work/

# chown -R jenkins.jenkins /appdata/jenkins

开启ssh登录

# usermod -s /bin/bash jenkins

# passwd jenkins

测试在 agent 上执行任务

pipeline {
    agent {
        label "agent01" // 根据标签来指定执行构建任务的agent
    }
    stages {
        stage('ShowAgent') {
            steps {
                echo "The node: ${env.NODE_NAME}."
                echo "The node label: ${env.NODE_LABELS}."
            }
        } 
        stage('Checkout') {
            steps {
                echo "Fetch codes from SCM..."
            }
        }
        stage('Build') {
            steps {
                echo "Building..."
            }
        }
    }
    post {
        always {
            mail to: 'sredevops@163.com',
            subject: "Status of pipeline ${currentBuild.fullDisplayName}",
            body: "${env.BUILD_URL} has result ${currentBuild.result}"
        }
    }
}