Amazon VPC (Virtual Private Cloud) 是AWS的网络基础设施。使用VPC服务可以在AWS中创建一个独立隔离的网络,在这个隔离的网络空间中可以创建任何AWS资源,例如EC2、Redis、RDS数据库等等,VPC网络使这些AWS资源互相连接,传递数据,并且提供外网访问的网关。

实际上很多人可能不知道,如果你已经在使用AWS的EC2,你就已经在不知不觉中使用了VPC。当我们最开始使用AWS服务时,AWS为我们创建了一个默认的VPC网络,我们创建的EC2实例(如果不手动选择)都默认加入到了这个VPC网络中。EC2、RDS等资源必须创建在一个VPC网路中,才能互相联通,访问网络。

Default VPC

除了默认的VPC,我们也可以自己创建VPC网络。VPC同时支持IPv4和IPv6组网,一个VPC网络由多个部分组成。

VPC和子网(Subnet)

当新建一个VPC,需要为虚拟网络定义IP地址范围作为CIDR地址,例如CIDR为10.1.0.0/16。IPv4的CIDR可以手动指定,但是IPv6的CIDR只能由AWS自动分配。

CIDR(无类别域间路由,Classless Inter-Domain Routing)将IP地址按照前缀分成一组,使用一种无类别的域际路由选择算法,大大减少了路由表维护的条目数。

VPC的IP地址段可以进一步划分IP段,从而创建子网(Subnet)。一个VPC横跨多个可用区(Availability Zone),但是一个子网只能位于一个可用区里面。

创建EC2、RDS等AWS资源的时候,除了要选择VPC,还要选择创建到VPC的哪个子网里面。EC2会被自动分配一个所属子网IP段内的私有IP地址,如果想要分配公网IP地址,需要手动指定弹性IP,或者可以配置子网自动为EC2分配公网IP地址。如果想要让EC2被外网访问到,除了需要配置公网IP地址,还需要配置子网的路由表,使其可以通过VPC网关(Internet Gateway)访问外网。

Subnet是一个VPC里面一个IP段. 创建任何AWS资源的时候可以选择一个Subnet。

AWS 以前没有VPC,而是叫做EC2-Classic的网络。2013年之后就支持EC2-VPC了。 对于只支持VPC的新账户,会有一个Default VPC,并且在每个Availability Zone里面都有一个默认的Default Subnet,新账号就默认使用个VPC,而不用自己选择。当然也可以自己创建VPC。

Default VPC 里面默认配置了网关(Internet Gateway),而且配置好了到网关的路由,每个Default Subnet里面的EC2都默认分配私有IP和公网IP。因此Default Subnet里面的EC2都是可以外网访问的。

Internet Gateway和Route Table

VPC是一个独立的虚拟的网络,与AWS其它的VPC、与外网都是隔离开得。如果想要让外网访问VPC里面的EC2,必须通过网关(Internet Gateway)。网关是VPC连接外网的组件,可以为VPC分配多个网关,每个网关都有唯一的ID,例如igw-8727e8e2。配置路由表的时候,网关ID作为路由表的目标地址(target)。

如果只想让instance主动访问外网,不想让外网主动访问instance。IPv4可以使用NAT,IPv6可以使用Egress-Only Internet Gateways

VPC里面的Subnet都关联了一张路由表(Route Table),路由表定义了VPC网络里面的网络流量的传输路径。

每个VPC创建之后都自动配置了一个路由表,这种关联在VPC上的路由表叫做主路由表(Main Route Table)。主路由表不能删除,但是可以替换为别的路由表。 每个Subnet创建之后默认使用主路由表,但是可以为Subnet创建一个自定义路由表(Custom Route Table)来设置特定路由规则。自定义路由表可以删除,删除之后就使用VPC的主路由表。

e.g. 一个使用主路由表的例子
Default VPC

在上面这个例子中,VPC的网段为10.1.0.0/16,里面有两个子网:10.1.1.0/2410.1.2.0/24。这两个子网没有自定义路由表,因此都使用VPC的主路由表。

主路由表中有两条路由规则:
- destination为10.1.0.0/16表示VPC内部的流量,因为VPC网段下的所有IP地址都是10.1开头。这些流量的target是local,表示内部之间通信。
- destination为0.0.0.0/0表示访问外网IP的流量,这些流量通过target指定ID的Internet Gateway访问外网。

Security Group

安全组(Security Group)定义了防火墙规则,包括出站规则和入站规则,可以细化到哪个IP段可以访问哪个端口。

为VPC中的EC2配置IPv6

VPC默认是使用IPv4来组网的,如果想要支持IPv6,创建VPC的时候需要手动指定CIDR IPv6地址段。对于已经创建好的IPv6 VPC,也可以添加IPv6 CIDR。

和IPv4不同的是,VPC的IPv6 CIDR前缀长度固定为/56。Subnet的IPv6 CIDR固定为/64。而且IPv6的CIDR段不能手动设置,全靠AWS自动分配。

和 IPv4 不同的是 IPv6 地址不区分私有地址和共网地址

要想创建的 EC2 实例添加IPv6,需要满足以下两个条件:
- EC2实例所属的Subnet配置了IPv6 CIDR
- 创建EC2实例的时候勾选上Auto-assign IPv6 IP设置。如果Subnet设置了Enable auto-assign IPv6 address选项,那么创建EC2的时候不需要再手动选择分配IPv6地址了。

不管Instance的状态是start还是stop,Instance的IPv6地址都不会被释放。只有当Instance Terminate的时候,IPv6地址才会释放。

让一个VPC支持IPv6需要完成一下配置:

  • 在VPC管理界面,选择想要更改的VPC,右键编辑他的CIDRs,在选项中添加IPv6 CIDR。AWS将自动分配一个IPv6 CIDR。
  • 找到VPC下面的Subnet,为想要修改的Subnet分配IPv6 CIDR。
  • 在VPC的主路由表里面添加一行路由表,destination设置为::/0,target为对应网关的ID。让IPv6流量通过网关访问到外网。

如果想要让一个支持IPv6的Subnet里面的EC2实例支持IPv6,还需要做如下配置:

  • 在 AWS EC2 管理界面里面选择要修改的EC2实例,在Actions里面选择Manage IP Address选项可以为EC2实例添加IPv6地址。
  • 修改实例关联的Security Group,添加IPv6地址的Inbound/Outbound规则。

注意:虽然在 AWS EC2 管理界面里面为实例分配了IPv6地址,但是操作系统里面未必识别到了IPv6地址。如果实例使用的是Amazon Linux 2016.09.0以后的版本,则实例会自动获得IPv6地址。但是Ubuntu/CentOS系统不能获得IPv6地址,需要在系统里面做进一步配置。

在Ubuntu 16.04系统里面执行如下命令可以马上获得分配的IPv6地址:

1
sudo dhclient -6

但是这个命令会在系统重启之后失效,为了让下次重启的时候,能够自动IPv6地址,执行下面的命令配置DHCPv6:

1
2
3
4
sudo vim /etc/network/interfaces.d/60-default-with-ipv6.cfg
// 在文件中添加: iface eth0 inet6 dhcp

sudo ifdown eth0 ; sudo ifup eth0

有时候执行dhclient命令不工作,只能用第二种方法。

为了让新建的Ubuntu实例也自动支持IPv6,需要将这一行加入到UserData中

1
echo "iface eth0 inet6 dhcp" >> /etc/network/interfaces.d/60-default-with-ipv6.cfg