AWSのシンプルなCI / CDコンテナー


14

AWS Code Pipeline、Code Buildを使用して新しいDockerコンテナーを作成し、ECRにプッシュしています。

私のアプリケーションは、シンプルで単純な単一コンテナーベースです。現在実行中のコンテナをプルダウンし、ECSレジストリから新しいコンテナを再起動するための摩擦の少ないアプローチ(コードパイプラインを介したコードビルドの出力)。

EC2ユーザーデータを使用してCloudFormationを試し、一方にカスタムスクリプトを、もう一方にECSを使用してCloudFormationを試しました(まだ成功していません)。もっと明確でシンプルなアプローチが必要だと強く感じています。

回答:


16

ECSコンテナーインスタンス(Dockerホストについて話している-ここでAWSの用語が気に入らない)とデプロイを2つの別個のものとして保持します。

ECSスタックを起動して実行します。CloudFormationおよびAuto-scalingグループを介して管理できますが、それで問題ありません。ちょうどあなたが展開するプラットフォームとしてクラスタを考える、あなたがする必要はありませ何か再デプロイ

次に、CDの場合、最も簡単な方法は、サービス定義を更新して新しいタスク定義を使用し、ECSでコンテナーをローリング更新することです。

タスクを開始するたびに、ECSは、イメージがローカルにある場合でもdocker pull image:tagを実行して、そのimage:tagの最新バージョンがあることを確認します。したがって、実際に使用するイメージタグは重要ではありません(ビルドごとにタグを変更する必要はありません)。

つまり、myimage:latestを何度も何度もビルドして、簡単にデプロイできます。

必要なのは、image = myimage:latestのタスク定義です。そのタスク定義を使用してサービスを作成し、ECSがタスク(サービスのインスタンス)を開始するたびに、作成した最新の「myimage:latest」になります。

そこから、パズルの1つのピースだけが欠落しています。CodeDeployから何か、おそらくラムダ関数を呼び出して、タスク定義の新しいリビジョンを作成し、サービスを更新すると、ECSはそのリビジョンの新しいタスクを自動的に作成します。古いタスクを削除します。

例:

MyServiceというサービスを作成したと仮定します。タスク定義MyTaskDefinition:1(リビジョン1)に対して2つのタスクを実行するようにそのサービスを構成したこと。そのタスク定義では、イメージが「myimage:latest」に設定されているコンテナ定義が1つあります。

  1. 昨日、ID(SHA)365d8f7bf565を持つmyimage:latestをビルドしました。
  2. コンテナインスタンスABCはMyTaskDefinition- 1 -containerName-someLongId という名前のタスクを実行しています。そのコンテナを検査すると、「sha256:365d8f7bf565 ..........」というイメージが実行されています
  3. 他のコンテナインスタンスDEFは別のタスクを実行しています。名前は似ていますが(IDのみが異なります)、同じイメージを実行しています。
  4. リポジトリに変更をプッシュします。
  5. CodePipelineはその変更をピックアップし、イメージをECRにビルドして公開します。
  6. その新しいDockerイメージもmyimage:latestですが、そのID(SHA)はf7ec5e54ac96です
  7. 次に、パイプラインにステップを追加して、Lambda関数とAWS NodeJS SDKを使用してクラスターへの呼び出しを行う必要があります。
    1. 新しいタスク定義を作成します(以前とまったく同じになります)。それはMyTaskDefinition:2になります
    2. MyServiceを更新して、MyTaskDefinition:2(1ではなく)を使用します。
  8. ECSは新しいタスクを作成します。コンテナ名はMyTaskDefinition- 2 -containerName-someLongIdになります。これらのコンテナを検査すると、「sha256:f7ec5e54ac96 .......」が実行されていることがわかります。おそらく、コンテナインスタンスABCに2つのタスクがあり、おそらくそれらはスプレーされます(サービスの構成によって異なります)
  9. しばらくすると、ECSはABCとDEFから古いタスクMyTaskDefinition-1-containerName-someLongIdを削除します。

注:実際に新しいタスク定義を作成する必要はありません。必要に応じて、代わりにサービスのタスクリストを取得し、それらを1つずつ手動で停止できます。新しいタスクを停止する前に、ECSがタスクを再起動するのを待つ必要があります(つまり、最初のコンテナーを停止し、ECSがそれを置き換えるのを待って、2番目のコンテナーを停止します)。ECSがコンテナーを再起動すると、前に説明したように、ビルドされた最新のmyimage:latestが取得されます。新しいタスク定義を作成する方が簡単でエラーが少ないと思います(新しいタスク定義があれば、ECSはローリング更新を処理します)。


すごい-CI / CD for dockerのマニュアルが欠けていると答えます。ありがとうございました。
ナビーンビジェイ

3

説明した簡単なユースケースでは、DockerのElastic Beanstalkをチェックすることをお勧めします。これは、ベアECSの使用のような最小のソリューションではありませんが、ELB、EC2 AutoScale、ヘルスモニタリングなどの自動管理および構成されたサービスの恩恵を受けることができます。

高レベルの要約:

  1. 特定のタグmyimage:testedを使用するようにElastic Beanstalkを設定します
  2. コードパイプライン/ビルドを使用して、「tested」タグをビルド、テスト、およびプロモーションします
  3. Elastic Beanstalkデプロイメントをトリガーします。これにより、昇格したイメージmyimage:testedがすべてのインスタンスにプルされ、さまざまなデプロイメント戦略が利用可能になります。

同じタグの再利用に基づくこのアプローチ、代替アプローチはビルドIDを使用してタグを生成します(myimage:tested-42など)。これは、新しいタグで毎回Elastic Beanstalkを更新する必要がありますが、デプロイされたリビジョンをよりきめ細かく制御できます。


0

2番目のElastic Beantalkは、その単純さのためです。セットアップと展開は非常に簡単です。

docker-composeに精通している場合、別のアプローチはdocker-compose.ymlを定義し、ecs-cliを使用してECSに直接デプロイすることです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.