You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jenkins脚本化流水线中启动已注册的EC2节点代理?

解决方案

以下是实现你需求的Jenkins声明式流水线方案,核心通过AWS CLI管控EC2实例生命周期,结合SSH与Jenkins内部机制确保代理上线后执行构建:

前置准备

  • 在Jenkins凭证管理中配置AWS密钥对(需具备ec2:StartInstances、ec2:StopInstances、ec2:DescribeInstances权限)
  • 配置EC2实例的SSH密钥为Jenkins SSH凭证(类型选"SSH Username with private key")
  • 提前在EC2实例中放置Jenkins代理jar包(agent.jar),或准备好下载脚本;同时从Jenkins节点配置页获取该节点的JNLP连接密钥
  • 确保Jenkins服务器能访问EC2实例的SSH端口(22)及Jenkins代理通信端口

流水线代码示例

pipeline {
    agent any
    environment {
        EC2_INSTANCE_ID = 'i-xxxxxxxxx' // 替换为你的EC2实例ID
        JENKINS_NODE_NAME = 'your-ec2-node' // 替换为已注册的Jenkins节点名
        JENKINS_URL = 'http://your-jenkins-server:8080' // 替换为你的Jenkins地址
        AGENT_SECRET = 'xxxxxxxxx' // 替换为节点的JNLP密钥
        AGENT_WORKDIR = '/var/lib/jenkins/agent' // 替换为代理工作目录
    }
    stages {
        stage('启动EC2实例') {
            steps {
                withCredentials([aws(credentialsId: 'aws-credentials', accessKeyVariable: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY')]) {
                    // 启动实例
                    sh 'aws ec2 start-instances --instance-ids ${EC2_INSTANCE_ID}'
                    // 等待实例进入running状态
                    sh 'aws ec2 wait instance-running --instance-ids ${EC2_INSTANCE_ID}'
                    // 获取实例公网IP(用私网IP的话,替换为PrivateIpAddress)
                    script {
                        EC2_PUBLIC_IP = sh(
                            script: "aws ec2 describe-instances --instance-ids ${EC2_INSTANCE_ID} --query 'Reservations[0].Instances[0].PublicIpAddress' --output text",
                            returnStdout: true
                        ).trim()
                    }
                    // 等待SSH端口就绪
                    sh "until nc -z ${EC2_PUBLIC_IP} 22; do echo '等待SSH端口就绪...'; sleep 10; done"
                }
            }
        }

        stage('启动Jenkins代理') {
            steps {
                sshagent(['ec2-ssh-key']) { // 替换为你的SSH凭证ID
                    // 远程启动代理(若agent.jar未提前放置,可先加wget ${JENKINS_URL}/jnlpJars/agent.jar命令)
                    sh """
                        ssh -o StrictHostKeyChecking=no ec2-user@${EC2_PUBLIC_IP} \
                        'nohup java -jar agent.jar -jnlpUrl ${JENKINS_URL}/computer/${JENKINS_NODE_NAME}/slave-agent.jnlp -secret ${AGENT_SECRET} -workDir "${AGENT_WORKDIR}" > agent.log 2>&1 &'
                    """
                }
                // 等待节点上线
                waitUntil {
                    script {
                        def node = Jenkins.instance.getNode(JENKINS_NODE_NAME)
                        return node != null && node.toComputer().isOnline()
                    }
                }
                echo "Jenkins代理 ${JENKINS_NODE_NAME} 已上线"
            }
        }

        stage('执行构建步骤') {
            agent {
                node {
                    label JENKINS_NODE_NAME
                }
            }
            steps {
                echo "在节点 ${JENKINS_NODE_NAME} 上执行构建..."
                // 此处添加你的具体构建命令,例如:
                // sh 'mvn clean package'
                // sh 'docker build -t my-app:latest .'
            }
        }
    }
    post {
        always {
            // 无论构建成败,均停止EC2实例
            withCredentials([aws(credentialsId: 'aws-credentials', accessKeyVariable: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY')]) {
                sh 'aws ec2 stop-instances --instance-ids ${EC2_INSTANCE_ID}'
                echo "EC2实例 ${EC2_INSTANCE_ID} 已停止"
            }
        }
    }
}

关键细节说明

  • 实例就绪校验:用aws ec2 wait确保实例启动完成,再通过nc检查SSH端口,避免提前执行远程命令失败
  • 代理后台运行:用nohup让代理脱离SSH会话在后台运行,防止连接断开后代理终止
  • 节点状态检查:直接调用Jenkins内部API查询节点在线状态,比轮询日志更高效可靠
  • 资源兜底回收:post块的always阶段保证实例无论构建结果如何都会停止,避免闲置资源浪费

内容的提问来源于stack exchange,提问作者howsmydriving42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:38:09