![](/media/images/Aws-82.webp)
[AWS] ECS 筆記
簡介
Amazon的ECS是一項完全托管的Conatiner服務,可以做到對Container的部署、管理、擴展。使得開發人員能放更多重心在應用程式的開發,而非環境的維護。
還有一個類似的服務是AWS的[[EKS]],他是一個完全托管的Kubernetes服務。(Kubernetes被廣泛使用於容器化應用程序的部署和管理)
如果本身已經有在使用Kubernets管理Container,同時希望對系統有更多的自訂性的話,可以考慮使用EKS。而ECS的學習難度曲線比Kubernetes低,適合期望能整合其他AWS資源的專案。
Launch Type
ECS提供了幾種不同的底層啟動方式(Launch Type),分別是EC2、Fargate、On-premises。
EC2 Launch Type
用EC2啟動的話,是將Conatiner跑在EC2的實體上。需要先備好一些EC2實體,然後在這些實體上運行Container,並且需要自行管理這些EC2。這些EC2還要另外執行一個稱為ECS Agent
的程式,讓EC2得以根ECS的服務溝通。這種方式提供了更大的靈活性和控制,適合有高度自定義需求的情境。
Fargate Launch Type
用Fargate啟動的Container則是一種類似Serverless的方式。只需要定義好Task
後告訴ECS要運行多少Container在Cluster裡面即可,而不用擔心EC2實體的管理問題。Fargate會自動處理所有低層細節,我們只需關注在應用程式的開發即可。如果要使用Load Balancer,則所使用的Target Group必須是IP Type!
On-premises
從外部的Instance(Server或VM)做啟動的動作。
系統設置
Tasks的設置
首先來定義Task。(這邊假設Image已經丟到ECR上面)
Task是定義了Docker Image怎麼跑的一種Template樣板。有點Docker Compose的味道在裡面。除了在這個地方指定Image的名稱,以及他的URI要去哪裡下載外,一些重要的設定像是:
- Container裡頭的應用程式的Port Mapping
- 如果有使用S3上面的.env檔案的話,需要指定S3的路徑
- 是否需要Mount外部的Volume
Data Volume
實務上Volumes會使用EFS的服務。把EFS載到每個ECS Task上面,就能讓跑在任何AZ上面的Task共享相同的資料。另外如果底層是跑Fargate,volume是掛載EFS的話,應用程式就等同於是個無伺服器的應用。
Clusters設置
再來需要建立的是ECS的叢集(Clusters)。這裡主要是希望你能確認好底層的啟動型態是Fargate
還是EC2
,同時Instances的Auto Scaling Group設定也會在這個階段做確認。(注意是ASG不是Load Balancer)
Services
再來需要建立Services,這個地方定義了要怎麼跑一開始要設定的Task們。
可選擇的定義負載平衡器
我們也可以在定義Services的時候,同時定義要不要使用負載平衡器(ALB或NLB)
一個需要注意的地方是,如果Container今天部署的速度比較慢的話,Load Balancer這邊設定的Health Check有可能會檢查失敗,導致服務一直收掉啟動不了。(系統以為Container們壞了)。
另外一個蠻蠢的,但如果沒注意就會發生錯誤的點是,Health Check URI最後的/
,也要根據後端伺服器做對應的設定。舉例來說:
- /health-check
- /health-check/
是完全不一樣的東西,寫錯會導致過不了。
IAM Roles for ECS
我們需要幫Task們給定兩個特殊的IAM Role,分別是Task Role
以及Task Execution Role
Task Role
這個Role是要給執行Task的實體們使用的,位於這些Instance底下的Container裡面的應用程式如果會去呼叫其他AWS資源的話,就要給他們能夠assume其他Role的權限。
可以參考Role裡面的Trust relationships設定:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
- 這個設定允許
EC2
去assume特定的Role,讓EC2有權限做跟該Role一樣的事情
Task Execution Role
這個Role是要給ECS Container
及Farget Agent
使用的。他賦予的權限主要用在管理Task的生命週期和執行環境,而不是用在Task裡面的Container身上。
比方說,啟動在Farget上面的Task需要從ECR把Image拉下來,從SSM拿出敏感的資料,把Container的Log送到CloudWatch…等等。
如果有使用s3上面的.env檔案
在定義Task的時後,有提到可能會使用到s3上面的.env檔案。這個時候,就需要放兩個權限到ECSTaskExecutionRole
上面
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::{ENV_FILE_PATH_S3}}"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:GetBucketLocation",
"Resource": "arn:aws:s3:::{ENV_BUCKET_S3}"
}
]
}
- 注意Bucket的Resource不要後面多了一條
/
,不然又會變成Objects - 假設今天S3上的Bucket名稱換掉了,那除了ExecutionRole內的Bucket名稱要換掉之外,Task定義的S3 Bucket名稱也要記得換掉
如果服務部署在Private Subnet
如果應用程式的架構是讓Task跑在Private Subnet裡面的話,會訪問不了AWS Global等級的服務,例如S3, ECR…。錯誤範例如下:
ResourceInitializationError:
unable to pull secrets or registry auth: execution resource retrieval failed:
unable to retrieve ecr registry auth: service call has been retried 3 time(s):
RequestError: send request failed caused by:
Post "https://api.ecr.ap-northeast-1.amazonaws.com/": dial tcp 52.119.220.175:443: i/o timeout
但我們可以透過設定下面的VPC Endpoint
讓我們的subnet能夠訪問到這些服務。
- com.amazonaws.region.ecr.dkr
- com.amazonaws.region.ecr.api
- S3 Gateway Endpoints
- com.amazonaws.region.logs
詳細的設置可參考AWS官方的文件