技術六處三部 工程師 BobChen
(© 2023, Amazon Elastic Container Service Amazon Web Services, Inc. 或其合作夥伴。保留所有權利。)
使用 Amazon ECS,您將不再需要手動安裝、操作、擴展自己的叢集管理基礎設施,讓您可輕鬆地使用容器,將其作為應用程式的建構模塊。
Amazon ECS 讓您可以對 Docker 容器進行任務排程,包括長期執行的應用程式、服務和批次任務。
Amazon ECS 維持應用程式的可用性,讓您擴展或縮減容器來符合應用程式的負載需求。
Amazon ECS 整合了您熟悉的功能,包括 Elastic Load Balancing(ELB)、Elastic Block Store(EBS)、Virtual Private Cloud (VPC) 和 Identity and Access Management(IAM)。
簡單的 API 讓您可以整合並使用自己的排程器,或將 Amazon ECS 連接到現有的軟體交付程序。
Amazon ECS 是一種全受管容器協同運作服務,可輕鬆地讓您部署、管理和擴展容器化應用程式。
AWS Fargate 是 Amazon ECS 的一項功能,可讓您在無需管理網路和伺服器的情況下,直接在容器中執行應用程式。
這使您可以專注於應用程式的開發,而無需擔心基礎架構的管理。
( 取自 Amazon ECS 頁面 網址: https://aws.amazon.com/tw/ecs/ © 2023, Partner Badge Amazon Web Services, Inc.或其合作夥伴。保留所有權利 )
( 圖片取自 AWS 官方 Advanced Architecting on AWS 課程 © Amazon Web Service )
創建一個 IAM role 用於 ECS task
IAM role 必須要有足夠的權限,這裡任務角色及執行角色都使用同一個 role
Policy 使用 AmazonEC2ContainerServiceforEC2Role
執行 ECS 的 IAM role json 如下:
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Principal":{ "Service":[ "ecs-tasks.amazonaws.com" ] }, "Action":"sts:AssumeRole", "Condition":{ "ArnLike":{ "aws:SourceArn":"arn:aws:ecs:us-west-2 :111122223333 :*" }, "StringEquals":{ "aws:SourceAccount":"111122223333 " } } } ] } |
us-west-2 更換成服務所在的區域, 111122223333 則更換成 AccountID
創建安全群組
允許 port 80 和 443流入
創建 Target group
須在 EC2 頁面下選擇左邊 負載均衡器 的 目標群組
以 IP 為方式建立, 後建立 ALB 進行關聯取得 TargetGroupArn
建立 EC2(用於使用 CLI 部署到 ECS on AWS Fargate)
安裝 docker 和 git
Sudo yum install docker Sudo yum install git |
從 github 複製 2048 的儲存庫
git clone https://github.com/gabrielecirulli/2048 |
切換目錄並建立 Dockerfile 文件,Docker 使用此文件構建容器映像,將軟體打包成用於開發、運輸和部署的標準化元件。
cd 2048 vim Dockerfile |
按 i 進行編輯
FROM nginx:lstest COPY . /usr/share/nginx/html EXPOSE 80 |
編輯完畢後按 Esc 後輸入 :wq 儲存跳出
確認目錄在 2048 底下,運行以下指令:
cd ~/2048 ls -s |
Web2048 是一款簡單的 2048 遊戲,可在您的網絡瀏覽器中運行。
◎注意:一個常見的開發人員問題是在不使用 sudo 的情況下運行 docker 命令並出現“權限被拒絕”錯誤。
將您的用戶放入 dock 組允許您女在沒有 sudo 權限的情況下運行 docker 命令,使本地用戶權限與最小權限訪問控制保持一致。
有一個簡單的解決方法,
運行以下命令來修復此錯誤:
sudo usermod -aG docker ec2-user newgrp docker |
現在可以使用 sudo 運行 docker 命令了
運行以下命令以運行 docker 並檢查有沒有其他映像檔:
sudo systemctl start docker docker images |
要為網站構建 Docker 容器,請運行以下命令:
docker build -t web2048 . |
會獲得如下方所顯示內容:
Sending build context to Docker daemon 1.36MB Step 1/3 : FROM nginx:latest latest: Pulling from library/nginx 461246efe0a7: Pull complete 060bfabbe2Ze: Pull complete b34d5ba6fa9e: Pull complete 8128ac56c745: Pull complete 44d36245a8c9: Pull complete ebcc2c821e6: Pull complete Digest: sha256:1761fb5661e4d77e107427d8012ad3a5955007d9970f4a3d41acc9ff20467c7 Status: Downloaded newer image for nginx:latest ---> 670dcc86b69d Step 2/3 : COPY . /usr/share/nginx/html ---> af91f0e53954 Step 3/3 : EXPOSE 80 ---> Running in c854197142b7 ... |
構建只需幾秒鐘即可完成。
滾動到終端窗口的底部,直到找到類似於以下內容的消息,這表明構建成功:
Successfully built 7de26addeed8 |
再次檢查映像檔:
docker images |
會獲得如下方所顯示內容:
REPOSITORY TAG IMAGE ID CREATED SIZE web2048 latest 7de26addeed8 24 minutes ago 143MB nginx latest 670dcc86b69d 3 days ago 142MB |
查看已經構建了哪些容器,運行以下命令:
docker container ls |
現在 Docker 鏡像已構建,要在命令主機上對其進行測試,請運行以下命令:
docker run -d -it -p 80:80 web2048 |
運行命令啟動容器。
命令中的 -d 標誌以分離模式運行容器。
按照設計,以分離模式啟動的容器會在用於運行容器的根進程退出時退出。
這樣,您可以在容器運行時繼續使用終端。
命令中的 -p 80:80 參數將命令主機上的端口 80 綁定到 Docker 容器上的端口 80。
注意:對於交互式進程(如 shell),必須同時使用 -i -t 為容器進程分配一個 TTY(通常用作 -it )。
本實驗不需要這些標誌;但是,它們對於容器故障排除非常有用。
運行以下命令來查看您的容器:
docker container ls |
會獲得如下方所顯示內容:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES Oe5c8fe77af7 web2048 "/docker-entrypoint..." 4 minutes ago Up. 4 minutes 0.0.0.0:80->80/tcp:::80->80/tcp elated_boy |
此 CONTAINER ID 後續會使用到
接下來,通過從 Web 瀏覽器訪問命令主機來測試容器。要獲取 EC2 實例的公共 IP 地址,請運行以下命令:
curl http://169.254.169.254/latest/meta-data/public-ipv4 -w "\n" |
從輸出中複製公共 IP
打開一個新的瀏覽器標籤,貼上複製的公共 IP 地址,應該能夠看到 2048 應用程序。
終止 container,將其中 CONTAINER ID 請更換成前面所查詢到的 ID
docker stop CONTAINER ID |
您現在已經成功構建了 web2048 容器。
現在您已經構建了一個工作容器鏡像,您需要將該鏡像存儲在其他人和資源可以訪問它的地方。
Amazon Elastic Container Registry (ECR) 是此用例的絕佳解決方案。
使用 AWS CLI,您將創建一個 Amazon ECR 存儲庫並將您剛剛測試過的映像檔發送到 Amazon ECR 中。
在先前的步驟,您創建了 Web2048 Docker 映像檔。
使用 docker images 命令再次查看您的映像。
注意目錄名稱(即 REPOSITORY、TAG、IMAGE ID、CREATED 和 SIZE),特別是 REPOSITORY 。
存儲庫是具有不同版本和名稱標籤的同一 Docker 映像的邏輯組。
到目前為止,存儲庫名稱只能在本地訪問。
要在共享鏡像存儲庫(例如 Amazon ECR)中共享容器鏡像,您必須將容器鏡像與中央鏡像存儲庫相關聯。
我們可以運行以下命令來獲取有關所有創建的 Docker 映像的信息:
docker images |
會獲得如下方所顯示內容:
REPOSITORY TAG IMAGE ID CREATED SIZE web2048 latest 7de26addeed8 24 minutes ago 143MB nginx latest 670dcc86b69d 3 days ago 142MB |
運行 aws configure 並將區域變量設置為您的區域。
每次使用需要區域的 AWS CLI 運行命令時,此步驟都無需使用 –region 標誌。
您可以通過按 Enter 將訪問密鑰 ID 和秘密訪問密鑰留空。
默認輸出格式是可選的。
aws configure |
AWS Access Key ID 和 AWS Secret Access Key 可留空
Default region name 請輸入您在的區域
Default output format 請輸入 json
AWS Access Key ID [None]: AWS Secret Access Key [None]: Default region name []: us-east-1 Default output format [json]: json |
要為您的 Docker 映像創建 Amazon ECR 存儲庫,可以運行以下命令:
aws ecr create-repository --repository-name web2048 |
會獲得如下方所顯示內容:
{ "repository": { "repositoryUri": "294373654843.dkr.ecr.us-east-1.amazonaws.com/web2048", "imageScanningConfiguration": { "scanOnPush": false }, "encryptionConfiguration": { "encryptionType": "AES256" }, "registryId": "294373654843", "imageTagMutability": "MUTABLE", "repositoryArn": "arn:aws:ecr:us-east-1:294373654843:repository/web2048", "repositoryName": "web2048", "createdAt": 1658766018.0 } } |
運行以下命令來查看您剛剛創建的 Amazon ECR 存儲庫:
aws ecr describe-repositories -query 'repositories[]. [repositoryName, repositoryUri]' --output table |
會跑出以下訊息: 其中 294373654843 會是您的 Account ID
稍後會使用到 URI。
您可以將 URI 值設置為環境變量,而不是將 URI 複製到文本編輯器或記事本以備後用。
這允許您在不查找 URI 值的情況下重用該命令。
要將存儲庫 URI 的值導出到環境變量並對 Amazon ECR 進行身份驗證,請運行以下命令:
export REPOSITORY_URI="$(aws ecr describe-repositories --query 'repositories[].[repositoryUri]' --output text)" echo "${REPOSITORY_URI}" export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account) export AWS_REGION=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region') aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION} |
若出現
Error response from daemon: Get "https://000000000000.dkr.ecr.us-east-1/v2/": dial tcp: lookup 000000000000.dkr.ecr.us-east-1 on 172.31.0.2:53: no such host |
改成直接指定ECR儲存庫位址
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 000000000000.dkr.ecr.us-east-1.amazonaws.com/web2048 |
echo 命令應顯示您的 ECR 存儲庫 URI。
在將 Docker 映像推送到存儲庫之前,您必須登錄 Amazon ECR。
get-login 命令返回一個 docker 登錄令牌,有效期為 12 小時。
您可以將此命令的輸出轉發到 shell 以運行 docker login 命令並完成身份驗證。
出現以下訊息代表建立完成:
WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store |
運行以下命令:
docker tag web2048:latest ${REPOSITORY_URI}: latest docker images |
會獲得如下方所顯示內容:
REPOSITORY TAG IMAGE ID CREATED SIZE 294373654843.dkr.ecr.us-east-1.amazonaws.com/web2048 latest 07a9581ba9e6 6 minutes ago 143MB web2048 latest 7de26addeed8 6 minutes ago 143MB nginx latest 670dcc86b69d 3 days ago 142MB |
運行以下命令:
docker push ${REPOSITORY_URI} : latest |
成功將您的容器映像發送到 Amazon ECR 應該會產生類似如以下所顯示內容:
The push refers to repository [294373654843.dkr.ecr.us-east-1.amazonaws.com/web2048] 9fb7edea8440: Pushed abc66ad258e9: Pushed 243243243ee2: Pushed f931b78377da: Pushed d7783033d823: Pushed 4553dc754574: Pushed 43b3c4e3001c: Pushed latest: digest: sha256:daac922f8e9d6d2445cleelab24a36190c0763d766908f7915cfcef53cec0123 size: 1780 |
運行以下命令查看您的圖像元數據並確認發送成功:
aws ecr describe-images --repository-name web2048 |
現在應該可以在 Amazon ECR 中看到圖像的元數據,如下方所顯示內容:
{ |
您已成功創建 Amazon ECR 存儲庫並將 Docker 映像推送到存儲庫。
運行以下命令創建 Amazon ECS 集群,將集群名稱 web2048 作為參數傳遞:
aws ecs create-cluster --cluster-name web2048 |
會獲得如下方所顯示內容:
{ |
在 ECS 集群上運行任務之前,您必須註冊任務定義。
任務定義是組合在一起的容器列表。
註冊新任務定義有兩個部分:
1. 傳遞給命令行的任務定義文件(這種方式更簡潔、更容易)
2. 使用標誌和參數值註冊新任務的 AWS CLI 命令
此處選擇使用第一個選項
創建任務定義文件。
首先先導航到您的主目錄。
獲取 Amazon ECR 報告 URI 並複製到文本編輯器,您將在下一步中需要此值。
並為您的任務定義創建一個文件。
cd ~ echo ${REPOSITORY_URI} vim web2048_task_definition.json |
json 內容如下:
{ |
將 taskRoleArn、executionRoleArn、image 紅字部分替換成自己的。
taskRoleArn:任務角色
executionRoleArn:任務執行角色
此處皆使用相同角色代入。
運行以下命令註冊新的任務定義:
aws ecs register-task-definition --cli-input-json file://web2048_task_definition.json |
成功創建後,您應該獲得包含任務定義詳細信息的 JSON 輸出。
接下來,創建一個服務。
服務運行並維護來自指定任務定義的所需數量的任務。
如果服務中運行的任務數低於 desiredCount,Amazon ECS 會在指定的集群中運行該任務的另一個副本。
要創建服務,您可以將參數傳遞給 AWS CLI,也可以像我們為任務定義所做的那樣傳遞 o –cli-input-json 標誌。
本實驗使用 json 文件方法。為服務創建一個新的輸入文件。
vim web2048_service.json |
將以下內容複製到文本編輯器內:
{ |
將 targetGroupArn、PublicSubnet1、PublicSubnet2、ecsSecurityGroup 的紅字部分替換成自己的
targetGroupArn:目標群組
PublicSubnet1、PublicSubnet2:VPC 子網
ecsSecurityGroup:ECS的安全群組
創建服務:
aws ecs create-service --cli-input-json file://web2048_service.json |
成功創建後,您應該獲得包含服務詳細信息的 JSON 輸出。
服務創建只需幾秒鐘;但是,一旦創建了服務,就會提供所需數量的任務,任務會進入掛起狀態,最終任務狀態會更改為 RUNNING 。
您可以通過運行以下命令來查看任務的狀態:
aws ecs describe-clusters --cluster web2048 |
會獲得如下方所顯示內容:
{ |
運行以下命令創建 Amazon ECS 集群,將集群名稱 web2048 作為參數傳遞:
aws ecs create-cluster --cluster-name web2048
會獲得如下方所顯示內容:
{ "cluster": { "status": "ACTIVE", "defaultCapacityProviderStrategy": [], "statistics": [], "capacityProviders": [], "tags": [], "clusterName": "web2048", "settings": [ { "name": "containerInsights", "value": "disabled" } ], "registeredContainerInstancesCount": 0, "pendingTasksCount": 0, "runningTasksCount": 0, "activeServicesCount": 0, "clusterArn": "arn:aws:ecs:us-east-1:294373654843:cluster/web2048" } } |
在 ECS 集群上運行任務之前,您必須註冊任務定義。
任務定義是組合在一起的容器列表。
註冊新任務定義有兩個部分:
1. 傳遞給命令行的任務定義文件(這種方式更簡潔、更容易)
2. 使用標誌和參數值註冊新任務的 AWS CLI 命令
此處選擇使用第一個選項
創建任務定義文件。
首先先導航到您的主目錄。
獲取 Amazon ECR 報告 URI 並複製到文本編輯器,您將在下一步中需要此值。
並為您的任務定義創建一個文件。
cd ~ echo ${REPOSITORY_URI} vim web2048_task_definition.json |
json 內容如下:
{ "family": "web2048", "networkMode": "awsvpc", "taskRoleArn": "arn:aws:iam::000000000000:role/test-lab-3-ECSTaskExecutionRole-0000000000000", "executionRoleArn": "arn:aws:iam::000000000000:role/test-lab-3-ECSTaskExecutionRole-0000000000000", "containerDefinitions": [ { "name": "web2048", "image": "000000000000.dkr.ecr.us-east-1.amazonaws.com/web2048:latest", "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ], "essential": true } ], "requiresCompatibilities": [ "FARGATE" ], "cpu": "256", "memory": "512" } |
將 taskRoleArn、executionRoleArn、image 紅字部分替換成自己的。
taskRoleArn:任務角色
executionRoleArn:任務執行角色
此處皆使用相同角色代入。
運行以下命令註冊新的任務定義:
aws ecs register-task-definition --cli-input-json file://web2048_task_definition.json |
成功創建後,您應該獲得包含任務定義詳細信息的 JSON 輸出。
接下來,創建一個服務。
服務運行並維護來自指定任務定義的所需數量的任務。
如果服務中運行的任務數低於 desiredCount,Amazon ECS 會在指定的集群中運行該任務的另一個副本。
要創建服務,您可以將參數傳遞給 AWS CLI,也可以像我們為任務定義所做的那樣傳遞 o –cli-input-json 標誌。
本實驗使用 json 文件方法。為服務創建一個新的輸入文件。
vim web2048_service.json |
將以下內容複製到文本編輯器內:
{ "cluster": "web2048", "serviceName": "web2048", "taskDefinition": "web2048", "loadBalancers": [ { "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:000000000000:targetgroup/ECS-Target-Group/00000000000000", "containerName": "web2048", "containerPort": 80 } ], "desiredCount": 2, "launchType": "FARGATE", "platformVersion": "LATEST", "networkConfiguration": { "awsvpcConfiguration": { "subnets": [ "PublicSubnet1", "PublicSubnet2" ], "securityGroups": [ "ecsSecurityGroup" ], "assignPublicIp": "ENABLED" } } } |
將 targetGroupArn、PublicSubnet1、PublicSubnet2、ecsSecurityGroup 的紅字部分替換成自己的
targetGroupArn:目標群組
PublicSubnet1、PublicSubnet2:VPC 子網
ecsSecurityGroup:ECS的安全群組
創建服務:
aws ecs create-service --cli-input-json file://web2048_service.json |
成功創建後,您應該獲得包含服務詳細信息的 JSON 輸出。
服務創建只需幾秒鐘;但是,一旦創建了服務,就會提供所需數量的任務,任務會進入掛起狀態,最終任務狀態會更改為 RUNNING 。
您可以通過運行以下命令來查看任務的狀態:
aws ecs describe-clusters --cluster web2048 |
會獲得如下方所顯示內容:
{ "clusters": [ { "status": "ACTIVE", "defaultCapacityProviderStrategy": [], "statistics": [], "capacityProviders": [], "tags": [], "clusterName": "web2048", "settings": [], "registeredContainerInstancesCount": 0, "pendingTasksCount": 0, "runningTasksCount": 2, "activeServicesCount": 1, "clusterArn": "arn:aws:ecs:us-east-1:310899899985:cluster/web2048" } ], "failures": [] } |
請注意活動的 ServiceCount,它指示與具有活動狀態的集群相關聯的服務的數量。
還要注意 pendingTasksCount 和 runningTaskCount。
當您創建服務時,您會看到掛起的數量發生變化,並且隨著任務的完成,它們的狀態變為 RUNNING,並且您的 runningTasksCount 反映了 desiredCount。
在此次過程中,服務中定義了兩個任務。
幾分鐘後,任務應進入 RUNNING 狀態。
您可以重複上一個命令來監控進度。
一旦 runningTaskCount 值等於 2,繼續下一步。
複製 000000000000.dkr.ecr.us-east-1.amazonaws.com/web2048:latest 並粘貼到網絡瀏覽器的新頁面中。
註:000000000000 應替換成自己的 Account ID
您應該會看到您的 web2048 應用程序。
通過使用計算機上的箭頭鍵玩遊戲來測試應用程序。
應該會與在前面部分測試的容器相同。
如此一來就成功了部署應用程序在 Amazon ECS 上了。
• 您現在已經成功了解構建 Docker 映像所需的步驟
• 將容器映像上傳到 Amazon ECR 存儲庫以用於 Amazon ECS 部署
• 將容器從存儲庫部署到 Amazon ECS Fargate 叢集
• 使用 AWS 部署示例應用程序在 Amazon ECS Fargate 叢集上運行的 CLI 和容器
MetaAge 邁達特數位在資安、網路、儲存、伺服器、虛擬化、資料庫管理有豐富經驗,技術深厚的架構師群與維運團隊是企業雲服務的最佳幫手。客戶無論想要部署 AWS 服務,進一步代管維運(Cloud Managed Service)、基礎架構即代碼(Infrastructure-as-code)、 API 整合、雲地整合等加值服務,邁達特均能一站式滿足多構面需求。
MetaAge 邁達特數位(原聚碩科技)於1998年創業之初,即以成為「The ICT Solution Provider 專業資訊應用服務供應商」角色自期,為經銷夥伴與企業用戶提供一流產品與專業服務,成為業界最佳之加值服務名牌通路商。針對廣大的經銷商夥伴以及雲市集之獨立軟體供應商 (ISV),也可洽談經銷合作方案,設計後續合作的框架。
MetaAge 邁達特代理的軟硬體產品線均為全球知名品牌,針對廣大的經銷商夥伴以及雲市集之獨立軟體供應商 (ISV),提供強大的技術支援與量身訂作之經銷合作方案,擴大合作夥伴的服務範圍,在多樣化的場域中一同實現更優質的客戶服務體驗。
邁達特持續作為 IT 智能化最佳夥伴,竭誠歡迎舊雨新知攜手共創數位新局。
MetaAge 邁達特數位 AWS MSP 團隊導入次世代監控系統,提供客戶完全託管和完整監控的 MSP 整合服務。
聯絡方式 —— 24小時免付費電話: 080-000-8669 | Email: aws@metaage.com.tw | MSP 服務官方LineID: @metaage_msp
掃碼聯繫邁達特 MSP 服務團隊, 或加入官方 LineID: @metaage_msp
其他延伸閱讀