Amazon Elastic Container Service (Amazon ECS) 是Amazon專有的、高度可擴展的高性能容器管理服務,可輕鬆運行、中止和管理集羣上的 Docker容器。html
使用ECS,再也不須要安裝、運維和擴展本身的集羣管理基礎設施。只需簡單的 API 調用即可以啓動和中止Docker應用程序,查詢集羣狀態等。能夠根據資源需求、隔離策略和可用性要求來安排容器在集羣中的位置。ECS集成了Amazon Elastic Container Registry、Elastic Load Balancing、Elastic Block Store、Elastic Network Interfaces、Virtual Private Cloud、IAM 和 CloudTrail,可提供運行各類容器化應用程序或服務的完整解決方案。java
ECS是一個久經考驗的解決方案,已應用於許多其餘 AWS 服務,好比Amazon SageMaker 和 Amazon Lex。這足以證實ECS的安全性、可靠性、可用性,可用於生產環境。web
ECS支持兩種啓動類型:Fargate和EC2。正則表達式
Fargate 啓動類型spring
Fargate 啓動類型無需配置和管理底層基礎設施,只需定義任務(至關於Kubernetes的Pod),指定CPU、內存、網絡、IAM策略等,便可運行容器化的應用程序。
docker
EC2 啓動類型apache
EC2 啓動類型容許在本身管理的 EC2 實例集羣上運行容器化的應用程序。
api
您可使用 Fargate 啓動類型啓動服務或任務,運行在ECS 管理的無服務器基礎設施上,沒必要管理 Amazon EC2 實例服務器或集羣。若要進行更多控制,可使用 EC2 啓動類型。安全
下面講解利用Fargate 啓動類型部署Angular 9集成Spring Boot 2詳解中的Spring Boot和Angular應用。服務器
Spring Boot項目的Dockerfile文件:
Dockerfile.spring
FROM openjdk:8-jdk-slim WORKDIR app ARG APPJAR=target/heroes-api-1.0.0.jar COPY ${APPJAR} app.jar ENTRYPOINT ["java","-jar","app.jar"]
Angular項目的Dockerfile文件:
Dockerfile.angular
FROM httpd:2.4 ARG DISTPATH=./dist/ ARG CONFFILE=./heroes-httpd.conf COPY ${DISTPATH} /usr/local/apache2/htdocs/ COPY ${CONFFILE} /usr/local/apache2/conf/httpd.conf
以部署到Apache爲例,運行如下命令獲取httpd.conf:
docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > heroes-httpd.conf
修改配置文件,啓用proxy_module、proxy_http_module、rewrite_module,而後添加以下內容:
ProxyPreserveHost on ProxyPass "/api" "http://127.0.0.1:8080/api" ProxyPa***everse "/api" "http://127.0.0.1:8080/api" RewriteEngine on RewriteRule ^/$ /en/index.html # If an existing asset or directory is requested go to it as it is RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] # If the requested resource doesn't exist, use index.html RewriteRule ^/zh /zh/index.html RewriteRule ^/en /en/index.html
咱們將在一個任務中包含這兩個image,使用apache代理後臺地址。
構建Image
運行以下命令構建Image:
docker build --build-arg APPJAR=heroes-api-1.0.0.jar -f Dockerfile.spring -t heroes-api . docker build -f Dockerfile.angular -t heroes-web .
Amazon Elastic Container Registry (Amazon ECR) 是一項Docker Container Registry服務,可以讓開發人員輕鬆存儲、管理和部署 Docker 容器映像。
首先建立兩個ECR存儲庫,能夠從控制檯建立,也能夠運行以下AWS CLI命令:
aws ecr create-repository --repository-name heroes/heroes-api aws ecr create-repository --repository-name heroes/heroes-web
執行以下命令:
`aws ecr get-login --no-include-email` 或 aws ecr get-login-password | docker login --username AWS --password-stdin 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn
docker tag heroes-api:latest 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-api:latest docker tag heroes-web:latest 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-web:latest
docker push 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-api:latest docker push 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-web:latest
Amazon ECS 集羣是任務或服務的邏輯分組,能夠在一個帳戶中建立多個集羣以保持資源獨立。
建立Fargate集羣很是簡單,進入ECS集羣控制檯,點擊「建立集羣」,選擇「僅限聯網」集羣模板,點擊「下一步」,而後輸入集羣名稱"heroes",點擊「建立」便可。
任務定義相似於應用程序的藍圖,須要任務定義才能在Amazon ECS 中運行 Docker 容器。
可在Fargate任務定義中指定的一些參數:
執行如下步驟建立任務定義:
內存、CPU的有效的組合
CPU 值 | 內存值 (MiB) |
---|---|
256 (.25 vCPU) | 512 MB、1 GB、2 GB |
512 (.5 vCPU) | 1 GB、2 GB、3 GB、4 GB |
1024 (1 vCPU) | 2 GB、3 GB、4 GB、5 GB、6 GB、7 GB、8 GB |
2048 (2 vCPU) | 4GB 到 16GB(以1GB爲增量) |
4096 (4 vCPU) | 8GB 到 30GB(以1GB爲增量) |
容器存儲與共享卷
Fargate 啓動類型,任務的最大容器存儲爲10GB,多個容器使用的共享卷的最大大小爲4GB。若要添加共享卷,在卷配置部分點擊「添加捲」,輸入卷名稱後點擊「添加」便可。注意,任務存儲是短暫存儲。Fargate 任務中止後,該存儲將被刪除。
添加容器
接下來,在容器定義部分點擊「添加容器」按鈕,添加heroes-api和heroes-web容器:
在高級容器配置下部的「存儲和日誌記錄」部分能夠添加掛載點和配置日誌:
默認,Fargate任務記錄日誌到CloudWatch Log,能夠設置每一個容器的日誌組名稱、日誌流前綴等。
最後,點擊「建立」,完成任務定義。
服務可在 Amazon ECS 集羣中同時運行和管理指定數量的任務定義實例。若是任務出於任何緣由失敗或中止,服務計劃程序將啓動另外一個任務定義實例來替換它並根據所用的計劃策略在服務中保留預期數量的任務。
除了在服務中保留預期數量的任務以外,還可選擇藉助負載均衡器運行服務。負載均衡器將在與服務關聯的各個任務間分配流量。
在ECS控制檯,從集羣和任務定義都可建立服務。以任務定義爲例,步驟以下:
配置基本參數
選中heroes任務定義,而後點擊操做 -> 建立服務,在配置服務頁面填充如下參數:
點擊下一步。
網絡配置
在VPC 和安全組部分,選擇集羣 VPC、子網。默認會自動生成一個安全組名稱,您能夠點擊編輯,修改安全組名稱,或者選擇一個現有安全組。若選擇新建安全組,默認配置了80端口的入站規則。
咱們使用ELB,不須要公有IP,將自動分配公有 IP選項設爲DISABLED。
負載均衡
咱們新建立一個ALB,先沒必要建立目標羣組。
設置 Auto Scaling
服務 Auto Scaling:請勿調整服務的預期計數
審覈
檢查無誤後點擊建立服務。
返回到集羣界面,能夠看到heroes集羣含有一個服務,一個正在運行的任務。
服務限制
在集羣任務界面,咱們若中止當前任務,稍後會自動重啓新任務,同時會自動更新ELB的目標羣組。
Amazon ECS 服務計劃程序包含限制服務任務在反覆啓動失敗後再啓動的頻率邏輯。
若是一個 ECS 服務的任務老是沒法進入 RUNNING 狀態(直接從 PENDING 跳到 STOPPED),則後續重啓嘗試間隔的時間會逐漸拉長,最多達到 15 分鐘
訪問服務
進入heroes集羣 -> 任務,點擊任務,進入任務詳細信息頁面,能夠看到任務的私有 IP 地址。在內部網絡中,可使用私有IP訪問每一個任務部署的應用。公網則經過ELB訪問服務。
默認,Fargate任務使用awslogs日誌驅動程序,記錄日誌到CloudWatch Log。
awslogs 日誌驅動程序選項
選項 | 必須 | 說明 |
---|---|---|
awslogs-create-group | 否 | 自動建立日誌組,IAM 策略必須包含 logs:CreateLogGroup 權限。默認值false |
awslogs-region | 是 | 日誌驅動程序應將Docker 日誌發送到的區域 |
awslogs-group | 是 | 日誌驅動程序將日誌流發送到的日誌組 |
awslogs-stream-prefix | 是 | 日誌流前綴,日誌流格式:prefix-name/container-name/ecs-task-id |
awslogs-datetime-format | 否 | 以 Python strftime 格式定義多行開始位置模式 |
awslogs-multiline-pattern | 否 | 使用正則表達式定義多行開始位置模式 |
說明:若是同時配置了 awslogs-datetime-format 和 awslogs-multiline-pattern, awslogs-datetime-format選項優先。多行日誌記錄對全部日誌消息執行正則表達式解析和匹配,這可能會對日誌記錄性能產生負面影響。
FireLens for Amazon ECS 可將日誌路由到 AWS 服務或 AWS 合做夥伴網絡(APN)目標位置,以進行日誌存儲和分析。FireLens 可與 Fluentd 和 Fluent Bit 結合使用。AWS 提供了 Fluent Bit 映像以及用於 CloudWatch Logs 和 Kinesis Data Firehose 的插件,也可使用本身的 Fluentd 或 Fluent Bit 映像。
Fluent Bit 和Fluentd是兩個日誌歸集工具,Fluent Bit 插件更節省資源、效率更高,建議使用 Fluent Bit 做爲日誌路由器。
選中咱們前面建立的任務,點擊「建立新修訂」,啓用FireLens 集成:
如上圖,選中fluentbit後會自動填充映像地址,點擊應用將自動添加log_router容器。
注意,使用CloudWatch插件,任務角色必須擁有CreateLogGroup、CreateLogStream、DescribeLogStreams、PutLogEvents權限;使用AmazonKinesisFirehose插件必須擁有 "firehose:PutRecordBatch"權限。
配置log_router
{ "essential": true, "image": "128054284489.dkr.ecr.cn-north-1.amazonaws.com.cn/aws-for-fluent-bit:latest", "name": "log_router", "firelensConfiguration": { "type": "fluentbit" }, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/firelens", "awslogs-region": "cn-north-1", "awslogs-create-group": "true", "awslogs-stream-prefix": "firelens" } }, "memoryReservation": 50 }
Log Router日誌使用awslogs驅動,記錄到CloudWatch:
下面咱們利用Fluent Bit將日誌分別轉發到CloudWatch Logs和Kinesis Data Firehose。
將日誌轉發到 CloudWatch Logs
修改容器heroes-api的日誌配置,驅動程序選擇"awsfirelens",日誌選項 "Name"值設爲"cloudwatch",啓用CloudWatch Logs插件,其它配置以下:
{ "essential": true, "image": "888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-api:latest", "name": "heroes-api", "logConfiguration": { "logDriver": "awsfirelens", "options": { "Name": "cloudwatch", "region": "cn-north-1", "log_group_name": "/ecs/heroes-api", "log_stream_prefix": "from-fluent-bit", "auto_create_group": "true" } } }
任務修改完畢後,點擊「建立」保存任務定義。
返回到集羣控制檯,選中咱們建立的服務,點擊「更新」,而後選擇最新的任務定義,選中「強制實施新部署」,一步步保存服務。
服務更新成功後將建立新的任務,進入Cloud Watch控制檯查看日誌,日誌格式以下:
{ "container_id": "cda4f603d8e485d48fd7e1a77b3737026221c165b8f6d582ed78bd947a12b911", "container_name": "/ecs-heroes-2-heroes-api-c2f3d4a8bdbcf3f9e601", "ecs_cluster": "arn:aws-cn:ecs:cn-north-1:888888888888:cluster/isd", "ecs_task_arn": "arn:aws-cn:ecs:cn-north-1:888888888888:task/078dd364-28b6-4650-b294-5eac6b39d08f", "ecs_task_definition": "heroes:2", "log": " /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\", "source": "stdout" }
能夠看到,日誌添加了新的標識字段:container_id、container_name、ecs_cluster、ecs_task_arn、ecs_task_definition和source。
在任務定義時,點擊「經過JSON配置」,設置fluentbit的選項enable-ecs-log-metadata爲false,能夠禁用上面三個ecs元數據:
"firelensConfiguration": { "type": "fluentbit", "options": { "enable-ecs-log-metadata": "false" } }
在容器的日誌配置中,增長log_key選項,能夠僅轉發log項:
"log_key": "log"
CloudWatch Logs插件支持的選項:
將日誌轉發到 Amazon Kinesis Data Firehose
Kinesis Data Firehose插件支持的選項:
Kinesis Data Firehose傳輸流能夠將日誌發送到Amazon S三、Amazon Redshift和Amazon Elasticsearch Service。
以S3爲例,咱們先建立到S3的傳輸流heroes-web-log,而後修改容器heroes-web的日誌配置,驅動程序選擇"awsfirelens",日誌選項 "Name"值設爲"firehose",啓用Kinesis Data Firehose插件,其它配置以下:
{ "essential": true, "image": "888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-web:latest", "name": "heroes-web", "logConfiguration": { "logDriver":"awsfirelens", "options": { "Name": "firehose", "region": "cn-north-1", "delivery_stream": "heroes-web-log", "data_keys": "log" } }, "memoryReservation": 100 }
保存任務定義、更新服務後便可到S3查看日誌了。
Amazon Elastic Kubernetes Service (Amazon EKS)是全託管的Kubernetes服務,運行開源的 Kubernetes來部署、管理和擴展容器化應用程序。EKS無需使用Kubernetes控制平面,消除了運行 Kubernetes 的重大操做負擔,使得能夠專一於構建應用程序而不是管理 AWS 基礎設施。EKS可跨多個 AWS 可用區運行,與 Kubernetes 兼容,可使用 Kubernetes 社區提供的全部現有插件和工具,全部標準 Kubernetes 環境中運行的應用程序都可輕鬆遷移到EKS。
通用性
ECS是AWS專有技術,而 EKS 則運行開源的 Kubernetes。所以,若是您的部署環境不侷限於AWS,好比可能部署到Google GKE(Google Kubernetes Engine)、Microsoft AKS(Azure Kubernetes Service)或標準Kubernetes,應選用EKS。
簡易性
ECS是一個開箱即用的解決方案,可經過 AWS 控制檯輕鬆部署。EKS有點複雜,須要更多的配置,須要更多的專業知識。
價格
ECS不收取任何額外費用,只需爲容器使用的計算資源付費。EKS集羣每小時需支付 0.688 CNY(能夠利用 Kubernetes 命名空間和 IAM 安全策略,使用一個EKS 集羣運行多個應用程序),用於運行 Kubernetes 工做節點的 AWS 資源需按實際使用量付費。
通過測試與對比ECS、EKS、Kubernetes三種容器編排解決方案,筆者工做中選用了ECS,ECS徹底知足項目需求,讓部署更輕鬆、運維更輕鬆、成本更輕鬆。