zl程序教程

您现在的位置是:首页 >  其他

当前栏目

探索入门云计算风向标Amazon的ECS容器技术

2023-04-18 17:00:55 时间

Amazon ECS 概述

对于经常接触云计算服务技术的同学们估计一听到ECS,耳朵都能磨出茧子,印象中ECS不就是弹性计算服务么,再人话点就是你按量充值的一台虚拟主机,然后通过SSH远程维护这台虚拟主机的操作系统呗,但是Amazon ECS就不同于你们理解的那个ECS啦!且听我慢慢道来。

Amazon ECS全称是(Amazon Elastic Container Service),它是针对容器技术高度弹性的的管理服务,我么如何去更通俗地理解呢?其实Amazon ECS就是希望用户直接面对容器进行管理(例如:Docker),而不是面对虚拟机操作系统,也就是说Amazon云平台提供给用户购买的计算单元粒度更细致了,那么这又带来什么好处呢?其实是两方面:

优势一:你没必要就为了部署一个服务(例如:部署Tomcat),就得先占用一台虚拟机,现在Amazon ECS给你了一个新方案,你部署维护一个Docker容器就够了,这个容器服务跑在哪台机器上,那个容器引擎上,这些你就不用关心了,Amazon ECS自己来维护计算资源的基础设施,由于资源占用少了,自然你充值就少了

优势二:现在的云服务大趋势是分布式,这样你的应用可以形成集群,以便增强系统高可靠性以及对服务性能的弹性伸缩管理,但是像以前我购买一台虚拟主机,即使我切分成了多个Docker,那也是在这一个虚拟主机节点上跑,依然是个伪分布式,除非你有更多的资金购买更多的虚拟主机。但是Amazon ECS默认提供的无服务(Serverless)模式就让你不再顾虑运行服务的集群分布问题,只考虑要上多少Docker容器,至于放置在什么地方,哪个机房,那台服务器,那更多是Amazon ECS考虑的事情,那么我就用一个整体上较低的综合成本,实现了一个真正比较强大的面相服务的集群环境。

对于Amazon ECS的一些简单介绍我们可以看看Amazon ECS官方的介绍:什么是 Amazon Elastic Container Service?

另外提一下亚马逊云科技最近活动力度还是蛮大的,提供了100余种产品免费套餐。其中,计算资源Amazon EC2首年12个月免费,750小时/月;存储资源 Amazon S3 首年12个月免费,5GB标准存储容量。

若小伙伴们有兴趣,也可以进去瞧瞧亚马逊云科技最新活动页,便宜不占白不占,对吧:亚马逊AWS海外区域账户免费套餐_免费云服务-AWS云服务

 Amazon ECS架构

我们先上一张Amazon ECS的官网发布的架构图,先对其有个概括的认识:

 Amazon ECS环境架构图

从上图中,我们看到了Amazon ECS的受控范围是一个Region(区域),这个区域我们可以理解为世界上某个国家、某个地区的云机房,例如:美国西部 (俄勒冈州) us-west-2,非洲 (开普敦) af-south-1,亚太地区 (香港) ap-east-1,你一开始接触会有些懵逼,这咋全世界都有Amazon的点,没办法,为啥Amazon是云计算大哥,就是因为人家的云服务是覆盖全世界的,这对于国内企业云服务未来走向国际化就具有比较潜在的基础设施优势。

Region内部的核心又分为了任务定义(Task definition)服务描述(Service description)的配置蓝图部分,任务和基础设施的运行实例部分,另外还有一个容器镜像注册(Container registry)的仓库部分,这三部分实际上就是Amazon ECS面向用户的核心服务。

例如:你有个不错的Docker镜像,那么就先注册到Container registry,然后下一步开始在Task definition中做容器运行所需的配置,其实通俗点说就是在任务配置中引用你上传的Docker镜像地址,给任务分配多少CPU、内存,属于VPC(虚拟私有云)中哪个子网等等这些容器镜像、配额、用户角色、基础设施的综合性说明文件。

