web-dev-qa-db-ja.com

ポートが使用中のため、ECSクラスターに新しいコンテナーをデプロイできません

私のサービスが使用するタスク定義は、イメージの「最新」のタグ付きバージョンを取得することです。

しかし、サービスを更新して「強制的に新しい展開」を行うと、イベントを見てこれを確認します。

service MYSERVICE was unable to place a task because no container instance met all of its requirements. The closest matching container-instance .... is already using a port required by your task

その後、クラスターに移動してすべてのタスクを停止しました。

その後、私のサービスに戻り、強制的に新しいデプロイで再度更新しました。これはうまくいったようです

新しいイメージをデプロイするたびに、すべてのタスクを停止してサービスを更新する必要がありますか?またはこれを行う「正しい」方法はありますか?

編集:したがって、1つのタスクを停止すると、サービスによって自動的に置き換えられます。そのため、サービスを更新して「強制的に新規デプロイ」し、一度に1つのタスクを停止して、一種のローリング更新を取得できます。私自身のスクリプトを超えてそれを自動化する機能があるかどうかわからない

ただフォローアップするために、答えで述べたように、私は動的ポートマッピングを使用する必要がありました。

最初は、起動時にロードバランサーがなかったため、実行中のコンテナーにアクセスするためにEC2インスタンスに直接アクセスしていました。もちろん、これを行うには、EC2ホストの静的ポートを公開する必要がありました。

ロードバランサーを追加しましたが、静的ポートマッピングは動的ポートマッピングのしくみを理解していません。ホストポートを「0」に設定するようにタスク定義を変更するだけで済みました。これで、ホストに静的ポートマッピングがなくなりました。NLBがルーティングを実行し、期待どおりに展開します。

8
red888

ECS(またはその他のオーケストレーター)を使用する場合は、 動的ポートマッピング を使用することをお勧めします。

基本的に、ECSはランダムに割り当てられていないポートをコンテナーに割り当てます。 ECSは、エージェントのイントロスペクションAPIまたはDockerクライアント自体を使用して、そのポート番号を取得する方法を提供します。ただし、ポートを取得しようとはしません。代わりに、Application Load Balancer(ALB)を使用します。ALBを使用すると、動的に割り当てられたポートとは関係なく、単一のエンドポイントを使用してターゲットコンテナーにアクセスできます。サービスを更新すると、ALBは中断することなくシームレスに最新バージョンのコンテナーに移行します。

最後に、コンテナ内のローカルポートは同じままなので、物事を異なる方法で処理する必要はありません。

他の答えは正しいですが、あなたが抱えている問題に当てはまるとは思いません。これは私のチームも直面している問題であり、同じインスタンスで複数のコンテナーを起動しようとすることとは実際には何の関係もないので、これを言います-私が正しく理解している場合は、既存のコンテナーを更新されたタスク定義。同じコンテナの複数のコピーを1つのボックスに配置する場合は、他の回答からの提案を(以下の詳細に加えて)必ず確認してください。ただし、ローリングデプロイの場合、動的ポートは必ずしも必要ではありません。

[[完全を期すための補足:EC2がECSによって停止されたリソースをクリーンアップするのにしばらく時間がかかるため、強制デプロイが投稿したエラーをスローした可能性があります。タスクを強制停止/開始しようとすると、同じ種類の問題が発生します。使用可能なインスタンスメモリの50%以上を割り当てるように構成されたコンテナーを再起動しようとすると、同様のエラーが発生します。 EC2インスタンスが完全にクリーンアップされ、ECSに報告されるまで、これらのタイプのリソースエラーが発生します。これには5分以上かかることを確認しました。 ]]

では、残念ながら今のところ、タスクのローリングリスタートを実行するためのAWSの優れた組み込みメカニズムはありません。ただし、canはローリングdeploysを実行します。

ご存知のように、サービスは指定されたタスク定義に依存しています。 タスク定義番号に依存しており、EC2インスタンスがコンテナタグを気にしないことに注意してください意志。

