在 AWS 上构建无服务器管理的容器应用实践 张浙 Amazon Web Services
容器应用在 AWS 平台上的部署演进 无服务管理的容器平台 Fargate 技术实践 Fargate 最新技术发布
容器应用在 AWS 平台上的部署演进
最开始阶段 Amazon EC2
然后是 Docker Containers EC2 Instance 开发人员开始在 EC2 实例上实现应用容器化
容器技术使得构建和发布云原生应用服务变得更加简单
开发人员需要一种更简单的方式来管理大规模的容器集群实例, 监控容器的运行及容器化后的业务服务的状态
调度和排程 集群管理器 置放引擎
开发人员仍然需要关注容器化业务以外的管理工作 EC2 Instance OS Docker Agent ECS Agent
大规模 EC2 实例管理仍然是一件很繁杂的工作 操作系统管理 : 软件补丁 系统升级 管理 Agent 软件 集群管理 : 设定 EC2 实例集群规模 管理集群资源使用率
Elastic Container Service EC2 Instance EC2 Instance EC2 Instance OS Docker Agent ECS Agent OS Docker Agent ECS Agent OS Docker Agent ECS Agent
AWS FARGATE 完全 AWS 管理无需配置 运行 管理 EC2 实例 Your Containerized Applications 弹性集群无感知扩容收缩, 只需为您实际消耗的资源付费 整合 AWS 生态和 AWS 服务生态完全整合 : VPC Networking, Elastic Load Balancing, IAM 权限管理, Cloudwatch 以及其他.
AWS Container 服务全景 管理服务部署, 调度, Scaling & 弹性扩展容器化的业务 Amazon Elastic Container Service Amazon Elastic Container Service for Kubernetes 托管服务容器化业务运行平台 Amazon EC2 AWS Fargate 镜像仓库容器镜像仓库 Amazon Elastic Container Registry
Fargate 技术实践
示例演示 三连线游戏 Scorekeep, 使用容器部署在 Fargate 平台 Dynamo DB Internet Load Balancer Port 8080 Frontend Server Container Angular + Nginx Port 5000 API Server Container Java SNS 一步一步演示配置 : 计算, 网络, 存储, 权限, 日志管理 然后实际运行这个小程序!
在 Fargate 上构造应用
在 Fargate 上构造应用 register Task Definition 定义应用容器属性 : 容器镜像 URL, C P U & 内存需求, 存储网络设定等等 run Task Task Defination 定义任务的一个运行时状态 使用 Fargate 运行模式 Elastic Load Balancer create Cluster 基础设施隔离边界 IAM 权限边界 create Service 维护多个在线应用副本 和弹性负载均衡器整合 自动替换不健康的 task
TASK DEFINITION Task Definition 小片段 静态不可变的 (Immutable), 带有版本控制的文档 "family": scorekeep", "containerdefinitions": [ "name": scorekeep-frontend", 通过 family:version 格式识别 最多包含 10 个容器定义 } ] "image":"xxx.dkr.ecr.us-east-1.amazonaws.com/fe" }, "name": scorekeep-api", } "image":"xxx.dkr.ecr.us-east-1.amazonaws.com/api" 所有的容器都会被调度到同一个实例上 每个容器定义主要包含 : 容器名字 docker 镜像 URL (ECR 或者公共的镜像仓库 ) 其他的配置 稍后介绍
容器镜像仓库 Amazon Elastic Container Registry (ECR) 公共的容器镜像仓库 3 rd Party 私有容器镜像仓库 ( 即将到来!)
计算相关配置
CPU & 内存设定 单位 : CPU : cpu-units. 1 vcpu = 1024 cpu-units Memory : MB Task 级别的资源设定 : 所有容器可以使用到的 CPU 和内存的总和 必须指定的设定 计费基准 容器级别的资源设定 : 定义容器之间的资源 可选设定 } "family": "scorekeep", "cpu": "1 vcpu", "memory": "2 gb", "containerdefinitions": [ "name": scorekeep-frontend", ] Task Definition 小片段 "image":"xx x.dkr. ecr.u s -east-1. amazon aws.co m/fe, "cpu": 256, "memoryreservation": 512 }, "name": scorekeep-api", Task 级别资源 容器 级别资源 "image":"xx x.dkr. ecr.u s -east-1. amazon aws.co m/api", "cpu": 768, "memoryreservation": 512 }
CPU Memory TASK CPU 内存配置组合 256 (.25 vcpu) 512MB, 1GB, 2GB 512 (.5 vcpu) 1GB, 2GB, 3GB, 4GB 1024 (1 vcpu) 2GB, 3GB, 4GB, 5GB, 6GB, 7GB, 8GB 2048 (2 vcpu) Between 4GB and 16GB in 1GB increments 4096 (4 vcpu) Between 8GB and 30GB in 1GB increments 50 种不同的 CPU/Memory 配置选择可选
计费方式 只需要为实际使用的计算资源付费 基于 Task 级别的 CPU 和内存消耗计费 按秒计费, 最小计费时间周期为 1 分钟
网络相关配置
Fargate Task 的 awsvpc 网络工作模式 172.31.0.0/16 Fargate Task 在 subnet 中执行 在此基础上 : 创建一个 Elastic Network Interface (ENI) ENI 从当前 subnet 中获取一个私有的 IP 地址 添加 ENI 到 Task 上 您的 Task 可以直接从 subnet 中获取 IP 地址了! Internet Subnet 172.31.1.0/24 ENI Public / Private IP 208.57.73.13 / 172.31.1.164 Fargate Task 您也可以为 Task 指定公有 IP 地址 通过安全组策略来设定流入和流出流量的安全规则 VPC 中的其他服务 EC2 LB DB etc.
Task 网络设定 Task Definition 小片段 } "family": "scorekeep", "cpu": "1 vcpu", "memory": "2 gb", "networkmode": "awsvpc", "containerdefinitions": [ "name": scorekeep-frontend", ] "image":"xx x.dkr. ecr.u s-east-1. amazon aws.co m/ fe", "cpu": 256, "memoryreservation": 512 }, "name": scorekeep-api", "image":"xx x.dkr. ecr.u s-east-1. amazon aws.co m/ api", "cpu": 768, "memoryreservation": 512 } 创建一个 ENI 并且添加到 Task 上 运行 Task $ aws ecs run-task... -- task-definition scorekeep:1 -- network-configuration awsvpcconfiguration = subnets=[subnet1-id, subnet2-id], securitygroups=[sg-id] }
Task 访问 Internet Task ENI 用来传输所有流入和流出 Task 的网络流量 它也可以被用作 : 拉取容器镜像 ( 从 ECR 或者公共的容器镜像仓库 ) 推送日志到 Cloudwatch Task ENI 需要对指定的 endpoint 可达 两种常用的 Task 访问 Internet 的设定方式 : 私有的 Task, 不允许 Internet 流量进入, 但是允许 Task 访问 Internet 公有网络访问的 Task, 允许 Internet 流量进入和流出
私有 TASK 的 Internet 访问设定 172.31.0.0/16 Internet Gateway Public subnet Private subnet 172.31.2.0/24 172.31.1.0/24 添加 Internet Gateway 到 VPC Internet NAT Gateway Public EIP 34.214.162.237 ENI Private IP 172.31.1.164 Fargate Task Public Subnet 配置 到 Internet Gateway 的路由规则 添加 NAT Gateway Destination Target 172.31.0.0/16 local 0.0.0.0/0 Internet Gateway Route Tables Destination Target 172.31.0.0/16 local 0.0.0.0/0 NAT Gateway Outbound Security Group Rules Type Port Destination All Traffic ALL 0.0.0.0/0 Private Subnet 配置 Fargate Task 到 NAT Gateway 的路由 配置安全组允许到 internet 的流量
Internet Outbound Inbound Internet Gateway 直接 Internet 访问的 TASK 设定 172.31.0.0/16 Public subnet 172.31.2.0/24 ENI Public IP 54.191.135.66 Fargate Task $ aws ecs run-task... -- network-configuration awsvpcconfiguration = subnets=[public-subnet], securitygroups=[sg-id], } Run Task assignpublicip=enabled Route Table Destination Target 172.31.0.0/16 local 0.0.0.0/0 Internet Gateway Outbound Security Group Rules Type Port Destination All Traffic ALL 0.0.0.0/0 Inbound Security Group Rule Type Port Source HTTP 8080 0.0.0.0/0 在 Public subnet 中运行 Task 为 Task 分配一个公网 IP 地址 在安全组中指定允许流入的网络流量
Task Definition ELB 配置 创建服务 } "family": "scorekeep", "cpu": "1 vcpu", "memory": "2 gb", "networkmode": awsvpc, "containerdefinitions": [ "name": scorekeep-frontend", "image":"xxx.dkr.ecr.us -east-1.amazonaws.com/fe", "cpu": 256, "memoryreservation": 512, ] "portmappings": [ ] "containerport": 8080 } }, "name": scorekeep-api", "image":"xxx.dkr.ecr.us -east-1.amazonaws.com/api", "cpu": 768, "memoryreservation": 512, } "portmappings": [ ] "containerport": 5000 } $ aws ecs create-service... -- task-definition scorekeep:1 -- network-configuration awsvpcconfiguration = subnets=[subnet-id], securitygroups=[sg-id] } -- load-balancers [ "targetgrouparn": <insert arn>", "containername": scorekeep-frontend", "containerport": 8080 } ]
面向 INTERNET 访问的 ELB 在 VPC 中的设定 172.31.0.0/16 us-east-1a us-east-1a Public subnet Private subnet 172.31.2.0/24 172.31.1.0/24 Task 在 private subnet 中分配到了私有的 IP 地址 ALB 在 public subnet 中分配到了公网的 IP 地址 Internet ALB Public IP 208.57.73.13 :80 ALB Security Group Inbound Rule Type Port Source HTTP 80 0.0.0.0/0 ENI Private IP 172.31.1.164 :8080 Fargate Task Task Security Group Inbound Rule Type Port Source Custom TCP 8080 ALB Security Group 确定两个子网的可用区是匹配的 设定 ALB 的 security group 允许来自互联网的指定流量 设定 Task 的 security group 允许来自 ALB 的 security group 的流量
存储相关配置
磁盘存储 基于 EBS 一次性存储, 提供下列存储机制 : Writable Layer Storage Volume Storage
LAYER STORAGE Docker 镜像由多个存储层组成 最顶层为写入层, 用来保存在容器运行产生时的临时文件 10GB per Task Fargate 允许每个 Task 使用 10GB Layer storage, 包括所有的容器以及镜像使用的存储空间 Writable Layer Writable Layer 容器内写操作在其他容器中不可见 Image Layers Image Layers 一次性存储 (Ephemeral). Task 停止后, 容器内数据无法找回 Container 1 Container 2
VOLUME STORAGE 跨容器访问的可写存储 Container 1 Container 2 Fargate 为每个 Task 提供 4GB Volume Storage 空间 /var/container1/data /var/container2/data 通过 Task Definition 中的 volume mount 参数进行配置 每个容器可以指定不同的 containerpaths 参数 不要指定宿主机的 sourcepath 参数 mount 一次性存储 (ephemeral), Task 停止后数据无法找回 4GB Volume Storage
IAM 权限相关配置
Cluster Fargate Task 权限层级 集群权限 : 控制哪些用户可以在指定集群中读取 Task 状态或运行 Task Application Permissions Cluster Permissions 应用权限 : 允许您的应用容器安全的访问 AWS 资源 应用相关管理 (Housekeeping) 权限 : Task Housekeeping Permissions 从 ECR 拉取镜像 向 Cloudwatch 推送日志 创建 ENI 在 ELB 上创建 / 删除 target group
您可以通过定制的 IAM 规则控制您的集群访问把定制好的权限添加到指定的 IAM 用户或者角色中 集群权限 演示规则 : } "Effect": "Allow", "Action": [ "ecs:runtask" ], "Condition": "ArnEquals": "ecs:cluster":"<cluster-arn>"} }, "Resource": [ <task_def_family>:*" ] } "Effect": "Allow", "Action": [ "ecs:listtasks, ecs:describetasks ], "Condition": "ArnEquals": "ecs:cluster":"<cluster-arn>"} }, "Resource": * 示例 1: 允许在指定集群中运行指定的 task definition 示例 2: 允许在指定集群中获取所有 Task 的状态信息
应用权限 您的应用容器需要访问其他的 AWS 资源, 您需要下载 AWS 认证凭据 (AWS ACCESS KEY) 到 Task 中的容器里? 请使用 Task Role 首先, 根据您应用的需求, 创建一个 IAM 角色 在 scorekeep 示例中, 我们的程序需要访问 DynamoDB 和 SNS 服务的权限 在这个角色中创建和 ecs-tasks.amazonaws.com 的信任关系. 这个设置允许 Fargate 切换到您定义的角色权限中, 并且关联相关认证凭据到您的 Task. 在您的 task definition 中增加 TaskRole 的 ARN Fargate 会自动为您的 Task 发布和滚动替换临时凭证 在您的应用容器中执行的 AWS CLI/SDK 调用将会自动获得 TaskRole 定义权限的认证凭证 } Task Definition "family": "scorekeep", "cpu": "1 vcpu", "memory": "2 gb", "networkmode": awsvpc, taskrolearn": arn:aws...role/scorekeeprole, "containerdefinitions": [ "name": scorekeep-frontend", "image":"xxx.dkr.ecr.us -east-1.amazonaws.com/fe", "cpu": 256, "memoryreservation": 512, "portmappings": [ "containerport": 8080 } ] }, "name": scorekeep-api", "image":"xxx.dkr.ecr.us -east-1.amazonaws.com/api", "cpu": 768, "memoryreservation": 512, "portmappings": [ "containerport": 5000 } ] } ]
应用相关管理 (HOUSEKEEPING) 权限 您需要在您的账号中定义一些特定的权限来运行 Fargate 引导您的 Task 并且让他们能够持续运行. Execution Role 赋予了下列权限 : 拉取保存在 ECR 中的容器镜像 向 Cloudwatch 推送日志 ECS Service Linked Role 赋予了下列权限 : ENI 管理 注册和删除 ELB Target Group
EXECUTION ROLE 需要使用保存在 ECR 容器镜像或者 Cloudwatch Logs 功能? Task Definition 通过 Execution Role 授予权限 创建一个 IAM 角色然后增加 ECR 的只读权限 ecr:getauthorizationtoken & ecr:batchgetimage 或者使用预定义的 AmazonEC2ContainerRegistryReadOnly 管理规则 增加 CloudWatchLogs 的写权限 logs:createlogstream & logs:putlogevents 或者使用预定义的 CloudWatchLogsFullAccess 管理规则 创建和 ecs-tasks.amazonaws.com. 的信任关系, 这个设置的作用是允许 Fargate 切换到这个角色中 把 execution role 的 arn 添加到您的 task definition } "family": "scorekeep", "cpu": "1 vcpu", "memory": "2 gb", "networkmode": awsvpc, taskrolearn": arn:aws...role/scorekeeprole, executionrolearn": arn:aws...role/scorekeepexecutionrole, "containerdefinitions": [ "name": scorekeep-frontend", "image":"xxx.dkr.ecr.us -east-1.amazonaws.com/fe", "cpu": 256, "memoryreservation": 512, "portmappings": [ "containerport": 8080 } ] }, "name": scorekeep-api", "image":"xxx.dkr.ecr.us -east-1.amazonaws.com/api", "cpu": 768, "memoryreservation": 512, "portmappings": [ "containerport": 5000 } ] } ]
ECS SERVICE LINKED ROLE service-linked role 是一种特定的 IAM 角色类型, 可以被直接连接到一种 AWS 的服务, 例如 ECS 当您创建第一个集群的时候, 在您的账号中被自动创建 这是一种预定义的规则, 并且不可变. 在本场景中, 主要涉及到 ENI & ELB 相关的授权. 您不需要在 task definition 或者任何 API 调用的时候显示的指定这个规则. 在这里提及到这个角色类型是为了避免您在 IAM 界面中看到相关角色类型而产生困惑
监控相关配置
CLOUDWATCH LOGS 配置 使用 awslogs 驱动把您的容器应用中发送到标准输出的信息记录到 Cloudwatch logs 中 在 Cloudwatch 中创建一个日志组 在 task definition 中指定 LogDriver 参数 在 Task Execution Role 中添加可写入的权限 "family": "scorekeep",... "containerdefinitions": [ "name": scorekeep-frontend",... "logconfiguration": "logdriver": "awslogs", "options": "awslogs-group": "scorekeep", "awslogs-region": us-east-1", "awslogs-stream-prefix": "scorekeep/frontend }} }, "name": scorekeep-api",... "logconfiguration": "logdriver": "awslogs", "options": "awslogs-group": "scorekeep", "awslogs-region": us-east-1", "awslogs-stream-prefix": "scorekeep/api"}} } ]} Task Definition
CLOUDWATCH LOGS 在 ECS 或者 Cloudwatch 界面中查看应用日志 Logs Tab in the Task Detail Page
其他监控工具 CloudWatch event - Task 状态发生变化时产生 Cloudwatch 监控 - CPU/Memory 使用率指标
DEMO
} FINAL SCOREKEEP TASK DEFINITION "family": "scorekeep", "cpu": "1 vcpu", "memory": "2 gb", "networkmode":"awsvpc", "taskrolearn": "arn:aws: ", "executionrolearn": arn:, "requirescompatibilities": [ "FARGATE" ], "containerdefinitions": [ ] Task Definition } "name": "scorekeep-frontend", "image": xxx.dkr.ecr frontend", "cpu": 256, "memoryreservation": 512, "portmappings" : [ "containerport": 8080 } ], "logconfiguration": "logdriver": "awslogs", "options": } } "awslogs-group": "scorekeep", "awslogs-region": "us-east-1", "awslogs-stream-prefix": "scorekeep/frontend" scorekeep-frontend Container Definition "name": "scorekeep-api", "image": xxx.dkr.ecr api", "cpu": 768, "memoryreservation": 512, "portmappings" : [ "containerport": 5000 } ], "logconfiguration": "logdriver": "awslogs", "options": "awslogs-group": "scorekeep", "awslogs-region": "us-east-1", "awslogs-stream-prefix": "scorekeep/api } }, "environment": [ ] #env var } scorekeep-api Container Definition
Fargate 最新技术发布
Task Metadata 查询 Task 的状态和容器的运行状态 NEW! "Cluster": "default", "TaskARN": "arn:aws:ecs:us-west-2:012345678910:task/9781c248-0edd-4cdb- 9a93-f63cb662a5d3", "Family": "nginx", "Revision": "5", "DesiredStatus": "RUNNING", "KnownStatus": "RUNNING", "Containers": [ "DockerId": "731a0d6a3b4210e2448339bc7015aaa", "Name": "~internal~ecs~pause", "DockerName": "ecs-nginx-5-internalecspause-1234", "Image": "amazon/amazon-ecs-pause:0.1.0", "ImageID": "", "Labels": "com.amazonaws.ecs.cluster": "default", "com.amazonaws.ecs.container-name": "~internal~ecs~pause", "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west- 2:012345678910:task/9781c248-0edd-4cdb-9a93-f63cb662a5d3", "com.amazonaws.ecs.task-definition-family": "nginx", "com.amazonaws.ecs.task-definition-version": "5" }, "DesiredStatus": "RESOURCES_PROVISIONED", "KnownStatus": "RESOURCES_PROVISIONED", "Limits": "CPU": 512, AWS 中国 ("Memory": 宁夏 ) 区域由西云数据运营 512 "CreatedAt": "2018-02-01T20:55:08.366329616Z", "StartedAt": "2018-02-01T20:55:09.058354915Z", "Type": "CNI_PAUSE", "Networks": [ "NetworkMode": "awsvpc", "IPv4Addresses": [ "10.0.2.106" ] } ] }, "PullStartedAt": "2018-02-01T20:55:09.372495529Z", "PullStoppedAt": "2018-02-01T20:55:10.552018345Z" }
容器健康检查 NEW! - 在 Task Definition 中指定自定义的健康检查命令
ECS/Fargate 托管服务发现 NEW! 服务注册 : 可预置的服务命名 自动更新到最近的健康的 IP 地址和端口号 全托管 : 无需安装部署及维护 高可用, 高可伸缩性 可扩展性 : 灵活的自动发现边界
总结 Fargate 是 ECS 服务的一种新的容器运行模式, 在这种模式下无需对 EC2 实例进行管理 如果您正在纠结于使用 EC2 模式还是 Fargate 模式, 可以尝试先从 Fargate 开始规划您的应用. 这种模式通过把应用从底层虚拟主机完全独立出来的方式, 强化了一种比较好的设计实践 如果您认为必须要访问和控制底层虚拟主机, 那么请您再次考虑一下. 一些特定的原因 : 特定类型的实例, EC2 dedicated instances, 使用 EC2 预留实例, GPU, Windows 负载 告诉我们您的需求, 我们想把这些需求加入到 Fargate 中! 从现在开始使用 Fargate! Fargate 完全兼容您现有的容器镜像 您只需要在现有的 ECS task definitions 做细微的修改就可以使用 Fargate 了.
感谢您的聆听 更多信息请参考 aws.amazon.com/fargate