有了这个综合性说明,再根据Service description配置就能在启动服务的过程中,将配置中的Docker镜像实例化成一到多个Docker容器服务的任务,并根据Amazon Fargate(Amazon的无服务技术),将任务放置在ECS集群的不同位置,形成高可靠的分布式系统(当然你也可以只选择部署一个任务)。Fargate类型比较重要,我们做Task definition的时候,一般会选择它,它的官方介绍:Amazon Fargate 上的 Amazon ECS

对于Amazon ECS产品的详细介绍我们可以进入官方的Amazon ECS产品详细介绍页做进一步的了解。 

Docker快速介绍

玩转Amazon ECS的底子就是会玩Docker,对于Docker还比较陌生的同学们,我先简单科普一下:

提起 Docker,有很多人第一印象会认为它就是一个虚拟化容器,所以大家特别容易陷入到一种误区,就是觉得 Docker 只是在 Linux 操作系统之上又增加了一层,就跟 OS 上跑了一个 VMWare 一样。Docker 一定变得又慢又复杂。还不如原生安装的服务看起来舒服。

实际上这是误区,Docker 管理的各种服务,都是操作系统原生的进程,并不是一个虚拟化产物,它的正确定义是应用容器引擎。

那怎么去理解这个应用容器引擎呢?就要说说 Docker 的核心原理了——其中主要机制之一,通过 Linux 的 namespace 机制实现了资源隔离,这个资源隔离就包括了:

  1. UTS,对主机名和域名的隔离
  2. IPC,对信号量、消息队列和共享内存的隔离
  3. PID,对进程编号的隔离
  4. Network,对网络设备、网络协议栈、网络端口对隔离
  5. Mount,对挂载点(文件系统)的隔离
  6. User,对用户和用户组的隔离。

这些隔离机制都是 Linux 内核的 namespace 机制实现,也是 Docker 容器设计的精髓。

我来打个比方吧:原来是一个 300 平米的大 house,就住着一家人,卧室、厨房、卫生间这一家人独享。可是房子太大完全可以住三个家庭,不仅能公摊一部分费用,还能为主家带来额外的收益。那么就要对这个大 house 重新进行规划设计,满足三个家庭的需要,制定一些生活制度,有些资源是可以共享的,但关键资源就必须隔离开,保护隐私嘛!其实大家说到底还是在一个大房子内平等的生活。

用了这个比喻其实就是告诉大家,你就把 Docker 理解为一个房子多个家庭的规划安排包租婆,Docker 管理了很多的容器服务,容器服务就是在宿主机上跑着的,例如 MySQL、Nginx、微服务等等都是容器服务,大家都是在一个 OS 上平等的运行着,只不过进了自己房间,你对别人房间的情况就一无所知了。那么这不仅保护了各个服务之间不会产生对资源争用,而且还能根据预先入户的协议,分配好 CPU、内存、磁盘的容量。这样大家住在一起也是明明白白的,谁也不能沾了谁的便宜。当然了对外的网络端口还是需要各家分配不同的。

有了这个本事,你就能在有限的云资源上跑很多服务啦!我自己做的公司网站就跑了三个 Docker 容器:Nginx、MySQL、Wordpress,我才给分配了 512M 内存,够抠门吧,但是运行地妥妥的,只是物理内存是在太小,有时候重启服务,OS 报内存资源就不够了,必须把 Docker 也重启,清空一下内存就好了。

我曾经做过两个互联网平台产品用了三台性能不错的云服务器,4 核,16G 内存,足足跑了 50 多个微服务和其他基础服务,真的是把资源榨得是干干净净。关键还有服务日志隔离、环境变量隔离、全局配置隔离等待,好处实在太多了。

说到这里,我相信同学们一定就有点理解了为什么Amazon ECS那么强调容器技术来管理,这对于计算资源的利用可以说是一台压榨机啊!那么我们的Docker到底跑在哪个虚拟服务器上的那个Docker Container这就无关紧要了,那是ECS考虑的事情。

