
เริ่มต้นกับ AWS ECS Part 1
ผมได้มีโอกาสรับงานที่ต้องใช้ AWS ECS เพื่อใช้งานแอพพลิเคชั่น ต้องบอกก่อนว่า ผมไม่เคยใช้ aws เลยใช้แต่ gcp มาตลอด ทำให้ใช้เวลาศึกษาและทดลองไปหนึ่งวัน เลยคิดว่าจะจดไว้กันนลืม เพราะขั้นตอนเยอะโครต -_-!
โดยบทความนี้ผมจะแบ่งเป็น 2 ตอน คือ
- เริ่มต้นกับ AWS ECS - ซึ่งจะเป็นการสร้าง ECS แบบเริ่มต้นก่อน โดยการนำ Image จาก Private registry มาใช้งาน
- นำ AWS load balancer มาใช้กับ AWS ECS - เพื่อให้ผู้ใช้งานเข้าผ่าน load balancer แล้วค่อยไปเจอ ECS ของเรา และจะมีการตั้งค่า scaling ด้วย
AWS ECS คือ?
Amazon Elastic Container Service หรือ ECS คือตัวจัดการ Container บน Cluster เพื่อให้เราสามารถ สร้าง ลบ หรือขยาย (Scaling) ได้ง่ายๆ

หากใครเคยใช้งาน K8S ก็คล้ายๆ กันแต่ตัวนี้ผมว่ามันจะบริหารจัดการง่ายกว่า แต่ก็สู้ K8S ไม่ได้นะ มันเหมาะสำหรับงานที่มี service น้อยๆ แต่ต้องการ scaling ได้
ซึ่ง ECS จะเทียบได้กับ Cloud run ของฝั่ง Google cloud ทำหน้าที่คล้ายกัน
โดยลำดับชั้นของ ECS จะเป็นประมาณนี้
Cluster > Service > Task > Container
สิ่งที่ต้องใช้งานใน AWS
- Amazon ECS
- IAM
- EC2 target groups
- AWS Secrets Manager
ขั้นตอน
- สร้าง ECS Cluster
- สร้าง Secrets ไว้เก็บ user, password ของ docker registry
- สร้าง Task เก็บข้อมูล Container
- เพิ่มสิทธิ์การอ่านให้ ecsTaskExecutionRole
- สร้าง Service เพื่อเรียกใช้งาน task
- ทดสอบ Service
1. สร้าง ECS Cluster
ให้เราไปหน้า ECS แล้วกด create cluster ได้เลย ในกรณีนี้เราจะเลือก "powered by AWS Fargate"

ตั้งชื่อ Cluster ของเรา

จากนั้นเราจะได้ Cluster มาใช้งานแล้ว

2. สร้าง Secret ไวเก็บ user, password ของ docker registry
ในกรณีนี้ถ้าใครต้องการเรียกใช้งาน Private docker registry ของตัวเองให้มาสร้าง secret เก็บ user และ password ไว้ก่อนเพื่อให้ ECS เราสามารถ pull image ของเรามาได้ ส่วนใครใช้พวก Public docker registry ก็ข้ามไป
ให้เราไปหน้า AWS Secrets manager จากนั้นกดปุ่ม "Store new secret" ให้เลือก Secret type เป็น "Other type" จากนั้นใส่ค่า username และ password ของ Private docker registry ของเราไป

ตั้งชื่อ และใส่รายละเอียด

ส่วนของ Configure automatic rotation ก็กด Next โลดดด

เพียงเท่านี้เราจะได้ user, password มาเก็บไว้แล้วพร้อมใช้งาน

3. สร้าง Task เก็บข้อมูล Container
เรากลับมาที่หน้าของ ECS กันใหม่ ให้เรามาสร้าง Task definitions ไว้ก่อนเพื่อบอกว่า container ของเรานั้นใช้ image อะไร ใช้ port อะไร หรือใช้ cpu เท่าไร เป็นต้น
ให้เราคลิกที่ Task definitions ที่เมนูซ้ายมือจากนั้นกด "Create new task definition"
เลือกแบบ Fargate เลย

แล้วจากนั้น config ดังนี้
- Task Definition Name - กำหนดชื่อ
- Task role - กำหนดสิทธิ์ของ task นี้ให้กำหนดเป็น "ecsTaskExecutionRole"
- Task size - เราเลือกเลยว่าจะให้ Container เรามีขนาด cup และ ram เท่าไร

