pig2 发表于 2023-10-23 10:38:40

在亚马逊云上部署复杂高可用生产级三层架构实战

多层架构已成为在云中设计和构建应用程序的最流行的方式。这主要是因为它们提供高可用性、复制、灵活性、安全性和许多其他好处。这与单层架构相反,单层架构通常涉及将软件应用程序的所有必需组件打包到单个服务器中。

最流行的多层设计模式是三层架构。三层架构由以下几层组成:

[*]表示层: 这是应用程序的最外层,提供与用户交互的界面。它还提供与其他层的安全通信通道。
[*]逻辑层:这是处理信息和执行应用程序逻辑的地方。它处理来自表示层的输入,并在必要时与数据层进行通信。它也称为应用层或中间件。
[*]数据层:这是数据库管理系统所在的位置,从而为它提供了一个安全、隔离的环境来存储和管理应用程序信息。

在本指南中,我们将使用三层架构设计模式在亚马逊云科技上设计一个高度容错、高度可扩展的 Flask 应用程序。

结构设计
表示层将包括:Cloudfront、弹性负载均衡器、Internet 网关、NAT 网关和两个堡垒主机。
应用程序(逻辑)层将由基于 EBS 卷的 EC2 实例组成,通过 Auto Scaling 组进行配置。
数据层将由带有只读副本的 PostgresQL 数据库组成。应用层中配置的EC2(云主机)(免费一年)实例将连接到弹性文件系统以进行数据存储。所以从技术上来说,EFS也驻留在这一层。

附赠牛叉功能

[*]AWS Route 53将用于为应用程序提供域名。
[*]我们将把ClodFront与应用程序负载均衡器集成,以提供全球范围内的加速内容交付并减少延迟。

让我们开始。
第 1 步:创建环境。首先我们将创建一个VPC。虚拟私有云是托管在公共云中的安全、隔离的网络环境。VPC 或多或少是云中的虚拟数据中心。这是我们大部分应用程序资源的托管位置。

我的 VPC 的名称标签为 project-x。这意味着在此 VPC 内创建的所有其他资源都将具有“project-x”前缀。还可以注意到,我将 CIDR 块 10.0.0.0/16 分配给我的 VPC。这是一个私有 IP 地址块,我的 VPC 资源将从中获取其本地地址。


我们的 VPC 将在三个可用区中进行配置。总共将创建 6 个子网。三个公立,三个私立。公共子网是唯一公共的,因为互联网网关将连接到它们。
另请注意,我正在创建 NAT 网关。托管我们的应用程序的 EC2 实例将使用此 NAT 网关连接到互联网(例如:用于更新)。

第2步:创建安全组
安全组就像防火墙一样,决定流量如何进入或退出实例。
由于我们的 Web 服务器将托管在逻辑层中,因此限制进入它们的流量类型非常重要。

我们的安全组的名称将为“project-x-logic-tier-sg”。
安全组必须允许端口 5000上的入站流量,因为这是 Flask 侦听的端口。



第 3 步:创建启动模板
启动模板是一种指定重要配置详细信息的方法,以便我们可以使用模板中的详细信息启动实例。自动扩展组将使用此模板在我们的应用程序层中创建实例。



我为我的模板指定了名称和描述。另请注意,我将环境适当地标记为“prod”。




我正在使用“t3.xlarge”实例类型。
请务必选择“project-x-logic-tier-sg”安全组。
保留所有其他标记不变。
在“高级详细信息”下,我将在用户数据下粘贴以下内容:
#!/bin/bash

# Mount EFS
fsname=fs-093de1afae7166759.efs.us-east-1.amazonaws.com # You must change this value to represent your EFS DNS name.
mkdir /efs
mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport $fsname:/ /efs

# install and set up Flask
apt update
apt upgrade -y
apt install python3-flask mysql-client mysql-server python3-pip python3-venv -y
apt install sox ffmpeg libcairo2 libcairo2-dev -y
apt install python3-dev default-libmysqlclient-dev build-essential -y
步骤 4:创建自动缩放组、弹性负载均衡器和目标组
负载均衡器是应用程序的入口点。驻留在表示层的
应用程序负载均衡器将通过AutoScaling 组将流量路由到驻留在逻辑层的逻辑层实例。






我将此自动缩放组命名为“project-x-asg”
单击下一步。选择我们之前创建的“ project-x-vpc ”。另请确保仅选择三个可用区域中的私有子网。这非常重要,因为我们的 VPC 将在逻辑层启动。子网不得是公共的。



单击下一步。
在“配置高级选项”下,选择“附加到新的负载均衡器”。另请选择“创建目标组”。
在下一页上,我们将配置 ASG 的最小容量为 2,所需容量为 4,最大容量为 6。我们还将根据目标跟踪指标设置扩展,以根据平均 CPU 利用率进行扩展。



你可以决定添加标签。我将添加标签名称“Environment”,值为“Prod”。在 CodeDeploy 阶段需要这样做。



创建你的 ASG。

