Simple Nginx Webserver deployment with EC2 Launch Type using ECS Cluster

Simple Nginx Webserver deployment with EC2 Launch Type using ECS Cluster

ကျတော် ဒီနေ့ sharing လုပ်ပေးမှာကတော့ AWS Containerlization service တစ်ခုဖြစ်တဲ့ ECS ကို သုံးပြီး Simple Nginx Webserver deployment လုပ်တဲ့အကြောင်းပဲဖြစ်ပါတယ်...အခုရေးမှာက ECS နဲ့ နဲနဲလေးစိမ်းနေတဲ့သူတွေ ECS နဲ့ Loadbalancer ကို အခုမှစပြီး စမ်းတဲ့သူတွေအတွက် ရည်ရွယ်ပြီးရေးတာဖြစ်လို့ Experienced Cloud / DevOps/ SRE တွေအတွက် easy ဖြစ်နေမှာပဲဖြစ်ပါတယ်။

ECS ဆိုတာကတော့ AWS Cloud မှာ containerlized applicaton တွေကို Deployment လုပ်တဲ့အခါ လွယ်လွယ်ကူကူဖြစ်အောင် support ပေးထားတဲ့ AWS Cloud ရဲ့ service တစ်ခုပဲဖြစ်ပါတယ်...
ဆိုတော့ နားလည်လွယ်အောင် ပြောရရင် ကျွန်တော်တို့ VM တစ်ခုပေါ်မှာပဲဖြစ်ဖြစ် Compute Instance ပေါ်မှာပဲဖြစ်ဖြစ် docker run တော့မယ်ဆိုရင် docker ကို ဟို repo က download လုပ်လိုက်ဦး ဒီ repo က download လုပ်လိုက်ဦး...အခု VM က user ကို docker user group ထဲ ထည့်လိုက်ဦး စသဖြင့် customization တွေ အများကြီး လုပ်ရမှာဖြစ်ပါတယ်... ဒါ့အပြင် Instances တွေ အများကြီး ဖြစ်နေတယ်ဆိုရင်လည်း အဲ့ဒီ instances ထဲက Docker containers တွေအချင်းချင်း network မိအောင် connection ရအောင် အများကြီး စဥ်းစားရမှာဖြစ်တဲ့ အတွက် AWS ဘက်ကနေ အဲ့ risk တွေကို လျှော့ချဖို့ ECS ကို ထွင်ထားလို့မြင်ပါတယ်...

ယေဘုယျအားဖြင့် ECS မှာ Cluster, Service,Task ,Task definition ဆိုတဲ့ အခြေခံကျတဲ့ services တွေပါပါတယ်...

ECS Cluster - ECS Cluster ဆိုတာက containers တွေရယ် services တွေရယ် tasks တွေရယ်ကို managed လုပ်တဲ့ service တစ်ခုပေါ့ ... ECS cluster ကို စပြီး create လုပ်တယ်ဆိုရင် EC2 launch type ကိုသုံးမှာလား Fargate ကိုသုံးမှာလားဆိုပြီး ကိုယ်စိတ်ကြိုက်ရွေးလို့ရပါတယ် Fargate ကိုရွေးလိုက်မယ်ဆိုရင်...ကျွန်တော်တို့ဟာ Infrastructure ပိုင်းကို လုံးဝစဥ်းစားစရာလိုမှာမဟုတ်တော့ပါဘူး... EC2 lunch type ကို ရွေးမယ်ဆိုရင်တော့ ကိုယ်သုံးမဲ့ Instance Type ကဘာလဲ Arm architrecture ကဘာလဲ စတာတွေကို ရွေးပေးရမှာဖြစ်ပါတယ်...ဒါ့အပြင် network type ကရော aws vpc ကိုရွေးမှာလား bridge လား စသဖြင့် ရွေးပေးရမှာပဲဖြစ်ပါတယ်...