以下の設定は、ローリングデプロイを有効にするための魔法です。これらの構成オプションは、サービス設定にあります。

magic

ローリングデプロイを実行するには、少なくとも2つのタスクを実行する必要があります。

  • タスクの数-サービスが実行したいタスクの数(n)
  • 最小正常パーセント-新しいタスクをデプロイするときのnの最小正常%
  • 最大パーセント-新しいタスクをデプロイするときに追加できるnの最大%

したがって、実際の例として、次の構成があるとします。

Number of tasks: 3
Minimum healthy percent:  50
Maximum percent: 100

サービスが指しているタスク定義を変更すると、ローリングデプロイが開始されます。 3実行中のタスクがありますが、>=50%は正常です。 ECSはタスクの1つを強制終了し、健全な%を66%まで下げますが、まだ50%を上回っています。新しいタスクが起動すると、サービスは再び100%になり、ECSは次のインスタンスへのデプロイのローリングを続行できます。

同様に、minimum % == 100およびmaximum % == 150(容量がある場合)の構成がある場合、ECSは追加のタスクを起動します;起動すると、133%のパーセンテージが正常になり、古いタスクの1つを安全に強制終了できます。このプロセスは、新しいタスクが完全にデプロイされるまで続きます。

14
MrDuk

動的ポートがない場合、インスタンスで使用されているポートは他のインスタンスでは使用できないため、コンテナごとにサービスのインスタンスを1つだけデプロイできます。サービスを更新すると、サービスはすべてのインスタンスを再起動しようとします。単一のEC2コンテナーで複数のインスタンスが起動されている場合、起動は失敗します。

ECSクラスターで動的ポートマッピングを備えたDockerコンテナーを使用する方が良い。

4
S.K.

自動スケーリングのために同じマイクロサービス(コンテナー)の新しいインスタンスが起動したときにも同じ問題に直面していました。各マイクロサービスのポートはapplication.ymlで修正および構成されているため、自動スケーリングによって同じサービスが同じEC2で起動すると、それが試行されます以前のインスタンスですでに使用されているのと同じポートを取得する(たとえば、Xをポート3102でマイクロサービスとして実行している場合、同じサービスの別のインスタンスが自動スケーリングによって起動した場合、別のEC2マシンまたは同じで起動する可能性がありますECSクラスター内のEC2マシンですが、ECSはCPUとRAMの可用性に基づいてマイクロサービスの新しいインスタンスを起動する場所を決定します。新しいインスタンスが別のEC2マシンで起動した場合、ポートは解放されるため問題はありませんが、インスタンスが同じec2で起動する場合起動せず、ポートがすでに使用されていることを叫ぶマシン)

これを解決するには、ECSクラスターのタスク定義のみを更新する必要があります。イメージを変更する必要はありません。タスク定義で動的ポートマッピングを有効にする必要があります。これにより、任意の数のマイクロサービスインスタンスを実行できます。同じEc2マシン上

動的ポートマッピングなしのタスク定義構成はになります

  1. ネットワークモード-ホスト
  2. ポートマッピングでは、コンテナーポートは次のようになります:application.ymlで構成されたアプリケーションのポート

enter image description here

enter image description here

ECSで動的ポートマッピングを有効にする場合

  • ネットワークモードの変更:ブリッジ
  • ポートマッピングを構成し、ホストポートを0に、コンテナーポートをapplication.ymlで構成されたアプリケーションのポートと同等にします

enter image description hereenter image description here

2
ABHAY JOHRI

まず、desired-countを0に設定します

aws ecs update-service --cluster cluster_name --service service_name --desired-count 0

以下のコマンドの後、実行中のコンテナインスタンスの数を動的に確認できます

aws ecs describe-services --cluster cluster_name --service service_name

次に、以下のコマンドを実行します

aws ecs update-service --cluster cluster_name --service service_name --desired-count 1
1
erncnerky