第 5 步:附加弹性文件系统
AWS EFS是云中完全托管、高度可扩展的共享存储解决方案。它与 NFS 兼容。
这个弹性文件系统将为我们所有的应用层服务器提供共享存储。由于EFS提供存储,因此它位于三层架构的数据层。

首先创建一个新的安全组。此安全组应仅允许来自逻辑层实例的安全组的入站 NFS 流量。可以在此处获取有关如何创建该文件的详细指南 ** 转至 EFS 控制台。单击“创建文件系统* ”,然后单击“**自定义*”。



为你的 EFS 指定一个名称。将所有其他设置保留为默认值。单击“下一步”。



在网络访问页面上,选择你的project-x VPC。选择创建的EFS安全组。单击下一步。

在Filesystem Policy下,将所有内容保留为默认值。



跳到查看,然后创建文件系统。
现在我们必须更新我们的用户数据,如下所示:
#!/bin/bash

# Use Google's DNS
echo "nameserver 8.8.8.8" >> /etc/resolv.conf

# Force apt to use IPV4
apt-get -o Acquire::ForceIPv4=true update

# Change hostname
echo "project-x-app-server" > /etc/hostname

# Install efs-utils
apt-get install awscli -y
mkdir /efs
sudo apt-get -y install git binutils
git clone https://github.com/aws/efs-utils
cd /efs-utils
./build-deb.sh
apt-get -y install ./build/amazon-efs-utils*deb

# Mount EFS
fsname=$(aws efs describe-file-systems --region us-east-1 --creation-token project-x --output table |grep FileSystemId |awk '{print $(NF-1)}')
mount -t efs $fsname /efs

# Get DB credentials
DB=$(aws rds describe-db-instances --db-instance-identifier --region us-east-1 database-1 --output table |grep DBName |awk '{print $(NF-1)}')
HOST=$( aws rds describe-db-instances --db-instance-identifier --region us-east-1 database-1 --output table |grep Address |awk '{print $(NF-1)}')
ARN=$(aws secretsmanager list-secrets --region us-east-1 --filters "Key=tag-value, Values=project-x-rds-mysqldb-instance" --output table |grep ARN |awk '{print $(NF-1)}')
USER=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id $ARN --output table |grep -w SecretString |awk '{print $3}' |cut -d: -f2 |sed 's/password//' |tr -d '",')
PRE_PASSWORD=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id $ARN --output table |grep -w SecretString |awk '{print $3}' |cut -d: -f3 |tr -d '"')
PASSWORD=${PRE_PASSWORD%?}

# install and set up Flask
apt-get update -y && apt-get upgrade -y
apt-get install python3-flask mysql-client mysql-server python3-pip python3-venv -y
apt-get install sox ffmpeg libcairo2 libcairo2-dev -y
apt-get install python3-dev default-libmysqlclient-dev build-essential -y

# Clone the app
cd /
git clone https://github.com/Kelvinskell/terra-tier.git
cd /terra-tier

# Populate App with environmental variables
echo "MYSQL_ROOT_PASSWORD=$PASSWORD" > .env
cd /terra-tier/application
echo "MYSQL_DB=$DB" > .env
echo "MYSQL_HOST=$HOST" >> .env
echo "MYSQL_USER=$USER" >> .env
echo "DATABASE_PASSWORD=$PASSWORD" >> .env
echo "MYSQL_ROOT_PASSWORD=$PASSWORD" >> .env
echo "SECRET_KEY=08dae760c2488d8a0dca1bfb" >> .env # FLASK EXTENSION KEY. NOT NECESSARILY A "SECRET".
echo "API_KEY=f39307bb61fb31ea2c458479762b9acc" >> .env
# YOU TYPICALLY DON'T ADD SECRETS SUCH AS API KEYS AS PART OF SOURCE CONTROL IN PLAIN TEXT.
# THIS IS BEIGN ADDED HERE SO THAT YOU CAN EASILY REPLICATE THIS INFRASTRUCTURE WITHOUT ANY HASSLES.
# YOU CAN REPLACE IT WITH YOUR OWN MEDIASTACK API KEY.

# Setup virtual environment
cd /terra-tier
python3 -m venv venv
source venv/bin/activate

# Run Flask Application
pip install -r requirements.txt
export FLASK_APP=run.py
export FLASK_ENV=production
flask run -h 0.0.0.0你可以在此处找到文件系统的 DNS 名称。 确保更改“ fsname ”变量的值以代表自己的文件系统的 DNS 名称。




第 6 步:创建堡垒主机堡垒主机是一种特殊的服务器,用于管理对位于内部网络中的服务器或外部网络中的其他私有 AWS 资源的访问。堡垒主机位于公共网络中,为管理员提供有限的访问权限,以登录位于隔离网络中的服务器。它通常也称为跳转盒或跳转服务器。
从堡垒主机,我们将能够获得应用程序层服务器的 SSH 访问权限,以用于管理目的。
这里有一个很好的资源,介绍如何创建堡垒主机并通过它连接到逻辑层服务器。
安全警告:不再推荐使用 ssh 密钥对连接到堡垒主机。相反,请使用AWS Systems Manager来实现更安全的连接,并通过堡垒主机通过隧道到达你的私有实例。

