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

咨询:Jenkins实现临时EC2实例执行流水线后销毁的方案

解决方案:Jenkins动态创建AWS EC2实例执行任务并销毁

一、可用插件推荐

1. Amazon EC2 Plugin

这是Jenkins官方适配AWS的核心插件,专门用来动态管理EC2作为Jenkins代理节点:

  • 配置后,Jenkins会自动在任务启动时创建EC2实例,将其注册为代理节点
  • 任务执行完成(无论成功/失败),自动销毁实例
  • 需提前准备预配置好依赖的AMI:比如预装Jenkins代理客户端、Docker、kubectl、Git等工具,减少实例初始化时间
  • 配置步骤:在Jenkins「系统管理」→「云」中添加Amazon EC2云,填入AWS凭证、区域、实例类型、安全组、AMI ID等参数,设置代理标签(比如ec2-dynamic-agent)

2. Pipeline AWS Plugin

如果需要更灵活地手动控制EC2实例的生命周期(比如自定义创建参数),可以用这个插件,它提供了流水线中调用AWS服务的step:

  • 支持awsEc2Create、awsEc2Terminate等step,直接在Jenkinsfile中编写实例创建/销毁逻辑
  • 需配合Jenkins凭证管理存储AWS Access Key/Secret Key

二、流水线实现示例(两种方式)

方式1:用Amazon EC2 Plugin自动管理代理(推荐新手)

这种方式无需手动写实例创建/销毁逻辑,Jenkins自动处理:

pipeline {
    agent {
        label 'ec2-dynamic-agent' // 对应EC2云配置的代理标签
    }
    stages {
        stage('拉取代码') {
            steps {
                git url: '你的代码仓库地址', branch: 'main'
            }
        }
        stage('构建Docker镜像') {
            steps {
                sh 'docker build -t your-docker-hub-username/your-image:latest .'
            }
        }
        stage('推送至Docker Hub') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'docker-hub-creds', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
                    sh 'echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin'
                    sh 'docker push your-docker-hub-username/your-image:latest'
                }
            }
        }
        stage('创建K8s Pod') {
            steps {
                sh 'kubectl apply -f your-pod-manifest.yaml'
            }
        }
    }
    post {
        always {
            // 可选:添加清理步骤,比如登出Docker Hub
            sh 'docker logout'
        }
    }
}

方式2:手动控制EC2生命周期(自定义场景)

如果需要完全自定义实例创建逻辑,可结合AWS CLI或Pipeline AWS Plugin编写:

pipeline {
    agent any // 用Jenkins主节点触发操作
    environment {
        INSTANCE_ID = ''
        INSTANCE_IP = ''
        AWS_REGION = 'us-east-1'
    }
    stages {
        stage('创建EC2实例') {
            steps {
                script {
                    // 用AWS CLI创建实例(需主节点已安装AWS CLI并配置凭证)
                    def instanceOutput = sh(script: "aws ec2 run-instances --image-id your-ami-id --instance-type t2.medium --security-group-ids your-security-group-id --region $AWS_REGION --query 'Instances[0].InstanceId' --output text", returnStdout: true).trim()
                    INSTANCE_ID = instanceOutput
                    echo "创建的EC2实例ID:$INSTANCE_ID"
                }
            }
        }
        stage('等待实例就绪') {
            steps {
                sh "aws ec2 wait instance-running --instance-ids $INSTANCE_ID --region $AWS_REGION"
                script {
                    def ipOutput = sh(script: "aws ec2 describe-instances --instance-ids $INSTANCE_ID --region $AWS_REGION --query 'Reservations[0].Instances[0].PublicIpAddress' --output text", returnStdout: true).trim()
                    INSTANCE_IP = ipOutput
                    echo "实例公网IP:$INSTANCE_IP"
                }
            }
        }
        stage('在EC2实例上执行任务') {
            steps {
                // 用SSH Pipeline Steps Plugin连接实例执行命令
                sshPublisher(publishers: [sshPublisherDesc(
                    configName: 'ec2-ssh-config', // 提前在Jenkins配置SSH凭证(实例密钥对)
                    transfers: [sshTransfer(
                        sourceFiles: '**/*',
                        remoteDirectory: '/home/ec2-user/project'
                    )],
                    execCommand: '''
                        cd /home/ec2-user/project
                        docker build -t your-docker-hub-username/your-image:latest .
                        echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
                        docker push your-docker-hub-username/your-image:latest
                        kubectl apply -f your-pod-manifest.yaml
                    '''
                )])
            }
        }
    }
    post {
        always {
            // 无论任务成功失败,都销毁实例
            sh "aws ec2 terminate-instances --instance-ids $INSTANCE_ID --region $AWS_REGION"
            echo "已销毁EC2实例:$INSTANCE_ID"
        }
    }
}

三、关键建议

  • 预打包AMI:把所有依赖工具(Jenkins代理、Docker、kubectl等)提前安装到AMI中,避免每次实例启动都耗时安装,减少出错概率
  • 安全配置:
    • EC2安全组仅允许Jenkins主节点的SSH/JNLP端口访问,禁止公网无限制访问
    • 所有敏感凭证(AWS密钥、Docker Hub密码、K8s kubeconfig)都存在Jenkins凭证管理中,禁止硬编码在流水线里
  • 容错处理:用post { always { ... } }确保实例销毁逻辑一定会执行,避免遗留闲置EC2产生不必要的费用
  • 资源优化:选择合适的实例类型(比如t2.medium满足大部分构建需求),设置实例自动终止的超时时间(Amazon EC2 Plugin中可配置)

内容的提问来源于stack exchange,提问作者a dysthemic student

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 23:48:12