我正在尝试设置一个Jenkins声明式管道,以便在其执行期间使用两个不同的代理。代理是由Kubernetes插件动态生成的。为了论证和简单起见,让我们假设我想这样做:
在代理1(云名称:"ubuntu")上:
- 运行apt-get和一些安装
- 运行shell脚本 <
- 额外步骤/gh>
在Agent 2(云名称:"fedora")上:
- 运行dnf和一些安装
- 运行shell脚本 <
- 额外步骤/gh>
我的问题是,如果如果我使用全局代理声明:
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 ....
"""
}
}
找到解决方案了。非常粗糙,但它工作:
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
"""
}
}
}
}
代理地址各不相同,但您可以这样做:
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....
"""
}
}
}
有一个使用顺序阶段的解决方案-您使用代理定义一个阶段,然后您可以在其中嵌套其他阶段
pipeline {
agent none
stages {
stage ("Provision dev agent") {
agent {
kubernetes {
cloud 'dev-cloud'
slaveConnectTimeout 300
yamlFile "jenkins-dev-agent.yaml"
}
}
stages {
stage ("Do something on dev agent") {
steps {
sh """
## Do something here
"""
}
}
stage ("Do something else on dev agent") {
steps {
sh """
## Do something here
"""
}
}
}
}
stage ("Provision prod agent") {
agent {
kubernetes {
cloud 'prod-cloud'
slaveConnectTimeout 300
yamlFile "jenkins-prod-agent.yaml"
}
}
stages {
stage ("Do something on prod agent") {
steps {
sh """
## Do something here
"""
}
}
stage ("Do something else on prod agent") {
steps {
sh """
## Do something here
"""
}
}
}
}
}
}