咨询: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
相关产品推荐
相关产品推荐

