使用創建 Amazon ECS 資源 AWS CDK - Amazon Elastic Container Service

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用創建 Amazon ECS 資源 AWS CDK

這 AWS Cloud Development Kit (AWS CDK) 是一個基礎架構即程式碼 (IAC) 架構,您可以使用您選擇的程式設計語言來定義 AWS 雲端基礎架構。若要定義您自己的雲端基礎結構,您必須先撰寫包含一或多個堆疊CDK的應用程式 (使用其中一種支援的語言)。然後,您將其合成到 AWS CloudFormation 模板中,並將資源部署到您的 AWS 帳戶. 請按照本主題中的步驟使用 Amazon 彈性容器服務 (AmazonECS) 和 Fargate AWS CDK 上部署容器化 Web 伺服器。

「 AWS 建構程式庫」CDK (隨附於) 提供的模組可讓您用來建立提 AWS 服務 供的資源模型。針對熱門服務,程式庫會提供具有智能預設和最佳實務的彙整建構。其中的模組,特別是 aws-ecs-patterns,提供了高階抽象概念,讓您可以僅憑幾行程式碼行定義您的容器化服務和所有必要的支援資源。

本主題使用 ApplicationLoadBalancedFargateService 建構。此建構會在應用程式負載平衡器後方的 Fargate 上部署 Amazon ECS 服務。該aws-ecs-patterns模塊還包括使用網絡負載平衡器並在 Amazon EC2 上運行的構造。

在開始這項工作之前,請先設定您的開 AWS CDK 發環境,然後執 AWS CDK 行下列命令來安裝。如需如何設定開 AWS CDK 發環境的指示,請參閱 AWS CDK -先決條件入門。

npm install -g aws-cdk
注意

這些指示假設您正在使用 AWS CDK v2。

步驟 1:設定您的 AWS CDK 專案

為您的新 AWS CDK 應用程序創建一個目錄並初始化項目。

TypeScript
mkdir hello-ecs cd hello-ecs cdk init --language typescript
JavaScript
mkdir hello-ecs cd hello-ecs cdk init --language javascript
Python
mkdir hello-ecs cd hello-ecs cdk init --language python

專案啟動後,啟動專案的虛擬環境並安裝 AWS CDK的基準相依性。

source .venv/bin/activate python -m pip install -r requirements.txt
Java
mkdir hello-ecs cd hello-ecs cdk init --language java

將此 Maven 項目導入到您的 Java 中IDE。例如,在 Eclipse 中,使用檔案 > 匯入 > Maven > 現有的 Maven 專案

C#
mkdir hello-ecs cd hello-ecs cdk init --language csharp
Go
mkdir hello-ecs cd hello-ecs cdk init --language go
注意

AWS CDK 應用程式範本會使用專案目錄的名稱來產生來源檔案和類別的名稱。在此範例中,目錄名為 hello-ecs。若使用不同的專案目錄名稱,您的應用程式將與這些說明不相符。

AWS CDK v2 在所謂aws-cdk-lib的單個包 AWS 服務 中包含所有人的穩定構造。在初始化專案時,此套件會安裝為相依性套件。使用某些程式設計語言時,套件會在您第一次建置專案時安裝。本主題介紹如何使用 Amazon ECS 模式構造,該構造提供了與 Amazon ECS 合作的高級抽象。此模組依賴 Amazon ECS 建構和其他建構來佈建 Amazon ECS 應用程式所需的資源。

您用來將這些程式庫匯入CDK應用程式的名稱可能會因您使用的程式設計語言而略有不同。作為參考,以下是每種受支持的CDK編程語言中使用的名稱。

TypeScript
aws-cdk-lib/aws-ecs aws-cdk-lib/aws-ecs-patterns
JavaScript
aws-cdk-lib/aws-ecs aws-cdk-lib/aws-ecs-patterns
Python
aws_cdk.aws_ecs aws_cdk.aws_ecs_patterns
Java
software.amazon.awscdk.services.ecs software.amazon.awscdk.services.ecs.patterns
C#
Amazon.CDK.AWS.ECS Amazon.CDK.AWS.ECS.Patterns
Go
github.com/aws/aws-cdk-go/awscdk/v2/awsecs github.com/aws/aws-cdk-go/awscdk/v2/awsecspatterns

步驟 2:使用在 AWS CDK Fargate 上定義容器化網頁伺服器

使用amazon-ecs-sample來自的容器映像檔 DockerHub。此映像包含在 Amazon Linux 2 上運行的PHP網絡應用程序。

在您建立的 AWS CDK 專案中,編輯包含堆疊定義的檔案,使其類似於下列其中一個範例。

注意