ECS Task Definition - ECS Task Definition ဆိုတာက တနည်းအားဖြင့် container definitionလို့နားလည်လို့ရပါတယ်...ကျတော်တို့ container တွေ create လုပ်တဲ့အခါ ဘယ်က Image ကိုယူသုံးမှာလဲ ဥပမာ - Public က Docker image တစ်ခုကို ယူသုံးမှာလား ECR repo ပေါ်က Image ကိုယူသုံးမှာလား...အဲ့ဒီ Container မှာ RAM က ဘယ်လောက်သုံးမှာလဲ CPU ကဘယ်လောက်သုံးမှာလဲ... Container Port 80 နဲ့ Host Port 8080 mapလုပ်မှာလား...EFS ကို contiainer ရဲ့ ဘယ်လိုနေရာမျိုးကို Mount ထည့်မှာလဲဆိုတဲ့ UI ပေါ်ကနေ create လုပ်လို့ရတဲ့ Container definition json file တစ်ခုပေါ့...

ECS Service - ECS Service ဆိုတာကတော့ အပေါ်က ကျွန်တော်တို့ Define လုပ်ထားတဲ့ Task definition fileကို အခြေခံပြီးတော့မှ Task ဘယ်နှခု runမယ်၊ အဲ့ Task ကို desired ဘယ်နှခုထိထားမယ်၊ Minimum ကတော့ ဘယ်လောက် Maximum ကတော့ Task ဘယ်နှခုလောက်ထိထားမယ်ဆိုတာမျိုးတွေ define လုပ်လို့ရပါတယ်...ပြီးတော့ Loadbalancer နဲ့တွဲမှာလား Loadbalancer နဲ့တွဲမယ်ဆိုရင်လည်း http listener ကိုသုံးမှာလား https listener ကိုသုံးမှာလား ဘယ် Target Group ကိုသုံးမှာလည်း ဆိုတာမျိုးတွေထိ configuration လုပ်လို့ရတဲ့ service တစ်ခုပေါ့...ဒါ့အပြင် scaling အနေနဲ့ဆိုရင်လည်း AWS Codedeploy နဲ့ပါချိတ်ဆက်ပြီး သုံးလို့ရပါသေးတယ်...

ECS Task - ECS Task ဆိုတာကတော့ ECS service ကိုသုံးပြီးရလာတဲ့ Running ဖြစ်နေတဲ့ Container တွေလို့ဆိုနိုင်ပါတယ်...

အခုနဲနဲရှုပ်သွားတယ်ဆိုပေမဲ့ Lab လေးနဲ့ရှင်းပြမယ်ဆိုရင် ပိုပြီးမြင်သာမယ်ထင်လို့ simple nginx webserver deployement လေးတစ်ခုလုပ်ပြပါမယ်...

အဲ့တာဆို ကျတော်တို့ ECS Cluster တစ်ခုကို EC2 lunch type နဲ့ create လုပ်ကြည့်ပါမယ်...ပထမဆုံးအနေနဲ့ Loadbalancer နဲ့ Target Group ကိုကြိုပြီး create လုပ်ထားလိုက်ပါမယ်...

ecs-test-lb ဆိုတဲ့ name နဲ့ LB တစ်ခု create လုပ်လိုက်ပါမယ်... LB ကို Internet-facing mode ပဲရွေးလိုက်ပါမယ် ဘာလို့ဆို ကျွန်တော်တို့က Load Balancer ရဲ့ traffic ကို public ကနေလက်ခံချင်တာကြောင့်ပဲဖြစ်ပါတယ်..ဒီနေရာမှာ Internal ကိုသာရွေးခဲ့မယ်ဆိုရင် ကျတော်တို့ရဲ့ Load Balancer endpoint ကို public ကနေ access လုပ်လို့ရမှာမဟုတ်တော့ပါဘူး...ဥပမာ EC2 လို service မျိုးကပဲ access လုပ်လို့ရတော့မှာဖြစ်ပါတယ်...

Load Balancer ရဲ့ security group ကို http နဲ့ https ကို allow လုပ်ထားတဲ့ security group တစ်ခု create လုပ်ပြီး attach တွဲပေးလိုက်ပါမယ်... Load Balancer ရဲ့ security groupဆိုတာက သူ့ကို အပြင် public internet ကနေ လာပြီး access လုပ်မဲ့အချိန်မှာ ဘယ် port တွေကိုတော့ allow ပေးမယ်ဆိုပီး define လုပ်လို့ရတဲ့ virtual firewall ဆိုပြီးနားလည်ထားလို့ရပါတယ်...

