Hakoで狙ったコンテナインスタンスにoneshotしたい

1週間くらい前からHakoに入門している @hatappiです

hatappi.hateblo.jp

以前hako oneshotを使用してサンプルのようなものを動かしました

今回は少しECSのタスク配置を掘り下げてそれをHakoで設定しようというものです

ECSにはクラスター内でタスクを起動する際にCPUやMemoryなどに基づいてタスクを配置していきます
これらはカスタマイズできてECS内ではタスク配置戦略, タスク配置の制約事項という2種類の定義があります

それぞれを公式のドキュメントから引用すると

タスク配置戦略

タスク配置戦略は、タスク配置またはタスクの終了でインスタンスを選択するためのアルゴリズムです。
たとえば、Amazon ECS でランダムにインスタンスを選択することも、インスタンスのグループ間に均等に分散されているタスクを持つインスタンスを選択することもできます。

タスク配置の制約事項

タスク配置の制約事項は、タスク配置中に考慮されるルールです。
たとえば、アベイラビリティーゾーンやインスタンスタイプに基づいたタスク配置の制約を使用できます。
名前と値のペアである属性をコンテナインスタンスに関連付け、属性に基づいて制約事項を使用しタスクを配置できます。

となっております
なるほど???
例としてはタスク配置戦略として複数のアベイラビリティーゾーンでタスクを均等に分散してタスク配置の制約事項としてインスタンスタイプがt2.mediumなものに配置といった感じでしょうか

今回に関しては後者のタスク配置の制約事項を使用していきます

やりたいこと

1つのクラスター内に6台のコンテナインスタンスが起動しているとする
ただこの内の1台だけはworkerAとして利用して他の5台でworkerBを動かしたいとする

やったこと

コンテナインスタンスには属性と呼ばれるカスタムメタデータがありECS側ではAMIのIDやインスタンスタイプなどが提供されています
この属性はユーザーがカスタム属性として追加することも出来るようになっています

コンテナインスタンスへのカスタム属性の追加に関しては下記の公式ドキュメントが参考になります
Amazon ECS タスク配置の制約事項 - Amazon EC2 Container Service

今回はコンテナインスタンスを起動したり削除したりを繰り返すので都度手動で設定するのは面倒だったのでAMIを作成する時に
/etc/ecs/ecs.configECS_INSTANCE_ATTRIBUTES={"role": "workerA"}のようにecsの設定ファイルに追記しています
※ 元となるAMIに関してはECS用に最適化されたものを使用しています 参考

今回ですとコンテナインスタンスrole=workerAという属性をもたせたので下記コマンドでフィルタリングできると思います

$ aws ecs list-container-instances --cluster my-cluster --filter 'attribute:role == workerA'
{
    "containerInstanceArns": [
        "arn:aws:ecs:ap-northeast-1:1111111:container-instance/aaaaaaaa"
    ]
}

最後にHakoの設定していきます
ところがここで1つ問題が発生しました
AWSRunTaskApi側にはタスクの配置戦略が設定出来るのですが
hako oneshotではそれが設定できませんでした

ここにきて出来ませんは残念な結果になってしまうので本体にPRを作成しました
そして無事マージしていただいたで安心して使用できます

github.com

設定はファイルは前回使用したものを編集して

test.yml

scheduler:
  type: ecs
  region: ap-northeast-1
  cluster: test-cluster
  placement_constraints:
    - type: 'memberOf'
      expression: 'attribute:role == workerA'
app:
  image: busybox
  log_configuration:
    log_driver: awslogs
    options:
      awslogs-group: test
      awslogs-region: ap-northeast-1

重要なところは

  placement_constraints:
    - type: 'memberOf'
      expression: 'attribute:role == workerA'

というところでこれによりカスタム属性として role=workerAと追加したインスタンスにたいしてタスクが配置できるようになります
後はこれをworkerBにも設定してあげれば hako oneshotで狙ったインスタンスにタスクを配置することが出来ます

最後に

Hako楽しい