堆疊是部署的單位。所有資源必須在同一堆疊中,而一個堆疊中的所有資源都要部署在一起。若某資源無法部署,任何已部署的其他資源將會復原。一個 AWS CDK 應用程序可以包含多個堆棧,並且一個堆棧中的資源可以引用另一個堆棧中的資源。

TypeScript

更新 lib/hello-ecs-stack.ts 使其相似於以下內容。

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as ecs from 'aws-cdk-lib/aws-ecs'; import * as ecsp from 'aws-cdk-lib/aws-ecs-patterns'; export class HelloEcsStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new ecsp.ApplicationLoadBalancedFargateService(this, 'MyWebServer', { taskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), }, publicLoadBalancer: true }); } }
JavaScript

更新 lib/hello-ecs-stack.js 使其相似於以下內容。

const cdk = require('aws-cdk-lib'); const { Construct } = require('constructs'); const ecs = require('aws-cdk-lib/aws-ecs'); const ecsp = require('aws-cdk-lib/aws-ecs-patterns'); class HelloEcsStack extends cdk.Stack { constructor(scope = Construct, id = string, props = cdk.StackProps) { super(scope, id, props); new ecsp.ApplicationLoadBalancedFargateService(this, 'MyWebServer', { taskImageOptions: { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), }, publicLoadBalancer: true }); } } module.exports = { HelloEcsStack }
Python

更新 hello-ecs/hello_ecs_stack.py 使其相似於以下內容。

import aws_cdk as cdk from constructs import Construct import aws_cdk.aws_ecs as ecs import aws_cdk.aws_ecs_patterns as ecsp class HelloEcsStack(cdk.Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) ecsp.ApplicationLoadBalancedFargateService(self, "MyWebServer", task_image_options=ecsp.ApplicationLoadBalancedTaskImageOptions( image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample")), public_load_balancer=True )
Java

更新 src/main/java/com.myorg/HelloEcsStack.java 使其相似於以下內容。

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.ecs.ContainerImage; import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedFargateService; import software.amazon.awscdk.services.ecs.patterns.ApplicationLoadBalancedTaskImageOptions; public class HelloEcsStack extends Stack { public HelloEcsStack(final Construct scope, final String id) { this(scope, id, null); } public HelloEcsStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); ApplicationLoadBalancedFargateService.Builder.create(this, "MyWebServer") .taskImageOptions(ApplicationLoadBalancedTaskImageOptions.builder() .image(ContainerImage.fromRegistry("amazon/amazon-ecs-sample")) .build()) .publicLoadBalancer(true) .build(); } }
C#

更新 src/HelloEcs/HelloEcsStack.cs 使其相似於以下內容。

using Amazon.CDK; using Constructs; using Amazon.CDK.AWS.ECS; using Amazon.CDK.AWS.ECS.Patterns; namespace HelloEcs { public class HelloEcsStack : Stack { internal HelloEcsStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { new ApplicationLoadBalancedFargateService(this, "MyWebServer", new ApplicationLoadBalancedFargateServiceProps { TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions { Image = ContainerImage.FromRegistry("amazon/amazon-ecs-sample") }, PublicLoadBalancer = true }); } } }
Go

更新 hello-ecs.go 使其相似於以下內容。

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" // "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" "github.com/aws/aws-cdk-go/awscdk/v2/awsecs" "github.com/aws/aws-cdk-go/awscdk/v2/awsecspatterns" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) type HelloEcsStackProps struct { awscdk.StackProps } func NewHelloEcsStack(scope constructs.Construct, id string, props *HelloEcsStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // The code that defines your stack goes here // example resource // queue := awssqs.NewQueue(stack, jsii.String("HelloEcsQueue"), &awssqs.QueueProps{ // VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)), // }) res := awsecspatterns.NewApplicationLoadBalancedFargateService(stack, jsii.String("MyWebServer"), &awsecspatterns.ApplicationLoadBalancedFargateServiceProps{ TaskImageOptions: &awsecspatterns.ApplicationLoadBalancedTaskImageOptions{ Image: awsecs.ContainerImage_FromRegistry(jsii.String("amazon/amazon-ecs-sample"), &awsecs.RepositoryImageProps{}), }, }, ) awscdk.NewCfnOutput(stack, jsii.String("LoadBalancerDNS"), &awscdk.CfnOutputProps{Value: res.LoadBalancer().LoadBalancerDnsName()}) return stack } func main() { defer jsii.Close() app := awscdk.NewApp(nil) NewHelloEcsStack(app, "HelloEcsStack", &HelloEcsStackProps{ awscdk.StackProps{ Env: env(), }, }) app.Synth(nil) } // env determines the AWS environment (account+region) in which our stack is to // be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html func env() *awscdk.Environment { // If unspecified, this stack will be "environment-agnostic". // Account/Region-dependent features and context lookups will not work, but a // single synthesized template can be deployed anywhere. //--------------------------------------------------------------------------- return nil // Uncomment if you know exactly what account and region you want to deploy // the stack to. This is the recommendation for production stacks. //--------------------------------------------------------------------------- // return &awscdk.Environment{ // Account: jsii.String("123456789012"), // Region: jsii.String("us-east-1"), // } // Uncomment to specialize this stack for the AWS Account and Region that are // implied by the current CLI configuration. This is recommended for dev // stacks. //--------------------------------------------------------------------------- // return &awscdk.Environment{ // Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")), // Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")), // } }

