实习日志(第六周2)

本文详细介绍了 Jenkins 的几个常用插件,包括 Subversion Plugin 的后提交钩子功能,Kerberos SSO 插件的用户认证机制,CloudBees Folders Plugin 对项目组织的管理,Promoted Builds 插件如何区分优质构建,以及 Dingding Notification 和 Dingding Json Pusher 插件在构建通知和复杂消息推送中的应用。

jenkins常用插件补充

1. Subversion Plugin
  1. Jenkins可以拉取Subversion存储库进行更改,这只能发生在每分钟一次,所以您可能还需要等待一整分钟才能发现更改。为了减少这种延迟,可以设置一个后提交钩子,以便Subversion存储库可以在对该存储库进行更改时通知Jenkins。 为此,请将以下脚本放在您的后提交文件($ REPOSITORY / hooks目录)中:
REPOS="$1"
REV="$2"
UUID=`svnlook uuid $REPOS`
/usr/bin/wget \
  --header "Content-Type:text/plain;charset=UTF-8" \
  --post-data "`svnlook changed --revision $REV $REPOS`" \
  --output-document "-" \
  --timeout=2 \
  http://server/subversion/${UUID}/notifyCommit?rev=$REV
  # 请注意rev = $ REV参数,这告诉Jenkins准确检查挂钩报告的修订版本。 如果您的工作有多个Subversion模块位置定义,这可能导致检出不一致 - 所以建议在这种情况下不要使用'?rev = $ REV'。
  ```
  如果您的Jenkins使用“防止跨站点请求伪造攻击”安全选项,则上述请求将被拒绝403错误(“未包含有效碎屑”)。 该请求中需要的碎屑可以从URL http:// server / crumbIssuer / api / xml(或/ api / json)获取。 这可以包含在上面的wget调用中,如下所示:
  ```
  --header `wget -q --output-document - \
  'http://server/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'`
  ```
  由于wget默认情况下重试次数不超过给定超时时间为20次,所以在慢速SVN服务器上的--timeout = 2可能会导致Jenkins扫描存储库多次,进一步减缓SVN服务器一段时间后,使詹金斯没有反应。
  此问题的可能解决方案是增加超时时间,使用参数-retries = 3添加更低的最大重试次数,或者通过添加2>&1&last而使wget调用异步(从而忽略任何通信错误) wget调用。超时太低可能导致您的提交挂起并抛出502错误,如果您在代理后面,或提交后错误,如果没有。 增加超时,直到不再看到wget重试。
  ```
  #!/bin/sh
  REPOS="$1"
  REV="$2"

  # No environment is passed to svn hook scripts; set paths to external tools explicitly:
  WGET=/usr/bin/wget
  SVNLOOK=/usr/bin/svnlook

  # If your server requires authentication, it is recommended that you set up a .netrc file to store your username and password
  # Better yet, since Jenkins v. 1.426, use the generated API Token in place of the password
  # See https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients
  # Since no environment is passed to hook scripts, you need to set $HOME (where your .netrc lives)
  # By convention, this should be the home dir of whichever user is running the svn process (i.e. apache)
  HOME=/var/www/

  UUID=`$SVNLOOK uuid $REPOS`
  NOTIFY_URL="subversion/${UUID}/notifyCommit?rev=${REV}"
  CRUMB_ISSUER_URL='crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'

  function notifyCI {
    # URL to Hudson/Jenkins server application (with protocol, hostname, port and deployment descriptor if needed)
    CISERVER=$1

    # Check if "[X] Prevent Cross Site Request Forgery exploits" is activated
    # so we can present a valid crumb or a proper header
    HEADER="Content-Type:text/plain;charset=UTF-8"
    CRUMB=`$WGET --auth-no-challenge --output-document - ${CISERVER}/${CRUMB_ISSUER_URL}`
    if [ "$CRUMB" != "" ]; then HEADER=$CRUMB; fi

    $WGET \
        --auth-no-challenge \
        --header $HEADER \
        --post-data "`$SVNLOOK changed --revision $REV $REPOS`" \
        --output-document "-"\
        --timeout=2 \
        ${CISERVER}/${NOTIFY_URL}
  }

  # The code above was placed in a function so you can easily notify multiple Jenkins/Hudson servers:
  notifyCI "http://myPC.company.local:8080"
  notifyCI "http://jenkins.company.com:8080/jenkins"
  ```
  如果您的服务器上启用了上述脚本,则会处理“防止跨站点请求伪造漏洞”选项。 如果您没有启用该选项,额外的wget调用是无害的,但如果您不需要,可随意删除它。 上述脚本还要求您将运行subversion的用户的主目录中的.netrc文件设置为(svnserve进程或httpd)。 有关.netrc文件语法的更多信息,请看这里。 上面的脚本可以轻松地向多个Jenkins服务器通知相同的SVN提交。 如果你有一个.netrc文件,即使他们有不同的管理用户设置,它也很容易。 如果您不想混淆.netrc文件,您可以在文件中硬编码用户和密码(或API Token)信息,并将--username = user和--password =“pass”标志添加到 wget调用。

#### 2. Jenkins Master/Slave架构
1. 当自动化测试用例需要在多个PC机或虚拟机中执行时,如果在每个虚拟机中均搭建类似tomcat+jenkins的环境,将会造成例如每台虚拟机资源占用大、对环境的配置维护成本大等弊端,此时,就可以采用Jenkins分布式构建方式了。<br>
远程工作目录:指定远程中的节点机器的工作目录,即Job中checkout出的代码所在的workspace目录<br>
标签:该节点的唯一标识,当在Job中要指定只在该节点进行构建与测试时,通过该唯一标识进行指定
1. Jenkins slave开机自启动
  1. 若要对所用用户均进行开机自启动,则将.bat启动文件的快捷方式放入 ‘\Documents and Settings\All Users\“开始”菜单\程序\启动’目录下
  1. 若只要对指定用户进行开机自启动,则将.bat启动文件的快捷方式放入 ‘\Documents and Settings\ <用户名字>\“开始”菜单\程序\启动’目录下
1. Jenkins节点监控
jenkins节点由于系统运行、网络环境等各种因素,难免会出现系统挂机、节点掉线等情况,因此要想及时发现这些情况,就需要对节点进行监控,
可以采用这里推荐的监控并重连机制:https://wiki.jenkins-ci.org/display/JENKINS/Monitor+and+Restart+Offline+Slaves
  1. 由于jenkins节点监控使用的是groovy脚本调用的jenkins内部api,因此需要先安装groovy plugin插件
  1. 在Master中新建一个名字为如monitor的job,设置为例如每30分钟运行一次。
  1. 新增Excute system Groovy script构建步骤:
<span style="font-size: 13px;">import hudson.model.*  
import hudson.node_monitors.*  
import hudson.slaves.*  
import java.util.concurrent.*  
jenkins = Hudson.instance
import javax.mail.internet.*;  
import javax.mail.*  
import javax.activation.*  
def sendMail (slave, cause) {  
//这里使用的是参数化构建中的变量,如果不使用此方式,可以注释掉,而使用下面的toAddress  
toAddress = build.buildVariableResolver.resolve("EMAIL_RECEIVERS")  
message = slave + " slave is down. Check http://192.168.10.181:8080/jenkins/computer/" + slave + "\nBecause " + cause  
subject = "【jenkins节点监控】" + slave + " slave is offline"  
//toAddress = "***@***.com;***@***.com"  
fromAddress = "***@***.com"  
host = "SMTP_SERVER"  
port = "SMTP_PORT"  
Properties props = new Properties();  
// 发送邮件的服务器  
props.setProperty("mail.smtp.host", "smtp.***.com");  
// 发送邮件的协议  
props.setProperty("mail.transport.protocol", "smtp");  
// 在连接服务器的时候是否需要验证,发邮件是需要验证的  
props.setProperty("mail.smtp.auth", "true");  
// 当需要进行验证的时候,会自动从Session中去取该Authenticator对象  
Authenticator authenticator = new Authenticator() {  
@Override  
protected PasswordAuthentication getPasswordAuthentication() {  
 return new PasswordAuthentication("your user name", "your passwd"); //输入用户名、密码  
}  
};  
Session lSession = Session.getInstance(props,authenticator);  
MimeMessage msg = new MimeMessage(lSession);  
//tokenize out the recipients in case they came in as a list  
StringTokenizer tok = new StringTokenizer(toAddress,";");  
ArrayList emailTos = new ArrayList();  
while(tok.hasMoreElements()){  
emailTos.add(new InternetAddress(tok.nextElement().toString()));  
}  
InternetAddress[] to = new InternetAddress[emailTos.size()];  
to = (InternetAddress[]) emailTos.toArray(to);  
msg.setRecipients(MimeMessage.RecipientType.TO,to);  
InternetAddress fromAddr = new InternetAddress(fromAddress);  
msg.setFrom(fromAddr);  
msg.setFrom(new InternetAddress(fromAddress));  
msg.setSubject(subject);  
msg.setText(message)  
Transport transporter = lSession.getTransport("smtp");  
transporter.connect();  
transporter.send(msg);  
}  
def getEnviron(computer) {  
def env  
def thread = Thread.start("Getting env from ${computer.name}", { env = computer.environment })  
thread.join(2000)  
if (thread.isAlive()) thread.interrupt()  
env  
}  

def slaveAccessible(computer) {  
getEnviron(computer)?.get('PATH') != null  
}  
def numberOfflineNodes = 0  
def numberNodes = 0  
for (slave in jenkins.slaves) {  
def computer = slave.computer  
numberNodes ++  
println ""  
println "Checking computer ${computer.name}:"  
def isOK = (slaveAccessible(computer) && !computer.offline)  
if (isOK) {  
 println "\t\tOK, got PATH back from slave ${computer.name}."  
 println('\tcomputer.isOffline: ' + slave.getComputer().isOffline());   
 println('\tcomputer.isTemporarilyOffline: ' + slave.getComputer().isTemporarilyOffline());  
 println('\tcomputer.getOfflineCause: ' + slave.getComputer().getOfflineCause());  
 println('\tcomputer.offline: ' + computer.offline);
} else {  
 numberOfflineNodes ++  
 println "  ERROR: can't get PATH from slave ${computer.name}."  
 println('\tcomputer.isOffline: ' + slave.getComputer().isOffline());   
 println('\tcomputer.isTemporarilyOffline: ' + slave.getComputer().isTemporarilyOffline());  
 println('\tcomputer.getOfflineCause: ' + slave.getComputer().getOfflineCause());  
 println('\tcomputer.offline: ' + computer.offline);   
 sendMail(computer.name, slave.getComputer().getOfflineCause().toString())  
 if (slave.getComputer().isTemporarilyOffline()) {  
  if (!slave.getComputer().getOfflineCause().toString().contains("Disconnected by")) {  
     computer.setTemporarilyOffline(false, slave.getComputer().getOfflineCause())          
  }  
 } else {  
     computer.connect(true)    
 }  
}  
}  
println ("Number of Offline Nodes: " + numberOfflineNodes)  
println ("Number of Nodes: " + numberNodes)  </span><span style="font-size:14px;">  
</span>

“`

