aws(学习笔记第三十四课) dockerized-app with asg-alb
aws(学习笔记第三十四课) dockerized-app with asg-alb
- 使用
cdk生成dockerized-app并使用AutoScalingGroup和ApplicationLoaderBalancer
学习内容:
- 使用
cdk生成dockerized-app并使用AutoScalingGroup和ApplicationLoaderBalancer - 在
AutoScalingGroup中使用efs以及RDS
1. 整体架构
1.1 代码链接
代码链接(docker-app-with-asg-alb)
1.2 代码手动修改部分
这里的代码没有完全实现是理想的部署就能运行,需要修改几个地方。
1.2.1 rds_stack.py
修改instance_type=ec2.InstanceType.of这里的参数。不修改的话创建数据库运行失败。
修改后的代码:
from aws_cdk import (aws_rds as rds,aws_ec2 as ec2,RemovalPolicy, Stack)
from constructs import Constructclass RDSStack(Stack):def __init__(self, scope: Construct, id: str, props, **kwargs) -> None:super().__init__(scope, id, **kwargs)# Creates a security group for AWS RDSsg_rds = ec2.SecurityGroup(self,id="sg_rds",vpc=props['vpc'],security_group_name="sg_rds")# Adds an ingress rule which allows resources in the VPC's CIDR# to access the database.sg_rds.add_ingress_rule(peer=ec2.Peer.ipv4("10.0.0.0/16"),connection=ec2.Port.tcp(3306))# Master username is 'admin' and database password is automatically# generated and stored in AWS Secrets Managermy_sql = rds.DatabaseInstance(self, "RDS",engine=rds.DatabaseInstanceEngine.mysql(version=rds.MysqlEngineVersion.VER_8_0_39),vpc=props['vpc'],port=3306,instance_type=ec2.InstanceType.of(ec2.InstanceClass.R7G,ec2.InstanceSize.LARGE,),removal_policy=RemovalPolicy.DESTROY,security_groups=[sg_rds])
1.2.2 efs_stack.py
修改了efs创建和security group的创建顺序