接着看一个我做过的Dockerfile配置:

from openresty/openresty
RUN sed -i 's#http://deb.debian.org#http://mirrors.tuna.tsinghua.edu.cn#' /etc/apt/sources.list && 
    sed -i '/http://security.debian.org/debian-security/d' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install procps net-tools locales -y
RUN localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8
ENV LANG=zh_CN.utf8
ENV TZ=Asia/Shanghai
COPY ["./work", "/work"]
CMD ["nginx","-p","/work","-c","conf/nginx.conf","-g","daemon off;"]

上面这个Dockerfile配置就是把Docker Hub的Openresty环境更为中文化了一些,并且也更为适合调试,那么通过这个自定义的Dockerfile打出来的镜像就非常适合我的生产环境,我接着通过如下命令,就能构建Docker镜像并在本地看到自己的Docker镜像

docker build -t apigateway -f openresty-cmd.df .
docker images|grep apigateway

 Dockerfile构建演示图

最后我们再将打好的Docker镜像apigateway:latest运行起API网关的Docker容器:

docker run -d --cpu-shares 512 --memory 1G --name api_proxy_1  -p 80:80 -p 443:443 -v /opt/api_proxy/work/:/work/ --restart=always apigateway

我们从上面的命令中可以看到docker run一些关键参数:

  • -d 代表服务在后台运行,
  • --cpu-shares代表cpu分享比例,1024为1个vcpu,那么512就是1个vcpu 50%的算力
  • --memory代表内存配额,目前为最大1G配额
  • -p代表了内外部端口的映射
  • -v代表了内外部磁盘的映射

上述这些Docker容器设定知识都是为我们下面理解Amazon ECS的任务定义提供了最基础的帮助。

Amazon EC2部署入门

现在问题来了,难道说Amazon云技术就只有无服务的弹性容器Amazon ECS吗?当然不是的,其实在我们印象中国内云厂商的ECS(弹性云计算服务器),对应在Amazon云产品中的术语中叫做Amazon EC2(Amazon Elastic Compute Cloud),Amazon EC2不仅可以创建服务器实例成为你的虚拟机节点,而且Amazon EC2和Amazon ECS具有共通的基础设施环境,这块是不是有些绕了?那么我们先看一张Amazon EC2和Amazon ECS的运行实例关系图:

Amazon EC2、Amazon ECS运行关系架构图

上图其实非常简单,只是将Amazon EC2和Amazon ECS之间的关系进行了梳理,从架构图中运行的Amazon EC2和Amazon ECS Task实例关系,我相信大家就不会那么绕了,其实它们都共享了Amazon提供的基础设施,这些基础设施项你可以在自己的Amazon EC2控制台中去维护,在Amazon ECS的任务定义中你可以新建一些基础设施项,同样也可以让Amazon ECS与Amazon EC2共享基础设施项,达到它们之间的协作,例如:让Amazon ECS与Amazon EC2使用同一个VPC的子网段,那么Amazon EC2就能轻松通过内网IP访问Amazon ECS容器服务。

注册配置

(1) 注册

首先我们要创建一个属于自己的Amazon账号,地址:Amazon云服务注册地址,注册登陆后,就进入到了Amazon管理控制台,我们先根据导航:所有服务->计算->EC2,进入到Amazon EC2 Dashboard,在这里就可以看到所有情况。如下图所示:这里面我们要注意右上角的区域,选择不同区域会统计不同的计算资源情况,这个区域(region)也是后续很多配置中需要格外注意的地方,左栏就是EC2实例和关键基础设施的维护入口,之后我们需要创建一个Amazon EC2实例,将此Amazon EC2实例作为我们后续对Amazon ECS协作与管理的服务节点。

 Amazon EC2 Dashboard效果图

(2) 用户、用户组和密钥

