繁体   English   中英

为什么 Kubernetes 中的 jenkins 代理有多个容器?

[英]Why multiple containers for a jenkins agent in Kubernetes?

我正在使用本指南在 kubernetes 中配置 jenkins + jenkins 代理:

https://akomljen.com/set-up-a-jenkins-ci-cd-pipeline-with-kubernetes/

下面给出了 jenkins 管道的以下示例,该管道在不同阶段使用多个/不同容器:

def label = "worker-${UUID.randomUUID().toString()}"

podTemplate(label: label, containers: [
  containerTemplate(name: 'gradle', image: 'gradle:4.5.1-jdk9', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'docker', image: 'docker', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'kubectl', image: 'lachlanevenson/k8s-kubectl:v1.8.8', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'helm', image: 'lachlanevenson/k8s-helm:latest', command: 'cat', ttyEnabled: true)
],
volumes: [
  hostPathVolume(mountPath: '/home/gradle/.gradle', hostPath: '/tmp/jenkins/.gradle'),
  hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock')
]) {
  node(label) {
    def myRepo = checkout scm
    def gitCommit = myRepo.GIT_COMMIT
    def gitBranch = myRepo.GIT_BRANCH
    def shortGitCommit = "${gitCommit[0..10]}"
    def previousGitCommit = sh(script: "git rev-parse ${gitCommit}~", returnStdout: true)
 
    stage('Test') {
      try {
        container('gradle') {
          sh """
            pwd
            echo "GIT_BRANCH=${gitBranch}" >> /etc/environment
            echo "GIT_COMMIT=${gitCommit}" >> /etc/environment
            gradle test
            """
        }
      }
      catch (exc) {
        println "Failed to test - ${currentBuild.fullDisplayName}"
        throw(exc)
      }
    }
    stage('Build') {
      container('gradle') {
        sh "gradle build"
      }
    }
    stage('Create Docker images') {
      container('docker') {
        withCredentials([[$class: 'UsernamePasswordMultiBinding',
          credentialsId: 'dockerhub',
          usernameVariable: 'DOCKER_HUB_USER',
          passwordVariable: 'DOCKER_HUB_PASSWORD']]) {
          sh """
            docker login -u ${DOCKER_HUB_USER} -p ${DOCKER_HUB_PASSWORD}
            docker build -t namespace/my-image:${gitCommit} .
            docker push namespace/my-image:${gitCommit}
            """
        }
      }
    }
    stage('Run kubectl') {
      container('kubectl') {
        sh "kubectl get pods"
      }
    }
    stage('Run helm') {
      container('helm') {
        sh "helm list"
      }
    }
  }
}

但是你为什么要为这种粒度级别而烦恼呢? 例如,为什么不只拥有一个容器来满足您的所有需求,jnlp、helm、kubectl、java 等,并将其用于所有阶段?

从纯粹主义者的角度来看,我知道保持容器/图像尽可能小是件好事,但如果这是唯一的论点,我宁愿拥有一个容器 + 不必打扰我的最终用户(编写 jenkinsfiles 的开发人员)选择正确的容器 - 他们不必担心这个级别的事情,而是他们需要能够获得代理,仅此而已。

还是我错过了这个多容器设置的一些功能原因?

使用一张图片处理所有流程在功能上是可行的,但会给您的操作增加负担。

我们并不总能找到满足我们所有需求的图像,即具有所需版本的所需工具。 最有可能的是,您将构建一个。

为此,您需要为不同的拱门(amd/arm)构建 docker 映像,并维护/使用 docker 注册表来存储构建的映像,随着映像变得更加复杂,此过程可能会很耗时。 更重要的是,您的某些工具很可能“偏爱”某些特定的 linua 发行版,您会发现这很困难,而且在功能上并不总是正常的。

假设您需要在管道步骤中使用更新版本的 docker 图像,您将重复构建和上传图像的整个过程。 或者,您只需更改管道中的映像版本,即可最大限度地减少您的操作工作量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM