Day 24 – CDK 建置 Amazon Elastic Container Service(ECS) Service – 一個 Container 服務多個 Port

2020 12th 鐵人賽

前面都只有介紹一個 Container 服務一個 Port 那大家是不是有一個疑問如果我的 Container 是多個 Port 的服務有沒有辦法用 ECS 嗎?答案是可以的呦!平常看到的範例都是多個 Port 就要開多個 Container 那我可以節省成本只用一個 Container 就好嗎?答案也是可以的呦!

今天就來教大家怎麼達成這件事情吧!

https://i2.wp.com/ithelp.ithome.com.tw/upload/images/20201010/20117701uiabPDJKWN.jpg?w=640&ssl=1

一個可以服務多個 Port 的程式

因為要測試多 Port 服務所以我寫了一個測試程式提供給大家測試,它可以顯示目前連線的網址與 Port 這支程式開的 Port 為:80、8080、8000 與 8888

https://i2.wp.com/ithelp.ithome.com.tw/upload/images/20201008/20117701LC0DYkGTZ3.png?w=640&ssl=1

建立 Fargate Task Definition

我們這次的 Task 與之前差不多,主要的重點是這次我們宣告了多個 container port

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 512,
  cpu: 256,
});
const container = taskDefinition.addContainer("container", {
  image: ecs.ContainerImage.fromDockerImageAsset(asset),
  memoryLimitMiB: 512,
});
container.addPortMappings(
  {
    containerPort: 80,
  },
  {
    containerPort: 8888,
  },
  {
    containerPort: 8080,
  },
  {
    containerPort: 8000,
  }
);

如此在 Task Definition 就可以看到我們宣告的 Port Mappings 表

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

設定 ALB

我們在 ALB 上面 Listen 剛剛的 80、8080、8000 與 8888

這邊有一個新的設定是 defaultAction 我們希望他在沒有 Rules 的時候做什麼事情,在後面我特別保留了 8888 port 沒有設定,這樣就可以看到它是什麼樣子了!

要注意這個值一定要設定不然會有問題呦!

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

const lb = new elbv2.ApplicationLoadBalancer(this, "LB", {
  vpc,
  internetFacing: true,
});
const listener1 = lb.addListener("Listener1", {
  port: 80,
  defaultAction: elbv2.ListenerAction.fixedResponse(200, {
    contentType: elbv2.ContentType.TEXT_PLAIN,
    messageBody: "OK",
  }),
});
const listener2 = lb.addListener("Listener2", {
  port: 8080,
  defaultAction: elbv2.ListenerAction.fixedResponse(200, {
    contentType: elbv2.ContentType.TEXT_PLAIN,
    messageBody: "OK",
  }),
});
const listener3 = lb.addListener("Listener3", {
  port: 8888,
  protocol: elbv2.ApplicationProtocol.HTTP,
  defaultAction: elbv2.ListenerAction.fixedResponse(200, {
    contentType: elbv2.ContentType.TEXT_PLAIN,
    messageBody: "OK",
  }),
});
const listener4 = lb.addListener("Listener4", {
  port: 8000,
  defaultAction: elbv2.ListenerAction.fixedResponse(200, {
    contentType: elbv2.ContentType.TEXT_PLAIN,
    messageBody: "OK",
  }),
});

註冊 Targets

我們分別把 Container 的 port 都跟 Listener 對應保留剛剛說的 8888 沒有設定對應 這邊有一個重點是 containerName 一定要與建立 Fargate Task Definition時設定的一樣,因為他們是靠同一個名稱做連結的

listener1.addTargets("ECS1", {
  port: 80,
  targets: [
    service.loadBalancerTarget({
      containerName: "container",
      containerPort: 80,
    }),
  ],
});

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

listener2.addTargets("ECS2", {
  port: 8080,
  targets: [
    service.loadBalancerTarget({
      containerName: "container",
      containerPort: 8080,
    }),
  ],
});

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

listener4.addTargets("ECS4", {
  port: 8000,
  protocol: elbv2.ApplicationProtocol.HTTP,
  targets: [
    service.loadBalancerTarget({
      containerName: "container",
      containerPort: 8000,
    }),
  ],
});

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

targets 使用同一個 IP

由上面三張圖我們可以觀察到,我們的 ECS Container 都是同一台

觀察一下

我們可以回到 ECS 的 Service 看一下我們只有一個 Service,而且只有一個 Running 的 Task https://i1.wp.com/ithelp.ithome.com.tw/upload/images/20201008/201177010R5iTJb2EQ.png?w=640&ssl=1

再到 ECS Task 確定只有一個 Task 在跑

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

測試一下

我們可以到 ALB 的網址 http://cdkec-lb8a1-iyxzyuebmegp-816266764.us-west-2.elb.amazonaws.com:80/ 看到服務正常並且有讀到 Port

https://i2.wp.com/ithelp.ithome.com.tw/upload/images/20201008/20117701J4D24OA6ht.png?w=640&ssl=1

ALB 的網址 http://cdkec-lb8a1-iyxzyuebmegp-816266764.us-west-2.elb.amazonaws.com:8080/ 看到服務正常並且有讀到 Port

https://i2.wp.com/ithelp.ithome.com.tw/upload/images/20201008/20117701K2mE20rMYL.png?w=640&ssl=1

ALB 的網址 http://cdkec-lb8a1-iyxzyuebmegp-816266764.us-west-2.elb.amazonaws.com:8000/ 也是一樣的情況

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

ALB 的網址 http://cdkec-lb8a1-iyxzyuebmegp-816266764.us-west-2.elb.amazonaws.com:8888/ 因為我們剛剛做了一點手腳所以只有回應 Default 的 OK

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


今天是測試如果一台機器需要服務多個 Port 的範例希望有幫助到大家!