准备阶段我们先不要着急创建EC2实例,我们先进入Identity and Access Management (IAM), 创建用户和组,也就是说我们不要使用注册Amazon云服务的账号,而是创建一个应用访问使用的账号,在创建组的权限中使用AdministratorAccess,不用选择密码方式,直接使用“访问密钥”,创建好用户之后,下载密钥CSV文件,文件中的Access key ID,Secret access key会在之后的对ECS的配置中使用,具体配置详情还可以参考:官网IAM设置

(3) EC2实例的密钥对

接着我们回到EC2 Dashboard,我们要创建一个密钥对,如下图所示

 密钥对效果图

创建好的密钥对下载后,可以直接用于之后EC2实例的SSH登陆使用,例如:ssh -i readbyte-key-pair.pem ec2-user@34.217.211.73,这个“readbyte-key-pair.pem”就是我创建的私钥。具体配置详情还可以参考:官网密钥对设置。这里需要注意的是区域,也就是说密钥对在哪个区域创建的,那么以后EC2实例创建的时候也在哪个区域。

(4) EFS文件系统

目前仍然不要着急创建Amazon EC2实例,我们先创建Elastic File System(EFS),这是Amazon的NFS网络文件系统,通过NFS我们就可以将Amazon ECS任务的容器目录挂载到EFS上,那么Amazon EC2实例就可以通过网络文件系统(NFS)挂载到本地目录的方式,访问EFS中ECS容器的内部文件,进行容器服务中的目录文件配置与数据操作了。

EFS的创建很简单,同时也创建接入点,但是需要主要vpc的设置应该与之后的Amazon EC2、Amazon ECS是一个子网段,目前初始阶段也就只有默认的vpc,

 EFS连接效果图

我们进入创建好的文件系统,点击右上角的连接就能看到EFS对外提供挂载的路径,就包括EFS挂载、或NFS客户端方式。

创建Amazon EC2实例

我们重新登陆EC2 Dashboard,点击做栏实例->创建EC2实例,如下图所示,尽量选择Amazon Linux 2 AMI (HVM),因为经过一些ECS优化,在尝试阶段可以使用符合条件的免费套,其实就是下一步的t2.micro实例类型,1vcpu,1G内存,作为我们体验够用了。

 Amazon EC2 购买选项效果图

在步骤三中有一步非常重要,那就是找到“文件系统”项,点击后,我们就能看到上面创建的EFS文件系统,我们需要将此文件系统挂载上,从图中可以看到挂载到了EC2实例的/mnt/efs/fs1下面。

 创建Amazon EC2实例阶段EFS挂载效果图

在第四步的添加存储中,我们就能看到EFS的挂载情况了

 创建Amazon EC2实例阶段存储效果图

创建EC2实例之后我们就能在实例列表中看到创建的EC2实例,进入实例后,我们可以看到下图中红色框这就是外网IP和内网IP,下一步我们通过SSH登陆EC2实例进行进一步的配置。

 Amazon EC2实例信息概览效果图

Amazon EC2实例的Docker环境打造

首先我们用前面创建的私钥进行ssh登陆,一定要注意 macOS 或 Linux 计算机将私钥的文件所属权变为400,如下面代码所示:

chmod 400 readbyte-key-pair.pem
ssh -i readbyte-key-pair.pem ec2-user@34.217.211.73

下一步我们来安装Docker服务并启动Docker:

sudo amazon-linux-extras install docker
sudo service docker start

然后再将ec2-user加入到Docker组:

sudo usermod -a -G docker ec2-user

这时候需要重新登陆一下ssh,我们以后操作Docker就不用再sudo了。也可以参考官网文档:Docker 基本知识

Amazon Elastic Container Registry

ECR是Amazon自己的Docker容器Registry仓库,通常情况下我们会使用Docker hub仓库,有时候也会建立自己的私有Docker仓库,例如:registry、htpasswd、nginx配合打造的私有Docker容器仓库,不过这种维护成本很大,Amazon ECR就非常方便,私密性也很好,关键为Amazon ECS的容器提供了一个很舒服的Docker镜像注册环境。

