在单个使用 Docker 的代理上执行 Jenkins 流水线。

huangapple go评论56阅读模式
英文:

Executing Jenkins Pipeline on a single agent with docker

问题

我理解你的问题。以下是你提到的内容的翻译:

你想要实现的目标:

我尝试执行一个流水线脚本,其中SCM(AccuRev)在“任何”代理上检出,然后阶段在同一代理上根据本地工作区执行。具体来说,构建阶段期望代码检出仅在映射到容器中的工作区中可用。

问题:

当我在Jenkins配置中添加多个代理时,SCM步骤会在一个代理上检出代码,然后在另一个代理上启动构建步骤,这是一个问题,因为代码是在另一个代理上检出的。

有效解决方案:

  • 配置只有一个代理/节点的Jenkins
pipeline {
   agent none    
   stages {
      stage('Checkout') {
         agent any
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

尝试但不起作用的解决方案:

  • 配置具有2个代理/节点的Jenkins
pipeline {
   agent {
      docker {
         image 'ubuntu'
      }
   }
   stages {
      stage('Checkout') {
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

上述解决方案不起作用,因为它期望在容器中安装AccuRev。虽然你可以采取这种方法,但它不太可扩展,可能会导致基于旧操作系统的容器出现问题。此外,容器内可能存在权限问题。

另一个尝试:

尝试在docker代理中添加'reuseNode true',如下所示:

pipeline {
   agent none    
   stages {
      stage('Checkout') {
         agent any
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
               reuseNode true
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

关于“自动检出SCM”的尝试:

你提到了“automatic checkout scm”,但在此示例中没有地方定义要检出的目标流/分支。这就是为什么我在这里声明了一个特定的阶段来处理SCM检出。可能可以处理检出而无需指定代理,但我不知道如何实现这一点。

另一种看似有效的解决方案(需要进一步测试确认):

以下代码似乎可以实现我想要的效果,即在“任何”代理上执行检出阶段,然后在容器中重用相同的代理执行构建阶段。

pipeline {
   agent any    
   stages {
      stage('Checkout') {
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
               reuseNode true
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

希望这些翻译对你有所帮助。

英文:

What I'm trying to achieve:

I'm trying to execute a pipeline script where SCM (AccuRev) is checked out on 'any' agent and then the stages are executed on that same agent per the local workspace. The build stage specifically is expecting the code checkout to just be available in the workspace that is mapped into the container.

The problem:

When I have more than one agent added to the Jenkins configuration, the SCM step will checkout the code on one agent and then start the build step starting the container on the other agent, which is a problem because the code was checked out on the other agent.

What works:

  • Jenkins configured with a single agent/node
pipeline {
   agent none    
   stages {
      stage('Checkout') {
         agent any
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

What I have tried, but doesn't work:

  • Jenkins configured with 2 agent(s)/node(s)
pipeline {
   agent {
      docker {
         image 'ubuntu'
      }
   }
   stages {
      stage('Checkout') {
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

The above doesn't work because it is expecting AccuRev to be installed in the container. I could go this route, but it is not really scalable and will cause issues on containers that are based on an older OS. There are also permission issues within the container.

I also tried adding 'reuseNode true' to the docker agent, as in the below:

pipeline {
   agent none    
   stages {
      stage('Checkout') {
         agent any
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
               reuseNode true
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

I'm somewhat aware or have read about 'automatic checkout scm' as with the following, but this is odd as there is no place to define the target stream/branch to checkout. This is why I'm declaring a specific stage to handle scm checkout. It is possible this would handle the checkout without needing to specify the agent, but I don't get how to do this.

pipeline {
    agent any
    stages {
        stage ('Build') {
            steps {
                sh 'cat Jenkinsfile'
            }
        }
    }
}

Edit: adding a solution that seems to work, but need more testing before confirming.

The following seems to do what I want, executing the checkout stage on 'any' agent and then reusing the same agent to execute the build state in a container.

pipeline {
   agent any    
   stages {
      stage('Checkout') {
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
               reuseNode true
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

答案1

得分: 0

以下是翻译后的内容:

下面似乎为我提供了所需的功能。管道从“任何”代理开始,允许主机级别处理“Checkout”阶段,并且“reuseNode”指示管道在与工作区位于同一节点上启动容器。

pipeline {
   agent any    
   stages {
      stage('Checkout') {
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
               reuseNode true
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
               '''
         }
      }
   }
}
英文:

The below appears to have given me the functionality that I needed. The pipeline starts on "any" agent allowing the host level to handle the Checkout stage, and the "reuseNode" informs the pipeline to start the container on the same node, where the workspace is located.

pipeline {
   agent any    
   stages {
      stage('Checkout') {
         steps {
            checkout accurev(depot: 'MyDepot', serverName: 'AccuRev', stream: 'SomeStream', wspaceORreftree: 'none')
         }
      }
      stage('Compile') {
         agent {
            docker {
               image 'ubuntu'
               reuseNode true
            }
         }
         steps {
            sh '''#!/bin/bash
                  make -j16
            '''
         }
      }
   }
}

huangapple
  • 本文由 发表于 2023年2月8日 10:39:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75380904.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定