【问题标题】:Jenkins Declarative: Kubernetes Plugin with multiple agentsJenkins 声明式:具有多个代理的 Kubernetes 插件
【发布时间】:2021-03-02 15:26:46
【问题描述】:

我正在尝试设置一个 Jenkins 声明式管道以在其执行期间使用两个不同的代理。代理由 Kubernetes 插件动态生成。为了论证和简单起见,假设我想这样做:

在代理 1 上(云名称:“ubuntu”):

  • 运行 apt-get 并进行一些安装
  • 运行 shell 脚本
  • 其他步骤

在代理 2 上(云名称:“fedora”):

  • 运行 dnf 和一些安装
  • 运行 shell 脚本
  • 其他步骤

我遇到的问题是,如果我使用全局代理声明:

pipeline {
  agent {
    kubernetes {
      cloud 'ubuntu'
      label "ubuntu-agent"
      containerTemplate {
        name 'support'
        image 'blenderfox/support'
        ttyEnabled true
        command 'cat'
      }
    }
  }
...
}

如果我没有在每个阶段声明代理,那么所有阶段都会使用它。

如果我使用agent none:

pipeline {
  agent none
  ...
}

然后我必须为每个阶段声明一个代理规范,例如:

    stage ("apt update") {
      agent {
        kubernetes {
          cloud 'ubuntu'
          label "ubuntu-agent"
          containerTemplate {
            name 'support'
            image 'blenderfox/support'
            ttyEnabled true
            command 'cat'
          }
        }
      }
      steps {
        sh """
        apt update
        """
      }
    }

虽然这对我有用,因为我可以在每个阶段声明我想要的代理,但这种方法导致的问题是它为 每个 阶段启动了一个新代理,这意味着状态是'不进行,例如,这两个阶段:

    stage ("apt-update") {
      agent {
        ....
      }
      steps {
        sh """
        apt update
        """
      }
    }
    stage ("apt-install") {
      agent {
        ....
      }
      steps {
        sh """
        apt install -y ....
        """
      }
    }

我可以跨阶段重复使用相同的代理吗?例如,像这样:

stage ("provision agent") {
  agent {
    ...
    label "ubuntu-agent"
    ...
  }
  steps {
    sh """
    echo "Provisioning agent"
    """
  }
}
stage ("apt-update") {
  agent {
    label "ubuntu-agent" //reuse agent from previous stage
  }
  steps {
    sh """
    apt update
    """
  }
}
stage ("apt-install") {
  agent {
    label "ubuntu-agent" //reuse agent from previous stage
  }
  steps {
    sh """
    apt install -y ....
    """
  }
}

【问题讨论】:

  • 您可以在完成后让代理保持活动状态以供重用(并使其等待 x 分钟以等待其他工作接受它 - 但我不确定您是否可以指定 - 完全接受这个代理,它会更多如果您需要上一个,可能会选择第一个可用的所以不是真的“稳定”。另外我想问你一个问题 - 你是否知道如何同时产生多个具有多个资源配额的代理? atm . 我很少有工作需要 9gb 的内存,而所有其他工作都需要 500mb 的最高容量 - 运行所有具有高限制的工作有点浪费
  • @potatopotato 可能我能想到的唯一方法是使用不同的“云”定义:

标签: jenkins kubernetes


【解决方案1】:

找到了解决办法。非常hacky,但它有效:

pipeline {

  agent none

  stages {
    stage ("Provision dev agent") {
      agent {
        kubernetes {
          cloud 'dev-cloud'
          label "dev-agent-${env.BUILD_NUMBER}"
          slaveConnectTimeout 300
          idleMinutes 5
          yamlFile "jenkins-dev-agent.yaml"
        }
      }
      steps {
        sh """
        ## Do any agent init steps here
        """
      }

    }
    stage ("Do something on dev agent") {
      agent {
        kubernetes {
          label "dev-agent-${env.BUILD_NUMBER}"
        }
      }
      steps {
        sh """
        ## Do something here
        """
      }
    }


    stage ("Provision production agent") {
      agent {
        kubernetes {
          cloud 'prod-cloud'
          label "prod-agent-${env.BUILD_NUMBER}"
          slaveConnectTimeout 300
          idleMinutes 5
          yamlFile "jenkins-prod-agent.yaml"
        }
      }
      steps {
        sh """
        ## Do any agent init steps here
        """
      }
    }
    stage ("Do something on prod agent") {
      agent {
        kubernetes {
          label "prod-agent-${env.BUILD_NUMBER}"
        }
      }
      steps {
        sh """
        ## Do something here
        """
      }
    }
  }
}

代理 yaml 各不相同,但您可以执行以下操作:

spec:
   containers:
   - name: docker
     image: docker:18.06.1
     command: ["tail", "-f", "/dev/null"]
     imagePullPolicy: Always
     volumeMounts:
       - name: docker
         mountPath: /var/run/docker.sock
   volumes:
   - hostPath:
      path: "/var/run/docker.sock"
     name: "docker"

然后像这样使用代理:

stage ("docker build") {
  agent {
    kubernetes {
      label "dev-agent-${env.BUILD_NUMBER}"
    }
  }
  steps {
    container('docker') {
      sh """
        ## docker build....
      """
    }
  }
}

【讨论】:

  • 对于其他使用这个出色解决方案的人:不要在代理设置中跳过 idleMinutes。如果没有这个,至少在我的情况下,Jenkins 试图生成一个具有相同名称但不在我想要的云上的新代理。
  • 如果没有 idleMinutes,代理将在其步骤完成后终止。这里的目的是让代理运行一段时间,以便其他步骤可以重用该代理。并确保代理标签足够独特,以免其他工作意外捡到它
  • 谢谢@Blender Fox,这就是我想指出的。我尝试采用您的解决方案,跳过该参数并想知道为什么它不起作用。 ;-)
猜你喜欢
  • 1970-01-01
  • 2020-02-27
  • 2021-07-25
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-10
相关资源
最近更新 更多