那么我就用构建一个PostgreSQL11的镜像文件作为实例,来看看ECR的注册流程。

首先我们建立一个Dockerfile->postgres.df,这个Dockerfile也是对Docker hub的Postgresql11.4版本进行了必要的中文化

FROM postgres:11.4
RUN localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8
ENV LANG=zh_CN.utf8
ENV TZ=Asia/Shanghai

Dockerfile构建PostgreSQL11.4版本效果图 

Dockerfile构建PostgreSQL11.4版本效果图当我们构建完成后,在本地的Docker images中就有了postgres_cn:11.4镜像,我们的重点是如何将此镜像发布到ECR上面去,那么紧接着就需要使用aws命令配置了,有了这项配置之后,就相当于具有了访问我的账号应用资源的授权。

aws configure

其实就是四项需要:Access key ID、Secret access key、Region和输出格式,前两项就是我们前面创建用户时下载到CSV文件中的密钥,Region就是你的EC2所在区域,可以在EC2 Dashboard右上角的区域中找到对应的region name,输出格式就是json。

 aws configure命令配置效果图

然后我们开始为Postgres_cn镜像创建一个Registry仓库:

aws ecr create-repository --repository-name postgres_cn-repository --region us-west-2

下面就是json输出结果,其中的repositoryUri就是将本地Postgres_cn镜像推送的地址:

{
    "repository": {
        "repositoryUri": "714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository", 
        "imageScanningConfiguration": {
            "scanOnPush": false
        }, 
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }, 
        "registryId": "714394534197", 
        "imageTagMutability": "MUTABLE", 
        "repositoryArn": "arn:aws:ecr:us-west-2:714394534197:repository/postgres_cn-repository", 
        "repositoryName": "postgres_cn-repository", 
        "createdAt": 1648633165.0
    }
}

看到上面的输出,就证明创建镜像仓库成功了,我们再接再厉,开始tag镜像、login仓库、push镜像

docker tag postgres_cn:11.4 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository
aws ecr get-login-password | docker login --username AWS --password-stdin 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository
docker push 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository

从下图中我们就能看到上述三项命令执行的效果。

 推送PostgreSQL镜像到Amazon ECR效果图

好了,目前Amazon ECR终于可以正常使用了,接下来的PostgreSQL镜像就也可以存在ECR中,方便被Amazon ECS的任务定义中所引用了,同时我们也可以在官网的Docker 基本知识中获得更详细的了解。

Amazon ECS部署入门

Amazon ECS组成部分

在第一章的概述中同学们会对Amazon ECS到底是什么,并且与传统ECS有什么区别有了一个基础的概念,我们这里就将这些概念再深化一下,方便后面的部署理解。

首先我们看下图,是官网的任务和计划的结构体系图,Amazon ECS在运行过程分为了集群、服务、任务,集群主要是给出了一个逻辑上的范畴,也就是说集群范围内所启动的任务共同组成了这样一个容器为主的计算服务集群。

接着在集群内就可以创建服务,创建一个服务后,会为接下来需要运行的任务配置了种种基础环境参数,例如:启动类型、操作系统选择、平台版本、任务数量、集群VPC、安全组等等,那么当服务运行后会通过任务计划在集群中放置任务,而任务如果出现故障停止,服务亦会监控到并启动新的任务,这就提供了一个高可靠的任务运行环境。

最后就是任务了,任务来源于任务定义,在任务定义中确定了Docker容器运行所需的参数、Amazon ECS环境参数的定义、计算资源的配额、EFS等网络文件卷的配置等等容器运行所需的元信息,甚至我们可以在一个任务中配置多个容器去运行,但是Amazon ECS并不鼓励这样一种做法,更倾向于一个任务一个运行的容器。具体细节我们可以深入调阅官方文档:什么是 Amazon ECS?

 Amazon ECS任务和技术结构体系示意图

创建Amazon ECS部署流程

(1) 创建ECS集群

