LoginSignup
18
18

More than 5 years have passed since last update.

Fargateで起動しているECSクラスタのタスクを特定の時間に起動・停止

Posted at

以前、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から特定の時間に起動させるだけです。

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18