如何 运行 在 jenkins 上并行动态阶段,每个阶段都有一个单独的 kubernetes 代理
How to run dynamic stages in paralell on jenkins with a separate kubernetes agent for each stage
我尝试结合我在语法上发现的东西,但这是我能得到的最接近的东西。它创建了多个阶段,但说它们没有步骤。
如果我将代理语法向下移动到定义“测试”阶段的位置,我可以在同一个代理上执行 运行 一系列并行步骤,但我想单独启动 pods 每一个这样我就可以有效地使用 kubernetes 集群并并行工作。
附上Jenkinsfile的例子供参考
def parallelStagesMap
def generateStage(job) {
return {
stage ("$job.key") {
agent {
kubernetes {
cloud 'kubernetes'
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: name
image: image
command:
- sleep
args:
- infinity
"""
}
}
steps {
sh """
do some important stuff
"""
}
}
}
}
pipeline {
agent none
stages {
stage('Create List of Stages to run in Parallel') {
steps {
script {
def map = [
"name" : "aparam",
"name2" : "aparam2"
]
parallelStagesMap = map.collectEntries {
["${it.key}" : generateStage(it)]
}
}
}
}
stage('Test') {
steps {
script {
parallel parallelStagesMap
}
}
}
stage('Release') {
agent etc
steps {
etc
}
}
}
}
如 中所述:
Dynamic parallel stages could be created only by using Scripted Pipelines. The API built-it Declarative Pipeline is not available (like agent).
因此,您不能 运行 在不同代理上并行执行动态阶段。
为了实现你想要做的事情,一个解决方案是在一个新的 kube pod 上触发另一个 运行 管道,并在下一步之前等待它完成。
这里是 Jenkinsfiles 以供更多理解:
- 主要工作 Jenkinsfile:
def parallelJobsMap
def triggerJob(item) {
return {
build job: 'myChildJob', parameters: [string(name: 'MY_PARAM', value: "${item.value}")], wait: true
}
}
pipeline {
agent none
stages {
stage('Create List of Stages to run in Parallel') {
steps {
script {
def map = [
"name" : "aparam",
"name2" : "aparam2"
]
parallelJobsMap = map.collectEntries {
["${it.key}" : triggerJob(it)]
}
}
}
}
stage('Test') {
steps {
script {
parallel parallelJobsMap
}
}
}
stage('Release') {
agent any
steps {
echo "Release stuff"
}
}
}
}
- 子作业 Jenkinsfile:
pipeline {
agent none
parameters {
string(
name: 'MY_PARAM',
description: 'My beautiful parameter',
defaultValue: 'A default value',
trim: true
)
}
stages {
stage ("Job") {
agent {
kubernetes {
cloud 'kubernetes'
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: name
image: image
command:
- sleep
args:
- infinity
"""
}
}
steps {
echo "Do some important stuff with the parameter " + params.MY_PARAM
}
}
}
}
为了 运行 并行动态创建的作业,您将必须使用脚本化管道语法。
脚本管道中声明性 kubernetes
代理的等效语法是 podTemplate
和 node
(请参阅完整的 Doucumentation):
podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8.1-jdk-8
command:
- sleep
args:
- 99d
''') {
node(POD_LABEL) {
...
}
}
注意 podTemplate
除了 yaml 之外还可以接收 cloud
参数,但它默认为 kubernetes
所以不需要传递它。
因此,在您的情况下,您可以使用此语法 运行 在不同代理上并行执行作业:
// Assuming yaml is same for all nodes - if not it can be passed as parameter
podYaml= """
apiVersion: v1
kind: Pod
spec:
containers:
- name: name
image: image
command:
- sleep
args:
- infinity
"""
pipeline {
agent none
stages {
stage('Create List of Stages to run in Parallel') {
steps {
script {
def map = ["name" : "aparam",
"name2" : "aparam2"]
parallel map.collectEntries {
["${it.key}" : generateStage(it)]
}
}
}
}
}
}
def generateStage(job) {
return {
stage(job.key) {
podTemplate(yaml:podYaml) {
node(POD_LABEL) {
// Each execution runs on its own node (pod)
sh "do some important stuff with ${job.value}"
}
}
}
}
}
我尝试结合我在语法上发现的东西,但这是我能得到的最接近的东西。它创建了多个阶段,但说它们没有步骤。
如果我将代理语法向下移动到定义“测试”阶段的位置,我可以在同一个代理上执行 运行 一系列并行步骤,但我想单独启动 pods 每一个这样我就可以有效地使用 kubernetes 集群并并行工作。
附上Jenkinsfile的例子供参考
def parallelStagesMap
def generateStage(job) {
return {
stage ("$job.key") {
agent {
kubernetes {
cloud 'kubernetes'
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: name
image: image
command:
- sleep
args:
- infinity
"""
}
}
steps {
sh """
do some important stuff
"""
}
}
}
}
pipeline {
agent none
stages {
stage('Create List of Stages to run in Parallel') {
steps {
script {
def map = [
"name" : "aparam",
"name2" : "aparam2"
]
parallelStagesMap = map.collectEntries {
["${it.key}" : generateStage(it)]
}
}
}
}
stage('Test') {
steps {
script {
parallel parallelStagesMap
}
}
}
stage('Release') {
agent etc
steps {
etc
}
}
}
}
如
Dynamic parallel stages could be created only by using Scripted Pipelines. The API built-it Declarative Pipeline is not available (like agent).
因此,您不能 运行 在不同代理上并行执行动态阶段。
为了实现你想要做的事情,一个解决方案是在一个新的 kube pod 上触发另一个 运行 管道,并在下一步之前等待它完成。
这里是 Jenkinsfiles 以供更多理解:
- 主要工作 Jenkinsfile:
def parallelJobsMap
def triggerJob(item) {
return {
build job: 'myChildJob', parameters: [string(name: 'MY_PARAM', value: "${item.value}")], wait: true
}
}
pipeline {
agent none
stages {
stage('Create List of Stages to run in Parallel') {
steps {
script {
def map = [
"name" : "aparam",
"name2" : "aparam2"
]
parallelJobsMap = map.collectEntries {
["${it.key}" : triggerJob(it)]
}
}
}
}
stage('Test') {
steps {
script {
parallel parallelJobsMap
}
}
}
stage('Release') {
agent any
steps {
echo "Release stuff"
}
}
}
}
- 子作业 Jenkinsfile:
pipeline {
agent none
parameters {
string(
name: 'MY_PARAM',
description: 'My beautiful parameter',
defaultValue: 'A default value',
trim: true
)
}
stages {
stage ("Job") {
agent {
kubernetes {
cloud 'kubernetes'
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: name
image: image
command:
- sleep
args:
- infinity
"""
}
}
steps {
echo "Do some important stuff with the parameter " + params.MY_PARAM
}
}
}
}
为了 运行 并行动态创建的作业,您将必须使用脚本化管道语法。
脚本管道中声明性 kubernetes
代理的等效语法是 podTemplate
和 node
(请参阅完整的 Doucumentation):
podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8.1-jdk-8
command:
- sleep
args:
- 99d
''') {
node(POD_LABEL) {
...
}
}
注意 podTemplate
除了 yaml 之外还可以接收 cloud
参数,但它默认为 kubernetes
所以不需要传递它。
因此,在您的情况下,您可以使用此语法 运行 在不同代理上并行执行作业:
// Assuming yaml is same for all nodes - if not it can be passed as parameter
podYaml= """
apiVersion: v1
kind: Pod
spec:
containers:
- name: name
image: image
command:
- sleep
args:
- infinity
"""
pipeline {
agent none
stages {
stage('Create List of Stages to run in Parallel') {
steps {
script {
def map = ["name" : "aparam",
"name2" : "aparam2"]
parallel map.collectEntries {
["${it.key}" : generateStage(it)]
}
}
}
}
}
}
def generateStage(job) {
return {
stage(job.key) {
podTemplate(yaml:podYaml) {
node(POD_LABEL) {
// Each execution runs on its own node (pod)
sh "do some important stuff with ${job.value}"
}
}
}
}
}