{"value":"### **Amazon ECS 概述**\n对于经常接触云计算服务技术的同学们估计一听到 ECS,耳朵都能磨出茧子,印象中 ECS 不就是弹性计算服务么,再人话点就是你按量充值的一台虚拟主机,然后通过SSH远程维护这台虚拟主机的操作系统呗,但是 **Amazon ECS 就不同于你们理解的那个 ECS 啦**!且听我慢慢道来。\nAmazon ECS全称是(Amazon Elastic Container Service),它是针对容器技术高度弹性的的管理服务,我么如何去更通俗地理解呢?其实 Amazon ECS 就是希望用户直接面对容器进行管理(例如:Docker),而不是面对虚拟机操作系统,也就是说 Amazon 云平台提供给用户购买的计算单元粒度更细致了,那么这又带来什么好处呢?其实是两方面:\n优势一:你没必要就为了部署一个服务(例如:部署 Tomcat),就得先占用一台虚拟机,现在 Amazon ECS 给你了一个新方案,你部署维护一个 Docker 容器就够了,这个容器服务跑在哪台机器上,那个容器引擎上,这些你就不用关心了,Amazon ECS 自己来维护计算资源的基础设施,**由于资源占用少了,自然你充值就少了**;\n优势二:现在的云服务大趋势是分布式,这样你的应用可以形成集群,以便增强系统高可靠性以及对服务性能的弹性伸缩管理,但是像以前我购买一台虚拟主机,即使我切分成了多个 Docker,那也是在这一个虚拟主机节点上跑,依然是个伪分布式,除非你有更多的资金购买更多的虚拟主机。但是 Amazon ECS 默认提供的无服务(Serverless)模式就让你不再顾虑运行服务的集群分布问题,只考虑要上多少 Docker 容器,至于放置在什么地方,哪个机房,那台服务器,那更多是 Amazon ECS 考虑的事情,那么我就用一个整体上较低的综合成本,实现了一个真正比较强大的面相服务的集群环境。\n对于 Amazon ECS 的一些简单介绍我们可以看看 Amazon ECS 官方的介绍:[什么是 Amazon Elastic Container Service](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/Welcome.html)?\n**另外提一下亚马逊云科技最近活动力度还是蛮大的,提供了100余种产品免费套餐。其中,计算资源 Amazon EC2首年12个月免费,750小时/月;存储资源 Amazon S3 首年12个月免费,5GB标准存储容量。\n若小伙伴们有兴趣,也可以进去瞧瞧亚马逊云科技最新活动页,便宜不占白不占,对吧:[亚马逊 Amazon 海外区域账户免费套餐_免费云服务-Amazon 云服务](https://aws.amazon.com/cn/free/?nc2=h_ql_pr_ft&all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all&trk=e0213267-9c8c-4534-bf9b-ecb1c06e4ac6&sc_channel=el),**\n\n### **Amazon ECS 架构**\n我们先上一张 Amazon ECS 的官网发布的架构图,先对其有个概括的认识:\n\n![image.png](https://dev-media.amazoncloud.cn/f058e60e1e544b7aa3b20c7775b6bb9c_image.png)\n\nAmazon ECS 环境架构图\n\n从上图中,我们看到了 Amazon ECS 的受控范围是一个 Region (区域),这个区域我们可以理解为世界上某个国家、某个地区的云机房,例如:美国西部 (俄勒冈州) us-west-2,非洲 (开普敦) af-south-1,亚太地区 (香港) ap-east-1,你一开始接触会有些懵逼,这咋全世界都有 Amazon 的点,没办法,为啥 Amazon 是云计算大哥,就是因为人家的云服务是覆盖全世界的,这对于国内企业云服务未来走向国际化就具有比较潜在的基础设施优势。\nRegion内部的核心又分为了**任务定义(Task definition)、服务描述(Service description)** 的配置蓝图部分,任务和基础设施的运行实例部分,另外还有一个**容器镜像注册(Container registry)** 的仓库部分,这三部分实际上就是 Amazon ECS 面向用户的核心服务。\n例如:你有个不错的 Docker 镜像,那么就先注册到 Container registry,然后下一步开始在 Task definition 中做容器运行所需的配置,其实通俗点说就是在任务配置中引用你上传的 Docker 镜像地址,给任务分配多少 CPU、内存,属于VPC(虚拟私有云)中哪个子网等等这些容器镜像、配额、用户角色、基础设施的综合性说明文件。\n有了这个综合性说明,再根据 Service description 配置就能在启动服务的过程中,将配置中的 Docker 镜像实例化成一到多个 Docker 容器服务的任务,并根据 Amazon Fargate(Amazon的无服务技术),将任务放置在ECS集群的不同位置,形成高可靠的分布式系统(当然你也可以只选择部署一个任务)。Fargate 类型比较重要,我们做 Task definition 的时候,一般会选择它,它的官方介绍:[Amazon Fargate 上的 Amazon ECS](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/AWS_Fargate.html/)\n对于 Amazon ECS 产品的详细介绍我们可以进入官方的 [Amazon ECS产品详细介绍页](https://aws.amazon.com/cn/ecs/?nc2=h_ql_prod_ct_ecs&trk=f33fd1af-e80b-4db6-93c8-2f2d5c39b9e5&sc_channel=el)做进一步的了解。\nDocker 快速介绍\n玩转 Amazon ECS 的底子就是会玩 Docker,对于 Docker 还比较陌生的同学们,我先简单科普一下:\n提起 Docker,有很多人第一印象会认为它就是一个虚拟化容器,所以大家特别容易陷入到一种误区,就是觉得 Docker 只是在 Linux 操作系统之上又增加了一层,就跟 OS 上跑了一个 VMWare 一样。Docker 一定变得又慢又复杂。还不如原生安装的服务看起来舒服。\n实际上这是误区,Docker 管理的各种服务,都是操作系统原生的进程,并不是一个虚拟化产物,它的正确定义是应用容器引擎。\n那怎么去理解这个应用容器引擎呢?就要说说 Docker 的核心原理了——其中主要机制之一,通过 Linux 的 namespace 机制实现了资源隔离,这个资源隔离就包括了:\n1. UTS,对主机名和域名的隔离\n2. IPC,对信号量、消息队列和共享内存的隔离\n3. PID,对进程编号的隔离\n4. Network,对网络设备、网络协议栈、网络端口对隔离\n5. Mount,对挂载点(文件系统)的隔离\n6. User,对用户和用户组的隔离。\n这些隔离机制都是 Linux 内核的 namespace 机制实现,也是 Docker 容器设计的精髓。\n我来打个比方吧:原来是一个 300 平米的大 house,就住着一家人,卧室、厨房、卫生间这一家人独享。可是房子太大完全可以住三个家庭,不仅能公摊一部分费用,还能为主家带来额外的收益。那么就要对这个大 house 重新进行规划设计,满足三个家庭的需要,制定一些生活制度,有些资源是可以共享的,但关键资源就必须隔离开,保护隐私嘛!其实大家说到底还是在一个大房子内平等的生活。\n用了这个比喻其实就是告诉大家,你就把 Docker 理解为一个房子多个家庭的规划安排包租婆,Docker 管理了很多的容器服务,容器服务就是在宿主机上跑着的,例如 MySQL、Nginx、微服务等等都是容器服务,大家都是在一个 OS 上平等的运行着,只不过进了自己房间,你对别人房间的情况就一无所知了。那么这不仅保护了各个服务之间不会产生对资源争用,而且还能根据预先入户的协议,分配好 CPU、内存、磁盘的容量。这样大家住在一起也是明明白白的,谁也不能沾了谁的便宜。当然了对外的网络端口还是需要各家分配不同的。\n有了这个本事,你就能在有限的云资源上跑很多服务啦!我自己做的公司网站就跑了三个 Docker 容器:Nginx、MySQL、Wordpress,我才给分配了 512M 内存,够抠门吧,但是运行地妥妥的,只是物理内存是在太小,有时候重启服务,OS 报内存资源就不够了,必须把 Docker 也重启,清空一下内存就好了。\n我曾经做过两个互联网平台产品用了三台性能不错的云服务器,4 核,16G 内存,足足跑了 50 多个微服务和其他基础服务,真的是把资源榨得是干干净净。关键还有服务日志隔离、环境变量隔离、全局配置隔离等待,好处实在太多了。\n说到这里,我相信同学们一定就有点理解了为什么 Amazon ECS 那么强调容器技术来管理,这对于计算资源的利用可以说是一台压榨机啊!那么我们的 Docker 到底跑在哪个虚拟服务器上的那个 Docker Container 这就无关紧要了,那是ECS考虑的事情。\n接着看一个我做过的 Dockerfile 配置:\nDockerfile\n```\nfrom openresty/openresty\nRUN sed -i 's#http://deb.debian.org#http://mirrors.tuna.tsinghua.edu.cn#' /etc/apt/sources.list && \\\n sed -i '/http:\\/\\/security.debian.org\\/debian-security/d' /etc/apt/sources.list\nRUN apt-get update\nRUN apt-get install procps net-tools locales -y\nRUN localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8\nENV LANG=zh_CN.utf8\nENV TZ=Asia/Shanghai\nCOPY [\"./work\", \"/work\"]\nCMD [\"nginx\",\"-p\",\"/work\",\"-c\",\"conf/nginx.conf\",\"-g\",\"daemon off;\"]\n```\n上面这个 Dockerfile 配置就是把 Docker Hub 的 Openresty 环境更为中文化了一些,并且也更为适合调试,那么通过这个自定义的 Dockerfile 打出来的镜像就非常适合我的生产环境,我接着通过如下命令,就能构建Docker镜像并在本地看到自己的 Docker 镜像\nShell\n```\ndocker build -t apigateway -f openresty-cmd.df .\ndocker images|grep apigateway\n```\n![image.png](https://dev-media.amazoncloud.cn/58624af21a9c4cd5bec8c5b69e91e240_image.png)\n\nDockerfile 构建演示图\n最后我们再将打好的 Docker 镜像 apigateway:latest 运行起 API 网关的 Docker 容器:\nShell\n```\ndocker 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\n\n```\n我们从上面的命令中可以看到 docker run一些关键参数:\n- -d 代表服务在后台运行,\n- --cpu-shares 代表 cpu 分享比例,1024为1个 vcpu,那么512就是1个 vcpu 50%的算力\n- --memory 代表内存配额,目前为最大1G配额\n- -p代表了内外部端口的映射\n- -v代表了内外部磁盘的映射\n上述这些 Docker 容器设定知识都是为我们下面理解 Amazon ECS 的任务定义提供了最基础的帮助。\n### **Amazon EC2 部署入门**\n现在问题来了,难道说 Amazon 云技术就只有无服务的弹性容器 Amazon ECS 吗?当然不是的,其实在我们印象中国内云厂商的 ECS(弹性云计算服务器),对应在 Amazon 云产品中的术语中叫做 Amazon EC2(Amazon Elastic Compute Cloud),Amazon EC2不仅可以创建服务器实例成为你的虚拟机节点,而且 Amazon EC2和Amazon ECS 具有共通的基础设施环境,这块是不是有些绕了?那么我们先看一张 Amazon EC2 和 Amazon ECS 的运行实例关系图:\n\n![image.png](https://dev-media.amazoncloud.cn/6c5b633ff21943d0b921024ae48e7f80_image.png)\n\nAmazon EC2、Amazon ECS 运行关系架构图\n上图其实非常简单,只是将 Amazon EC2和Amazon ECS 之间的关系进行了梳理,从架构图中运行的 Amazon EC2 和 Amazon ECS Task 实例关系,我相信大家就不会那么绕了,其实它们都共享了Amazon提供的基础设施,这些基础设施项你可以在自己的 Amazon EC2控制台中去维护,在 Amazon ECS 的任务定义中你可以新建一些基础设施项,同样也可以让 Amazon ECS 与 Amazon EC2共享基础设施项,达到它们之间的协作,例如:让 Amazon ECS 与A mazon EC2使用同一个 VPC 的子网段,那么 Amazon EC2就能轻松通过内网 IP 访问 Amazon ECS容器服务。\n#### **注册配置**\n##### **(1) 注册**\n首先我们要创建一个属于自己的 Amazon 账号,地址:Amazon 云服务注册地址,注册登陆后,就进入到了 Amazon 管理控制台,我们先根据导航:所有服务->计算->EC2,进入到 Amazon EC2 Dashboard,在这里就可以看到所有情况。如下图所示:这里面我们要注意右上角的区域,选择不同区域会统计不同的计算资源情况,这个区域(region)也是后续很多配置中需要格外注意的地方,左栏就 EC2实例和关键基础设施的维护入口,之后我们需要创建一个 Amazon EC2实例,将此 Amazon EC2实例作为我们后续对 Amazon ECS 协作与管理的服务节点。\n\n![image.png](https://dev-media.amazoncloud.cn/8ddbed27bf054cf880e35d56ff8fbd97_image.png)\n\nAmazon EC2 Dashboard效果图\n##### **(2) 用户、用户组和密钥**\n准备阶段我们先不要着急创建 EC2实例,我们先进入 [Identity and Access Management (IAM)](https://us-east-1.console.aws.amazon.com/iam/home#/home), 创建用户和组,也就是说我们不要使用注册Amazon云服务的账号,而是创建一个应用访问使用的账号,在创建组的权限中使用 AdministratorAccess,不用选择密码方式,直接使用“访问密钥”,创建好用户之后,下载密钥 CSV 文件,文件中的 Access key ID,Secret access key 会在之后的对 ECS 的配置中使用,具体配置详情还可以参考:[官网 IAM 设置](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/get-set-up-for-amazon-ecs.html)。\n##### **(3) EC2实例的密钥对**\n接着我们回到 [EC2 Dashboard](https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#Home:),我们要创建一个密钥对,如下图所示\n\n![image.png](https://dev-media.amazoncloud.cn/4c80779524e04c0f968bc2e911d7b481_image.png)\n\n密钥对效果图\n创建好的密钥对下载后,可以直接用于之后EC2实例的SSH登陆使用,例如:ssh -i readbyte-key-pair.pem ec2-user@34.217.211.73,这个“readbyte-key-pair.pem”就是我创建的私钥。具体配置详情还可以参考:[官网密钥对设置](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/get-set-up-for-amazon-ecs.html)。这里需要注意的是区域,也就是说密钥对在哪个区域创建的,那么以后EC2实例创建的时候也在哪个区域。\n\n##### **(4) EFS文件系统**\n目前仍然不要着急创建 Amazon EC2实例,我们先创建 [Elastic File System](https://us-west-2.console.aws.amazon.com/efs?region=us-west-2#/get-started)(EFS),这是 Amazon 的 NFS 网络文件系统,通过 NFS 我们就可以将 Amazon ECS 任务的容器目录挂载到 EFS 上,那么 Amazon EC2 实例就可以通过网络文件系统(NFS)挂载到本地目录的方式,访问 EFS 中 ECS 容器的内部文件,进行容器服务中的目录文件配置与数据操作了。\nEFS 的创建很简单,同时也创建接入点,但是需要主要 vpc 的设置应该与之后的 Amazon EC2、Amazon ECS 是一个子网段,目前初始阶段也就只有默认的 vpc,\n\n![image.png](https://dev-media.amazoncloud.cn/2e3f18fb8b014acc8ca786b8340f1aa0_image.png)\n\nEFS 连接效果图\n我们进入创建好的文件系统,点击右上角的连接就能看到 EFS 对外提供挂载的路径,就包括 EFS 挂载、或 NFS 客户端方式。\n\n#### **创建 Amazon EC2实例**\n我们重新登陆 [EC2 Dashboard](https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#Home:),点击做栏实例->创建 EC2实例,如下图所示,尽量选择 Amazon Linux 2 AMI (HVM),因为经过一些 ECS 优化,在尝试阶段可以使用符合条件的免费套,其实就是下一步的 t2.micro 实例类型,1vcpu,1G内存,作为我们体验够用了。\n\n![image.png](https://dev-media.amazoncloud.cn/2aa3d34ae74f4736b70a7143597cc1a1_image.png)\n\nAmazon EC2 购买选项效果图\n在步骤三中有一步非常重要,那就是找到“文件系统”项,点击后,我们就能看到上面创建的 EFS 文件系统,我们需要将此文件系统挂载上,从图中可以看到挂载到了 EC2 实例的/mnt/efs/fs1下面\n\n![image.png](https://dev-media.amazoncloud.cn/9b9f5ef813984f64bb3319712645ab69_image.png)\n\n创建 Amazon EC2实例阶段EFS挂载效果图\n在第四步的添加存储中,我们就能看到 EFS 的挂载情况了\n\n![image.png](https://dev-media.amazoncloud.cn/144a067315f64581962350618eac937d_image.png)\n\n创建 Amazon EC2实例阶段存储效果图\n创建 EC2实例之后我们就能在实例列表中看到创建的 EC2实例,进入实例后,我们可以看到下图中红色框这就是外网 IP 和内网 IP,下一步我们通过 SSH 登陆 EC2实例进行进一步的配置。\n\n![image.png](https://dev-media.amazoncloud.cn/40197cdb52d74a2b9ef7244a3cb43164_image.png)\n\nAmazon EC2实例信息概览效果图\n\n#### **Amazon EC2实例的 Docker 环境打造**\n首先我们用前面创建的私钥进行 ssh 登陆,一定要注意 macOS 或 Linux 计算机将私钥的文件所属权变为400,如下面代码所示:\nShell\n```\nchmod 400 readbyte-key-pair.pem\nssh -i readbyte-key-pair.pem ec2-user@34.217.211.73\n```\n下一步我们来安装 Docker 服务并启动 Docker:\nShell\n```\nsudo amazon-linux-extras install docker\nsudo service docker start\n```\n然后再将 ec2-user 加入到 Docker 组:\nApache\n```\nsudo usermod -a -G docker ec2-user\n```\n这时候需要重新登陆一下ssh,我们以后操作Docker就不用再sudo了。也可以参考官网文档:[Docker 基本知识](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/docker-basics.html)\n#### **Amazon Elastic Container Registry**\nECR 是 Amazon 自己的 Docker 容器 Registry 仓库,通常情况下我们会使用Docker hub仓库,有时候也会建立自己的私有 Docker 仓库,例如:registry、htpasswd、nginx 配合打造的私有 Docker 容器仓库,不过这种维护成本很大,Amazon ECR 就非常方便,私密性也很好,关键为 Amazon ECS 的容器提供了一个很舒服的 Docker 镜像注册环境。\n那么我就用构建一个 PostgreSQL11的镜像文件作为实例,来看看 ECR 的注册流程。\n首先我们建立一个 Dockerfile->postgres.df,这个 Dockerfile 也是对 Docker hub的 Postgresql11.4版本进行了必要的中文化\nDockerfile\n```\nFROM postgres:11.4\nRUN localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8\nENV LANG=zh_CN.utf8\nENV TZ=Asia/Shanghai\n```\n我们开始执行 Docker 镜像构建:\nShell\n```\ndocker build -t postgres_cn:11.4 -f postgres.df .\n```\n![image.png](https://dev-media.amazoncloud.cn/73ea45f887674e91bdeb74ae4ba3d361_image.png)\n\nDockerfile 构建 PostgreSQL11.4版本效果图\n当我们构建完成后,在本地的 Docker images 中就有了postgres_cn:11.4镜像,我们的重点是如何将此镜像发布到 ECR 上面去,那么紧接着就需要使用 Amazon 命令配置了,有了这项配置之后,就相当于具有了访问我的账号应用资源的授权。\nShell\n```\naws configure\n```\n其实就是四项需要:**Access key ID、Secret access key、Region和输出格式**,前两项就是我们前面创建用户时下载到 CSV 文件中的密钥,Region 就是你的 EC2所在区域,可以在 EC2 Dashboard 右上角的区域中找到对应的 region name,输出格式就是 json。\n\n![image.png](https://dev-media.amazoncloud.cn/164874f074a14d5d9d54a4f56e07e28b_image.png)\n\naws configure 命令配置效果图\n然后我们开始为 Postgres_cn 镜像创建一个 Registry 仓库:\n\nShell\n```\naws ecr create-repository --repository-name postgres_cn-repository --region us-west-2\n```\n下面就是 json 输出结果,其中的 repositoryUri 就是将本地Postgres_cn 镜像推送的地址:\nJSON\n```\n{\n \"repository\": {\n \"repositoryUri\": \"714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\", \n \"imageScanningConfiguration\": {\n \"scanOnPush\": false\n }, \n \"encryptionConfiguration\": {\n \"encryptionType\": \"AES256\"\n }, \n \"registryId\": \"714394534197\", \n \"imageTagMutability\": \"MUTABLE\", \n \"repositoryArn\": \"arn:aws:ecr:us-west-2:714394534197:repository/postgres_cn-repository\", \n \"repositoryName\": \"postgres_cn-repository\", \n \"createdAt\": 1648633165.0\n }\n}\n```\n看到上面的输出,就证明创建镜像仓库成功了,我们再接再厉,开始 tag 镜像、login 仓库、push 镜像\nShell\n```\ndocker tag postgres_cn:11.4 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\naws ecr get-login-password | docker login --username AWS --password-stdin 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\ndocker push 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\n```\n 从下图中我们就能看到上述三项命令执行的效果。\n\n![image.png](https://dev-media.amazoncloud.cn/eacb173409e64adfb1c517055abb21d3_image.png)\n\n推送 PostgreSQL 镜像到 Amazon ECR 效果图\n好了,目前 Amazon ECR 终于可以正常使用了,接下来的 PostgreSQL 镜像就也可以存在 ECR 中,方便被 Amazon ECS 的任务定义中所引用了,同时我们也可以在官网的 Docker 基本知识中获得更详细的了解。\n\n### **Amazon ECS 部署入门**\n#### **Amazon ECS 组成部分**\n在第一章的概述中同学们会对Amazon ECS到底是什么,并且与传统ECS有什么区别有了一个基础的概念,我们这里就将这些概念再深化一下,方便后面的部署理解。\n首先我们看下图,是官网的任务和计划的结构体系图,Amazon ECS 在运行过程分为了**集群、服务、任务**,集群主要是给出了一个逻辑上的范畴,也就是说集群范围内所启动的任务共同组成了这样一个容器为主的计算服务集群。\n接着在集群内就可以创建服务,创建一个服务后,会为接下来需要运行的任务配置了种种基础环境参数,例如:启动类型、操作系统选择、平台版本、任务数量、集群 VPC、安全组等等,那么当服务运行后会通过任务计划在集群中放置任务,而任务如果出现故障停止,服务亦会监控到并启动新的任务,这就提供了一个高可靠的任务运行环境。\n最后就是任务了,任务来源于任务定义,在任务定义中确定了 Docker 容器运行所需的参数、Amazon ECS 环境参数的定义、计算资源的配额、EFS等网络文件卷的配置等等容器运行所需的元信息,甚至我们可以在一个任务中配置多个容器去运行,但是 Amazon ECS 并不鼓励这样一种做法,更倾向于一个任务一个运行的容器。具体细节我们可以深入调阅官方文档:[什么是 Amazon ECS](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/Welcome.html)?\n\n![image.png](https://dev-media.amazoncloud.cn/3820b11bf7214d43b4ff44a9f53e9d08_image.png)\n\nAmazon ECS任务 和技术结构体系示意图\n### **创建 Amazon ECS 部署流程**\n#### **(1) 创建 ECS 集群**\n首先我们进入[ECS主界面](https://us-west-2.console.aws.amazon.com/ecs/home),左栏包括了 Amazon ECS、Amazon EKS、Amazon ECR,我们主要看 Amazon ECS。点击创建集群,我们选择创建仅限联网的集群模板就可以了,后两种并非单纯的 Docker 容器组成的任务,我们创建的集群名叫:DBCluster。\n\n![image.png](https://dev-media.amazoncloud.cn/2347c7f91320443a9bc17d5ca430be3e_image.png)\n\nAmazon ECS 集群创建步骤一示意图\n\n#### **(2) 创建任务定义**\n接着在任务定义入口进入后,点击创建新任务定义,启动类型分为了 Fargate、EC2、External,Fargate 是 Amazon ECS 的一项无服务技术,通俗点理解就是让我们不用去考虑基础设施中的计算资源怎样优化 ,Fargate 给你包办了,我们主要使用这个类型,Amazon EC2和外部计算服务连接这两项我们这次先暂不考虑。Fargate 的具体描述可以参考官方文档 [Amazon Fargate](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/AWS_Fargate.html) 介绍。\n\n![image.png](https://dev-media.amazoncloud.cn/5376841b817e4361b6ccbca039988ca8_image.png)\n\nAmazon ECS 任务定义创建步骤一示意图\n下一步是任务定义,我做了一个可参考的实例:\n- 任务定义名称:pg-run-task-definition\n- 需要兼容性:FARGATE\n- 任务角色:ecsTaskExecutionRole\n- 网络模式:awsvpc\n- Operating system family:Linux\n- 任务执行角色:ecsTaskExecutionRole\n- 任务内存 (GB):2GB\n- 任务 CPU (vCPU):1VCPU\n- 添加卷:名称=fs-3,卷类型=EFS,文件系统ID=(选择 EFS id),访问点ID=(选择EFS 访问点 id),传输中加密:选择\n添加容器\n- 容器名称*:postgres_cn-db\n- 映像*:714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\n- 内存限制 (MiB)*:软限制=2048\n- 端口映射:5432\n- CPU 单元数:1024\n- 环境变量:Key=POSTGRES_PASSWORD,Value=123456\n- 挂载点:源卷=fs-3,容器路径=/var/lib/postgresql/data\n接着点击创建,任务定义完成后,我们看看创建后的完整Json输出,这个Json文本就是任务定义后Amazon ECS需要启动任务实例化时读取的信息,若回想一下我们一般用docker run时配置参数的场景,其实这些参数都可以囊括在这个Json文本中。\n**推荐大家多去了解这个 Json 的内容含义,这对于以后进入高级阶段使用 Amazon CDK 等命令方式来创建维护 Amazon ECS 集群以及基础设施环境会大有裨益。**\nJSON\n```\n{\n \"ipcMode\": null,\n \"executionRoleArn\": \"arn:aws:iam::714394534197:role/ecsTaskExecutionRole\",\n \"containerDefinitions\": [\n {\n \"dnsSearchDomains\": null,\n \"environmentFiles\": null,\n \"logConfiguration\": {\n \"logDriver\": \"awslogs\",\n \"secretOptions\": null,\n \"options\": {\n \"awslogs-group\": \"/ecs/pg-run-task-definition-1\",\n \"awslogs-region\": \"us-west-2\",\n \"awslogs-stream-prefix\": \"ecs\"\n }\n },\n \"entryPoint\": null,\n \"portMappings\": [\n {\n \"hostPort\": 5432,\n \"protocol\": \"tcp\",\n \"containerPort\": 5432\n }\n ],\n \"command\": null,\n \"linuxParameters\": null,\n \"cpu\": 1024,\n \"environment\": [\n {\n \"name\": \"POSTGRES_PASSWORD\",\n \"value\": \"123456\"\n }\n ],\n \"resourceRequirements\": null,\n \"ulimits\": null,\n \"dnsServers\": null,\n \"mountPoints\": [\n {\n \"readOnly\": null,\n \"containerPath\": \"/var/lib/postgresql/data\",\n \"sourceVolume\": \"fs-3\"\n }\n ],\n \"workingDirectory\": null,\n \"secrets\": null,\n \"dockerSecurityOptions\": null,\n \"memory\": null,\n \"memoryReservation\": 2048,\n \"volumesFrom\": [],\n \"stopTimeout\": null,\n \"image\": \"714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\",\n \"startTimeout\": null,\n \"firelensConfiguration\": null,\n \"dependsOn\": null,\n \"disableNetworking\": null,\n \"interactive\": null,\n \"healthCheck\": null,\n \"essential\": true,\n \"links\": null,\n \"hostname\": null,\n \"extraHosts\": null,\n \"pseudoTerminal\": null,\n \"user\": null,\n \"readonlyRootFilesystem\": null,\n \"dockerLabels\": null,\n \"systemControls\": null,\n \"privileged\": null,\n \"name\": \"postgres_cn-db\"\n }\n ],\n \"placementConstraints\": [],\n \"memory\": \"2048\",\n \"taskRoleArn\": \"arn:aws:iam::714394534197:role/ecsTaskExecutionRole\",\n \"compatibilities\": [\n \"EC2\",\n \"FARGATE\"\n ],\n \"taskDefinitionArn\": \"arn:aws:ecs:us-west-2:714394534197:task-definition/pg-run-task-definition:1\",\n \"family\": \"pg-run-task-definition\",\n \"requiresAttributes\": [\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"com.amazonaws.ecs.capability.logging-driver.awslogs\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"ecs.capability.execution-role-awslogs\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"ecs.capability.efsAuth\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"com.amazonaws.ecs.capability.ecr-auth\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"com.amazonaws.ecs.capability.docker-remote-api.1.19\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"ecs.capability.efs\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"com.amazonaws.ecs.capability.docker-remote-api.1.21\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"com.amazonaws.ecs.capability.task-iam-role\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"com.amazonaws.ecs.capability.docker-remote-api.1.25\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"ecs.capability.execution-role-ecr-pull\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"com.amazonaws.ecs.capability.docker-remote-api.1.18\"\n },\n {\n \"targetId\": null,\n \"targetType\": null,\n \"value\": null,\n \"name\": \"ecs.capability.task-eni\"\n }\n ],\n \"pidMode\": null,\n \"requiresCompatibilities\": [\n \"FARGATE\"\n ],\n \"networkMode\": \"awsvpc\",\n \"runtimePlatform\": {\n \"operatingSystemFamily\": \"LINUX\",\n \"cpuArchitecture\": null\n },\n \"cpu\": \"1024\",\n \"revision\": 1,\n \"status\": \"ACTIVE\",\n \"inferenceAccelerators\": null,\n \"proxyConfiguration\": null,\n \"volumes\": [\n {\n \"fsxWindowsFileServerVolumeConfiguration\": null,\n \"efsVolumeConfiguration\": {\n \"transitEncryptionPort\": null,\n \"fileSystemId\": \"fs-08359de466dce1153\",\n \"authorizationConfig\": {\n \"iam\": \"DISABLED\",\n \"accessPointId\": \"fsap-029ff71869daae77d\"\n },\n \"transitEncryption\": \"ENABLED\",\n \"rootDirectory\": \"/\"\n },\n \"name\": \"fs-3\",\n \"host\": null,\n \"dockerVolumeConfiguration\": null\n }\n ]\n}\n```\n#### **(3) 创建服务**\n**在开始创建 Amazon ECS 服务之前,我们先解决安全组问题,这里需要特别注意**(我在这里碰了一鼻子灰)\n我们在创建 EC2的时候,进入 [EC2实例列表](https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#Instances:),然后再进入实例,如下图所示,它会有两个安全组,其中红色框的安全组就是与 EFS 相互联通的安全组,如果你有兴趣,可以再看看 EFS 那边的安全组就一目了然啦,这就是为什么我开始创建 Amazon EC2 实例的时候先创建 EFS 并添加为该 EC2实例文件系统的原因,Amazon EC2实例创建后就会设置好与 EFS 之间访问控制的安全组,那么大家理解起更具体的安全组配置就有了参考。我就是先创建 Amazon EC2再创建 EFS,结果总是各种挂载不通,当你看懂安全组配置后,那么以后你就可以轻松驾驭 EFS 了。\n\n![image.png](https://dev-media.amazoncloud.cn/b2cb5efc711b4303ad0fa36b9652bad0_image.png)\n\nAmazon EC2实例安全组示意图\n后面我们会直接将 Amazon EC2实例安全组的这条配置加入到 Amazon ECS 服务的安全组内,这样 Amazon ECS 就能和 EFS 之间就畅通无阻了,同时我们进入 [EC2安全组](https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#SecurityGroups:),创建一个应用于 PostgreSQL 对外服务的安全组,主要是给入站规则加上 PG 的5432端口,出站规则不变,名称为 PG-Safe。\n\n![image.png](https://dev-media.amazoncloud.cn/49aa35b426464870889bd173dde07444_image.png)\n\n创建 Amazon ECS 使用的安全组示意图\n接下来在集群列表中我们就能看到 DBCluste r集群,进入以后第一项就是服务,我们点击创建,开始服务创建流程。\n配置服务项我也列一下:\n- 启动类型:FARGATE\n- 操作系统系列:Linux\n- 任务定义:pg-run-task-definition\n- 修订:1\n- 平台版本:LATEST\n- 集群:DBCluster\n- 服务名称:PG_DB_Server\n- 服务类型:REPLICA\n- 任务数:1\n下一步是网络配置\n- 集群 VPC:一定选择和 EC2、EFS 一致的 vpc,\n- 子网:如果有多个,就都选择上,最大化 ECS 容器的IP可用范围。\n- 安全组:**选择现有安全组,其中选择两个安全组项,一个是新场景的PG-Safe,另一个就是上述 EC2实例中专门与 EFS 通讯的那条安全组**。\n\n![image.png](https://dev-media.amazoncloud.cn/d98ec266a85b407e8b1b31a9489ecacd_image.png)\n\n创建 Amazon ECS 服务选择安全组示意图\n- 负载均衡器类型:无\n然后一路下一步,创建服务即可,创建完服务后,也会同步创建好一个 Task,我们可以再任务标签页看到成功运行的情况:\n\n![image.png](https://dev-media.amazoncloud.cn/341ce6efffac4caa9d3074c9978ab5a5_image.png)\n\nPostgreSQL 任务运行示意图\n下图的任务日志就是 PostgreSQL 启动日志输出。\n\n![image.png](https://dev-media.amazoncloud.cn/6f3e97889b4d4b1db79e76de34ffae12_image.png)\n\nPostgreSQL 任务日志示意图\n#### **(4) ECS、EC2、EFS关联检查**\n但是别忘了最重要的一件事情,那就是我们要看看在 EC2实例上挂载的 EFS 文件系统是否能看到 Amazon ECS 任务启动后映射出去的文件目录(PGSQL数据目录),SSH 登陆我的 EC2实例,然后执行命令:\nGroovy\n```\ndf -Th\nsudo ls /mnt/efs/fs1/\n```\n第一条命令我们可以看到在/mnt/efs/fs1目录挂载了 nfs4类型的网络文件系统,这就是挂载了 EFS。\n第二条命令,我们可以看到挂载目录下有 PostgreSQL 的数据和配置文件,这就是 Amazon ECS 任务中 PGSQL容器的路径——/var/lib/postgresql/data映射到 EFS 文件系统上的数据。\n\n![image.png](https://dev-media.amazoncloud.cn/720f4998634540498488cb02bd1656c9_image.png)\n\nAmazon EC2与 Amazon ECS 通过 EFS 共享文件示意图\n\n### **总结**\n好了,今天就先聊到这里, 对于 Amazon 容器应用程序基础设施,也不仅包括了面向 Docker 的 ECS,还有特别适合入门级学习的 Amazon Lightsail,也有针对大规模服务进行容器编排的 Kubernetes,充分利用其灵活性和 Amazon 托管的安全性和弹性,具体入门指南我们可以进入官网学习[选择您的容器应用程序基础设施-入门指南](https://aws.amazon.com/cn/getting-started/guides/deploy-containers-decision/?trk=84adbd45-91d2-4240-bd5f-358eab49cee5&sc_channel=ba)\n除了 Amazon ECS 的图形界面之外,其实 Amazon ECS 最大的优势还提供特别强大的命令操作工具集合,包括: [Amazon Copilot](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/getting-started-aws-copilot-cli.html)、[Amazon ECS CLI](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/ECS_CLI.html)、[Amazon CDK](https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/tutorial-ecs-web-server-cdk.html) 等。这些功能可以通过非图形界面的终端命令方式、编程的方式(TypeScrpit、JavaScrpit、Python、Java、C#),更全面且细粒度的去创建与维护 Amazon ECS 基础设施,控制和优化 Amazon ECS 集群与任务。\n不过这些功能的操作复杂程度也使人震惊,真的不得不佩服Amazon的技术大神们,创造了如此庞大的操作 Amazon ECS 工具集,然而对于新人来讲,一开始接触这些会烦死的!因此饭还是一口一口吃比较容易消化,大家先通过最简单界面操作方式,让 Amazon EC2 和 Amazon ECS 先能正常的运转起来。\n若你是一位具有探索新知精神的极客,当你真正开始触碰到 Amazon ECS 这些高级强大的工具精髓时,那么你就会迷上它,它一种高度可扩展的技术平台,你可以基于此打造出属于自己的集群化容器自动运维体系,那么就可以从更全面且更细致的态势去感知你所运维的服务发生的一切!好吧,更高级的 Amazon ECS 探索演示以后有机会再聊。\n\n亚马逊云科技专为开发者们打造了多种学习平台:\n1. 入门资源中心:从0到1 轻松上手云服务,内容涵盖:成本管理,上手训练,开发资源。 [Amazon 入门_ Amazon 入门使用教程_ Amazon 云计算资源-Amazon 云服务](https://aws.amazon.com/cn/getting-started/?nc1=h_ls&trk=32540c74-46f0-46dc-940d-621a1efeedd0&sc_channel=el)\n2. 架构中心:亚马逊云科技架构中心提供了云平台参考架构图表、经过审查的架构解决方案、Well-Architected 最佳实践、模式、图标等。[Amazon 架构中心部署说明_Amazon 云架构白皮书-Amazon 云服务](https://aws.amazon.com/cn/architecture/?intClick=dev-center-2021_main&trk=3fa608de-d954-4355-a20a-324daa58bbeb&sc_channel=el)\n3. 构建者库:了解亚马逊云科技如何构建和运营软件。[Amazon Builders' Library](https://aws.amazon.com/cn/builders-library/?cards-body.sort-by=item.additionalFields.sortDate&cards-body.sort-order=desc&awsf.filter-content-category=*all&awsf.filter-content-type=*all&awsf.filter-content-level=*all&trk=835e6894-d909-4691-aee1-3831428c04bd&sc_channel=el)\n4. 用于在亚马逊云科技平台上开发和管理应用程序的工具包:[Amazon 工具下载_Amazon 开发工具_资源下载- Amazon 云服务](https://aws.amazon.com/cn/tools/?intClick=dev-center-2021_main&trk=972c69e1-55ec-43af-a503-d458708bb645&sc_channel=el)\n\n\n【专属福利】\n福利一:100余种产品免费套餐。其中,计算资源 Amazon EC2首年12个月免费,750小时/月;存储资源 Amazon S3 首年12个月免费,5GB标准存储容量。\n[亚马逊 Amazon 海外区域账户免费套餐_免费云服务- Amazon 云服务](https://aws.amazon.com/cn/free/?nc2=h_ql_pr_ft&all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all&trk=e0213267-9c8c-4534-bf9b-ecb1c06e4ac6&sc_channel=el)\n福利二:最新优惠大礼包,200$数据与分析抵扣券,200$机器学习抵扣券,200$微服务与应用开发抵扣券。[最新优惠活动_云服务器促销 - 亚马逊云科技](https://www.amazonaws.cn/campaign/?sc_channel=el&sc_campaign=credit-acts-ldr&sc_country=cn&sc_geo=chna&sc_category=mult&sc_outcome=field&trkCampaign=request-credit-glb-ldr&trk=f45email&trk=02faebcb-3f61-4bcb-b68e-c63f3ae33c99&sc_channel=el)\n福利三:解决方案 CloudFormation 一键部署模版库\n[云服务解决方案部署快速入门_云服务部署- Amazon 云服务](https://aws.amazon.com/cn/quickstart/?solutions-all.sort-by=item.additionalFields.sortDate&solutions-all.sort-order=desc&awsf.filter-tech-category=*all&awsf.filter-industry=*all&awsf.filter-content-type=*all&trk=afdbbdf0-610b-4421-ac0c-a6b31f902e4b&sc_channel=el)","render":"<h3><a id=\"Amazon_ECS__0\"></a><strong>Amazon ECS 概述</strong></h3>\n<p>对于经常接触云计算服务技术的同学们估计一听到 ECS,耳朵都能磨出茧子,印象中 ECS 不就是弹性计算服务么,再人话点就是你按量充值的一台虚拟主机,然后通过SSH远程维护这台虚拟主机的操作系统呗,但是 <strong>Amazon ECS 就不同于你们理解的那个 ECS 啦</strong>!且听我慢慢道来。<br />\nAmazon ECS全称是(Amazon Elastic Container Service),它是针对容器技术高度弹性的的管理服务,我么如何去更通俗地理解呢?其实 Amazon ECS 就是希望用户直接面对容器进行管理(例如:Docker),而不是面对虚拟机操作系统,也就是说 Amazon 云平台提供给用户购买的计算单元粒度更细致了,那么这又带来什么好处呢?其实是两方面:<br />\n优势一:你没必要就为了部署一个服务(例如:部署 Tomcat),就得先占用一台虚拟机,现在 Amazon ECS 给你了一个新方案,你部署维护一个 Docker 容器就够了,这个容器服务跑在哪台机器上,那个容器引擎上,这些你就不用关心了,Amazon ECS 自己来维护计算资源的基础设施,<strong>由于资源占用少了,自然你充值就少了</strong>;<br />\n优势二:现在的云服务大趋势是分布式,这样你的应用可以形成集群,以便增强系统高可靠性以及对服务性能的弹性伸缩管理,但是像以前我购买一台虚拟主机,即使我切分成了多个 Docker,那也是在这一个虚拟主机节点上跑,依然是个伪分布式,除非你有更多的资金购买更多的虚拟主机。但是 Amazon ECS 默认提供的无服务(Serverless)模式就让你不再顾虑运行服务的集群分布问题,只考虑要上多少 Docker 容器,至于放置在什么地方,哪个机房,那台服务器,那更多是 Amazon ECS 考虑的事情,那么我就用一个整体上较低的综合成本,实现了一个真正比较强大的面相服务的集群环境。<br />\n对于 Amazon ECS 的一些简单介绍我们可以看看 Amazon ECS 官方的介绍:<a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/Welcome.html\" target=\"_blank\">什么是 Amazon Elastic Container Service</a>?<br />\n<strong>另外提一下亚马逊云科技最近活动力度还是蛮大的,提供了100余种产品免费套餐。其中,计算资源 Amazon EC2首年12个月免费,750小时/月;存储资源 Amazon S3 首年12个月免费,5GB标准存储容量。<br />\n若小伙伴们有兴趣,也可以进去瞧瞧亚马逊云科技最新活动页,便宜不占白不占,对吧:<a href=\"https://aws.amazon.com/cn/free/?nc2=h_ql_pr_ft&all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all&trk=e0213267-9c8c-4534-bf9b-ecb1c06e4ac6&sc_channel=el\" target=\"_blank\">亚马逊 Amazon 海外区域账户免费套餐_免费云服务-Amazon 云服务</a>,</strong></p>\n<h3><a id=\"Amazon_ECS__9\"></a><strong>Amazon ECS 架构</strong></h3>\n<p>我们先上一张 Amazon ECS 的官网发布的架构图,先对其有个概括的认识:</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/f058e60e1e544b7aa3b20c7775b6bb9c_image.png\" alt=\"image.png\" /></p>\n<p>Amazon ECS 环境架构图</p>\n<p>从上图中,我们看到了 Amazon ECS 的受控范围是一个 Region (区域),这个区域我们可以理解为世界上某个国家、某个地区的云机房,例如:美国西部 (俄勒冈州) us-west-2,非洲 (开普敦) af-south-1,亚太地区 (香港) ap-east-1,你一开始接触会有些懵逼,这咋全世界都有 Amazon 的点,没办法,为啥 Amazon 是云计算大哥,就是因为人家的云服务是覆盖全世界的,这对于国内企业云服务未来走向国际化就具有比较潜在的基础设施优势。<br />\nRegion内部的核心又分为了<strong>任务定义(Task definition)、服务描述(Service description)</strong> 的配置蓝图部分,任务和基础设施的运行实例部分,另外还有一个<strong>容器镜像注册(Container registry)</strong> 的仓库部分,这三部分实际上就是 Amazon ECS 面向用户的核心服务。<br />\n例如:你有个不错的 Docker 镜像,那么就先注册到 Container registry,然后下一步开始在 Task definition 中做容器运行所需的配置,其实通俗点说就是在任务配置中引用你上传的 Docker 镜像地址,给任务分配多少 CPU、内存,属于VPC(虚拟私有云)中哪个子网等等这些容器镜像、配额、用户角色、基础设施的综合性说明文件。<br />\n有了这个综合性说明,再根据 Service description 配置就能在启动服务的过程中,将配置中的 Docker 镜像实例化成一到多个 Docker 容器服务的任务,并根据 Amazon Fargate(Amazon的无服务技术),将任务放置在ECS集群的不同位置,形成高可靠的分布式系统(当然你也可以只选择部署一个任务)。Fargate 类型比较重要,我们做 Task definition 的时候,一般会选择它,它的官方介绍:<a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/AWS_Fargate.html/\" target=\"_blank\">Amazon Fargate 上的 Amazon ECS</a><br />\n对于 Amazon ECS 产品的详细介绍我们可以进入官方的 <a href=\"https://aws.amazon.com/cn/ecs/?nc2=h_ql_prod_ct_ecs&trk=f33fd1af-e80b-4db6-93c8-2f2d5c39b9e5&sc_channel=el\" target=\"_blank\">Amazon ECS产品详细介绍页</a>做进一步的了解。<br />\nDocker 快速介绍<br />\n玩转 Amazon ECS 的底子就是会玩 Docker,对于 Docker 还比较陌生的同学们,我先简单科普一下:<br />\n提起 Docker,有很多人第一印象会认为它就是一个虚拟化容器,所以大家特别容易陷入到一种误区,就是觉得 Docker 只是在 Linux 操作系统之上又增加了一层,就跟 OS 上跑了一个 VMWare 一样。Docker 一定变得又慢又复杂。还不如原生安装的服务看起来舒服。<br />\n实际上这是误区,Docker 管理的各种服务,都是操作系统原生的进程,并不是一个虚拟化产物,它的正确定义是应用容器引擎。<br />\n那怎么去理解这个应用容器引擎呢?就要说说 Docker 的核心原理了——其中主要机制之一,通过 Linux 的 namespace 机制实现了资源隔离,这个资源隔离就包括了:</p>\n<ol>\n<li>UTS,对主机名和域名的隔离</li>\n<li>IPC,对信号量、消息队列和共享内存的隔离</li>\n<li>PID,对进程编号的隔离</li>\n<li>Network,对网络设备、网络协议栈、网络端口对隔离</li>\n<li>Mount,对挂载点(文件系统)的隔离</li>\n<li>User,对用户和用户组的隔离。<br />\n这些隔离机制都是 Linux 内核的 namespace 机制实现,也是 Docker 容器设计的精髓。<br />\n我来打个比方吧:原来是一个 300 平米的大 house,就住着一家人,卧室、厨房、卫生间这一家人独享。可是房子太大完全可以住三个家庭,不仅能公摊一部分费用,还能为主家带来额外的收益。那么就要对这个大 house 重新进行规划设计,满足三个家庭的需要,制定一些生活制度,有些资源是可以共享的,但关键资源就必须隔离开,保护隐私嘛!其实大家说到底还是在一个大房子内平等的生活。<br />\n用了这个比喻其实就是告诉大家,你就把 Docker 理解为一个房子多个家庭的规划安排包租婆,Docker 管理了很多的容器服务,容器服务就是在宿主机上跑着的,例如 MySQL、Nginx、微服务等等都是容器服务,大家都是在一个 OS 上平等的运行着,只不过进了自己房间,你对别人房间的情况就一无所知了。那么这不仅保护了各个服务之间不会产生对资源争用,而且还能根据预先入户的协议,分配好 CPU、内存、磁盘的容量。这样大家住在一起也是明明白白的,谁也不能沾了谁的便宜。当然了对外的网络端口还是需要各家分配不同的。<br />\n有了这个本事,你就能在有限的云资源上跑很多服务啦!我自己做的公司网站就跑了三个 Docker 容器:Nginx、MySQL、Wordpress,我才给分配了 512M 内存,够抠门吧,但是运行地妥妥的,只是物理内存是在太小,有时候重启服务,OS 报内存资源就不够了,必须把 Docker 也重启,清空一下内存就好了。<br />\n我曾经做过两个互联网平台产品用了三台性能不错的云服务器,4 核,16G 内存,足足跑了 50 多个微服务和其他基础服务,真的是把资源榨得是干干净净。关键还有服务日志隔离、环境变量隔离、全局配置隔离等待,好处实在太多了。<br />\n说到这里,我相信同学们一定就有点理解了为什么 Amazon ECS 那么强调容器技术来管理,这对于计算资源的利用可以说是一台压榨机啊!那么我们的 Docker 到底跑在哪个虚拟服务器上的那个 Docker Container 这就无关紧要了,那是ECS考虑的事情。<br />\n接着看一个我做过的 Dockerfile 配置:<br />\nDockerfile</li>\n</ol>\n<pre><code class=\"lang-\">from openresty/openresty\nRUN sed -i 's#http://deb.debian.org#http://mirrors.tuna.tsinghua.edu.cn#' /etc/apt/sources.list && \\\n sed -i '/http:\\/\\/security.debian.org\\/debian-security/d' /etc/apt/sources.list\nRUN apt-get update\nRUN apt-get install procps net-tools locales -y\nRUN localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8\nENV LANG=zh_CN.utf8\nENV TZ=Asia/Shanghai\nCOPY ["./work", "/work"]\nCMD ["nginx","-p","/work","-c","conf/nginx.conf","-g","daemon off;"]\n</code></pre>\n<p>上面这个 Dockerfile 配置就是把 Docker Hub 的 Openresty 环境更为中文化了一些,并且也更为适合调试,那么通过这个自定义的 Dockerfile 打出来的镜像就非常适合我的生产环境,我接着通过如下命令,就能构建Docker镜像并在本地看到自己的 Docker 镜像<br />\nShell</p>\n<pre><code class=\"lang-\">docker build -t apigateway -f openresty-cmd.df .\ndocker images|grep apigateway\n</code></pre>\n<p><img src=\"https://dev-media.amazoncloud.cn/58624af21a9c4cd5bec8c5b69e91e240_image.png\" alt=\"image.png\" /></p>\n<p>Dockerfile 构建演示图<br />\n最后我们再将打好的 Docker 镜像 apigateway:latest 运行起 API 网关的 Docker 容器:<br />\nShell</p>\n<pre><code class=\"lang-\">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\n\n</code></pre>\n<p>我们从上面的命令中可以看到 docker run一些关键参数:</p>\n<ul>\n<li>-d 代表服务在后台运行,</li>\n<li>–cpu-shares 代表 cpu 分享比例,1024为1个 vcpu,那么512就是1个 vcpu 50%的算力</li>\n<li>–memory 代表内存配额,目前为最大1G配额</li>\n<li>-p代表了内外部端口的映射</li>\n<li>-v代表了内外部磁盘的映射<br />\n上述这些 Docker 容器设定知识都是为我们下面理解 Amazon ECS 的任务定义提供了最基础的帮助。</li>\n</ul>\n<h3><a id=\"Amazon_EC2__74\"></a><strong>Amazon EC2 部署入门</strong></h3>\n<p>现在问题来了,难道说 Amazon 云技术就只有无服务的弹性容器 Amazon ECS 吗?当然不是的,其实在我们印象中国内云厂商的 ECS(弹性云计算服务器),对应在 Amazon 云产品中的术语中叫做 Amazon EC2(Amazon Elastic Compute Cloud),Amazon EC2不仅可以创建服务器实例成为你的虚拟机节点,而且 Amazon EC2和Amazon ECS 具有共通的基础设施环境,这块是不是有些绕了?那么我们先看一张 Amazon EC2 和 Amazon ECS 的运行实例关系图:</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/6c5b633ff21943d0b921024ae48e7f80_image.png\" alt=\"image.png\" /></p>\n<p>Amazon EC2、Amazon ECS 运行关系架构图<br />\n上图其实非常简单,只是将 Amazon EC2和Amazon ECS 之间的关系进行了梳理,从架构图中运行的 Amazon EC2 和 Amazon ECS Task 实例关系,我相信大家就不会那么绕了,其实它们都共享了Amazon提供的基础设施,这些基础设施项你可以在自己的 Amazon EC2控制台中去维护,在 Amazon ECS 的任务定义中你可以新建一些基础设施项,同样也可以让 Amazon ECS 与 Amazon EC2共享基础设施项,达到它们之间的协作,例如:让 Amazon ECS 与A mazon EC2使用同一个 VPC 的子网段,那么 Amazon EC2就能轻松通过内网 IP 访问 Amazon ECS容器服务。</p>\n<h4><a id=\"_81\"></a><strong>注册配置</strong></h4>\n<h5><a id=\"1__82\"></a><strong>(1) 注册</strong></h5>\n<p>首先我们要创建一个属于自己的 Amazon 账号,地址:Amazon 云服务注册地址,注册登陆后,就进入到了 Amazon 管理控制台,我们先根据导航:所有服务->计算->EC2,进入到 Amazon EC2 Dashboard,在这里就可以看到所有情况。如下图所示:这里面我们要注意右上角的区域,选择不同区域会统计不同的计算资源情况,这个区域(region)也是后续很多配置中需要格外注意的地方,左栏就 EC2实例和关键基础设施的维护入口,之后我们需要创建一个 Amazon EC2实例,将此 Amazon EC2实例作为我们后续对 Amazon ECS 协作与管理的服务节点。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/8ddbed27bf054cf880e35d56ff8fbd97_image.png\" alt=\"image.png\" /></p>\n<p>Amazon EC2 Dashboard效果图</p>\n<h5><a id=\"2__88\"></a><strong>(2) 用户、用户组和密钥</strong></h5>\n<p>准备阶段我们先不要着急创建 EC2实例,我们先进入 <a href=\"https://us-east-1.console.aws.amazon.com/iam/home#/home\" target=\"_blank\">Identity and Access Management (IAM)</a>, 创建用户和组,也就是说我们不要使用注册Amazon云服务的账号,而是创建一个应用访问使用的账号,在创建组的权限中使用 AdministratorAccess,不用选择密码方式,直接使用“访问密钥”,创建好用户之后,下载密钥 CSV 文件,文件中的 Access key ID,Secret access key 会在之后的对 ECS 的配置中使用,具体配置详情还可以参考:<a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/get-set-up-for-amazon-ecs.html\" target=\"_blank\">官网 IAM 设置</a>。</p>\n<h5><a id=\"3_EC2_90\"></a><strong>(3) EC2实例的密钥对</strong></h5>\n<p>接着我们回到 <a href=\"https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#Home:\" target=\"_blank\">EC2 Dashboard</a>,我们要创建一个密钥对,如下图所示</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/4c80779524e04c0f968bc2e911d7b481_image.png\" alt=\"image.png\" /></p>\n<p>密钥对效果图<br />\n创建好的密钥对下载后,可以直接用于之后EC2实例的SSH登陆使用,例如:ssh -i readbyte-key-pair.pem ec2-user@34.217.211.73,这个“readbyte-key-pair.pem”就是我创建的私钥。具体配置详情还可以参考:<a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/get-set-up-for-amazon-ecs.html\" target=\"_blank\">官网密钥对设置</a>。这里需要注意的是区域,也就是说密钥对在哪个区域创建的,那么以后EC2实例创建的时候也在哪个区域。</p>\n<h5><a id=\"4__EFS_98\"></a><strong>(4) EFS文件系统</strong></h5>\n<p>目前仍然不要着急创建 Amazon EC2实例,我们先创建 <a href=\"https://us-west-2.console.aws.amazon.com/efs?region=us-west-2#/get-started\" target=\"_blank\">Elastic File System</a>(EFS),这是 Amazon 的 NFS 网络文件系统,通过 NFS 我们就可以将 Amazon ECS 任务的容器目录挂载到 EFS 上,那么 Amazon EC2 实例就可以通过网络文件系统(NFS)挂载到本地目录的方式,访问 EFS 中 ECS 容器的内部文件,进行容器服务中的目录文件配置与数据操作了。<br />\nEFS 的创建很简单,同时也创建接入点,但是需要主要 vpc 的设置应该与之后的 Amazon EC2、Amazon ECS 是一个子网段,目前初始阶段也就只有默认的 vpc,</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/2e3f18fb8b014acc8ca786b8340f1aa0_image.png\" alt=\"image.png\" /></p>\n<p>EFS 连接效果图<br />\n我们进入创建好的文件系统,点击右上角的连接就能看到 EFS 对外提供挂载的路径,就包括 EFS 挂载、或 NFS 客户端方式。</p>\n<h4><a id=\"_Amazon_EC2_107\"></a><strong>创建 Amazon EC2实例</strong></h4>\n<p>我们重新登陆 <a href=\"https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#Home:\" target=\"_blank\">EC2 Dashboard</a>,点击做栏实例->创建 EC2实例,如下图所示,尽量选择 Amazon Linux 2 AMI (HVM),因为经过一些 ECS 优化,在尝试阶段可以使用符合条件的免费套,其实就是下一步的 t2.micro 实例类型,1vcpu,1G内存,作为我们体验够用了。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/2aa3d34ae74f4736b70a7143597cc1a1_image.png\" alt=\"image.png\" /></p>\n<p>Amazon EC2 购买选项效果图<br />\n在步骤三中有一步非常重要,那就是找到“文件系统”项,点击后,我们就能看到上面创建的 EFS 文件系统,我们需要将此文件系统挂载上,从图中可以看到挂载到了 EC2 实例的/mnt/efs/fs1下面</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/9b9f5ef813984f64bb3319712645ab69_image.png\" alt=\"image.png\" /></p>\n<p>创建 Amazon EC2实例阶段EFS挂载效果图<br />\n在第四步的添加存储中,我们就能看到 EFS 的挂载情况了</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/144a067315f64581962350618eac937d_image.png\" alt=\"image.png\" /></p>\n<p>创建 Amazon EC2实例阶段存储效果图<br />\n创建 EC2实例之后我们就能在实例列表中看到创建的 EC2实例,进入实例后,我们可以看到下图中红色框这就是外网 IP 和内网 IP,下一步我们通过 SSH 登陆 EC2实例进行进一步的配置。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/40197cdb52d74a2b9ef7244a3cb43164_image.png\" alt=\"image.png\" /></p>\n<p>Amazon EC2实例信息概览效果图</p>\n<h4><a id=\"Amazon_EC2_Docker__129\"></a><strong>Amazon EC2实例的 Docker 环境打造</strong></h4>\n<p>首先我们用前面创建的私钥进行 ssh 登陆,一定要注意 macOS 或 Linux 计算机将私钥的文件所属权变为400,如下面代码所示:<br />\nShell</p>\n<pre><code class=\"lang-\">chmod 400 readbyte-key-pair.pem\nssh -i readbyte-key-pair.pem ec2-user@34.217.211.73\n</code></pre>\n<p>下一步我们来安装 Docker 服务并启动 Docker:<br />\nShell</p>\n<pre><code class=\"lang-\">sudo amazon-linux-extras install docker\nsudo service docker start\n</code></pre>\n<p>然后再将 ec2-user 加入到 Docker 组:<br />\nApache</p>\n<pre><code class=\"lang-\">sudo usermod -a -G docker ec2-user\n</code></pre>\n<p>这时候需要重新登陆一下ssh,我们以后操作Docker就不用再sudo了。也可以参考官网文档:<a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/docker-basics.html\" target=\"_blank\">Docker 基本知识</a></p>\n<h4><a id=\"Amazon_Elastic_Container_Registry_148\"></a><strong>Amazon Elastic Container Registry</strong></h4>\n<p>ECR 是 Amazon 自己的 Docker 容器 Registry 仓库,通常情况下我们会使用Docker hub仓库,有时候也会建立自己的私有 Docker 仓库,例如:registry、htpasswd、nginx 配合打造的私有 Docker 容器仓库,不过这种维护成本很大,Amazon ECR 就非常方便,私密性也很好,关键为 Amazon ECS 的容器提供了一个很舒服的 Docker 镜像注册环境。<br />\n那么我就用构建一个 PostgreSQL11的镜像文件作为实例,来看看 ECR 的注册流程。<br />\n首先我们建立一个 Dockerfile->postgres.df,这个 Dockerfile 也是对 Docker hub的 Postgresql11.4版本进行了必要的中文化<br />\nDockerfile</p>\n<pre><code class=\"lang-\">FROM postgres:11.4\nRUN localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8\nENV LANG=zh_CN.utf8\nENV TZ=Asia/Shanghai\n</code></pre>\n<p>我们开始执行 Docker 镜像构建:<br />\nShell</p>\n<pre><code class=\"lang-\">docker build -t postgres_cn:11.4 -f postgres.df .\n</code></pre>\n<p><img src=\"https://dev-media.amazoncloud.cn/73ea45f887674e91bdeb74ae4ba3d361_image.png\" alt=\"image.png\" /></p>\n<p>Dockerfile 构建 PostgreSQL11.4版本效果图<br />\n当我们构建完成后,在本地的 Docker images 中就有了postgres_cn:11.4镜像,我们的重点是如何将此镜像发布到 ECR 上面去,那么紧接着就需要使用 Amazon 命令配置了,有了这项配置之后,就相当于具有了访问我的账号应用资源的授权。<br />\nShell</p>\n<pre><code class=\"lang-\">aws configure\n</code></pre>\n<p>其实就是四项需要:<strong>Access key ID、Secret access key、Region和输出格式</strong>,前两项就是我们前面创建用户时下载到 CSV 文件中的密钥,Region 就是你的 EC2所在区域,可以在 EC2 Dashboard 右上角的区域中找到对应的 region name,输出格式就是 json。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/164874f074a14d5d9d54a4f56e07e28b_image.png\" alt=\"image.png\" /></p>\n<p>aws configure 命令配置效果图<br />\n然后我们开始为 Postgres_cn 镜像创建一个 Registry 仓库:</p>\n<p>Shell</p>\n<pre><code class=\"lang-\">aws ecr create-repository --repository-name postgres_cn-repository --region us-west-2\n</code></pre>\n<p>下面就是 json 输出结果,其中的 repositoryUri 就是将本地Postgres_cn 镜像推送的地址:<br />\nJSON</p>\n<pre><code class=\"lang-\">{\n "repository": {\n "repositoryUri": "714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository", \n "imageScanningConfiguration": {\n "scanOnPush": false\n }, \n "encryptionConfiguration": {\n "encryptionType": "AES256"\n }, \n "registryId": "714394534197", \n "imageTagMutability": "MUTABLE", \n "repositoryArn": "arn:aws:ecr:us-west-2:714394534197:repository/postgres_cn-repository", \n "repositoryName": "postgres_cn-repository", \n "createdAt": 1648633165.0\n }\n}\n</code></pre>\n<p>看到上面的输出,就证明创建镜像仓库成功了,我们再接再厉,开始 tag 镜像、login 仓库、push 镜像<br />\nShell</p>\n<pre><code class=\"lang-\">docker tag postgres_cn:11.4 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\naws ecr get-login-password | docker login --username AWS --password-stdin 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\ndocker push 714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository\n</code></pre>\n<p>从下图中我们就能看到上述三项命令执行的效果。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/eacb173409e64adfb1c517055abb21d3_image.png\" alt=\"image.png\" /></p>\n<p>推送 PostgreSQL 镜像到 Amazon ECR 效果图<br />\n好了,目前 Amazon ECR 终于可以正常使用了,接下来的 PostgreSQL 镜像就也可以存在 ECR 中,方便被 Amazon ECS 的任务定义中所引用了,同时我们也可以在官网的 Docker 基本知识中获得更详细的了解。</p>\n<h3><a id=\"Amazon_ECS__217\"></a><strong>Amazon ECS 部署入门</strong></h3>\n<h4><a id=\"Amazon_ECS__218\"></a><strong>Amazon ECS 组成部分</strong></h4>\n<p>在第一章的概述中同学们会对Amazon ECS到底是什么,并且与传统ECS有什么区别有了一个基础的概念,我们这里就将这些概念再深化一下,方便后面的部署理解。<br />\n首先我们看下图,是官网的任务和计划的结构体系图,Amazon ECS 在运行过程分为了<strong>集群、服务、任务</strong>,集群主要是给出了一个逻辑上的范畴,也就是说集群范围内所启动的任务共同组成了这样一个容器为主的计算服务集群。<br />\n接着在集群内就可以创建服务,创建一个服务后,会为接下来需要运行的任务配置了种种基础环境参数,例如:启动类型、操作系统选择、平台版本、任务数量、集群 VPC、安全组等等,那么当服务运行后会通过任务计划在集群中放置任务,而任务如果出现故障停止,服务亦会监控到并启动新的任务,这就提供了一个高可靠的任务运行环境。<br />\n最后就是任务了,任务来源于任务定义,在任务定义中确定了 Docker 容器运行所需的参数、Amazon ECS 环境参数的定义、计算资源的配额、EFS等网络文件卷的配置等等容器运行所需的元信息,甚至我们可以在一个任务中配置多个容器去运行,但是 Amazon ECS 并不鼓励这样一种做法,更倾向于一个任务一个运行的容器。具体细节我们可以深入调阅官方文档:<a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/Welcome.html\" target=\"_blank\">什么是 Amazon ECS</a>?</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/3820b11bf7214d43b4ff44a9f53e9d08_image.png\" alt=\"image.png\" /></p>\n<p>Amazon ECS任务 和技术结构体系示意图</p>\n<h3><a id=\"_Amazon_ECS__227\"></a><strong>创建 Amazon ECS 部署流程</strong></h3>\n<h4><a id=\"1__ECS__228\"></a><strong>(1) 创建 ECS 集群</strong></h4>\n<p>首先我们进入<a href=\"https://us-west-2.console.aws.amazon.com/ecs/home\" target=\"_blank\">ECS主界面</a>,左栏包括了 Amazon ECS、Amazon EKS、Amazon ECR,我们主要看 Amazon ECS。点击创建集群,我们选择创建仅限联网的集群模板就可以了,后两种并非单纯的 Docker 容器组成的任务,我们创建的集群名叫:DBCluster。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/2347c7f91320443a9bc17d5ca430be3e_image.png\" alt=\"image.png\" /></p>\n<p>Amazon ECS 集群创建步骤一示意图</p>\n<h4><a id=\"2__235\"></a><strong>(2) 创建任务定义</strong></h4>\n<p>接着在任务定义入口进入后,点击创建新任务定义,启动类型分为了 Fargate、EC2、External,Fargate 是 Amazon ECS 的一项无服务技术,通俗点理解就是让我们不用去考虑基础设施中的计算资源怎样优化 ,Fargate 给你包办了,我们主要使用这个类型,Amazon EC2和外部计算服务连接这两项我们这次先暂不考虑。Fargate 的具体描述可以参考官方文档 <a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/AWS_Fargate.html\" target=\"_blank\">Amazon Fargate</a> 介绍。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/5376841b817e4361b6ccbca039988ca8_image.png\" alt=\"image.png\" /></p>\n<p>Amazon ECS 任务定义创建步骤一示意图<br />\n下一步是任务定义,我做了一个可参考的实例:</p>\n<ul>\n<li>任务定义名称:pg-run-task-definition</li>\n<li>需要兼容性:FARGATE</li>\n<li>任务角色:ecsTaskExecutionRole</li>\n<li>网络模式:awsvpc</li>\n<li>Operating system family:Linux</li>\n<li>任务执行角色:ecsTaskExecutionRole</li>\n<li>任务内存 (GB):2GB</li>\n<li>任务 CPU (vCPU):1VCPU</li>\n<li>添加卷:名称=fs-3,卷类型=EFS,文件系统ID=(选择 EFS id),访问点ID=(选择EFS 访问点 id),传输中加密:选择<br />\n添加容器</li>\n<li>容器名称*:postgres_cn-db</li>\n<li>映像*:714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository</li>\n<li>内存限制 (MiB)*:软限制=2048</li>\n<li>端口映射:5432</li>\n<li>CPU 单元数:1024</li>\n<li>环境变量:Key=POSTGRES_PASSWORD,Value=123456</li>\n<li>挂载点:源卷=fs-3,容器路径=/var/lib/postgresql/data<br />\n接着点击创建,任务定义完成后,我们看看创建后的完整Json输出,这个Json文本就是任务定义后Amazon ECS需要启动任务实例化时读取的信息,若回想一下我们一般用docker run时配置参数的场景,其实这些参数都可以囊括在这个Json文本中。<br />\n<strong>推荐大家多去了解这个 Json 的内容含义,这对于以后进入高级阶段使用 Amazon CDK 等命令方式来创建维护 Amazon ECS 集群以及基础设施环境会大有裨益。</strong><br />\nJSON</li>\n</ul>\n<pre><code class=\"lang-\">{\n "ipcMode": null,\n "executionRoleArn": "arn:aws:iam::714394534197:role/ecsTaskExecutionRole",\n "containerDefinitions": [\n {\n "dnsSearchDomains": null,\n "environmentFiles": null,\n "logConfiguration": {\n "logDriver": "awslogs",\n "secretOptions": null,\n "options": {\n "awslogs-group": "/ecs/pg-run-task-definition-1",\n "awslogs-region": "us-west-2",\n "awslogs-stream-prefix": "ecs"\n }\n },\n "entryPoint": null,\n "portMappings": [\n {\n "hostPort": 5432,\n "protocol": "tcp",\n "containerPort": 5432\n }\n ],\n "command": null,\n "linuxParameters": null,\n "cpu": 1024,\n "environment": [\n {\n "name": "POSTGRES_PASSWORD",\n "value": "123456"\n }\n ],\n "resourceRequirements": null,\n "ulimits": null,\n "dnsServers": null,\n "mountPoints": [\n {\n "readOnly": null,\n "containerPath": "/var/lib/postgresql/data",\n "sourceVolume": "fs-3"\n }\n ],\n "workingDirectory": null,\n "secrets": null,\n "dockerSecurityOptions": null,\n "memory": null,\n "memoryReservation": 2048,\n "volumesFrom": [],\n "stopTimeout": null,\n "image": "714394534197.dkr.ecr.us-west-2.amazonaws.com/postgres_cn-repository",\n "startTimeout": null,\n "firelensConfiguration": null,\n "dependsOn": null,\n "disableNetworking": null,\n "interactive": null,\n "healthCheck": null,\n "essential": true,\n "links": null,\n "hostname": null,\n "extraHosts": null,\n "pseudoTerminal": null,\n "user": null,\n "readonlyRootFilesystem": null,\n "dockerLabels": null,\n "systemControls": null,\n "privileged": null,\n "name": "postgres_cn-db"\n }\n ],\n "placementConstraints": [],\n "memory": "2048",\n "taskRoleArn": "arn:aws:iam::714394534197:role/ecsTaskExecutionRole",\n "compatibilities": [\n "EC2",\n "FARGATE"\n ],\n "taskDefinitionArn": "arn:aws:ecs:us-west-2:714394534197:task-definition/pg-run-task-definition:1",\n "family": "pg-run-task-definition",\n "requiresAttributes": [\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "ecs.capability.execution-role-awslogs"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "ecs.capability.efsAuth"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "com.amazonaws.ecs.capability.ecr-auth"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "ecs.capability.efs"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "com.amazonaws.ecs.capability.task-iam-role"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "com.amazonaws.ecs.capability.docker-remote-api.1.25"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "ecs.capability.execution-role-ecr-pull"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"\n },\n {\n "targetId": null,\n "targetType": null,\n "value": null,\n "name": "ecs.capability.task-eni"\n }\n ],\n "pidMode": null,\n "requiresCompatibilities": [\n "FARGATE"\n ],\n "networkMode": "awsvpc",\n "runtimePlatform": {\n "operatingSystemFamily": "LINUX",\n "cpuArchitecture": null\n },\n "cpu": "1024",\n "revision": 1,\n "status": "ACTIVE",\n "inferenceAccelerators": null,\n "proxyConfiguration": null,\n "volumes": [\n {\n "fsxWindowsFileServerVolumeConfiguration": null,\n "efsVolumeConfiguration": {\n "transitEncryptionPort": null,\n "fileSystemId": "fs-08359de466dce1153",\n "authorizationConfig": {\n "iam": "DISABLED",\n "accessPointId": "fsap-029ff71869daae77d"\n },\n "transitEncryption": "ENABLED",\n "rootDirectory": "/"\n },\n "name": "fs-3",\n "host": null,\n "dockerVolumeConfiguration": null\n }\n ]\n}\n</code></pre>\n<h4><a id=\"3__450\"></a><strong>(3) 创建服务</strong></h4>\n<p><strong>在开始创建 Amazon ECS 服务之前,我们先解决安全组问题,这里需要特别注意</strong>(我在这里碰了一鼻子灰)<br />\n我们在创建 EC2的时候,进入 <a href=\"https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#Instances:\" target=\"_blank\">EC2实例列表</a>,然后再进入实例,如下图所示,它会有两个安全组,其中红色框的安全组就是与 EFS 相互联通的安全组,如果你有兴趣,可以再看看 EFS 那边的安全组就一目了然啦,这就是为什么我开始创建 Amazon EC2 实例的时候先创建 EFS 并添加为该 EC2实例文件系统的原因,Amazon EC2实例创建后就会设置好与 EFS 之间访问控制的安全组,那么大家理解起更具体的安全组配置就有了参考。我就是先创建 Amazon EC2再创建 EFS,结果总是各种挂载不通,当你看懂安全组配置后,那么以后你就可以轻松驾驭 EFS 了。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/b2cb5efc711b4303ad0fa36b9652bad0_image.png\" alt=\"image.png\" /></p>\n<p>Amazon EC2实例安全组示意图<br />\n后面我们会直接将 Amazon EC2实例安全组的这条配置加入到 Amazon ECS 服务的安全组内,这样 Amazon ECS 就能和 EFS 之间就畅通无阻了,同时我们进入 <a href=\"https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#SecurityGroups:\" target=\"_blank\">EC2安全组</a>,创建一个应用于 PostgreSQL 对外服务的安全组,主要是给入站规则加上 PG 的5432端口,出站规则不变,名称为 PG-Safe。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/49aa35b426464870889bd173dde07444_image.png\" alt=\"image.png\" /></p>\n<p>创建 Amazon ECS 使用的安全组示意图<br />\n接下来在集群列表中我们就能看到 DBCluste r集群,进入以后第一项就是服务,我们点击创建,开始服务创建流程。<br />\n配置服务项我也列一下:</p>\n<ul>\n<li>启动类型:FARGATE</li>\n<li>操作系统系列:Linux</li>\n<li>任务定义:pg-run-task-definition</li>\n<li>修订:1</li>\n<li>平台版本:LATEST</li>\n<li>集群:DBCluster</li>\n<li>服务名称:PG_DB_Server</li>\n<li>服务类型:REPLICA</li>\n<li>任务数:1<br />\n下一步是网络配置</li>\n<li>集群 VPC:一定选择和 EC2、EFS 一致的 vpc,</li>\n<li>子网:如果有多个,就都选择上,最大化 ECS 容器的IP可用范围。</li>\n<li>安全组:<strong>选择现有安全组,其中选择两个安全组项,一个是新场景的PG-Safe,另一个就是上述 EC2实例中专门与 EFS 通讯的那条安全组</strong>。</li>\n</ul>\n<p><img src=\"https://dev-media.amazoncloud.cn/d98ec266a85b407e8b1b31a9489ecacd_image.png\" alt=\"image.png\" /></p>\n<p>创建 Amazon ECS 服务选择安全组示意图</p>\n<ul>\n<li>负载均衡器类型:无<br />\n然后一路下一步,创建服务即可,创建完服务后,也会同步创建好一个 Task,我们可以再任务标签页看到成功运行的情况:</li>\n</ul>\n<p><img src=\"https://dev-media.amazoncloud.cn/341ce6efffac4caa9d3074c9978ab5a5_image.png\" alt=\"image.png\" /></p>\n<p>PostgreSQL 任务运行示意图<br />\n下图的任务日志就是 PostgreSQL 启动日志输出。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/6f3e97889b4d4b1db79e76de34ffae12_image.png\" alt=\"image.png\" /></p>\n<p>PostgreSQL 任务日志示意图</p>\n<h4><a id=\"4_ECSEC2EFS_492\"></a><strong>(4) ECS、EC2、EFS关联检查</strong></h4>\n<p>但是别忘了最重要的一件事情,那就是我们要看看在 EC2实例上挂载的 EFS 文件系统是否能看到 Amazon ECS 任务启动后映射出去的文件目录(PGSQL数据目录),SSH 登陆我的 EC2实例,然后执行命令:<br />\nGroovy</p>\n<pre><code class=\"lang-\">df -Th\nsudo ls /mnt/efs/fs1/\n</code></pre>\n<p>第一条命令我们可以看到在/mnt/efs/fs1目录挂载了 nfs4类型的网络文件系统,这就是挂载了 EFS。<br />\n第二条命令,我们可以看到挂载目录下有 PostgreSQL 的数据和配置文件,这就是 Amazon ECS 任务中 PGSQL容器的路径——/var/lib/postgresql/data映射到 EFS 文件系统上的数据。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/720f4998634540498488cb02bd1656c9_image.png\" alt=\"image.png\" /></p>\n<p>Amazon EC2与 Amazon ECS 通过 EFS 共享文件示意图</p>\n<h3><a id=\"_506\"></a><strong>总结</strong></h3>\n<p>好了,今天就先聊到这里, 对于 Amazon 容器应用程序基础设施,也不仅包括了面向 Docker 的 ECS,还有特别适合入门级学习的 Amazon Lightsail,也有针对大规模服务进行容器编排的 Kubernetes,充分利用其灵活性和 Amazon 托管的安全性和弹性,具体入门指南我们可以进入官网学习<a href=\"https://aws.amazon.com/cn/getting-started/guides/deploy-containers-decision/?trk=84adbd45-91d2-4240-bd5f-358eab49cee5&sc_channel=ba\" target=\"_blank\">选择您的容器应用程序基础设施-入门指南</a><br />\n除了 Amazon ECS 的图形界面之外,其实 Amazon ECS 最大的优势还提供特别强大的命令操作工具集合,包括: <a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/getting-started-aws-copilot-cli.html\" target=\"_blank\">Amazon Copilot</a>、<a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/ECS_CLI.html\" target=\"_blank\">Amazon ECS CLI</a>、<a href=\"https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/tutorial-ecs-web-server-cdk.html\" target=\"_blank\">Amazon CDK</a> 等。这些功能可以通过非图形界面的终端命令方式、编程的方式(TypeScrpit、JavaScrpit、Python、Java、C#),更全面且细粒度的去创建与维护 Amazon ECS 基础设施,控制和优化 Amazon ECS 集群与任务。<br />\n不过这些功能的操作复杂程度也使人震惊,真的不得不佩服Amazon的技术大神们,创造了如此庞大的操作 Amazon ECS 工具集,然而对于新人来讲,一开始接触这些会烦死的!因此饭还是一口一口吃比较容易消化,大家先通过最简单界面操作方式,让 Amazon EC2 和 Amazon ECS 先能正常的运转起来。<br />\n若你是一位具有探索新知精神的极客,当你真正开始触碰到 Amazon ECS 这些高级强大的工具精髓时,那么你就会迷上它,它一种高度可扩展的技术平台,你可以基于此打造出属于自己的集群化容器自动运维体系,那么就可以从更全面且更细致的态势去感知你所运维的服务发生的一切!好吧,更高级的 Amazon ECS 探索演示以后有机会再聊。</p>\n<p>亚马逊云科技专为开发者们打造了多种学习平台:</p>\n<ol>\n<li>入门资源中心:从0到1 轻松上手云服务,内容涵盖:成本管理,上手训练,开发资源。 <a href=\"https://aws.amazon.com/cn/getting-started/?nc1=h_ls&trk=32540c74-46f0-46dc-940d-621a1efeedd0&sc_channel=el\" target=\"_blank\">Amazon 入门_ Amazon 入门使用教程_ Amazon 云计算资源-Amazon 云服务</a></li>\n<li>架构中心:亚马逊云科技架构中心提供了云平台参考架构图表、经过审查的架构解决方案、Well-Architected 最佳实践、模式、图标等。<a href=\"https://aws.amazon.com/cn/architecture/?intClick=dev-center-2021_main&trk=3fa608de-d954-4355-a20a-324daa58bbeb&sc_channel=el\" target=\"_blank\">Amazon 架构中心部署说明_Amazon 云架构白皮书-Amazon 云服务</a></li>\n<li>构建者库:了解亚马逊云科技如何构建和运营软件。<a href=\"https://aws.amazon.com/cn/builders-library/?cards-body.sort-by=item.additionalFields.sortDate&cards-body.sort-order=desc&awsf.filter-content-category=*all&awsf.filter-content-type=*all&awsf.filter-content-level=*all&trk=835e6894-d909-4691-aee1-3831428c04bd&sc_channel=el\" target=\"_blank\">Amazon Builders’ Library</a></li>\n<li>用于在亚马逊云科技平台上开发和管理应用程序的工具包:<a href=\"https://aws.amazon.com/cn/tools/?intClick=dev-center-2021_main&trk=972c69e1-55ec-43af-a503-d458708bb645&sc_channel=el\" target=\"_blank\">Amazon 工具下载_Amazon 开发工具_资源下载- Amazon 云服务</a></li>\n</ol>\n<p>【专属福利】<br />\n福利一:100余种产品免费套餐。其中,计算资源 Amazon EC2首年12个月免费,750小时/月;存储资源 Amazon S3 首年12个月免费,5GB标准存储容量。<br />\n<a href=\"https://aws.amazon.com/cn/free/?nc2=h_ql_pr_ft&all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all&trk=e0213267-9c8c-4534-bf9b-ecb1c06e4ac6&sc_channel=el\" target=\"_blank\">亚马逊 Amazon 海外区域账户免费套餐_免费云服务- Amazon 云服务</a><br />\n福利二:最新优惠大礼包,200$数据与分析抵扣券,200$机器学习抵扣券,200$微服务与应用开发抵扣券。<a href=\"https://www.amazonaws.cn/campaign/?sc_channel=el&sc_campaign=credit-acts-ldr&sc_country=cn&sc_geo=chna&sc_category=mult&sc_outcome=field&trkCampaign=request-credit-glb-ldr&trk=f45email&trk=02faebcb-3f61-4bcb-b68e-c63f3ae33c99&sc_channel=el\" target=\"_blank\">最新优惠活动_云服务器促销 - 亚马逊云科技</a><br />\n福利三:解决方案 CloudFormation 一键部署模版库<br />\n<a href=\"https://aws.amazon.com/cn/quickstart/?solutions-all.sort-by=item.additionalFields.sortDate&solutions-all.sort-order=desc&awsf.filter-tech-category=*all&awsf.filter-industry=*all&awsf.filter-content-type=*all&trk=afdbbdf0-610b-4421-ac0c-a6b31f902e4b&sc_channel=el\" target=\"_blank\">云服务解决方案部署快速入门_云服务部署- Amazon 云服务</a></p>\n"}