第7步:创建数据库数据库与 Elastic 文件系统一起牢固地位于数据层。
我们的 Flask 应用程序需要连接到关系数据库。我们将使用 MYSQL 来实现此架构。
MYSQL是一个广泛使用的关系数据库管理系统(DBMS),它是免费且开源的。MYSQL 以其支持大型生产工作负载的能力而闻名,因此它适合我们的项目。
不过,我们将使用Amazon RDS for MYSQL。它是云中完全托管的数据库解决方案。在 RDS 控制台上,单击“数据库” ,然后单击“创建数据库”。



我正在选择Production模板并选择Multi-AZ DB-instance。




选择你的主用户名和数据库实例类。我们将使用 AWS SEcrets 管理器来管理我们的数据库凭证。



在“连接”下,选择project-x-vpc。单击“创建新安全组”。



创建一个安全组,仅允许来自应用层服务器安全组的端口 3306传入流量。选择安全组。在“数据库身份验证”下,选择“密码”。转到“高级选项”,在“数据库名称”下,选择“ newsreadb ”。(你必须为 Flask 应用程序选择这个确切的名称才能连接到数据库)。单击创建数据库。现在我们的架构几乎准备好了!



为了连接到数据库,我们的应用程序将对 AWS Secrets Manager 执行 API 调用,以获取数据库凭证。因此,我们必须创建一个IAM角色以允许其执行此操作。我们还将修改启动模板以将角色附加为应用程序层服务器的实例配置文件。
步骤 8:创建 IAM 角色并修改启动模板转到 IAM 仪表板并单击角色。
单击创建角色。在UseCase下,选择 EC2 并单击Next。
搜索秘密并选择弹出的权限。


单击“下一步”,然后单击“创建角色”。

接下来,我们需要修改启动模板以包含此角色,以便我们的逻辑层服务器可以假设它与 AWS Secrets Manager 进行通信。

转到 EC2 控制台,选择启动模板、操作,然后单击“修改启动模板”



转到“高级详细信息”,单击IAM 实例配置文件下的框,然后选择新创建的角色。单击“创建”。




最后,请务必将新版本设置为默认版本。




你就完成了!!!!!!
我们的三层应用程序现在应该已启动并运行。

第 9 步:访问应用程序
如果已完成所有这些步骤,那么恭喜。
现在要访问应用程序,必须访问 EC2 控制台以获取负载均衡器的域名。

转到EC2 控制台并单击负载均衡器。



复制 DNS 名称




现在将其粘贴到网络浏览器中。








就是这样。如果你已经做到了这一步,那么恭喜你。


附赠功能

现在我们将使用 AWS Route53 为我们的应用程序提供域名。最后,我们将应用程序负载均衡器与 CloudFront 集成,以加速向用户交付内容。如果你要在生产环境中运行此架构,这是必要的步骤。
第 1 步:创建域名需要一个有效的域名来完成该项目的其余部分。可以直接从Route53

步骤 2:创建托管区域
托管区域是记录容器,它定义你希望如何将流量路由到域。
要创建公共托管区域,请转至 Route53 控制台,单击托管区域并使用你的值填充字段。


步骤 3:创建 SSL 证书
SSL /TLS 证书是一种数字对象,允许系统验证身份并随后使用安全套接字层/传输层安全 (SSL/TLS) 协议建立与另一个系统的加密网络连接。AWS Certificate Manager是一项配置和管理公共和私有 SSL/TLS 证书的服务。转到证书管理器控制台并单击“请求证书”。
输入你的完全限定域名并单击“请求”。AWS 通常需要一些时间才能批准此请求,特别是如果你在 AWS 之外购买了域名。所以这里你必须要有一点耐心。


在生产环境中配置 CloudFront 发行版时,将需要此证书。
但是,由于后勤原因,我不会在这里使用 HTTPS。因此,完成该项目不需要执行此步骤。
步骤 4:创建 CloudFront 分配并与 ALB 集成
AWS CloudFront 是一个Contnet 交付网络,可以以极低的延迟在全球范围内向用户提供数据。它通过通过最近的边缘位置路由用户请求来实现此目的。
我们将 CloudFront 与 ALB 集成,以加速动态网络交付。
注意:在生产环境中,需要在 ALB 上实现 SSL 终止。但由于我们在此项目中没有使用 SSL 证书,因此你无需执行此操作即可完成后续操作。转到 CloudFront 控制台,单击“创建分配”。
选择你的应用程序负载均衡器作为源域。


选择HTTP Only。将其他字段保留为默认值。




选择“ CachingDisabled ”作为您的缓存策略。源请求策略应为AllViewer。





单击"Create Distribution"


第 5 步(最后一步):复制分发域名并粘贴到 Web 浏览器中





我们开始吧!!!!



三层架构是一种完善的软件应用程序部署模式。它们使应用程序架构具有完全的弹性、容错性和安全性。

完成此项目后,应该能够在 AWS 上设计和部署类似的架构。


页: [1]
查看完整版本: 在亚马逊云上部署复杂高可用生产级三层架构实战