首先我们进入ECS主界面,左栏包括了Amazon ECS、Amazon EKS、Amazon ECR,我们主要看Amazon ECS。点击创建集群,我们选择创建仅限联网的集群模板就可以了,后两种并非单纯的Docker容器组成的任务,我们创建的集群名叫:DBCluster。

 Amazon ECS集群创建步骤一示意图

(2) 创建任务定义

接着在任务定义入口进入后,点击创建新任务定义,启动类型分为了Fargate、EC2、External,Fargate是Amazon ECS的一项无服务技术,通俗点理解就是让我们不用去考虑基础设施中的计算资源怎样优化,Fargate给你包办了,我们主要使用这个类型,Amazon EC2和外部计算服务连接这两项我们这次先暂不考虑。Fargate的具体描述可以参考官方文档Amazon Fargate介绍。

Amazon ECS任务定义创建步骤一示意图

下一步是任务定义,我做了一个可参考的实例:

  • 任务定义名称:pg-run-task-definition
  • 需要兼容性:FARGATE
  • 任务角色:ecsTaskExecutionRole
  • 网络模式:awsvpc
  • Operating system family:Linux
  • 任务执行角色:ecsTaskExecutionRole
  • 任务内存 (GB):2GB
  • 任务 CPU (vCPU):1VCPU
  • 添加卷:名称=fs-3,卷类型=EFS,文件系统ID=(选择EFS id),访问点ID=(选择EFS 访问点 id),传输中加密:选择
  • 添加容器
    •  容器名称*:postgres_cn-db
    • 映像*:714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository
    • 内存限制 (MiB)*:软限制=2048
    • 端口映射:5432
    • CPU 单元数:1024
    • 环境变量:Key=POSTGRES_PASSWORD,Value=123456
    • 挂载点:源卷=fs-3,容器路径=/var/lib/postgresql/data 

接着点击创建,任务定义完成后,我们看看创建后的完整Json输出,这个Json文本就是任务定义后Amazon ECS需要启动任务实例化时读取的信息,若回想一下我们一般用docker run时配置参数的场景,其实这些参数都可以囊括在这个Json文本中。

推荐大家多去了解这个Json的内容含义,这对于以后进入高级阶段使用Amazon CDK等命令方式来创建维护Amazon ECS集群以及基础设施环境会大有裨益。