Target Group create လုပ်တဲ့အချိန်မှာရွေးစရာတွေအမျာကြီးထဲကမှ IP address ကိုရွေးပြီး create လုပ်ခဲ့ပါမယ်...Protocol Port ကို 80 ပေးပြီး vpc ကိုတော့ ကိုယ်သုံးမဲ့ vpc ကိုရွေးပေးခဲ့ရပါမယ်...
ကျွန်တော်တို့က အခု simple nginx webserver ကို စမ်းမှာ ဖြစ်တဲ့အတွက် health check path ကို / နဲ့ ပဲထားခဲ့ပါမယ်...အချို့ Laravel application တို့လို Node JS application တို့လို application တွေမှာဆိုရင်တော့ organization culture အရ domain/heath-check (or) domain/api စတဲ့ customize endpoint တွေထားထားတယ်ဆိုရင် health check path နေရာမှာ domain/health-check or domain/api ဆိုပီး ထည့်ပေးရမှာဖြစ်ပါတယ်... နားလည်လွယ်အောင်ပြောရရင် ECS မှာဆိုရင် application တစ်ခုက Task (container) အနေနဲ့ run နေမှာဖြစ်ပြီး အဲ့ဒီ ECS Task (container) မှာ private IP address တစ်ခု assign ရှိနေမှာပါ...application ရဲ့ health-check URL ကလည်း ခုနက ပြောခဲ့တဲ့ organization culture အရ domain/api-health-check ဆိုပါတော့ Target Group ကနေ container instance ကို health check လုပ်တဲ့အခါ IP/api-health-check ဆိုတဲ့ URL ကိုပဲ သွားပြီး check နေမှကို 200 response code ပြန်ပြီး Target Group မှာ healthy instance အနေနဲ့ run နေမှာဖြစ်ပါတယ်...

Listener ကိုရွေးတဲ့အချိန်မှာတော့ http နဲ့ https နှစ်ခုကို target group နဲ့ ရွေးပြီး create လုပ်ခဲ့ပါမယ်...များသောအားဖြင့် http listener ကိုတော့ https ဆီကို redirect လုပ်ဖို့အတွက်ပဲသုံးကြပါတယ်...

https Listener အတွက်ဆိုရင်တော့ ကျတော်တို့သုံးမဲ့ domain ရဲ့ certificate ကို Certificate from ACM နေရာမှာ ရွေးပေးခဲ့ဖို့လိုပါမယ်...ဒါမှသာ application ကို public ကနေ access လုပ်တဲ့အခါ Loadbalancer က သုံးမဲ့ domain ရဲ့ ACM certificate ကို resolveဖြစ်ပြီး https နဲ့ access လုပ်လို့ရမှာဖြစ်ပါတယ်...

ကျတော်တို့က အခုlab မှာ WAF တို့ Global Accelerator တို့နဲ့ ချိတ်ဆက်ပြီးအသုံးပြုမှာမဟုတ်တဲ့အတွက် သူတို့ကို setup လုပ်မဲ့အပိုင်းကိုတော့ကျော်ထားခဲ့လိုက်ပါမယ်...

အခုဆိုရင် ကျွန်တော်တို့ Load Balancer နဲ့ Target Group create လုပ်ပြီးပြီဆိုတော့ ECS ဘက်ကိုပြန်သွားပါမယ်...ကျွန်တော်ဘာလို့ Load Balancer နဲ့ Target Group ကို create လုပ်ရသလဲဆိုရင် ECS service ကနေ container တွေ create လုပ်တဲ့အချိန်မှာ ရလာတဲ့ container instance ကို Target Group မှာ running instance အနေနဲ့ အလုပ်လုပ်တယ်ဆိုတာကို တွဲမြင်စေချင်လို့ပဲဖြစ်ပါ တယ်...

