Jenkins的K8s插件:始终在pod

时间:2018-05-31 12:34:26

标签: docker jenkins kubernetes jenkins-plugins

我创建了 Dockerfile (对于Node JNLP 从属,可以与 Jenkins的Kubernetes插件一起使用)。我是从官方图片jenkinsci/jnlp-slave

延伸出来的
FROM jenkinsci/jnlp-slave

USER root


MAINTAINER Aryak Sengupta <aryak.sengupta@hyland.com>
LABEL Description="Image for NodeJS slave"

COPY cert.crt /usr/local/share/ca-certificates
RUN update-ca-certificates

RUN curl -sL https://deb.nodesource.com/setup_8.x | bash \
    && apt-get install -y nodejs

ENTRYPOINT ["jenkins-slave"]

我将此图像保存在我的Pod模板中(在K8s插件配置中)。现在,当我尝试在这个 slave 上运行构建时,我发现在Pod内部产生了两个容器(截图也证明了相同。)。

enter image description here

我的Pod模板如下所示:

enter image description here

我的Kubernetes配置如下所示: enter image description here

现在如果我做一个简单的docker ps,我发现有两个容器启动了(为什么?):

enter image description here

现在,在Jenkins的Jenkins Job配置中,无论我在构建步骤中添加什么,步骤都会在第一个容器中执行。

即使我在Node内使用官方PodTemplate容器,结果仍然相同:

enter image description here

我尝试在Jenkins Job中打印Node版本,输出“Node not found”。另外,为了验证我的骚扰,我在第二个容器中完成了docker exec并尝试打印Node版本。在这种情况下,它的工作绝对正常。

这就是我的构建步骤:

enter image description here

所以,归结起来,我有两个主要问题:

  1. 为什么两个分开(一个用于JNLP,另一个用于所有自定义更改)容器会在我启动Jenkins作业时启动?
  2. 为什么我的作业在没有安装Node的第一个容器上运行?如何使用此配置实现使用Node构建项目所需的行为?
  3. 我错过了什么?

    P.S。 - 如果某些部分的问题不清楚,请告诉我。

    编辑:我知道可以使用Pipeline Jenkins插件完成此操作,我可以在其中明确提及container名称,但我需要从Jenkins UI执行此操作。有没有办法指定容器名称以及我已经这样做的从属名称:

    enter image description here

3 个答案:

答案 0 :(得分:5)

Jenkins kubernetes插件将始终在pod中创建一个JNLP从属容器,用于执行构建。 podTemplate是您定义执行构建所需的其他容器的地方。

在这种情况下,您似乎想要在podTemplate中添加一个Node容器。在构建中,您将在命名的Node容器内进行构建。

你应该不关心Pod的运行位置。您需要做的就是确保添加具有所需资源的容器(在本例中为Node)。您可以根据需要向podTemplate添加任意数量的容器。我有一些带有10个或更多容器的容器,用于PMD,Maven,curl等步骤。

我使用带有管道的Jenkins文件。

podTemplate(cloud: 'k8s-houston', label: 'api-hire-build', 
  containers: [
    containerTemplate(name: 'maven', image: 'maven:3-jdk-8-alpine', ttyEnabled: true, command: 'cat'),
    containerTemplate(name: 'pmd', image: 'stash.company.com:8443/pmd:pmd-bin-5.5.4', alwaysPullImage: false, ttyEnabled: true, command: 'cat')
  ],
  volumes: [
    persistentVolumeClaim(claimName: 'jenkins-pv-claim', mountPath: '/mvn/.m2nrepo')
  ]
)
{
  node('api-hire-build') {
    stage('Maven compile') {
      container('maven') {
        sh "mvn -Dmaven.repo.local=/mvn/.m2nrepo/repository clean compile"
      }
    }
    stage('PMD SCA (docker)') {
      container('pmd') {
        sh 'run.sh pmd -d "$PWD"/src -f xml -reportfile "$PWD"/target/pmd.xml -failOnViolation false -rulesets java-basic,java-design,java-unusedcode -language java'
        sh 'run.sh pmd -d "$PWD"/src -f html -reportfile "$PWD"/target/pmdreport.html -failOnViolation false -rulesets java-basic,java-design,java-unusedcode -language java'
        sh 'run.sh cpd --files "$PWD"/src --minimum-tokens 100 --failOnViolation false --language java --format xml > "$PWD"/target/duplicate-code.xml'
      }
      archive 'target/duplicate-code.xml'
      step([$class: 'PmdPublisher', pattern: 'target/pmd.xml'])
    }
  }
}

答案 1 :(得分:1)

好的,所以我想出了解决方案。 mhang li 的答案是线索,但他没有解释。

基本上,您需要修改找到的here的官方Jenkins从属映像,并对其进行修改以包括对从属的更改。本质上,您是将JNLP和Slave容器整合到一个容器中并构建组合的映像。

修改格式如下所示(从链接的Dockerfile中提取)

FROM jenkins/slave:3.27-1
MAINTAINER Oleg Nenashev <o.v.nenashev@gmail.com>
LABEL Description="This is a base image, which allows connecting Jenkins agents via JNLP protocols" Vendor="Jenkins project" Version="3.27"

COPY jenkins-slave /usr/local/bin/jenkins-slave

**INCLUDE CODE FOR YOUR SLAVE. Eg install node, java, whatever**

ENTRYPOINT ["jenkins-slave"] # Make sure you include this file as well

现在,将从属容器命名为jnlp(原因-bug)。因此,现在,您将产生一个容器,即您的JNLP +从站。总而言之,您的Kubernetes插件Pod模板将如下所示。请注意我放入的docker映像的自定义URL。此外,请确保您不包括Command To Run,除非您需要一个。

enter image description here

完成!您的构建现在应该在此容器中运行,并且应该完全像对Dockerfile编程一样起作用!

答案 2 :(得分:0)

要设置容器模板->名称为jnlp。 https://issues.jenkins-ci.org/browse/JENKINS-40847