Day 22 – CDK 建置 Amazon Elastic Container Service(ECS) Service – Fargate

2020 12th 鐵人賽

今天來介紹 ECS 使用 Fargate 它是一個由 AWS 直接管理 Container 的服務,之前介紹的 EC2 使用 ECS 需要自己管理 Host 的部分,使用了 Fargate 連 Host 都不用自己管理了,聽起來是不是很吸引人呢 ヽ(●´∀`●)ノ

https://i0.wp.com/ithelp.ithome.com.tw/upload/images/20201008/20117701YXiGtZFHZF.jpg?w=640&ssl=1

ECS 使用 Fargate 的好處

不用管理 ECS agent

使用 Fargate 除了 Host 不用自己管理之外還有什麼好處呢?另外一個是 ECS agent 的部分,在之前的文章沒有介紹到其實 EC2 如果要跑 ECS 上面會跑有 ECS 的 Agent 而這個版本常常會更新(如左下角),如果更新就需要用右上角的 Update agent 去更新,在更新的時候其實 ECS 會把目前這台機器上所有的 Container 移走那可能就需要自己注意會不會有服務不穩定的問題,如果使用 Fargate 就不用擔心這件事情,因為 AWS 會處理好這件事情

https://i0.wp.com/ithelp.ithome.com.tw/upload/images/20201006/20117701eozvve49xX.png?w=640&ssl=1

不會有資源浪費

如果自己維護 ECS host 還會遇到像是一台機器可能有 100 vCPU 而我們今天全部的 ECS conatiner 只用到了 80 vCPU 剩下的 20 vCPU 還是需要付費的,而使用 Fargate 就沒有這個問題,因為 Fargate 計價是直接計算 vCPU 與記憶體計價的,用多少拿多少減少資源浪費

用 EC2 沒有好處嗎?

其實也不能說沒有好處,因為如果我們有特別需求需要進入 Host 查看東西或是自己有更多的調教 Host 方法這樣在 Fargate 機器上就沒有辦法實作,所以基本上還是看有需求決定應該怎麼選擇機器

CDK 使用 Fargate

定義 Cluster

就算使用 Fargate 我們還是需要一個 Cluster 來管理我們的 Fargate 機器

const cluster = new ecs.Cluster(this, "EcsCluster", { vpc });

定義 Fargate Task Definition

Fargate 需要定義自己的 Task Definition 與昨天的 EC2 一樣需要先定義 Task Definition

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef");

https://i0.wp.com/ithelp.ithome.com.tw/upload/images/20201006/20117701UFJ2oimJld.png?w=640&ssl=1

定義 Container

今天的測試一樣使用 amazon/amazon-ecs-sample 來當測試腳本

const container = taskDefinition.addContainer("WebContainer", {
  image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
  memoryLimitMiB: 512,
});
container.addPortMappings({
  containerPort: 80,
});

定義 Fargate Service

把剛剛定義好的 Cluster 與 Task Definition 組合成一個 Service

const fatgetService = new ecs.FargateService(this, "FargateService", {
  cluster,
  taskDefinition,
});

https://i1.wp.com/ithelp.ithome.com.tw/upload/images/20201006/20117701qQ10GKW9z0.png?w=640&ssl=1

定義 ALB

為了測試需要我們還是設定一個 ALB 好讓我們在外面可直接戳 DNS 拿到結果

const lb = new elbv2.ApplicationLoadBalancer(this, "LB", {
  vpc,
  internetFacing: true,
});
const listener = lb.addListener("Listener", { port: 80 });
listener.addTargets("ECS", {
  port: 80,
  targets: [fatgetService],
});

觀察一下 ECS Instances

我們可以看一下如果是使用 Fargate 的 task 就不會在 ECS Instances 的地方看到任何機器囉!

https://i0.wp.com/ithelp.ithome.com.tw/upload/images/20201006/20117701HCagSxayOU.png?w=640&ssl=1

整理一下

其實整個程式量真的很少大概 30 行就可以起一個可以用的 Web 服務而且是高可用性的真的很簡單 ~

const vpc = new ec2.Vpc(this, "Vpc", { maxAzs: 3, natGateways: 1 });

const cluster = new ecs.Cluster(this, "EcsCluster", { vpc });

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef");

const container = taskDefinition.addContainer("WebContainer", {
  image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
  memoryLimitMiB: 512,
});
container.addPortMappings({
  containerPort: 80,
});

const fatgetService = new ecs.FargateService(this, "FargateService", {
  cluster,
  taskDefinition,
});

const lb = new elbv2.ApplicationLoadBalancer(this, "LB", {
  vpc,
  internetFacing: true,
});
const listener = lb.addListener("Listener", { port: 80 });
listener.addTargets("ECS", {
  port: 80,
  targets: [fatgetService],
});

測試 ALB

最後我們還是測試一下 ALB 的結果,可想而知一定也是正常拉 XD https://i1.wp.com/ithelp.ithome.com.tw/upload/images/20201006/20117701qpFuuZq221.png?w=640&ssl=1


今天教大家實作 Fargate 機器,其實如果是小團隊我滿推薦使用 Fargate 的因為他的價錢其實跟實際開一台一樣等級的機器差不多,而且可以減少很多麻煩事 XD ~