ဟုတ်ပြီ ဒါဆို ကျတော်တို့ ECS Cluster တစ်ခုစပြီး create လုပ်တော့မယ်ပေါ့...ဒီ Lab မှာ Fargate ထက်နဲနဲပြောစရာပိုများတဲ့ EC2 launch type ကိုပဲ ရွေးလိုက်ပါမယ်...ECS cluster ကို ကိုယ်deployမဲ့ project နဲ့လိုက်မဲ့ unique ဖြစ်မဲ့ Name တစ်ခုပေးခဲ့ပြီး Infrastructure section မှာ Amazon EC2 instances ကို ရွေးခဲ့ပါမယ်...EC2 instance Type မှာလည်း ကိုယ့် project ရဲ့ traffic ပေါ်မူတည်ပြီး define လုပ်လို့ရပါတယ်...ဥပမာ...c5.large , c5.xlarge, t3a.medium စသဖြင့်ကိုယ်ကြိုက်သလို define လုပ်လို့ရပါတယ်... Cluster မှာ run မဲ့ EC2 instanceက t3a.medium (2core 4GB)ဆိုပါဆို့ ...ကျတော်တို့ define လုပ်ထားတဲ့ Task definition file ထဲမှာ container ရဲ့ specificationဟာ 1Core 2GB ဆိုရင် အဲ့ instance ပေါ်မှာ Task နှစ်ခု (Container 2လုံး ) run လို့ရမယ်ပေါ့...အဲ့ထက်ပို runမယ်ဆိုရင် အောက်ကပုံမှာ ပြထားတဲ့အတိုင်း Maximum capacity ကို 2 or 3 လောက်ထားပေးခဲ့ရပါမယ်...ကျတော်တို့က AWS Fargate ကိုမသုံးပဲ EC2 launch type ကိုသုံးထားတဲ့အတွက် Autoscaling Group ကို AWS ဘက်က automatically create လုပ်ပေးမှာပဲဖြစ်ပါတယ်...ဘာလို့လုပ်ပေးထားလဲဆိုရင် နောက်လာမဲ့ ECS service creation မှာ implement လုပ်ရမဲ့ scaling policy အရ application က traffic များလာတယ်ဆိုရင် အခုလက်ရှိ running ဖြစ်နေတဲ့ ECS Cluster ရဲ့ EC2 instance ဟာ သူ့ရဲ့ CPU တွေ Memory တွေကို Scale up ဖြစ်လာတဲ့ contianers တွေကနေ ယူသုံးလို့ရဖို့ အခုအောက်ပုံမှာပြထားတဲ့ Maximum capacityကို define လုပ်ပေးရမှာပဲဖြစ်ပါတယ်...Maximum ကို 2 or 3 or 4 လောက်ထားမှ နောက်ထပ်လိုတဲ့ EC2 instances တွေထပ် provision ဖြစ်လာပြီး traffic ကို handle နိုင်မှာပဲဖြစ်ပါတယ်။

Network Setting အတွက်ဆိုရင်တော့ ကိုယ်သုံးမဲ့ vpc ကိုရွေးခဲ့ပေးပြီး subnet တွေကိုတော့ ကိုယ်က အဲ့ EC2 instance ကို public ကနေ access လုပ်မယ်ဆိုရင် public subnet တွေပဲ ရွေးပေးရပါမယ်...
security group ကိုတော့ http,https ရယ် ssh port ရယ် allow လုပ်ထားတဲ့ sg တစ်ခုနဲ့ attach တွဲပေးလိုက်ပါမယ်...

cluster create လုပ်ပြီးသွားရင်တော့ EC2 တစ်လုံး provision ဖြစ်လာပြီး အောက်ကအတိုင်းတွေ့ရမှာပဲဖြစ်ပါတယ်...ညာဘက်အောက်ဆုံးနားက memory available မှာ 952 ဆိုပီးတွေ့နေရတာက t2.micro (1Core 1GB) နဲ့ EC2 ကို create လုပ်ပါလို့ define ထားပေမဲ့ memory က အပြည့်သုံးလို့မရတဲ့သဘောပါပဲ ...Task definition မှာ 1Core 1GB သွားပေးလိုက်ရင် application က resource မလောက်တဲ့ ပြဿနာတက်မှာဖြစ်ပါတယ်...1Core 1GB ရှိတဲ့ container ကို create လုပ်လို့ရမှာကိုမဟုတ်တော့ပါဘူး...

