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彻底知足项目需求,让部署更轻松、运维更轻松、成本更轻松。