{
  "ipcMode": null,
  "executionRoleArn": "arn:aws:iam::714394534197:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "dnsSearchDomains": null,
      "environmentFiles": null,
      "logConfiguration": {
        "logDriver": "awslogs",
        "secretOptions": null,
        "options": {
          "awslogs-group": "/ecs/pg-run-task-definition-1",
          "awslogs-region": "us-west-2",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "entryPoint": null,
      "portMappings": [
        {
          "hostPort": 5432,
          "protocol": "tcp",
          "containerPort": 5432
        }
      ],
      "command": null,
      "linuxParameters": null,
      "cpu": 1024,
      "environment": [
        {
          "name": "POSTGRES_PASSWORD",
          "value": "123456"
        }
      ],
      "resourceRequirements": null,
      "ulimits": null,
      "dnsServers": null,
      "mountPoints": [
        {
          "readOnly": null,
          "containerPath": "/var/lib/postgresql/data",
          "sourceVolume": "fs-3"
        }
      ],
      "workingDirectory": null,
      "secrets": null,
      "dockerSecurityOptions": null,
      "memory": null,
      "memoryReservation": 2048,
      "volumesFrom": [],
      "stopTimeout": null,
      "image": "714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository",
      "startTimeout": null,
      "firelensConfiguration": null,
      "dependsOn": null,
      "disableNetworking": null,
      "interactive": null,
      "healthCheck": null,
      "essential": true,
      "links": null,
      "hostname": null,
      "extraHosts": null,
      "pseudoTerminal": null,
      "user": null,
      "readonlyRootFilesystem": null,
      "dockerLabels": null,
      "systemControls": null,
      "privileged": null,
      "name": "postgres_cn-db"
    }
  ],
  "placementConstraints": [],
  "memory": "2048",
  "taskRoleArn": "arn:aws:iam::714394534197:role/ecsTaskExecutionRole",
  "compatibilities": [
    "EC2",
    "FARGATE"
  ],
  "taskDefinitionArn": "arn:aws:ecs:us-west-2:714394534197:task-definition/pg-run-task-definition:1",
  "family": "pg-run-task-definition",
  "requiresAttributes": [
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "ecs.capability.execution-role-awslogs"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "ecs.capability.efsAuth"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.ecr-auth"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "ecs.capability.efs"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.task-iam-role"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.25"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "ecs.capability.execution-role-ecr-pull"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
    },
    {
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "ecs.capability.task-eni"
    }
  ],
  "pidMode": null,
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "networkMode": "awsvpc",
  "runtimePlatform": {
    "operatingSystemFamily": "LINUX",
    "cpuArchitecture": null
  },
  "cpu": "1024",
  "revision": 1,
  "status": "ACTIVE",
  "inferenceAccelerators": null,
  "proxyConfiguration": null,
  "volumes": [
    {
      "fsxWindowsFileServerVolumeConfiguration": null,
      "efsVolumeConfiguration": {
        "transitEncryptionPort": null,
        "fileSystemId": "fs-08359de466dce1153",
        "authorizationConfig": {
          "iam": "DISABLED",
          "accessPointId": "fsap-029ff71869daae77d"
        },
        "transitEncryption": "ENABLED",
        "rootDirectory": "/"
      },
      "name": "fs-3",
      "host": null,
      "dockerVolumeConfiguration": null
    }
  ]
}

(3) 创建服务

在开始创建Amazon ECS服务之前,我们先解决安全组问题,这里需要特别注意(我在这里碰了一鼻子灰)

我们在创建EC2的时候,进入EC2实例列表,然后再进入实例,如下图所示:

它会有两个安全组,其中红色框的安全组就是与EFS相互联通的安全组,如果你有兴趣,可以再看看EFS那边的安全组就一目了然啦,这就是为什么我开始创建Amazon EC2实例的时候先创建EFS并添加为该EC2实例文件系统的原因,Amazon EC2实例创建后就会设置好与EFS之间访问控制的安全组,那么大家理解起更具体的安全组配置就有了参考。我就是先创建Amazon EC2再创建EFS,结果总是各种挂载不通,当你看懂安全组配置后,那么以后你就可以轻松驾驭EFS了。

   Amazon EC2实例安全组示意图

后面我们会直接将Amazon EC2实例安全组的这条配置加入到Amazon ECS服务的安全组内,这样Amazon ECS就能和EFS之间就畅通无阻了,同时我们进入EC2安全组,创建一个应用于PostgreSQL对外服务的安全组,主要是给入站规则加上PG的5432端口,出站规则不变,名称为PG-Safe。

   创建Amazon ECS使用的安全组示意图

接下来在集群列表中我们就能看到DBCluster集群,进入以后第一项就是服务,我们点击创建,开始服务创建流程。

配置服务项我也列一下:

  • 启动类型:FARGATE
  • 操作系统系列:Linux
  • 任务定义:pg-run-task-definition
  • 修订:1
  • 平台版本:LATEST
  • 集群:DBCluster
  • 服务名称:PG_DB_Server
  • 服务类型:REPLICA
  • 任务数:1

下一步是网络配置

  • 集群VPC:一定选择和EC2、EFS一致的vpc,
  • 子网:如果有多个,就都选择上,最大化ECS容器的IP可用范围。
  • 安全组:选择现有安全组,其中选择两个安全组项,一个是新场景的PG-Safe,另一个就是上述EC2实例中专门与EFS通讯的那条安全组。

   创建Amazon ECS服务选择安全组示意图

  • 负载均衡器类型:无