3. Kerberos SSO 插件
  1. 该插件读取用户的Kerberos票证并使用它将用户记录到Jenkins。 它可以与Active Directory插件一起很好地使用。 它还可以重定向在请求中忽略指定域的用户。
  2. 可以通过在请求中设置Bypass-Kerberos头来绕过特定请求的身份验证。 它的价值无关紧要,用户将被认证为匿名的。
  3. 插件可以被配置为允许未经身份验证的请求,并且只有在请求时进行身份验证。 否则,将为每个请求执行身份验证。
    jenkins上进入系统管理>系统配置中进行配置
    kerberos1.png
    在linux服务器上安装指南:

    1. krb5.conf的位置默认为“/etc/krb5.conf”。此外,如果用户在该字段中输入其他信息,并且在该位置找不到该文件,它将返回到“/etc/krb5.conf”以查找该文件。libdefaults部分告诉Spnego在领域中使用哪种加密类型,而领域告诉Spnego密钥分配中心所在的位置。 提供的Kerberos票证的请求被发送到该服务器。Jenkins已读取这个文件的权限是非常重要的!

      [libdefaults]
      default_realm = INTERNALDOMAIN.NET
      default_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5
      default_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5
      preferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5
      
      [realms]
      INTERNALDOMAIN.NET = {
        kdc = 59.169.100.36
        kdc = 7b99:a413:0:ac1b::00:01
        kdc = 7b99:a413:0:ac1b::00:02
        kdc = 7b99:a413:0:ac1b::00:03
      }
    2. Login.conf的位置是设置中最重要的部分,而且是最复杂的。 如果这是错误的指定,Jenkins将立即告诉你一个Servlet异常。 它必须指向名为“login.conf”的服务器上的文件,或通常在文档等中指定“jaas.conf”。 与“krb5.conf”文件一样,Jenkins对此文件的读取权限非常重要!

      Kerberos {
      com.sun.security.auth.module.Krb5LoginModule required
      principal="HTTP/hostname01@INTERNALDOMAIN.NET"
      doNotPrompt="false"
      useTicketCache="false"
      useKeyTab="true"
      keyTab="/etc/krb5.keytab";
      };
      
      spnego-client {
      com.sun.security.auth.module.Krb5LoginModule required;
      };
      
      spnego-server {
      com.sun.security.auth.module.Krb5LoginModule required
      isInitiator="false"
      useKeyTab="true"
      keyTab="/etc/krb5.keytab"
      principal="HTTP/hostname01@INTERNALDOMAIN.NET"
      tryFirstPass="true"
      storePass="true"
      storeKey="true";
      };
      
      com.sun.security.jgss.initiate {
      com.sun.security.auth.module.Krb5LoginModule required
      principal="HTTP/hostname01@INTERNALDOMAIN.NET"
      useKeyTab="true"
      keyTab="/etc/krb5.keytab";
      };
      
      com.sun.security.jgss.accept {
      com.sun.security.auth.module.Krb5LoginModule required
      principal="HTTP/hostname01@INTERNALDOMAIN.NET"
      useKeyTab="true"
      keyTab="/etc/krb5.keytab";
      };
    3. Jenkins对keytab文件的读取权限非常重要!设置服务器时,可能需要在服务器上修改此keytab文件:

      
      # Write the following into a terminal:
      
      
      sudo net ads keytab list
      
      
      # If the server is correctly set up, it the keytab will contain rows looking something like this: HTTP/HOSTNAME01@INTERNALDOMAIN.NET
      
      
      
      # The important part here is the HTTP principal. If it doesn't contain such a row, type the following:
      
      
      sudo net ads keytab add \-P HTTP
      
      
      # Verify with the list command that the keytab now contains HTTP entries.
      

    要注意的一个重要事情是,您的servlet容器(例如Tomcat)需要具有足够的头部大小。 这种情况因环境而异,当事情似乎错误时,并不总是容易发现问题.