EC2 launch type ကို သုံးရတဲ့အားသာချက်တစ်ခုကတော့ Ec2 instance ထဲကို လွယ်လွယ်ကူကူ ssh ကနေ login ဝင်ပြီး Container တွေကို access လုပ်လို့ရတာပဲဖြစ်ပါတယ်...login ဝင်ဖို့ခုနက cluster create လုပ်တုန်းက ရွေးခဲ့တဲ့ keypair ကိုသုံးပါမယ်...wsl ကနေ login လှမ်းဝင်ရင် key ကို 400 နဲ့ ပေးမထားရင် bad permission error တက်လို့ 400 ပေးလိုက်ပါတယ်...ပီးရင် Ec2ရဲ့ public IP နဲ့ login လှမ်းဝင်ပြီး container တွေကို list လုပ်ကြည့်ပါမယ်...ကျတော် အစပိုင်းက mention ခဲ့သလိုပဲ AWS ဟာ ECS cluster ကနေ create လုပ်တဲ့ EC2 instances တွေကို docker agent တွေ automatically install လုပ်ပေးထားမှာပဲဖြစ်ပါတယ်...

ဒါဆို Task definition file တစ်ခုလုပ်ကြည့်ပါမယ်၊ Infrastructure requirements မှာ အောက်ကအတိုင်းရွေးပေးလိုက်ပါမယ်၊ကျွန်တော်က ec2 ကို t2.micro (1core 1GB) ရွေးထားခဲ့တဲ့အတွက် task defination မှာ container အတွက် resource လောက်အောင် 0.5vCPU နဲ့ 0.5Memory ပေးလိုက်ပါတယ်၊

Container Name ကို ecs-nginx လို့ပေးလိုက်ပြီး image URL ကိုတော့ nginx:latest လို့ထည့်ပေးလိုက်ပါမယ်၊ nginx latest ဆိုတာက public က docker image ကို ယူသုံးလိုက်တာဖြစ်ပါတယ်၊Container port ကိုလည်း Nginx web server ရဲ့ default port ဖြစ်တဲ့ 80ကိုထည့်ပေးလိုက်ပါမယ်၊ Image URI ကိုလည်း nginx:latest မဟုတ်ပဲ ECR ပေါ်က image ကိုလည်းယူသုံးလို့ရပါတယ်။ ပြီးရင် ကျန်တာတွေ default အတိုင်းထားပီး task definition ဖိုင်တစ်ခု create လုပ်လိုက်ပါမယ်။

ပြီးရင် cluster ထဲမှာ ecs service တစ်ခု create လုပ်ကြည့်ပါမယ်...service creation လုပ်ဖို့ဆိုရင် အစောက ကျွန်တော်တို့ create လုပ်ခဲ့တဲ့ task definition file ရယ် Loadbalancer , target group စတဲ့ component တွေပါပါတယ်၊ ပြီးတော့ Autoscaling ကို CPU အလိုက်လုပ်မှာလား Memory အလိုက်လုပ်မှာလား ဆိုတာမျိုးတွေရွေးပေးလို့ရပါတယ်၊

Task definition ရွေးရတဲ့ အချိန်မှာ အပေါ်က create လုပ်ခဲ့တဲ့ ecs-nginx ဆိုတဲ့ task definition ကိုထည့်ပေးလိုက်ပါမယ်၊

Service connect တို့ Service discovery တို့လို Section တို့ကို ကျော်ထားခဲ့လို့ရပါတယ်၊ Networking setting မှာတော့ cluster create လုပ်ခဲ့တဲ့ vpc ကိုပြန်သုံးပြီး subent တွေကိုတော့ public ရော private subnet တွေရောအကုန်ရွေးပေးခဲ့လိုက်ပါ၊ sg ကိုလည်း cluster ရဲ့ ec2 instance မှာသုံးခဲ့တဲ့ ecs-nginx-svr ဆိုတဲ့ sg ကိုပဲ ပြန်ရွေးပေးခဲ့လိုက်ပါမယ်၊

Load Balancer section မှာဆိုရင်လည်း အစောနက ကြိုပြီး create လုပ်ခဲ့တဲ့ LB ကိုရွေးပေးပြီး ရှိပြီးသား https listener ကိုပဲ ရွေးပေးလိုက်ပါမယ်၊

Target Group section မှာဆိုရင်လည်း ကြိုပြီး create လုပ်ထားတဲ့ ecs-nginx-tg ဆိုတဲ့ tg ကိုပဲ ရွေးပေးခဲ့လိုက်ပါမယ်၊

