ECS で EC2 と Fargate の起動タイプのタスクを併用して同じアプリケーションを実行してみた。ワークロードがない場合は、EC2 の1タスクだけ実行され(Fargate のタスクは 0)、EC2 のCPU使用率が50%を超えると EC2 に1タスク追加され、EC2 のCPU使用率が80% を超えると Fargate のタスクが追加されていくというのを試してみた。
EC2インスタンスから ab で負荷をかけて、
ECS の EC2 インスタンスにログインして htop でワークロードを確認するとこんな感じ。
CloudWatch のダッシュボードを見るとこんな感じで、CPU使用率が上がり、
ECS の EC2 は +1、Fargate は +1 タスクがスケールアウトしている。
手順は以下の通り。
準備
キーペア作成
- ECSを利用するリージョンでキーペアを作成していない場合は作成しておく。
ELB
ECS
ECSタスク定義(EC2タイプ)作成
ECSタスク定義(Fargateタイプ)作成
クラスター作成
サービス(EC2起動タイプ)作成
- 起動タイプ: EC2
- タスク定義: ec2-task
- クラスター: ec2-fg-mix-cluster
- サービス名: ec2-service
- タスクの数: 1
- ELBタイプ: Application Load Balancer
- ELB名: ec2-fg-mix-alb
- パスパターン: /
- 評価順:1
- ヘルスチェックパス: /
- Service Auto Scaling: Service Auto Scaling の設定を変更することで、サービスの必要数を調整する
- タスクの最小数: 1
- タスクの最大数: 2
- 自動タスクスケーリングポリシー
- ポリシー名: EC2ScaleOutPolicy
- 既存のアラームの使用: EC2ScaleOutAlarm
- スケーリングアクション: 追加 1 tasks、次の条件の場合 50 <= CPUUtilization
- クールダウン期間: 30
- ポリシー名: EC2ScaleInPolicy
- 既存のアラームの使用: EC2ScaleInAlarm
- スケーリングアクション: 削除 1 tasks、次の条件の場合 40 <= CPUUtilization
- クールダウン期間: 30
- ポリシー名: EC2ScaleOutPolicy
サービス(FARGATE起動タイプ)作成
- 起動タイプ: FARGATE
- タスク定義: fargate-task
- クラスター: ec2-fg-mix-cluster
- サービス名: fg-service
- タスクの数: 1
- クラスター VPC: デフォルトVPC
- サブネット: ap-northeast-1a のサブネット
- パブリック IP の自動割り当て: ENABLED
- セキュリティグループ: ECS-SG
- ELBタイプ: Application Load Balancer
- ELB名: ec2-fg-mix-alb
- パスパターン: /
- 評価順:1
- ヘルスチェックパス: /
- Service Auto Scaling: Service Auto Scaling の設定を変更することで、サービスの必要数を調整する
- タスクの最小数: 1
- タスクの最大数: 10
- 自動タスクスケーリングポリシー
- ポリシー名: FgScaleOutPolicy
- 既存のアラームの使用: FgScaleOutAlarm
- スケーリングアクション: 追加 1 tasks、次の条件の場合 80 <= CPUUtilization
- クールダウン期間: 30
- ポリシー名: Fg2ScaleInPolicy
- 既存のアラームの使用: FgScaleInAlarm
- スケーリングアクション: 削除 1 tasks、次の条件の場合 70 <= CPUUtilization
- クールダウン期間: 30
- ポリシー名: FgScaleOutPolicy
CloudWatch Alarm
EC2起動タイプのスケールアウト用
- 名前: EC2ScaleOutAlarm
- CPUUtilization: >= 50
- 期間: 1 / 1 データポイント
- アクション
- アラームが次の時: 警告
- リソースタイプから: EC2 Container Service
- 次から: service/ec2-fg-mix-cluster/ec2-service
- 次のアクションを実行: EC2ScaleOutPolicy
EC2起動タイプのスケールイン用
- 名前: EC2ScaleInAlarm
- CPUUtilization: <= 40
- 期間: 1 / 1 データポイント
- アクション
- アラームが次の時: 警告
- リソースタイプから: EC2 Container Service
- 次から: service/ec2-fg-mix-cluster/ec2-service
- 次のアクションを実行: EC2ScaleInPolicy
Fargate起動タイプのスケールアウト用
- 名前: FgScaleOutAlarm
- CPUUtilization: >= 80
- 期間: 1 / 1 データポイント
- アクション
- アラームが次の時: 警告
- リソースタイプから: EC2 Container Service
- 次から: service/ec2-fg-mix-cluster/fg-service
- 次のアクションを実行: FgScaleOutPolicy
Fargate起動タイプのスケールイン用
- 名前: FgScaleInAlarm
- CPUUtilization: <= 70
- 期間: 1 / 1 データポイント
- アクション
- アラームが次の時: 警告
- リソースタイプから: EC2 Container Service
- 次から: service/ec2-fg-mix-cluster/fg-service
- 次のアクションを実行: FgScaleInPolicy
負荷をかけてスケールアウト/インを試す
- ECSのEC2ホストに
$ sudo yum -y install htop
$ sudo yum -y install httpd
- 負荷をかける
$ ab -k -n 900000000 -c 100 http://*****.ap-northeast-1.elb.amazonaws.com/ & $ ab -k -n 900000000 -c 100 http://*****.ap-northeast-1.elb.amazonaws.com/ & $ ab -k -n 900000000 -c 100 http://*****.ap-northeast-1.elb.amazonaws.com/ & $ ab -k -n 900000000 -c 100 http://*****.ap-northeast-1.elb.amazonaws.com/ & $ ab -k -n 900000000 -c 100 http://*****.ap-northeast-1.elb.amazonaws.com/ & $ ab -k -n 900000000 -c 100 http://*****.ap-northeast-1.elb.amazonaws.com/ &
補足
- ECSのサービスを作成時にスケールアウト/インポリシーを仮で作成後に、CloudWatch Alarm でスケールアウト/インのアラームを作成し、ECSのサービスを更新して作成した CloudWatch Alarm と紐付ける。
- 同じサービス名で削除して作り直すとマネジメントコンソールでは消えていても、バックグラウンドで削除完了していないと "Unable to Start a service that is still Draining." というエラーになる模様。しばらくして作り直すと成功した。
- 同一クラスターにEC2とFARGATEのタスクを共存させる場合に以下のネットワークモードの組合せは可能なことを確認済。
- FARGATE:awsvpc、EC2:awsvpc
- FARGATE:awsvpc、EC2:bridge
- 起動タイプがEC2でネットワークモードを awsvpc にした場合、1タスクで1つのENIを使うので、EC2インスタンスの ENI の最大数を超えるタスクを起動することはできない。ENIの最大数を超えるタスクを起動しようとすると RESOURCE:ENI エラーが発生する。
RESOURCE:* (container instance ID)
API failures エラーメッセージ - Amazon Elastic Container Service
タスクによってリクエストされたリソースは、指定したコンテナインスタンスで使用できません。リソースが CPU、メモリ、ポート、または Ellastic Network Interface の場合は、コンテナインスタンスのクラスターへの追加が必要になる場合があります。RESOURCE:ENI エラーの場合、awsvpc ネットワークモードを使用するタスクで必要な Elastic Network Interface アタッチメントポイントが、クラスターで利用できないことを示しています。Amazon EC2 インスタンスにアタッチできるネットワークインターフェイスの数には制限があり、プライマリネットワークインターフェイスも 1 つ分としてカウントされます。各インスタンスタイプでサポートされる Network Interface の数の詳細については、Linux インスタンス用 Amazon EC2 ユーザーガイドの「各インスタンスタイプのネットワークインターフェイスごとの IP アドレス」を参照してください。
- ab コマンドは -k オプションをつけて keep alive にしたほうがTCP接続のオーバーヘッドが小さくサーバーサイド(ECS)の CPU 使用率を上げやすい。