Router 概述

文章详细介绍了如何创建和配置虚拟路由器,包括添加内部和外部网络子网,设置GatewayIP,以及通过iptables进行SNAT规则设置,以实现内部实例通过浮动IP访问外网的功能。同时,提到了浮动IP的DNAT规则,确保外部流量能正确路由到内部实例。
摘要由CSDN通过智能技术生成

Router 概述

  1. 创建虚拟路由器router_100_101,并加入两个子网subnet_172_16_101_0,subnet_172_16_100_0,
  2. 通过 ip netns exec ip a 命令查看 router_100_101 namespace 中的 veth interface 配置。
    在这里插入图片描述
    namespace 中有两个 interface:

qr-e17162c5-00 上设置了 Gateway IP 172.16.101.1,与 root namespace 中的 tape17162c5-00 组成 veth pair。

qr-d568ba1a-74 上设置了 Gateway IP 172.16.100.1,与 root namespace 中的 tapd568ba1a-74 组成 veth pair。

  1. 新增路由表
    在这里插入图片描述
    源码如下:(注意,原生实现router功能都是先删除router的端口,路由,再重新添加)
   def _internal_network_added(self, ns_name, network_id, port_id,
                                fixed_ips, mac_address,
                                interface_name, prefix, mtu=None):
        LOG.debug("adding internal network: prefix(%s), port(%s)",
                  prefix, port_id)
        // 新增qr口
        self.driver.plug(network_id, port_id, interface_name, mac_address,
                         namespace=ns_name,
                         prefix=prefix, mtu=mtu)

        ip_cidrs = common_utils.fixed_ip_cidrs(fixed_ips)
        // qr ns增加gateway ip 172.16.100.1以及添加路由
        self.driver.init_router_port(
            interface_name, ip_cidrs, namespace=ns_name)
  1. 创建外部网络,并且创建 subnet_10_10_10_0,IP 地址为 10.10.10.0/24。
    在这里插入图片描述
    该 veth pair 命名为 qg-b8b32a88-03,上面配置了 IP 10.10.10.2。
    在这里插入图片描述
    新增router路由:默认网关10.10.10.1,意味着对于访问 vlan100 和 vlan101 租户网络以外的所有流量,router_100_101 都将转发给 ext_net 的网关 10.10.10.1。

同时需要添加一条iptables规则,当数据包从 router 连接外网的接口 qg-b8b32a88-03 发出的时候,会做一次 Source NAT,即将包的源地址修改为 router 的接口地址 10.10.10.2,这样就能够保证目的端能够将应答的包发回给 router,然后再转发回源端 instance。
在这里插入图片描述
SNAT 让 instance 能够直接访问外网,但外网还不能直接访问 instance。因为 instance 没有外网 IP。这里 “直接访问 instance” 是指通信连接由外网发起,例如从外网 SSH cirros-vm3。(这里只能通过浮动IP访问)
源码如下:

def _process_external_gateway(self, ex_gw_port):
    # TODO(Carl) Refactor to clarify roles of ex_gw_port vs self.ex_gw_port
    ex_gw_port_id = (ex_gw_port and ex_gw_port['id'] or
                     self.ex_gw_port and self.ex_gw_port['id'])

    interface_name = None
    if ex_gw_port_id:
        interface_name = self.get_external_device_name(ex_gw_port_id)
    if ex_gw_port:
        if not self.ex_gw_port:
            // 配置qg口以及相关默认路由
            self.external_gateway_added(ex_gw_port, interface_name)
            self.agent.pd.add_gw_interface(self.router['id'],
                                           interface_name)
        elif not self._gateway_ports_equal(ex_gw_port, self.ex_gw_port):
            self.external_gateway_updated(ex_gw_port, interface_name)
    elif not ex_gw_port and self.ex_gw_port:
        self.external_gateway_removed(self.ex_gw_port, interface_name)
        self.agent.pd.remove_gw_interface(self.router['id'])
    elif not ex_gw_port and not self.ex_gw_port:
        for p in self.internal_ports:
            interface_name = self.get_internal_device_name(p['id'])
            self.gateway_redirect_cleanup(interface_name)

    self._delete_stale_external_devices(interface_name)

    # Process SNAT rules for external gateway
    gw_port = self._router.get('gw_port')
    // SNAT规则
    self._handle_router_snat_rules(gw_port, interface_name)
  1. 浮动IP,分配浮动IP 10.10.10.3到vm3 对应租户IP 172.16.101.3在这里插入图片描述
    可以看到,floating IP 已经配置到 router 的外网 interface qg-b8b32a88-03 上。查看 router 的 NAT 规则:

在这里插入图片描述

iptables 增加了两条处理 floating IP 的规则:

  1. 当 router 接收到从外网发来的包,如果目的地址是 floating IP 10.10.10.3,将目的地址修改为 cirros-vm3 的 IP 172.16.101.3。这样外网的包就能送达到 cirros-vm3。

  2. 当 cirros-vm3 发送数据到外网,源地址 172.16.101.3 将被修改为 floating IP 10.10.10.3。

源码如下:

def process_external(self):
    fip_statuses = {}
    try:
        with self.iptables_manager.defer_apply():
            ex_gw_port = self.get_ex_gw_port()
            self._process_external_gateway(ex_gw_port)
            if not ex_gw_port:
                return

            # Process SNAT/DNAT rules and addresses for floating IPs
            self.process_snat_dnat_for_fip()

        # Once NAT rules for floating IPs are safely in place
        # configure their addresses on the external gateway port
        interface_name = self.get_external_device_interface_name(
            ex_gw_port)
        // 添加浮动IP到gw口
        fip_statuses = self.configure_fip_addresses(interface_name)

参考链接:https://mp.weixin.qq.com/s?__biz=MzIwMTM5MjUwMg==&mid=2653587539&idx=1&sn=b41b18336c593b143e7495660fa2f086&chksm=8d30804aba47095c5ab109d963c7cc88a024c6aed8a75105e32db3e3d5cea846a878b6f12a31&scene=21#wechat_redirect

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值