修改后的代码:
from aws_cdk import (aws_efs as efs,aws_ec2 as ec2,Stack)
from constructs import Constructclass StorageStack(Stack):def __init__(self, scope: Construct, id: str, props, **kwargs) -> None:super().__init__(scope, id, **kwargs)sg_efs = ec2.SecurityGroup(self,id="sg_efs",vpc=props['vpc'],security_group_name="sg_efs")sg_efs.add_ingress_rule(peer=ec2.Peer.ipv4("10.0.0.0/16"),connection=ec2.Port.tcp(2049))elasticfilestore = efs.CfnFileSystem(self, "efs-storage",encrypted=False,lifecycle_policies=None# security_group_ids=[sg_efs.security_group_id])
1.2.3 asg_stack.py
这里主要是因为AutoScalingGroup默认使用的是config方式来创建,但是最新版aws已经不支持config方式,这里主要改成launchTemplate方式。而且AutoScalingGroup启动的ec2是在private subnet,因此,需要public ec2进行访问,这里Allows only the IP of "123.123.123.123"换成自己的公网的ec2。

from aws_cdk.aws_ec2 import SubnetType
from aws_cdk import (aws_ec2 as ec2,aws_autoscaling as autoscaling,aws_elasticloadbalancingv2 as elbv2,Stack)
from constructs import Constructclass ASGStack(Stack):def __init__(self, scope: Construct, id: str, props, **kwargs) -> None:super().__init__(scope, id, **kwargs)userdata_file = open("./userdata.sh", "rb").read()# Creates a userdata object for Linux hostsuserdata = ec2.UserData.for_linux()# Adds one or more commands to the userdata object.userdata.add_commands(str(userdata_file, 'utf-8'))# Creates a security group for our applicationsg_nextcloud = ec2.SecurityGroup(self,id="sg_nextcloud",vpc=props['vpc'],security_group_name="sg_nextcloud")# Allows only the IP of "123.123.123.123"# to access this security group for SSHsg_nextcloud.add_ingress_rule(peer=ec2.Peer.ipv4("18.183.236.249/32"),connection=ec2.Port.tcp(22))# create launch templatelaunch_template = ec2.LaunchTemplate(self, "MyLaunchTemplate",machine_image=ec2.AmazonLinuxImage(generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2),instance_type=ec2.InstanceType.of(ec2.InstanceClass.MEMORY5, ec2.InstanceSize.XLARGE),security_group=sg_nextcloud,user_data=userdata,key_name="***", # )asg = autoscaling.AutoScalingGroup(self,"app-asg",vpc=props['vpc'],vpc_subnets=ec2.SubnetSelection(subnet_type=SubnetType.PRIVATE_WITH_NAT),launch_template=launch_template,min_capacity=1,max_capacity=3,)# Creates a security group for the application load balancersg_alb = ec2.SecurityGroup(self,id="sg_alb",vpc=props['vpc'],security_group_name="sg_alb")# Allows connections from security group "sg_alb"# inside the "sg_nextcloud" security group to access port 8080# where our app listenssg_nextcloud.connections.allow_from(sg_alb, ec2.Port.tcp(8080), "Ingress")# Creates an application load balancelb = elbv2.ApplicationLoadBalancer(self,"ALB",vpc=props['vpc'],security_group=sg_alb,internet_facing=True)listener = lb.add_listener("Listener", port=80)# Adds the autoscaling group's (asg) instance to be registered# as targets on port 8080listener.add_targets("Target", port=8080, targets=[asg])# This creates a "0.0.0.0/0" rule to allow every one to access the# applicationlistener.connections.allow_default_port_from_any_ipv4("Open to the world")
1.2.4 userdata.sh
这里主要修改docker-compose的版本,因为太低的版本已经不支持了。
另外DB的设置,要根据实际的RDSStack创建的DB进行重新设置。后面会详细说明。

#!/bin/shyum install docker -y
yum install -y amazon-efs-utils# makes a directory
mkdir /nextclouddata
mount -t efs fs-d48c7f8c:/ /nextclouddata# enable and start docker
systemctl enable docker
systemctl start docker# bootstraps "docker compose"
yum install libxcrypt-compat
curl -L "https://github.com/docker/compose/releases/download/v2.34.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
usermod -aG docker ec2-user# Gets local-persist
curl -fsSL https://raw.githubusercontent.com/CWSpear/local-persist/master/scripts/install.sh | bash
docker volume create -d local-persist -o mountpoint=/nextclouddata/nextcloud-data --name=nextcloud-data# Heredoc for a docker-compose.yaml file
cat << 'EOF' > /home/ec2-user/docker-compose.yaml
version: '2'volumes:nextcloud-data:external: trueservices:app:image: nextcloudports:- 8080:80volumes:- nextcloud-data:/var/www/htmlrestart: alwaysenvironment:- MYSQL_DATABASE=nextcloud- MYSQL_USER=admin- MYSQL_PASSWORD=bflbfl1980314- MYSQL_HOST=nextcloud.csetrrtzbxti.ap-northeast-1.rds.amazonaws.com
EOFdocker-compose -f /home/ec2-user/docker-compose.yaml up
1.2 整体架构

这里,整体的架构已经被分为四个stack,并且其他三个stack都依赖NetworkStack。

- 首先构建网络,
VPC和public subnet以及private subnet,之后构筑MySQL数据库,以及EFS存储,最后构建AutoScalingGroup以及ApplicationLoaderBalancer。AutoScalingGroup需要每个主机共享存储,所以需要构建EFS。
2.代码解析
2.1 全体app.py
props = {'namespace': 'NetworkStack '}
app = App()
ns = NetworkStack(app, "NetworkStack", props)rds = RDSStack(app, "RDSStack", ns.outputs)
rds.add_dependency(ns)asg = ASGStack(app, "ASGStack", ns.outputs)
asg.add_dependency(ns)efs = StorageStack(app, "StorageStack", ns.outputs)
app.synth()
每个stack独立定义,都可以独立执行,也可以-all进行执行。
cdk --require-approval never deploy -all
cdk --require-approval never deploy NetworkStack
cdk --require-approval never deploy RDSStack
cdk --require-approval never deploy StorageStack
cdk --require-approval never deploy ASGStack
注意,这里后三个stack依赖NetowokStack。
2.2 NetworkStatck网络
class NetworkStack(Stack):def __init__(self, scope: Construct, id: str, props, **kwargs) -> None:super().__init__(scope, id, **kwargs)# Subnet configurations for a public and private tiersubnet1 = SubnetConfiguration(name="Public",subnet_type=SubnetType.PUBLIC,cidr_mask=24)subnet2 = SubnetConfiguration(name="Private",subnet_type=SubnetType.PRIVATE_WITH_NAT,cidr_mask=24)vpc = Vpc(self,"TheVPC",cidr="10.0.0.0/16",enable_dns_hostnames=True,enable_dns_support=True,max_azs=2,nat_gateway_provider=NatProvider.gateway(),nat_gateways=1,subnet_configuration=[subnet1, subnet2])# This will export the VPC's ID in CloudFormation under the key# 'vpcid'CfnOutput(self, "vpcid", value=vpc.vpc_id)# Prepares output attributes to be passed into other stacks# In this case, it is our VPC and subnets.self.output_props = props.copy()self.output_props['vpc'] = vpcself.output_props['subnets'] = vpc.public_subnets@propertydef outputs(self):return self.output_props

这里构建如下:
- 构建整个
vpc - 构建一个
public subnet - 构建一个
private subnet - 将
vpc和subnet作为props参数保存起来。
2.3 MySQL数据库
class RDSStack(Stack):def __init__(self, scope: Construct, id: str, props, **kwargs) -> None:super().__init__(scope, id, **kwargs)# Creates a security group for AWS RDSsg_rds = ec2.SecurityGroup(self,id="sg_rds",vpc=props['vpc'],security_group_name="sg_rds")# Adds an ingress rule which allows resources in the VPC's CIDR# to access the database.sg_rds.add_ingress_rule(peer=ec2.Peer.ipv4("10.0.0.0/16"),connection=ec2.Port.tcp(3306))# Master username is 'admin' and database password needs to be set after creationmy_sql = rds.DatabaseInstance(self, "RDS",engine=rds.DatabaseInstanceEngine.mysql(version=rds.MysqlEngineVersion.VER_8_0_39),vpc=props['vpc'],port=3306,instance_type=ec2.InstanceType.of(ec2.InstanceClass.R7G,ec2.InstanceSize.LARGE,),removal_policy=RemovalPolicy.DESTROY,security_groups=[sg_rds])
构建的为绿框的部分。

主要构建如下:
- 为
RDS构建一个SecurityGroup - 设定
ingress_rule - 之后构建
RDS数据库
2.4 创建efs
因为AutoScalingGroup启动的多个ec2 instance都需要将/var/www/html使用相同的磁盘进行存储,所以要创建efs实现各个AutoScalingGroup启动的多个ec2 instance共享磁盘。
from aws_cdk import (aws_efs as efs,aws_ec2 as ec2,Stack)
from constructs import Constructclass StorageStack(Stack):def __init__(self, scope: Construct, id: str, props, **kwargs) -> None:super().__init__(scope, id, **kwargs)sg_efs = ec2.SecurityGroup(self,id="sg_efs",vpc=props['vpc'],security_group_name="sg_efs")sg_efs.add_ingress_rule(peer=ec2.Peer.ipv4("10.0.0.0/16"),connection=ec2.Port.tcp(2049))elasticfilestore = efs.CfnFileSystem(self, "efs-storage",encrypted=False,lifecycle_policies=None# security_group_ids=[sg_efs.security_group_id])

从ec2对efs进行mount如下图所示:

2.4 对efs创建mount target
aws(学习笔记第十一课) 使用AWS的EFS,以及AWS Storage Gateway,这里也对efs进行了详细的介绍。在ec2对efs进行mount之前,需要对其创建挂载目标mount target。可以认为,efs就是创建了一块磁盘,而创建挂载目标mount target就是对这块磁盘,又绑定了一个nfs server。

3.部署执行
3.1.部署NetworkStack
cdk --require-approval never deploy NetworkStack
3.2.部署RDSStack
cdk --require-approval never deploy RDSStack
3.3.部署StorageStack
cdk --require-approval never deploy StorageStack
3.4 修改userdata.sh文件
根据生成的DB和efs的具体值,重新设置userdata.sh文件。

3.5 最后部署ASGStack
cdk --require-approval never deploy ASGStack
相关文章:
aws(学习笔记第三十四课) dockerized-app with asg-alb
aws(学习笔记第三十四课) dockerized-app with asg-alb 使用cdk生成dockerized-app并使用AutoScalingGroup和ApplicationLoaderBalancer 学习内容: 使用cdk生成dockerized-app并使用AutoScalingGroup和ApplicationLoaderBalancer在AutoScalingGroup中使用efs以及R…...
嵌入式c学习七
c语言指针:程序需要载入内存中运行,在32bit系统中内存地址的范围是:0x0000 0000-0xFFFF FFFF,内存大小为4GB,内存地址指的是内存单元的编号是固定的,本身就是一个整数,对于32bit系统,…...
Selenium Web UI自动化测试:从入门到实战
引言 在当今快速迭代的软件开发周期中,自动化测试已成为保障产品质量、提升测试效率的核心手段之一。而针对Web应用的UI自动化测试,Selenium作为最流行的开源工具之一,凭借其跨浏览器、多语言支持(Python、Java、C#等)…...
【实战指南】用MongoDB存储文档和图片等大文件(Java实现)
一、前言 在现代应用开发中,经常需要处理和存储大量的文档、图片等大文件。传统的关系型数据库在处理这类大文件时,往往会面临性能瓶颈、存储成本高等问题。而 MongoDB 作为一款流行的 NoSQL 数据库,提供了 GridFS 规范,能够很好地解决大文件存储的问题。GridFS 可以将大文…...
Jetpack Compose 显示时间
Jetpack Compose 显示时间 介绍主体代码使用 介绍 在软件中实时显示时间 主体代码 import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStat…...
vue3中,通过获取路由上的token直接进入首页,跳过登录页面
1.需求 A系统想快速进入到B系统,但又不想输入账号密码,A系统的token与B系统共用token,因此在访问B系统就会在路径上携带token(https://magictool-box.com/login?token《token》),通过token直接进入B系统首…...
软考通关利器:中级软件设计师结构化开发核心考点
简介: 作为国家软考中级认证的核心科目,“软件设计师” 结构化开发能力是职业进阶的黄金敲门砖。本模块聚焦考试大纲高频考点,深度解析需求建模、结构化分析方法(SA/SD)、模块设计原则、数据流图(DFD&#…...
[思考记录]两则:宏观视角、理想化
#宏观视角# 昨天听金老师讲解了他初步整理的大模型宏观概念关系图,受益不少。图上不仅是涵盖了诸多概念,更厉害的应该在于把概念之间的关系进行了描述,更直观展现了概念是如何与其他概念相互作用的。帮助从整体的角度去理解,以及透…...
MySQL 性能优化方向
MySQL 性能优化是一个系统性的工作,涉及数据库设计、查询优化、索引优化、硬件配置等多个方面。以下是 MySQL 性能优化的主要方向和具体优化方案: 一、数据库设计优化 1. 合理设计表结构 规范化设计:避免数据冗余,确保数据一致性。适度反规范化:在查询频繁的场景下,适当…...
3-22 vector的使用详解---STL C++
C中的vector容器展开系统讲解,具体内容如下: 1. vector的定义和特性(基础概念) 讲解vector作为动态数组的核心特性:自动内存管理、动态扩容机制(倍增策略)对比普通数组:支持随机访…...
Collectors.toList / list 转 list
前言 略 Collectors.toList List<User> userList ...; List<Long> userIdList userList.stream().map(User::getUserId).collect(Collectors.toList());...
uniapp 和 webview 之间的通信
1.背景 应用使用了uniapp开发跨端应用,在uniapp中内嵌webview页面实现页面热更新效果,不需要用户单独重新安装软件即可实现页面的版本更新。 2.webview通知uniapp 在开发过程中我们难会遇到需要uniapp和webview来实现数据通信的场景,接下来…...
【Linux】Hadoop-3.4.1的伪分布式集群的初步配置
配置步骤 一、检查环境 JDK # 目前还是 JDK8 最适合 Hadoop java -version echo $JAVA_HOME Hadoop hadoop version echo $HADOOP_HOME 二、配置SSH免密登录 Hadoop需要通过SSH管理节点(即使在伪分布式模式下) sudo apt install openssh-server …...
【Java】深入了解下Java Bitset
【Java】深入了解下Java Bitset 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战 目录 【Java】深入了解下Java Bitset引言如果Java Bitset不是布尔数组,那它是什么…...
Linux CentOS7 安装 ffmpeg教程
官网:FFmpeg 操作 先用uname -a 查看内核版本,如果是 3.2.0或者以上就可以按照此办法来安装 cd /tmp wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz# 2. 解压 tar xvf ffmpeg-release-amd64-static.tar.xz# 3. 将…...
楼宇自控系统的结构密码:总线与分布式结构方式的差异与应用
在现代建筑中,为了实现高效、智能的管理,楼宇自控系统变得越来越重要。它就像建筑的 智能管家,可自动控制照明、空调、通风等各种机电设备,让建筑运行更顺畅,还能节省能源成本。而在楼宇自控系统里,有两种关…...
Fourier-Lerobot——把斯坦福人形动作策略iDP3封装进了Lerobot(含我司七月人形研发落地实践)
前言 近期在抠lerobot源码时,看到其封装了ALOHA ACT、diffusion policy、π0时,我就在想,lerobot其实可以再封装下idp3 我甚至考虑是否从我联合带的那十几个具身研究生中选几个同学做下这事,对他们也是很好的历练然当25年3.18日…...
系统架构设计知识体系总结
1.技术选型 1.什么是技术选型? 技术选型是指评估和选择在项目或系统开发中使用的最合适的技术和工具的过程。这涉及考虑基于其能力、特性、与项目需求的兼容性、可扩展性、性能、维护和其他因素的各种可用选项。技术选型的目标是确定与项目目标相符合、能够有效解…...
计划管理工具应该具备的能(甘特图)
在当今快节奏的项目管理环境中,高效地规划和跟踪项目进度是至关重要的。甘特图,作为项目管理领域的经典工具,以其直观的时间轴和任务分配方式,深受项目管理者的青睐。 随着数字化时代的到来,甘特图线上编辑器应运而生&…...
简单实用!百度AI + Raphael AI = 免费生图
简单实用!百度AI Raphael AI 免费生图 --  第一步:下载或截取一些好看的图片当参考图片 第二步:用百度AI描述你想要的图片&…...
2 相交链表
1 常规思路 比较两个链表的长度,然后让较短的链表走二者长度之差,此时两个链表就一样长了,开始用双指针遍历,如果有相等返回,没有返回null; 为了减少冗余代码,我们设置一个minCur和maxCur分别…...
2025-03-22 学习记录--C/C++-C 库函数 - getchar()
C 库函数 - getchar() ⭐️ C 标准库 - <stdio.h> (一)、函数声明 🍭 int getchar(void)从标准输入 stdin 获取一个字符(一个无符号字符)。 参数:🎀 NA 返回值:Ἰ…...
APM 仿真遥控指南
地面站开发了一段时间了,由于没有硬件,所以一直在 APM 模拟器中验证。我们已经实现了 MAVLink 消息接收和解析,显示无人机状态,给无人机发送消息,实现一键起飞,飞往指定地点,降落,返…...
如何防止大语言模型生成有害内容?技术与非技术手段解析
目录 如何防止大语言模型生成有害内容?技术与非技术手段解析 1. 技术手段 方法 1:使用内容过滤(Content Filtering) 方法 2:基于模型的有害内容检测(Toxicity Classification) 方法 3&#…...
BBR 和 CUBIC 对长肥管道的不同反应
有个关于 CUBIC(等一众 AIMD-based cc) 和 BBR 在长肥管道中的行为比较挺有趣,它们的表现竟然截然相反: CUBIC 流共存,RTT 越大,Goodput 越低;BBR 流共存,RTT 越大,Goodput 越高。 前一个被看…...
架构师面试(十九):IM 架构
问题 IM 系统从架构模式上包括 【介绍人模式】和 【代理人模式】。介绍人模式也叫直连模式,消息收发不需要服务端的参与,即客户端之间直连的方式;代理人模式也叫中转模式,消息收发需要服务端进行中转。 下面关于这两类模式描述的…...
Spring框架入门指南:从Hello World到IOC容器
第一章:Spring框架的介绍 1. Spring框架的概述 Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。 Spring是于2003 年兴起的一个轻量级的Java开发框架&…...
嵌入式电路设计软件个人安装步骤分享
各位小伙伴大家好,今天给大家分享一个,电路设计软件的安装方法,希望对大家有所帮助。 一、下载【Multisim14.0安装包】: 链接:夸克网盘分享 提取码:kHSP 电脑安装Multisim14.0并且汉化 准备安装包以及汉化包双击“NI_Circuit_Design_Suite_14_0【海量免费资源:kebaiwan…...
git | 回退版本 并保存当前修改到stash,在进行整合。[git checkout | git stash 等方法 ]
目录 一些常见命令: git 回退版本 一、临时回退(不会修改历史,可随时回到当前版本) 方法1:git checkout HEAD~1 二、永久回退(改变分支指向) 方法2:git reset 1. 保留修改&am…...
学习笔记:黑马程序员JavaWeb开发教程(2025.3.22)
11.1 案例-员工管理-新增员工 考试完之后,时隔一个月再次运行项目,出现了报错: class lombok.javac.apt.LombokProcessor (in unnamed module 0x5d7f1e59) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironme…...