ต่อมาในส่วนของ Container definitions เป็นการบอกว่าเราจะ pull image ไหนมาใช้งานให้กด "add container"
- Container name - ใส่ชื่อ
- Image - ใส่ image url
- Private repository - หากใครใช้เป็น private docker registry ก็ให้มาติ้กช่องนี้
- Secrets Manager ARN - ให้เรากลับหน้า Secret manager แล้วไป Secret ที่สร้างไว้ก่อนหน้าเอาค่า Secrets arn มาใช้ มาจะยาวๆ หน่อย เช่น arn:aws:secretsmanager:foo:bar
- Port mappings - กำหนด port ของ container เรา

หากไม่ต้องการใส่ค่าอื่นๆ ก็กด Create ได้เลย เมื่อกลับมาหน้า Task definition ก็จะเจอ task เรา

4. เพิ่มสิทธิ์การอ่านให้ ecsTaskExecutionRole
จากการสร้าง Task ข้างต้นเราในส่วนของ Task role ที่เรากำหนดเลือก "ecsTaskExecutionRole" นำมาใช้ เราจำเป็นต้องเพิ่มสิทธิ์ให้มันสามารถอ่านค่า aws secret ได้ด้วย
ให้เราไปหน้า IAM แล้วเลือกเมนูซ้ายว่า Role จากคลิก "ecsTaskExecutionRole" ด้านขวา

คลิก Attach policies

ค้นหา "SecretsManagerReadWrite" แล้วเพิ่มเข้าไป

จากนั้น ecsTaskExecutionRole จะได้สิทธิ์อ่าน secret มาแล้ว

5. สร้าง Service เพื่อเรียกใช้งาน task
กลับมาหน้า ECS Cluster แล้วคลิกที่ cluster เราเข้ามาจะพบกับ Service อยู่ด้านล่าง กด create ซะ

กำหนดค่าดังนี้
- Launch type - fargate
- Task definition - เลือก task ที่เราสร้างไว้
- Service name - ตั้งชื่อ service
- Number of tasks - จำนวนที่จะสร้าง container ขึ้นมาเริ่มต้น
- คลิก Next step

ต่อมาเป็นการกำหนด network ให้กับ service ซึ่งในส่วนของ VPC กับ Subnet กำหนดได้เลยตามต้อง แต่ในส่วนของ Security groups จะเป็นการบอกว่า ip ไหนเข้า port ไหนมาได้ ดังนั้นเราต้องกำหนด port ให้เหมือน Task เรา ให้เรากด Edit ข้างๆ
จากนั้นเลือก port ที่เราต้องการเปิดให้เข้าถึง container ของเรา ซึ่งในรูปตัวอย่างผมจะเปิด 80 กับ 3030 ไว้

ในส่วนของ Auto-assign public IP เป็นการจ่าย ip จริงให้กับ container เราเลยทำให้เราสามารถเข้า container ได้ตรงๆ ผมแนะนำให้ปิดไว้ แต่เปิดไว้เพื่อทดสอบก็ได้
ซึ่งสรุปแล้วเราจะตั้งค่าประมาณนี้

ค่าอื่นๆ ไว้ใช้งานคราวหลัง จากนั้นกด create service ได้เลย
6. ทดสอบ Service
กลับมาดูที่หน้า Cluster ของเราจะเจอกับ service ที่สร้างไว้

เมื่อคลิกเข้าไปเราจะเจอกับรายละเอียดของ service แต่ให้คลิกดูที่ Tasks tab ในนั้นจะมี task id ที่ run อยู่สามารถกดเข้าไปดูได้

โดยมันจะเป็นส่วนของ Container ที่ run อยู่เราสามารถดูได้ว่าใช้ docker image ตัวไหนอยู่ แล้วก็จะมี public ip มาให้ นั้นแสดงว่าเราสามารถ access เข้าไปยัง container ได้เลย

เมื่อผมลองเข้าตาม ip ที่ได้มาก็จะเจอกับหน้าเว็บ Reactjs ที่ผมทำไว้

บทสรุป
จากที่ทำมาจะเห็นเราจะได้ public ip ของ container มาเลยซึ่งสามารถเอาไปผูกกับโดเมนได้เลย
แต่การทำแบบนี้กรุณาอย่าเอาไปใช้งานจริง!!!
เพราะต้องอย่าลืมว่า Container เป็นสิ่งที่ตายได้ตลอดเวลาดังนั้น ip จะมีโอกาสเปลี่ยนได้แน่ และแถมถ้ามีการ scale เกิดขึ้นละ? นั้นหมายความว่า เราจะมีหลาย public ip ตามจำนวน Container ที่เกิดขึ้น
ดังนั้นวิธีทำที่ดีคือนำ Load balancer มาดักไว้ก่อนเข้า ECS ของเรา ซึ่งผมจะเขียนไว้ใน Part 2 เน้อ...