service autoscaling section မှာဆိုရင် skip ထားခဲ့လို့လည်းရပါတယ်၊ မ skip ပဲရွေးခဲ့မယ်ဆိုရင် policy name တစ်ခုပေးခဲ့ပြီး CPU target based scaling နဲ့ပဲသွားလိုက်ပါမယ်၊ အောက်ဆုံးနား အဝါလေးဝိုင်းထားတဲ့ Turn off scale-in ကိုသာ အမှန်ခြစ်ထားမယ်ဆိုရင်တော့ scaling policy ကို trigger ပြီး scale up ဖြစ်လာတဲ့ container instances တွေဟာ scale down ဖြစ်မှာမဟုတ်တော့ပဲ cost တွေအတွက် impact ရှိစေမှာပဲဖြစ်ပါတယ်၊ scale in ထားထားတယ်ဆိုရင်လည်း scale up ဖြစ်လာတဲ့ container instance ပေါ်မှာ running ဖြစ်နေတဲ့ container တွေမရှိတော့ ဘူးဆိုရင်တောင်မှ 15mins (900s) ကြာပါတယ်၊ အချိန်မြန်မြန် scaling down ဖြစ်ဖို့ ကျတော်သိသလောက်တော့ တခြားနည်းလမ်းတော့မရှိသေးပါဘူး...ရှာဖတ်ကြည့်သလောက်ကတော့ script တစ်ခုကို cronb job နဲ့ run ပီး 5mins အတွင်းမှာ running ဖြစ်နေတဲ့ containers instances တွေမရှိဘူးဆိုရင် instance ကို terminate လုပ်ပစ်မယ်ဆိုတဲ့ custom script ကို launch template ထဲမှာထည့်ထားလို့ရတယ်ဆိုပြီး ဖတ်ဘူးပါတယ်၊

service create လုပ်ပြီးသွားပြီးရင်တော့ အောက်က ပုံထဲမှာလို Task တစ်ခု run နေမှာပဲဖြစ်ပါတယ်၊

ဟုတ်ပြီ အဲ့တာဆို ကျွန်တော်တို့ custom domain တစ်ခုနဲ့ public ကနေ access ရအောင် implement ဆက်လုပ်ကြပါမယ်၊ https နဲ့ public ကနေ access လုပ်ချင်တာဖြစ်တဲ့ အတွက် loadbalancer ရဲ့ https listener မှာ rule တစ်ခု သွားထည့်ပါမယ်၊

Add rule ကို click ပြီး ecs-nginx-web-svr ဆိုတဲ့ Name နဲ့ rule တစ်ခု create လုပ်ပါမယ်၊

Host header ကိုရွေးပြီး host header ကသာ nginx.dailydevops.site ဖြစ်မယ်ဆိုရင် ecs-nginx-tg ကိုသွားမယ်ဆိုပြီး ရွေးပေးလိုက်ပါမယ်၊

ပြီးတော့ domain မ point ရသေးတဲ့အတွက် godaddy ဘက်မှာ loadbalancer ရဲ့ DNS ကို CNAME အနေနဲ့ သွားထည့်လိုက်ပါမယ်၊

ပြီးသွားပြီဆိုရင်တော့ cmd ကနေ nslookup နဲ့ domain ကို DNS resolveဖြစ်ပြီလား သွားစစ်ပါမယ်၊address မှာ ip တွေကျပြီဆိုရင် loadbalancer ရဲ့ DNS ဟာ nginx.dailydevops.site ဆိုတဲ့ domain နဲ့ resolve ဖြစ်ပြီလို့ဆိုနိုင်ပါတယ်၊

ကျတော်တို့ web browser ကနေ domain ကို ခေါ်ကြည့်လိုက်ရင် simple welcome nginx web page ကိုတွေ့ရမှာဖြစ်ပါတယ်။

အဆုံးထိဖတ်ပေးလို့ အားလုံးကို ကျေးဇူးတင်ပါတယ်။
ကျတော်ရေးထားတာ နဲနဲများသွားတဲ့ အတွက်အမှားပါရင်လည်း ဖြည့်ပြီးတွေးပေးကြဖို့တောင်းဆိုပါတယ်။