<p>I am trying to setup a Jenkins declarative pipeline to use two different agents during its execution. The agents are dynamically spawned by the Kubernetes plugin. For sake of argument and simplicity, let's assume I want to do this:</p>
<p>On Agent 1 (Cloud name: &quot;ubuntu&quot;):</p>
<ul>
<li>Run apt-get and some installs</li>
<li>Run a shell script</li>
<li>Additional steps</li>
</ul>
<p>On Agent 2 (Cloud name: &quot;fedora&quot;):</p>
<ul>
<li>Run dnf and some installs</li>
<li>Run a shell script</li>
<li>Additional steps</li>
</ul>
<p>The problem I have is that if if I use a global agent declaration:</p>
<pre><code>pipeline {
  agent {
    kubernetes {
      cloud 'ubuntu'
      label &quot;ubuntu-agent&quot;
      containerTemplate {
        name 'support'
        image 'blenderfox/support'
        ttyEnabled true
        command 'cat'
      }
    }
  }
...
}
</code></pre>
<p>Then that is used across all the stages if I don't declare an agent on each of the stages.</p>
<p>If I use <code>agent none</code>:</p>
<pre><code>pipeline {
  agent none
  ...
}
</code></pre>
<p>Then I have to declare an agent spec for each stage, for example:</p>
<pre><code>    stage (&quot;apt update&quot;) {
      agent {
        kubernetes {
          cloud 'ubuntu'
          label &quot;ubuntu-agent&quot;
          containerTemplate {
            name 'support'
            image 'blenderfox/support'
            ttyEnabled true
            command 'cat'
          }
        }
      }
      steps {
        sh &quot;&quot;&quot;
        apt update
        &quot;&quot;&quot;
      }
    }
</code></pre>
<p>While this would work for me in that I can declare per stage which agent I want, the problem this method causes, is that it spins up a new agent for <em>each</em> stage, meaning the state isn't carried between, for example, these two stages:</p>
<pre><code>    stage (&quot;apt-update&quot;) {
      agent {
        ....
      }
      steps {
        sh &quot;&quot;&quot;
        apt update
        &quot;&quot;&quot;
      }
    }
    stage (&quot;apt-install&quot;) {
      agent {
        ....
      }
      steps {
        sh &quot;&quot;&quot;
        apt install -y ....
        &quot;&quot;&quot;
      }
    }
</code></pre>
<p>Can I reuse the same agent across stages? For example, something like this:</p>
<pre><code>stage (&quot;provision agent&quot;) {
  agent {
    ...
    label &quot;ubuntu-agent&quot;
    ...
  }
  steps {
    sh &quot;&quot;&quot;
    echo &quot;Provisioning agent&quot;
    &quot;&quot;&quot;
  }
}
stage (&quot;apt-update&quot;) {
  agent {
    label &quot;ubuntu-agent&quot; //reuse agent from previous stage
  }
  steps {
    sh &quot;&quot;&quot;
    apt update
    &quot;&quot;&quot;
  }
}
stage (&quot;apt-install&quot;) {
  agent {
    label &quot;ubuntu-agent&quot; //reuse agent from previous stage
  }
  steps {
    sh &quot;&quot;&quot;
    apt install -y ....
    &quot;&quot;&quot;
  }
}
</code></pre>

<p>Found a solution. Very hacky but it works:</p>
<pre><code>pipeline {

  agent none

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

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


    stage (&quot;Provision production agent&quot;) {
      agent {
        kubernetes {
          cloud 'prod-cloud'
          label &quot;prod-agent-${env.BUILD_NUMBER}&quot;
          slaveConnectTimeout 300
          idleMinutes 5
          yamlFile &quot;jenkins-prod-agent.yaml&quot;
        }
      }
      steps {
        sh &quot;&quot;&quot;
        ## Do any agent init steps here
        &quot;&quot;&quot;
      }
    }
    stage (&quot;Do something on prod agent&quot;) {
      agent {
        kubernetes {
          label &quot;prod-agent-${env.BUILD_NUMBER}&quot;
        }
      }
      steps {
        sh &quot;&quot;&quot;
        ## Do something here
        &quot;&quot;&quot;
      }
    }
  }
}
</code></pre>
<p>The agent yamls vary, but you can do something like this:</p>
<pre><code>spec:
   containers:
   - name: docker
     image: docker:18.06.1
     command: [&quot;tail&quot;, &quot;-f&quot;, &quot;/dev/null&quot;]
     imagePullPolicy: Always
     volumeMounts:
       - name: docker
         mountPath: /var/run/docker.sock
   volumes:
   - hostPath:
      path: &quot;/var/run/docker.sock&quot;
     name: &quot;docker&quot;
</code></pre>
<p>And then use the agent like so:</p>
<pre><code>stage (&quot;docker build&quot;) {
  agent {
    kubernetes {
      label &quot;dev-agent-${env.BUILD_NUMBER}&quot;
    }
  }
  steps {
    container('docker') {
      sh &quot;&quot;&quot;
        ## docker build....
      &quot;&quot;&quot;
    }
  }
}
</code></pre>
