前言
内容全部都为个人理解,不一定正确,如果你发现了文章中有存疑的地方或者你对某个地方有疑问,欢迎在评论区留言,大家一起学习。
在前面的实践中,我们完成了架构一和架构二的实施与部署,接下来我们就可以对课程设计附加分部分进行操作了。
题目
在完成以上所有任务过程中,如果你使用了如下资源或服务,均可作为本课程设计成绩的加分项:
1.部分静态资源(如网页上的图片等)存储在S3中,通过CloudFront分发
2.使用堡垒机登录实例
3.VPC通过CloudFormation模板构建
4.基于CloudWatch指标做AutoScaling
5.使用DynamoDB保存会话状态
6.使用Amazon ElastiCache for Redis作数据库缓存
7.使用消息队列SQS
准备工作
基础补习
老规矩,先补习基础,看懂专有名词才能完成接下来的操作
- S3 (Simple Storage Service): Amazon Simple Storage Service 是一种对象存储服务,用于存储和检索大量数据,适用于各种用例,如备份和恢复、存档、大数据分析等。
- CloudFront: Amazon CloudFront 是一项快速内容传递网络服务 (CDN),可帮助加速静态和动态网络内容的传输。
- 堡垒机: 在云计算环境中,堡垒机是一种用于安全访问云资源的中间服务器。它充当了控制和监视用户对云资源访问的关键角色。
- CloudFormation: Amazon CloudFormation 是一项基础设施即代码服务,允许您以声明性模板的方式定义和部署 AWS 资源。
- CloudWatch: Amazon CloudWatch 是一项监控和管理 AWS 资源的服务,可帮助您收集和跟踪指标、监控日志文件和设置警报。
- DynamoDB: Amazon DynamoDB 是一种全托管的 NoSQL 数据库服务,具有高可扩展性和低延迟,适用于各种应用程序。
- Amazon ElastiCache for Redis: Amazon ElastiCache for Redis 是一种托管的 Redis 内存数据库服务,用于加速读取操作,缓存数据和提高性能。
- SQS (Simple Queue Service): Amazon Simple Queue Service 是一项托管的消息队列服务,用于在分布式系统中传递消息。
思路解析
由于我一开始并没打算做这部分的操作,导致我的web程序就没办法实现上面的很多内容。但笔记都写两篇了,感觉这部分也能争取做一下。
先简单说一下接下来的操作:
✔1.部分静态资源(如网页上的图片等)存储在S3中,通过CloudFront分发:做,我打算给我的web程序加一个背景图,这个背景图就用s3存储,通过CloudFront分发
✔2.使用堡垒机登录实例:做,比如在完成架构二后,我们需要对私有子网中的EC2实例进行一些操作,就可以通过这个堡垒机来操作。
✔3.VPC通过CloudFormation模板构建:不做,因为这需要会AWS的CloudFormation语法与清楚AWS资源的相关资源代码,比较麻烦,所以我这里就不去完成这个点。但实际上这个操作实用性非常强,可以摆脱web页面上的一些操作,直接通过代码来创建相关的VPC,对云计算比较感兴趣,可以操作一下。本来是不想做的,但无奈,某个月黑风高的晚上好奇心爆棚,进CloudFormation页面看了一眼,发现已经有一个堆栈,出于强迫症,我把这个堆栈删了,睡了一觉后实验就再也开启不了了。这个堆栈是实验初始化的堆栈,删了会把堆栈之前创建出来的资源也删除,所以后面实验就会启动不了。最后被逼无奈只能对账号来一个reset操作,想了一下反正账号实验环境都格式化了,就动手做了一下这部分。
✔4.基于CloudWatch指标做AutoScaling:做,这个操作其实在前面架构二的笔记中 创建AutoScaling时就已经完成了。
❌5.使用DynamoDB保存会话状态:
❌6.使用Amazon ElastiCache for Redis作数据库缓存
❌7.使用消息队列SQS
5.6.7都不做,因为我的web应用用不上,就不进行具体得操作了,但实操中会有相对应的个人思考讲解。
实操
1.使用S3存储,通过CloudFront分发
模拟需求:给Web应用设置一个背景图片,背景图片使用使用S3存储,通过CloudFront分发。
操作步骤:创建S3存储桶-->上传背景图片-->创建CloudFront-->修改Web程序代码,重新打包上传EC2-->创建新Web应用的AMI-->修改启动模板
创建S3存储桶
进入S3控制台,创建S3存储桶,在常规配置中填写桶名称。
这里要注意,因为我们这里的要求是用s3存储内容,通过CloudFront分发,所以我们的s3桶应该只对CloudFront开放访问,所以公共访问权限应该 阻止所有公开访问。存储桶版本控制看你的需求,如果你希望你的资源能自动备份,能回溯,那就开启。我这里就默认禁用了。
然后创建即可
上传图片到S3桶中
略,这个太简单了,进去桶里上传文件就行了。
创建CloudFront
搜索CloudFront进入CloudFront控制台创建CloudFront
在源设置这里,Origin domain选择上面创建的S3桶,Origin path的意思是你希望CloudFront的源为S3中的哪个文件夹,比如Origin Path 为 /images
,这样 CloudFront 将仅缓存和提供存储桶中 images
文件夹下的内容,我这里希望CloudFront 指向整个S3,所以我这里不填。
来源访问不要设置公开,如果选择公开,这里给S3分配CloudFront 就没什么意义了。选择第二个或者第三个都可以,两者的区别在于CloudFront对S3的访问方式,有兴趣的可以自己去了解。我这里选择了第三个,没有OAI就创建一个。你也可以选择AWS推荐的第二个选项--来源访问控制设置,但这样,需要你在CloudFront创建后手动修改S3桶的存储桶策略(放心,不需要你去写,这个存储桶策略会在你创建完CloudFront后在顶部给你提示出来,你只需要复制粘贴到对应的S3桶的存储桶策略);
而选择第三个--Legacy access identities,AWS会自动给你选择的S3桶配置存储桶策略。(所以我这里图方便,我选择了第三个选项,但第二个选项我也创建过,然后手动配置策略,我推荐你也试试)
Enable Origin Shield直接默认否。
默认缓存行为和函数关联 不动,默认即可。或者你按需设置
我觉得WAF保护作用不大,我这选择关闭
这部分根据需求自定义,比如你希望这个CloudFront能绑定你自己的域名,能通过你自己的域名来访问,那么你就得在备用域名那增加上你的域名,然后上传或者创建你的域名证书,并且把你的域名CNAME解析到AWS给你分配的主域名;比如你觉得你的CloudFront并不需要给IPv6提供服务,那么就像我这样关闭IPv6的解析服务。当然,你这部分直接默认也可以。
然后完成创建即可
访问测试
等CloudFront部署完成(上次修改时间那显示时间就是部署完成了,显示 部署 就是在部署中),即可进行访问测试。图示有两个CloudFront,是因为上面两种不同的来源访问 我都创建了一个,并且都分配给了同一个S3桶,你上面创建有一个CloudFront就行了。
复制分配的CloudFront域名
在域名后加上S3桶中的文件路径即可完成访问,比如我的图片存在S3根目录下,文件名为background.jpg。
然后,你可以尝试在S3桶中复制对象的URL在浏览器打开,访问失败,那么我们就成功完成了AWS中的相关配置。接下来就是修改代码,重新打包程序发布了。
修改Web程序代码,重新打包上传EC2
因为距离最终的检查还有一段时间,这个CloudFront不一定就是我最终检查使用的那一个,所以我接下来打算把这个CloudFront的host放到配置文件application.yml文件中,实现动态配置。(实际上,如果只是背景图其实是可以直接在html中写死url的,但如果你的项目中使用了很多图片等静态资源,那么我还是建议把url中host部分抽离到配置文件中)
application.yml文件中新增custom.s3CloudFrontHost字段
在
中加入css内联样式。通过${@environment.getProperty('custom.s3CloudFrontHost')}
读取我们刚刚在上面application.yml文件中新增的custom.s3CloudFrontHost
属性。(爆红也别怕,我这里使用的thymeleaf,idea的语法检查当纯html检查了)然后再修修样式,加个卡片,防止背景和文字混在一起看不清。
完美,程序成功运行。重新打包上传EC2就不演示了,可以看架构一笔记中的操作。
创建新Web应用的AMI
很简单,如图所示
修改启动模板
EC2控制台,进入启动模板页,选择之前创建的启动模板,操作->修改模板
只需在要这里的AMI设置选择上面新建的AMI就行,其他配置不变。
访问负载均衡器,难搞喔,显示的内容怎么还是原来的版本,怎么没有自动更新?是缓存?还在构建新实例?
修改Auto Scaling 组
答案是,前面我们在创建Auto Scaling 组的时候选择启动模板,选择的版本是Default,Default版本,如果你不去改变它,那么就默认为1版本,而我们上面对启动模板进行了修改,修改后的版本为2,所以Auto Scaling 组还在使用着原来版本的AMI。
那么接下来就是要让Auto Scaling 组能启动到我们刚刚新建的AMI,那么有2种办法。两种办法的依据是不一样,看你这个Auto Scaling 组的定位来决定。
第一种方案
比如我现在这个Auto Scaling 组,已经确定了是生产环境下的了,那么我们可以对启动模板版本的Default进行修改,把Default设置成需要的版本,比如这里我需要它设置为2,
第二种方案
还有一种情况,就是我这个Auto Scaling 组是在开放环境下运行,我希望实例都是用的最新版本启动模板,那么我们就对Auto Scaling 组中启动模板的配置进行修改,把启动模板版本的配置改成Latest,那么Auto Scaling 组以后就会使用最新版本的启动模板来启动实例。
启动实例刷新
一般情况下,无论是修改启动版本的版本还是修改Auto Scaling 组绑定的启动模板版本,Auto Scaling 组都无法立刻对正在运行的实例进行更新,这个更新只会影响到以后的实例,而不会应用到已在运行的实例。所以如果就需要以下操作,来启动实例刷新
进入相关的Auto Scaling 组详情页,启动实例刷新
替换方案按照提示,根据你的需求来,我这里选择了第一个。
关掉跳过匹配,因为我们需要他根据新版本启动模板来启动新实例,所以不能跳过匹配。
所需的配置部分默认即可,因为我们已经对启动模板的默认版本进行了修改。
然后启动,Auto Scaling 组就会自动完成实例的更新。
再次访问负载均衡器的URL,成功访问最新版本的Web应用,并且背景图为CloudFront分发的S3桶对象。
2.使用堡垒机登录实例
模拟需求:在架构二中,我们使用Auto Scaling 组在私有子网中创建了若干个EC2实例,由于这些实例都是在私有子网上运行,那么我们就无法通过互联网连接到这些EC2实例上,那么这就需要堡垒机来做跳板(所以堡垒机又称跳板机),我们可以通过这个部署在公有子网的堡垒机连接私有子网的实例。
操作步骤:创建与修改安全组->创建堡垒机实例->创建实例连接
创建与修改安全组
在安全组标签页新建安全组
VPC选择我们创建的那个
增加一个入站规则,端口为22,源看情况。比如你的设备ip是固定的ip段,那么你就可以设置为固定的ip段,而我不确定我的网络情况,所以我这里设置了0.0.0.0,全开放。
出站规则的目标,我们这里是可以确定的,因为我这里的堡垒机作用就是连接Auto Scaling 组在私有子网中创建的那若干个EC2实例,那么这个目标就可以设置成这些实例绑定的安全组。
创建了堡垒机的安全组,那么还需要修改Auto Scaling 组创建的那若干个EC2实例绑定的安全组,使其对堡垒机开放。新增一个入站规则,端口为22,源设置为上面创建的堡垒机安全组
创建堡垒机实例
名称随意,AMI默认的Amazon Linux 2023就行
实例类型默认即可,或者选择最便宜的就行,因为我们只需要这个实例做跳板。密钥对默认,懒得下载配置。
VPC选择我们创建的,子网一定要选择公有子网,两个公有子网都无所谓;分配公有ip;安全组选择上面我们新建的堡垒机安全组。
登录私有实例
我这里以FinalShell为例,其他ssh也行,原理一样,触类旁通。
创建堡垒机隧道
复制堡垒机的公有IP地址
FinalShell里新建一个shh连接,先把常规内容填好,别点确定。
回到浏览器,选择Auto Scaling 组创建的实例,复制私有的IP地址
点击 隧道 新增一个隧道,名称随意;类型:本地;
监听端口:填你电脑未被占用的端口;
绑定ip:默认的127.0.0.1就行;
目标地址:上面复制的私有ip地址;目标端口:22。
然后确定新建隧道,确定新建连接。
创建私有实例连接
新建一个ssh连接,主机那里的ip部分填127.0.0.1;端口填上面堡垒机上的隧道中设置的端口;其他照常即可。
测试堡垒机连接
先连接我们的堡垒机,看登录信息,显示登录ip为电脑ip地址。
再连接私有EC2实例,可以看到登录的ip为局域网ip,一致堡垒机的私有ip一致。这就完成了堡垒机登录私有子网中实例的操作,同理,你也可以登录到私有子网中另一个实例,只需要对堡垒机的连接进行编辑,新增对应的隧道即可。
3.通过CloudFormation模板构建VPC
写CloudFormation模板
想使用CloudFormation模板来完成创建VPC这个操作,得先弄清楚CloudFormation模板的基本结构。那么不妨看一下官方文档的介绍。
使用 AWS CloudFormation 模板 - AWS CloudFormation (amazon.com)
我个人来说,更推荐使用YAML格式,更简洁。主要要了解的是这个 模板部分 ,这样你才能看得懂这yaml中到底在描述着什么。(这些蓝色标题是这个yaml的组成部分,在yaml中是英文的,别傻乎乎在yaml写什么“元数据”、“条件”,这AWS估计用的机翻,都给翻译过来了)
下面是我根据实验需求写的关于VPC的CloudFormation模板。如果你需要完成下面创建堆栈的操作,那么你需要在你电脑插件一个xxx.yaml文件,然后把我下面的这个CloudFormation模板复制进去。
# 描述
Description: "Create a VPC with two public and two private subnets, as well as corresponding routing tables and NAT gateways."
# 参数变量部分,创建堆栈时,可进行填写
Parameters:
VpcCIDR:
Type: String
Default: "10.0.0.0/16"
Description: "Please enter the CIDR for this VPC"
PublicSubnet1CIDR:
Description: "Please enter the CIDR for the public subnet"
Type: String
Default: "10.0.0.0/24"
PublicSubnet2CIDR:
Description: "Please enter the CIDR for the public subnet"
Type: String
Default: "10.0.2.0/24"
PrivateSubnet1CIDR:
Description: "Please enter the CIDR for the private subnet"
Type: String
Default: "10.0.1.0/24"
PrivateSubnet2CIDR:
Description: "Please enter the CIDR for the private subnet"
Type: String
Default: "10.0.3.0/24"
# 资源部分
Resources:
# VPC
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
# 互联网网关
InternetGateway:
Type: AWS::EC2::InternetGateway
# 网关关联
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref InternetGateway
# 公有子网1
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
# 可用区选择
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet1CIDR
# 公有子网2
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: !Select [ 1, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet2CIDR
# 私有子网1
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet1CIDR
# 私有子网2
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: !Select [ 1, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet2CIDR
# 弹性IP
NatGatewayEIP:
Type: AWS::EC2::EIP
DependsOn: VPCGatewayAttachment
Properties:
Domain: vpc
# NAT网关
NATGateway:
Type: AWS::EC2::NatGateway
Properties:
# 给NAT网关授权上面这个弹性IP
AllocationId: !GetAtt NatGatewayEIP.AllocationId
SubnetId: !Ref PrivateSubnet1
# 公有路由表
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
# 私有路由表
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
# 给公有路由表关联互联网网关
DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: VPCGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
# 公有路由表关联公有子网1
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
# 公有路由表关联公有子网2
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
# 给私有路由表关联NAT网关
DefaultPrivateRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref NATGateway
# 私有路由表关联私有子网1
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref PrivateRouteTable
# 私有路由表关联私有子网2
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref PrivateRouteTable
创建堆栈
进入CloudFormation操作台,这里已经有一个堆栈了,别动它,这个是账号实验环境初始化的堆栈,你第一次启动实验为什么慢,就是因为在运行这个堆栈。不管这个堆栈,我们新建一个堆栈。
选择上传模板文件,把上面保存的ymal文件上传上去
这里其实已经不用怎么改了,因为其实在ymal中,我就已经预设好了。
选一下IAM角色,把我们的LabRole加进去,相当于给这个堆栈授权。这个操作相当于在linux中授权root用户,所以这个操作实际上是不安全的,但我们自己写的CloudFormation模板,我们知道这些操作基本不会造成什么不可逆的影响(实际上是我懒得去新建角色)。其他配置默认,然后下一步提交即可。
然后点开这个新建的堆栈,打开资源页,即可看到堆栈在创建我们yaml中定义的资源。
进入VPC页面,查看创建的VPC资源地图,创建成功,后续就可以在这个VPC上完成相关操作了。
4.基于CloudWatch指标做AutoScaling组
我们在架构二中创建AutoScaling组时就已经完成这个操作了,具体你也可以进入EC2页面中AutoScaling组标签页看里面配置的动态扩展策略,图中这个策略就是根据CloudWatch指标做的动态扩展策略,这个策略表示:Amazon EC2 Auto Scaling 会根据需要启动和终止 EC2 实例,以将组中所有实例的累计 CPU 使用率保持在 80%。当然你也可以新建更多的策略来规划AutoScaling组的弹性伸缩。
5.Amazon ElastiCache for Redis、DynamoDB、SQS
关于这三者,我上面也说了,我的实验应用用不到,所以就不进行操作了。
Amazon ElastiCache for Redis是我比较推荐在这个实验中使用的,因为这个简单!因为Redis是一个开源的软件,它有一套公共认可的统一的开发规范,而且Spring Boot就集成了Redis的控制类,直接就能通过maven导入到项目中,然后像使用MySQL数据库一样,在配置文件设置相关参数即可。如果你想在你的项目中使用,只需要在Amazon ElastiCache中创建一个Redis实例,然后把程序中配置文件的参数修改成这个实例的参数,和迁移MySQL数据库的操作基本一致。
剩下的DynamoDB与SQS,如果你想在你的项目中集成就会有一点点难,因为这两个服务在AWS是无服务器类的资源,你想集成到你的程序中,你得在你的项目中使用AWS官方提供的SDK,你需要使用AWS提供的规范,就比较难受了,因为这样就需要你通过对文档和DEMO进行研究。下面是我找到的一些文档与DEMO,如果你有兴趣,也可以研究一下。
aws-doc-sdk-examples/javav2 at main · awsdocs/aws-doc-sdk-examples (github.com)