上篇回顾:
更多内容关注我的公众号:Linux运维实战派
我会持续分享更多云计算实战项目
AWS VPC规划和建设指南及其中的坑
1 VPC的网段(CIDR)的规划
- 网段(CIDR)务必提前规划,与企业办公网、AWS上的其他VPC、其他公有云VPC、还有IDC机房网段隔离。当然这不是一个强制要求,只是为了防止后续需要将多个地区vpc互联互通做好准备,否则IP网段如果有重叠,是无法支持的互通的
- CIDR的大小,按自己业务需求来进行规划,网段分配可以使用ipcalc命令工具
2 我们真的需要三AZ吗?
在AWS上,在做VPC规划的时候,是必须强制包含至少两个AZ的。那我们需要扩展到三AZ吗?比如上边我这边的规划是使用了三AZ的。
-
**可用性考虑:**三AZ分布,可以保证更高的业务可用率,一些需要强制三节点选举的服务如etcd、consul等,推荐的做法都是三个实例分别放置于三个AZ内,这样可以保证任何一个AZ故障,都不会对整个服务造成影响。如果是两AZ,必然会有两个选举节点被置放在一个AZ,假设这个AZ故障,那这种依赖集群选举的服务就会不可用
-
**复杂度考虑:**AWS内部在多AZ网络上的支持是很便捷的,在管理上并不会代理额外的管理成本
-
**成本考虑:**AWS多个AZ之间的数据传输是要收费的,经过我的实践,如果内部东西向流量比较大的话,这个流量成本还是很高的
这里我简单画了流量传输示意图,实际上在多个AZ之间,任何服务存在跨AZ访问,产生的流量都会计费。
我的实践建议:
- 两AZ已经可以满足绝大部分的高可用设计了,除非你的应用场景对于3az有着强需求
- 三AZ可以不用,但必须规划(如AWS SaaS服务OpenSearch是强制三AZ分布的),即网段必须提前预留,备用的az,网段可以略小(具体根据你们的VPC CIDR规模决策)
3 公有子网(Public Subnet)与私有子网(Private Subnet)
AWS的公有子网和私有子网必须在规划创建的时候,进行确定,这一点是区别于国内云厂商的。
否则你后续会发现经常发现,自己的公网EC2,公网ELB,已经绑定的公网IP,开放了安全组,但是仍然无法访问,此类问题是AWS使用过程中的高频问题
公有子网: 路由表的默认路由(0.0.0.0/0) 指向**IGW(Internet Gateway)**的网段,即公有子网绑定的路由表,默认路由必须指向IGW
私有子网: 绑定的路由表默认路由没有指向IGW,如果私有子网内的设备需要能访问互联网,必须创建NAT网关,将默认路由指向NGW(NAT Gateway)
4 子网规划
- 每个AZ内部至少需要包含一个公有子网,一个私有子网
- 网段大小:
- 公有子网: 我们核心业务一般都是需要放置在私有子网内,强烈不建议将服务至于公有子网内,部分服务,如EKS的Node,至于公有子网的话,是需要分配公网IP的,否则你的Node是不能ready的。所以公有子网的cidr可以略小。
- 私有子网: 私有子网是您服务主要置放的位置,应该保证CIDR有足够的可用IP数。如果使用EKS(AWS托管AWS服务)每个POD都会占用一个私有IP地址
- 是否交给AWS自动分配CIDR:
- 经过多位同事的实践,强烈建议自定义子网CIDR(Customize subnets CIDR blocks)
- AWS的自动分配,会按照子网数量平均划分VPC的CIDR,即公有和私有子网的大小是一致的,如果你的业务规模不大、私有IP网段充足,那是很便捷的。但是如果规划的网段有限,则需要保障核心使用的私有网段有充足的IP地址
- 子网划分时的取头或取尾原则:如下表,对于需要继续划分更小子网的时候,要么从CIDR的头(10.250.0.0/18)开始划分,要么从尾(10.250.192.0/18)开始划分
我的实践:
我的业务场景中,核心使用了两个AZ,是在可用性和成本上做了取舍,也为业务扩展做了子网保留;公有子网一般只会放置极少的EC2和公网ELB,防火墙等设备,所以2k的IP规模是足够的。ip地址计算和划分使用ipcalc计算
CIDR | 子网1 | 子网2 | 类型 | IP规模 | |
---|---|---|---|---|---|
10.250.0.0/16 | VPC CIDR | 65534 | 可划分4个/18的子网 | ||
10.250.0.0/18 | Private AZ1 | 32766 | 核心使用的私有子网 | ||
10.250.64.0/18 | Private AZ2 | 32766 | 核心使用的私有子网 | ||
10.250.128.0/18 | 保留子网 | ||||
10.250.192.0/18 | 继续分配 | ||||
10.250.192.0/19 | Private AZ3 | 8190 | AZ3的子网,几乎不用 | ||
10.250.224.0/21 | Public AZ1 | 2046 | 公有子网 | ||
10.250.232.0/21 | Public AZ2 | 2046 | 公网子网 | ||
10.250.240.0/21 | Public AZ3 | 2046 | 公网子网 | ||
10.250.248.0/21 | 保留子网 |
5 NAT网关需要每一个AZ一个吗?
我的实践: 核心业务所在的两个子网是一个子网一个,我将架构图中这部分抽离出来,实际我先上生效的结构是这样的
考量点
- 成本: NAT实例本身成本与跨AZ访问的流量成本(只是主动访问公网这部分,不包括VPC内部东西向跨AZ的流量)对比,从公网下载数据不多的话,使用一个NAT成本会更低
- 管理复杂度: 要考虑到VPC内服务的发展,在一个周期内,如(1年),会不会新增大量的从公网下载数据的需求。如果有,请提前调整到每个AZ一个NAT网关,因为NAT网关扩容,会新增一个NAT的出口IP,访问外部服务,如果对方有加IP白名单的话,不太好调整
注意点: NAT网关必须置放于公有子网内
6 子网路由表需要每个网段独立一个吗?
- 公有子网与私有子网的路由表必须独立,因为默认网关一个指向IGW,一个指向NGW
- 公有子网都可以只使用一个路由表,因为路由是一致的
- 私有子网需要看你的NAT网关是整个VPC一个,还是每个AZ一个,每个AZ一个,就需要每个AZ独立一个私有网段的路由表,因为默认网关指向的NAT网关是不同的
7 DNS配置(DNS settings)
DNS解析(DNS resolution)与DNS主机名(DNS hostnames)需要选择打开
8 DHCP选项(DHCP option sets)
DHCP选项,如果你需要为你的EC2主机自定义主机名的话,可以选择新建一个,并修改VPC配置,关联到当前VPC即可。DNS Server我推荐使用AWS提供的Route53,如下图填入"AmazonProviderDNS".
自定义主机名,需要在Route53上创建PrivateHostZone,并绑定到对应的VPC。但请注意,每个EC2主机创建的时候,是需要自己去更新主机名记录到Route53的。
9 如何解决跨境国内到AWS的跨境访问问题
国内访问境外AWS环境,直接走公网访问的质量很不稳定的,如果业务上还有请求交互,那质量是无法保证的。一般的连接方式有VPN和DX专线。当然跨境专线的成本比较高,我们只满足当前的办公网访问即可,所以选择了VPN。
9.1 Site-To-Site VPN
VPN从国内直接到境外的AWS也是不行的,毕竟也是直接走的公网。所以,我们借用了国内云厂商的跨境线路,然后再通过境外两家云厂商VPN打通,来解决控制链路的访问问题
关于如何配置AWS的Site-to-Site VPN打通阿里云及AWS的VPC,可以参考阿里云的文档:通过IPsec-VPN实现阿里云VPC和AWS VPC互通
9.2 从办公网访问AWS上的管理后台服务
VPN我们只是打通了网络链路,一般在AWS的VPC内部会部署很多管理服务,是需要从办公网进行访问的,甚至对于SRE来说,我们在一些特殊情况下,是需要能够通过本地的终端直接连接缓存及数据库节点。
我目前的解决方式是通过proxy代理【nginx httpproxy及nginx stream proxy】的方式来解决
这里是逻辑示意图,VPN链路不是直接同国内VPC建立的
9.3 Direct Connect(DX专线)
DX专线是AWS提供的专线互联服务,不管是我们的线下IDC,还是公有云,都可以通过DX专线服务,接入到AWS的任意一个DX的接入点,就可以完成对整个AWS VPC的互联互通。
DX专线本次我并未使用,按照多年前使用过的印象画的架构图,仅作参考。
10 PrivateLink解决VPC内访问AWS SaaS服务
在AWS的一个Region内,我们需要访问AWS的SaaS服务,比如最常见的S3对象存储服务,正常情况下,S3的域名解析出来是公网IP,我们访问S3内的数据的时候,就必须要走NAT,然后走到我们VPC的IGW网关,走到互联网,再访问到AWS自己VPC内的S3服务。
这样的访问路径,会额外产生两部分成本:S3桶的公网流量成本、VPC的公网入流量成本。除了成本,这个过程访问链路更长,质量会受到NAT,及公网稳定性的影响。
AWS的PrivateLink支持在客户的VPC内创建一个Endpoint端点,从这个端点可以直接走VPC内部访问到S3,就跟做了一层反向代理一样。当然AWS的PrivateLink服务,支持两种类型,S3是DynamoDB使用"Gateway"类型的端点服务,不产生任何成本。
10.1 PrivateLink的创建
“VPC” --> “Endpoints(终端节点)” --> “Create endpoint”
可以看到AWS的PrivateLink端点,可以支持AWS的SaaS服务,还有应用市场(Marketplace services)的第三方合作伙伴的服务,即你如果需要访问一个第三方公司的接口,如果他们的服务也部署在AWS内,你就可以通过PrivateLink端点去访问,而不需要绕行公网。
除了S3和DynamoDB这两个AWS自有的SaaS服务是需要创建Gateway类型的端点之外,其他的服务需要使用Interface类型的端点,这种类型,会真实的在我们的VPC内部,创建一个ENI网卡。
10.2 Endpoint是如何实现内网直接访问S3的
下边是我在VPC内部解析S3域名的返回,可以看到返回的IP地址是公网IP,那按照常规理解,内网服务就会走到NAT,出公网访问。所以,这一小节,我们来揭秘一下
# dig s3.ap-southeast-2.amazonaws.com +short
52.219.124.190
52.219.125.92
在创建S3的endpoints的时候,这里选择你的VPC,之后会出现你需要绑定的子网,访问Policy 选择默认的FullAccess,就可以创建一个S3的访问端点。
之后去查看我们的路由表,就可以看到Destination(目标)是pl开头的资源,指向了vpce的端点,这个端点就是刚刚创建的。
这里的pl这个资源,则是AWS路由的Prefix list,在这个s3 prefix 资源的内部,维护了AWS S3的IP地址地址段,那路由表中的这条路由则表示,访问目标为s3 prefix资源中定义的IP地址段时,路由走到vpce 这个刚创建的S3 Endpoint端点上。
10.3 PrivateLink的Endpoint和Endpoint Service
Endpoints:就是前边我们说过了,可以在VPC内部创建一个端点,用来访问AWS的SaaS服务,或者第三方AWS用户的服务;
Endpoint services:是和Endpoints成对出现的,它允许AWS服务提供者或第三方服务提供者将其服务作为可访问的终端节点(Endpoint Service)发布到AWS中。这样,其他人就可以通过创建一个Endpoints 来访问这里定义的Endpoint services