虚拟网络跨VPC NAT
函数计算服务中,业务用户提交计算任务到服务平台,在函数计算平台底层,以K8S作为基础设施底座,所有业务用户提交的计算任务都以K8S POD形式运行,所有函数POD运行在函数服务VPC,该VPC不区分业务POD,所有业务用户的函数POD在同一VPC内。业务用户在自有VPC内部署相关服务,如DB等,业务在函数计算平台提交的计算任务可访问业务自有VPC内的服务,如在函数任务中的代码访问业务自有VPC内的DB。这种场景下就需要连通函数计算服务平台的统一VPC与业务自有VPC,而不同的业务用户VPC地址段是可重叠的,这就出现不同的函数任务访问相同IP地址,如下图:
# -*- coding: utf8 -*-
import redis
def main_handler(event,context):
r = redis.StrictRedis(host='172.16.0.3', port=6379, db=0,password="crs-i4kg86dg:abcd1234")
print(r.set('foo', 'bar'))
print(r.get('foo'))
return r.get('foo')
如上所示,用户A\B分别在自有VPC内部署Redis服务(IP地址均为172.16.0.3),以上述代码提交函数,函数代码内访问各自VPC内的Redis服务,用户提交函数后,在函数计算平台的K8S集群中创建对应POD后,两个POD的源地址处在统一VPC,去往172.16.0.3的流量由vSwitch转发,由于目标地址相同,vSwitch无法区分流量目标所属的VPC,也就无法完成转发动作,针对该场景需求,方案如下:
方案选择
数据流设计
函数计算连通业务VPC场景下,VPC NAT网关转发逻辑如下:
如上图所示(红色为请求流量,蓝色为返回流量),分别在业务VPC内创建NAT ENI,函数POD创建时,由CNI Agent注入业务VPC路由,目标MAC调整为NAT ENI MAC(唯一),vSwitch根据目标MAC区分目标业务VPC流量(不同业务VPC,VNI不同),封装VXLAN报文时,将VNI调整为目标业务VPC VNI,并将报文发至VPC NAT网关,VPC NAT网关根据源段地址\VNI\目标段地址查找NAT策略,策略匹配后,进行SNAT,将源地址调整为业务VPC内的NAT ENI地址,创建SESSION信息,封装VXLAN报文发送至业务VPC内目标IP服务应用所在的物理节点,服务应用回包时,物理节点将流量发送至VPC NAT网关,VPC NAT网关解封VXLAN后,根据SESSION信息进行DNAT,将目标地址调整为函数POD的地址,封装VXLAN报文后发送到函数POD所在物理节点,节点vSwitch完成节点内流量转发,根据该转发逻辑即可区分函数POD访问的目标业务VPC,完成流量NAT转换
该场景下,还有另外一个场景:函数POD访问公网的流量从目标业务VPC的公网出口链路转发
针对函数POD复用业务VPC的公网出口,在VPC NAT的VPC NAT Table中增加默认策略,未匹配到目标地址段的流量,源地址进行SNAT,调整为业务VPC的EIP后推入UNDERLAY,回流根据SESSION信息进行DNAT操作后(目标地址调整为函数POD IP)封装VXLAN发送至函数POD所在物理节点
通过VPC NAT网关,即可实现函数计算POD连通业务VPC,函数内访问业务VPC内私网地址即可
控制流设计
- 用户在HULK平台创建vpc_nat,用于函数POD(VPC A)访问业务VPC(VPC B)内服务
- HULK调用ultron,创建vpc_nat,传入VPC A的ID、VPC B的ID
- ultron调用neutron创建资源
- 3.1 在VPC B创建port,device_owner为“network:vpc_nat”,port占用的IP(NAT IP)作为VPC A访问VPC B的身份
- 3.2 在VPC A创建vpc_nat,传入3.1中port的IP地址、MAC地址、VPC B的tunnel ID等。neutron根据这些信息在底层下发转发规则
- HULK调用NAT网关,传入VPC A的cidr、VPC B的cidr等。NAT网关根据这些信息在网关下发转发规则
总结
虚拟网络跨VPC NAT实现了实例之间跨VPC互访的功能,具有使用方便的特点,很好地解决了不同VPC之间网段重叠造成的流量路径选择问题,并且在利用了NAT网关原有功能的基础上扩展了NAT网关的功能。除了函数计算服务以外,后续也能方便提供给其他服务使用,具有好的可扩展性。
更多云产品请搜索:360智汇云~