4. CloudBees Folders Plugin
  1. 随着项目和团队的数量的增加,Jenkins的相应数量的工作也会增加。 用户发现他们需要组织他们的项目和工作,使他们的管理更容易。 詹金斯不提供内置的功能来满足这一需求。
  2. CloudBees Folders 插件允许您将作业组织到分层文件夹中,就像在文件系统目录中组织文件一样。 这可以让您将相关作业组合在一起,然后可以对特定文件夹中的部门,项目和作业进行分组。 文件夹还可以定义内部作业可见的属性,使您能够简化分支和/或工作流管理。
  3. CloudBees Folders 插件允许您在每个文件夹的基础上设置安全权限(基于角色的访问控制插件)。 角色可以在嵌套文件夹层次结构中继承(或过滤掉)。 例如:工程部门文件夹可以给予所有工程师广泛的权限,但项目Foo子文件夹只允许某些工程师进行修改。
  4. 文件夹然后允许您快速完整地克隆一个文件夹与其子文件夹。
  5. 文件夹是命名空间感知的。 因此,您可以拥有位于不同层级下的相同名称的作业。
5. Promoted Builds插件
  1. 这个插件允许您通过引入promotion“促销”的概念来区分好的构建和坏的构建。简单地说,如果Promoted Builds通过了额外的标准(例如设置为下游作业的更全面的测试)则是一个成功的构建。
  2. 您使用Promoted的典型情况是有多个“测试”作业挂接为“构建”作业的下游作业。
  3. 然后,您将配置构建作业,以便在所有测试作业成功传递时升级构建。这允许您保持构建作业运行速度快(以便开发人员在构建失败时获得更快的反馈),并且您仍然可以与构建编译运行的问题进行区分。
  4. 在构建配置时勾选这个选项
    promoted_builds1.png
  5. promoted builds的例子
    1. 工件存储 - 您可能不想在每个版本上将工件推送到您的主要工件存储库。通过构建促销,只有当工件符合某些标准时,才能推送。例如,您可能只想在运行集成测试后推送它。
    2. Manual Promotions(手动 promotion) - 您可以选择一组可以运行Manual Promotions的人。 这样做可以在构建系统中进行“注销”。 例如,开发人员可以验证一个构建,并且只有在完全完成了工作产品时才批准它进行质量检查。 那么可以再增加一个promotion活动来进行质量保证。
    3. 工件的聚合 - 如果您有一个软件版本由几个不直接相关的工件组成,这些工件位于单独的作业中,则可能需要将经过验证的质量的所有工件聚合到分发位置。 要做到这一点,您可以创建一个新的作业,为每个要聚合的项目添加“从另一个作业复制工件”(可通过“复制工件插件”获得))。要获得一定的升级,请在副本中选择“使用固定链接” 工件步骤,则您的promoted builds应显示在要复制的项目列表中。
6. Dingding Notification 插件

允许用户通过Dingding-钉钉发送构建通知
1. 在钉钉创建一个钉钉机器人
dingding1.png
1. 安装插件后,每个作业都可以添加一个后期制作步骤,选择’叮当通知配置’
dingding2.png
dingding3.png

7. Dingding Json Pusher插件
  1. 允许用户将存储在JSON文件中的复杂消息推送到多个Dingding组。
  2. Dingding支持的任何格式消息都可以由此插件推送。
  3. 支持Jenkins管道。
  4. 支持Jenkins工作DSL。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值