前面的簡短程式碼片段包括以下內容:

  • 服務的邏輯名稱:MyWebServer

  • 從以下位置取得的容器影像 DockerHub:amazon/amazon-ecs-sample

  • 其他相關資訊,例如負載平衡器具有公有地址,而且可以從網際網路存取的事實。

AWS CDK 將建立部署 Web 伺服器所需的所有資源,包括下列資源。此範例中省略了這些資源。

  • Amazon ECS 集群

  • Amazon VPC 和 Amazon EC2 實例

  • Auto Scaling 群組

  • Application Load Balancer

  • IAM 角色和政策

堆疊中定義的所有 Amazon ECS 服務會共用部分自動佈建的資源。

保存來源檔案,然後在應用程式的主目錄中執行 cdk synth 指令。 AWS CDK 運行該應用程序並從中合成 AWS CloudFormation 模板,然後顯示模板。範本是大約 600 行的檔YAML案。檔案的開頭如此處所示。您的範本可能與此範例不同。

Resources: MyWebServerLB3B5FD3AB: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: LoadBalancerAttributes: - Key: deletion_protection.enabled Value: "false" Scheme: internet-facing SecurityGroups: - Fn::GetAtt: - MyWebServerLBSecurityGroup01B285AA - GroupId Subnets: - Ref: EcsDefaultClusterMnL3mNNYNVpcPublicSubnet1Subnet3C273B99 - Ref: EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2Subnet95FF715A Type: application DependsOn: - EcsDefaultClusterMnL3mNNYNVpcPublicSubnet1DefaultRouteFF4E2178 - EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2DefaultRouteB1375520 Metadata: aws:cdk:path: HelloEcsStack/MyWebServer/LB/Resource MyWebServerLBSecurityGroup01B285AA: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Automatically created Security Group for ELB HelloEcsStackMyWebServerLB06757F57 SecurityGroupIngress: - CidrIp: 0.0.0.0/0 Description: Allow from anyone on port 80 FromPort: 80 IpProtocol: tcp ToPort: 80 VpcId: Ref: EcsDefaultClusterMnL3mNNYNVpc7788A521 Metadata: aws:cdk:path: HelloEcsStack/MyWebServer/LB/SecurityGroup/Resource # and so on for another few hundred lines

若要在您的中部署服務 AWS 帳戶,請在應用程式的主目錄中執行cdk deploy命令。系統會要求您核准 AWS CDK 產生的IAM原則。

部署需要幾分鐘的時間,在此期間 AWS CDK 建立數個資源。部署輸出的最後幾行包括負載平衡器的公用主機名稱和新 Web 伺服器URL。如下所示:

Outputs: HelloEcsStack.MyWebServerLoadBalancerDNSXXXXXXX = Hello-MyWeb-ZZZZZZZZZZZZZ-ZZZZZZZZZZ.us-west-2.elb.amazonaws.com HelloEcsStack.MyWebServerServiceURLYYYYYYYY = http://Hello-MyWeb-ZZZZZZZZZZZZZ-ZZZZZZZZZZ.us-west-2.elb.amazonaws.com

步驟 3:測試 Web 伺服器

URL從部署輸出複製並貼到您的網頁瀏覽器中。此時會顯示下列來自 Web 伺服器的歡迎使用訊息。

Amazon ECS 示例應用程序的屏幕截圖。輸出表明「您的應用程序現在正在 Amazon 上運行ECS」。

步驟 4:清理

在您完成 Web 伺服器之後,請在應用程式的CDK主目錄中執行cdk destroy命令,以結束服務。這樣做可以防止您未來意外產生任何費用。

後續步驟

若要進一步了解如何使用開發 AWS 基礎結構 AWS CDK,請參閱開發AWS CDK 人員指南

如需以您選擇的語言撰寫 AWS CDK 應用程式的相關資訊,請參閱下列內容:

TypeScript

使用 AWS CDK 中 TypeScript

JavaScript

使用 AWS CDK 中 JavaScript

Python

AWS CDK 在 Python 中使用

Java

AWS CDK 在 Java 中使用

C#

AWS CDK 在 C# 中使用

Go

AWS CDK 在 Go 中使用

如需有關本主題中使用之「 AWS 建構程式庫」模組的詳細資訊,請參閱下列 AWS CDK API參考概觀。