以前、EC2インスタンスを特定の時間に起動・停止について投稿しました。
こちらではEC2インスタンスと、Auto Scaling環境のEC2インスタンスを、営業時間以外に停止する方法です。
こちらのAuto Scaling環境でのEC2インスタンスは、ECSクラスタを想定したものだったのですが、今回はFargateで構成されたECSクラスタ場合です。
コスト削減を目的とした場合、EC2インスタンスで構成されたECSクラスタは、そもそもEC2インスタンス自体を停止しなければなりませんでした。
ただ、ECSクラスタのインスタンスはAuto Scaling環境下で動いているいるので、EC2インスタンス自体を終了させても、ゾンビのように何度も立ち上がります。
そのため、Auto Scalingの Desired Capacity
(希望するキャパシティ)を 0 にすることで、EC2インスタンスを停止させていました。
それと異なり、Fargateでは停止するインスタンスは存在しません。
また、Fargateの料金体系を見ると、
Amazon ECS の場合、AWS Fargate の料金は、コンテナイメージのダウンロード (docker pull) を開始した時点から Amazon ECS タスク が終了するまでに使用された vCPU およびメモリリソースに基づいて計算され、最も近い秒数に切り上げられます。1 分の最低料金が適用されます。
とされています。
そのため、Fargate環境では、ECSクラスタのサービス設定にある Desired Count
を変えることでタスクを停止させます。
逆に単純です。
AWS-Cli
タスクの停止
aws ecs update-service \
--service $service_name \
--cluster $cluster_name \
--desired-count 0
タスクの起動
aws ecs update-service \
--service $service_name \
--cluster $cluster_name \
--desired-count ${desired_count:-1}
Lambda
タスクの停止
'use strict';
var AWS = require('aws-sdk');
module.exports.handler = function(event, context) {
var ecs = new AWS.ECS();
ecs.listClusters({}, function(err, data) {
if (err) { console.log(err, err.stack); return }
data.clusterArns.forEach(function(clusterArn) {
var cluster = clusterArn.split("/")[1];
ecs.listServices({cluster: cluster}, function(err, data) {
if (err) { console.log(err, err.stack); return }
var service = clusterArn.split("/")[1];
ecs.updateService({cluster: cluster, service: service, desiredCount: 0}, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
});
});
});
});
};
タスクの起動
'use strict';
var AWS = require('aws-sdk');
module.exports.handler = function(event, context) {
var ecs = new AWS.ECS();
ecs.listClusters({}, function(err, data) {
if (err) { console.log(err, err.stack); return }
data.clusterArns.forEach(function(clusterArn) {
var cluster = clusterArn.split("/")[1];
ecs.listServices({cluster: cluster}, function(err, data) {
if (err) { console.log(err, err.stack); return }
var service = clusterArn.split("/")[1];
ecs.updateService({cluster: cluster, service: service, desiredCount: 1}, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
});
});
});
});
};
但し、上記の場合では、対象アカウントのECSクラスタがすべて対象になってしまうので、クラスタに特定のタグを付け、対象のECSクラスタを絞るなど、対象となるECSクラスタのサービスを選別させる必要があれば、個別に対応が必要です。
また起動・停止させるクラスタやサービスが分かっているのであれば、ここまで複雑にする必要はなく、
'use strict';
var AWS = require('aws-sdk');
module.exports.handler = function(event, context) {
var ecs = new AWS.ECS();
ecs.updateService({cluster: CLUSTER_NAME, service: SERVICE_NAME, desiredCount: 0}, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
});
};
停止ならこれでOK。(起動の場合は、desiredCountを希望のタスク数に)
Lambda関数を作成したら、CloudWatch Eventsから特定の時間に起動させるだけです。