根据AWS文档,他们说:“ Fargate支持调度任务以响应CloudWatch事件。您可以轻松启动和停止仅需在特定时间运行的Fargate任务 “
可以从CLoudWatch Events或ECS Task Scheduler轻松启用Fargate任务的启动。
但是我找不到Fargate Tasks的STOP。 是否可能需要使用Lambda而不是本机Fargate功能来停止任务?
我的目标是仅在8ap-5pm之间运行ECS容器!
答案 0 :(得分:3)
我已经采用了建议的代码@ Mr3381并进行了一些改进:
interface EventLambda {
status: string,
services: string[]
}
interface UpdateServiceParams {
cluster: string
service: string
desiredCount: number
}
// Load AWS SDK for Node.js
import AWS from 'aws-sdk';
export const handler = async (event: EventLambda): Promise<string[]> => {
const ecs = new AWS.ECS({region: 'sa-east-1'});
const promises = new Array<Promise<any>>();
const desiredCount = event.status == 'start' ? 1 : 0
event.services.forEach(service => {
var params: UpdateServiceParams = {
cluster: process.env.ECS_CLUSTER!,
service,
desiredCount
};
promises.push(updateService(ecs, params, desiredCount))
}
)
return Promise.all(promises)
};
function updateService(ecs: AWS.ECS, params: UpdateServiceParams, desiredCount: number): Promise<string> {
return new Promise((resolve, reject) => {
ecs.updateService(params, function(err, data) {
if (err) {
console.log(err, err.stack); // An error occurred
resolve(`${params.service} not updated`);
}
else {
console.log(data); // Successful response
resolve(`${params.service} updated => Desired count: ${desiredCount}`)
}
});
})
}
它现在在TypeScript中,并支持一系列服务作为输入。
仅需将其转换为JavaScript即可在AWS上运行。
确保具有执行功能和更新服务所需的权限。这可以通过将ECS中的策略 describeServices 和 updateServices 附加到Lambda函数IAM角色来实现。
答案 1 :(得分:1)
我相信这是解决您办公时间问题的最佳解决方案。
只需使用以下命令在EC2实例中安排本地cron作业即可根据时间戳更新所需的计数,您就可以开始了。
$ aws ecs update-service --cluster <cluster-name> --service <service-name> --desired-count x
如果这对您有帮助,请告诉我。
答案 2 :(得分:0)
与“开始”相同,但是您需要将“所需任务”指定为0。 我的问题是计划程序需要任务定义,因此,如果升级它,则还需要更改计划程序。 存在一些服务,lambda或项目来处理吗? 我需要停止Fargate容器的群集。
答案 3 :(得分:0)
答案是正确的。通过我们可以创建以下资源,以按计划触发此操作:
DesiredCount
来启动或停止。基于CloudWatch Events的输入将启动或停止ECS服务的Lambda函数:
if(event.status == 'stop'){
var params = {
cluster: process.env.ECS_CLUSTER,
service: process.env.ECS_SERVICE_NAME,
desiredCount: 0
};
}
else{
var params = {
cluster: process.env.ECS_CLUSTER,
service: process.env.ECS_SERVICE_NAME,
desiredCount: 1
};
}
var ecs = new AWS.ECS();
ecs.updateService(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
在Cloudformation模板中,创建将按计划调用Lambda函数的资源:
StartEcsLambdaSchedule:
Type: AWS::Events::Rule
Properties:
Description: >
A schedule for the Lambda function to start ECS service during office hours.
ScheduleExpression: !Ref StartEcsLambdaScheduleExpression
State: ENABLED
Targets:
- Arn: !Sub ${EcsTaskScheduleLambdaFunction.Arn}
Id: StartEcsLambdaScheduleV1
Input: '{"status": "start"}'
StopEcsLambdaSchedule:
Type: AWS::Events::Rule
Properties:
Description: >
A schedule for the Lambda function to stop ECS service after office hours.
ScheduleExpression: !Ref StopEcsLambdaScheduleExpression
State: ENABLED
Targets:
- Arn: !Sub ${EcsTaskScheduleLambdaFunction.Arn}
Id: StopEcsLambdaScheduleV1
Input: '{"status": "stop"}'
答案 4 :(得分:0)
下面将找出所有的qa、uat或dev集群(前提是它们的名字中有字符串qa、uat或dev),然后将其下所有服务的任务数设置为0。只需cron如果您想启动所有非生产环境,请使用此脚本并为 --desired-count 1
创建另一个 cron。创建 /tmp/ecs-stop.log 文件以按原样使用脚本。确保文件是可写的,并且脚本是可执行的,以便 cron 能够运行脚本并写入日志文件。
#!/bin/bash
export AWS_PAGER="" # Doesnt ask user to press q for paginated outputs
export AWS_PROFILE=default
d=$(date +%Y-%m-%d)
for cluster in $(/usr/local/bin/aws ecs list-clusters --output text | awk '{print $2}' | egrep -i 'qa|uat|dev' )
do
echo -e "Cluster ==> $cluster"
for service in $(/usr/local/bin/aws ecs list-services --cluster $cluster --output text | awk '{print $2}')
do
echo "Service ==> Stopping $service..."
/usr/local/bin/aws ecs update-service --cluster $cluster --service $service --desired-count 0 > /dev/null 2>&1
done
echo
done
echo "Stopped all non-prod ECS services."
echo "The script ran on $d" >> /tmp/ecs-stop.log
答案 5 :(得分:0)
这是我的解决方案,它高度依赖于一位出色的 AWS 员工 (Alfredo J)。
首先,您需要创建一个 Lambda 函数并添加此 Python 脚本:
import json
import boto3
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
client = boto3.client('ecs')
def lambda_handler(event, context):
cluster = event["cluster"]
service_names = event["service_names"]
service_desired_count = int(event["service_desired_count"])
for service_name in service_names.split(","):
response = client.update_service(
cluster=cluster,
service=service_name,
desiredCount=service_desired_count
)
logger.info("Updated {0} service in {1} cluster with desire count set to {2} tasks".format(service_name, cluster, service_desired_count))
return {
'statusCode': 200,
'new_desired_count': service_desired_count
}
脚本需要以下 JSON 格式的变量:
{
"cluster": "clusterName",
"service_names": "service1,service2",
"service_desired_count": "0"
}
地点:
cluster
是您要修改的集群的名称。service_names
是服务集合的数组。service_desired_count
是所需服务的数量。 0 是停止服务/秒,任何其他数字是启动服务/秒。创建完所有内容后,您需要在 Amazon EventBridge(以前称为 CloudWatch Events)中创建一些规则。在这里,您可以根据预期的时间表定义要触发的事件。
如果出现故障,您需要仔细检查创建的 IAM 角色是否具有所需的策略,例如:ecs:UpdateService
。您可以从日志中检查这一点。