然后一路下一步,创建服务即可,创建完服务后,也会同步创建好一个Task,我们可以再任务标签页看到成功运行的情况:

  PostgreSQL 任务运行示意图

下图的任务日志就是PostgreSQL启动日志输出。  PostgreSQL 任务日志示意图

(4) ECS、EC2、EFS关联检查

但是别忘了最重要的一件事情,那就是我们要看看在EC2实例上挂载的EFS文件系统是否能看到Amazon ECS任务启动后映射出去的文件目录(PGSQL数据目录),SSH登陆我的EC2实例,然后执行命令:

df -Th
sudo ls /mnt/efs/fs1/

 第一条命令我们可以看到在/mnt/efs/fs1目录挂载了nfs4类型的网络文件系统,这就是挂载了EFS。

第二条命令,我们可以看到挂载目录下有PostgreSQL的数据和配置文件,这就是Amazon ECS 任务中PGSQL容器的路径——/var/lib/postgresql/data映射到EFS文件系统上的数据。

Amazon EC2与Amazon ECS通过EFS共享文件示意图 

总结

好了,今天就先聊到这里, 对于Amazon容器应用程序基础设施,也不仅包括了面向Docker的ECS,还有特别适合入门级学习的Amazon Lightsail,也有针对大规模服务进行容器编排的Kubernetes,充分利用其灵活性和Amazon托管的安全性和弹性,具体入门指南我们可以进入官网学习选择您的容器应用程序基础设施-入门指南

除了Amazon ECS的图形界面之外,其实Amazon ECS最大的优势还提供特别强大的命令操作工具集合,包括:AWS CopilotAmazon ECS CLIAWS CDK等。这些功能可以通过非图形界面的终端命令方式、编程的方式(TypeScrpit、JavaScrpit、Python、Java、C#),更全面且细粒度的去创建与维护Amazon ECS基础设施,控制和优化Amazon ECS集群与任务。

不过这些功能的操作复杂程度也使人震惊,真的不得不佩服Amazon的技术大神们,创造了如此庞大的操作Amazon ECS工具集,然而对于新人来讲,一开始接触这些会烦死的!因此饭还是一口一口吃比较容易消化,大家先通过最简单界面操作方式,让Amazon EC2和Amazon ECS先能正常的运转起来。

若你是一位具有探索新知精神的极客,当你真正开始触碰到Amazon ECS这些高级强大的工具精髓时,那么你就会迷上它,它一种高度可扩展的技术平台,你可以基于此打造出属于自己的集群化容器自动运维体系,那么就可以从更全面且更细致的态势去感知你所运维的服务发生的一切!好吧,更高级的Amazon ECS探索演示以后有机会再聊。


亚马逊云科技专为开发者们打造了多种学习平台:

1. 入门资源中心:从0到1 轻松上手云服务,内容涵盖:成本管理,上手训练,开发资源。AWS入门_AWS入门使用教程_AWS云计算资源-AWS云服务

2. 架构中心:亚马逊云科技架构中心提供了云平台参考架构图表、经过审查的架构解决方案、Well-Architected 最佳实践、模式、图标等。AWS架构中心部署说明_AWS云架构白皮书-AWS云服务

3. 构建者库:了解亚马逊云科技如何构建和运营软件。Amazon Builders' Library

4. 用于在亚马逊云科技平台上开发和管理应用程序的工具包:aws工具下载_aws开发工具_资源下载-AWS云服务

【专属福利】

福利一:100余种产品免费套餐。其中,计算资源Amazon EC2首年12个月免费,750小时/月;存储资源 Amazon S3 首年12个月免费,5GB标准存储容量。

亚马逊AWS海外区域账户免费套餐_免费云服务-AWS云服务

福利二:最新优惠大礼包,200$数据与分析抵扣券,200$机器学习抵扣券,200$微服务与应用开发抵扣券。最新优惠活动_云服务器促销 - 亚马逊云科技

福利三:解决方案CloudFormation一键部署模版库

云服务解决方案部署快速入门_云服务部署-AWS云服务