重用现有的 Neutron 网络

https://blueprints.launchpad.net/kuryr/+spec/existing-neutron-network

当前的 Kuryr 实现假定 Neutron 网络、子网池、子网和端口是由 Kuryr 创建的,并且其生命周期完全由 Kuryr 控制。然而,在用户需要将虚拟机实例和/或裸机节点与容器混合使用的情况下,重用现有的 Neutron 网络来实现 Kuryr 网络的能力变得很有价值。

问题描述

本规范要解决的主要用例如下

  • 使用独立于 Kuryr 创建的现有 Neutron 网络和子网资源

随着 Neutron 资源添加标签 添加标签到 Neutron 资源规范,容器网络与 Neutron 网络之间的关联是通过将标签(或标签)关联到 Neutron 网络来实现的。特别是,容器网络 ID 存储在这些标签中。目前标签的最大大小为 64 字节。因此,我们当前为每个网络使用两个标签来存储相应的 Docker ID。

提议的变更

本规范建议使用在创建 Docker 网络期间用户可以指定的 Options。我们建议使用 Neutron 网络的 UUID 或名称来标识要使用的 Neutron 网络。如果指定的 Neutron 网络 UUID 或名称不存在,或者在指定网络名称的情况下存在多个这样的网络,则创建操作将失败。否则,将使用现有的网络。类似地,如果现有网络未关联子网,Kuryr 将创建它。否则,将使用现有的子网。

指定的 Neutron 网络将被标记一个众所周知的字符串,以便可以验证它是在创建 Docker 网络时已经存在还是后来创建的。

提议的工作流程

  1. 用户创建一个 Docker 网络,并通过指定其 UUID 将其绑定到现有的 Neutron 网络

    $ sudo docker network create --driver=kuryr --ipam-driver=kuryr \
           --subnet 10.0.0.0/16 --gateway 10.0.0.1 --ip-range 10.0.0.0/24 \
           -o neutron.net.uuid=25495f6a-8eae-43ff-ad7b-77ba57ed0a04 \
           foo
    286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364
    
    $ sudo docker network create --driver=kuryr --ipam-driver=kuryr \
           --subnet 10.0.0.0/16 --gateway 10.0.0.1 --ip-range 10.0.0.0/24 \
           -o neutron.net.name=my_network_name \
           foo
    286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364
    

    这将创建一个名为 foo(在本例中)的 Docker 网络,通过使用具有指定 UUID 或名称的 Neutron 网络来实现。

    如果通过 --subnet--gateway--ip-range(如上所示命令所示)指定了子网信息,则将创建相应的子网池和子网,或者根据提供的 CIDR 等信息,适当重用现有资源。例如,如果命令中的给定 UUID 的网络存在,并且该网络具有与 --subnet 和可能 --ip-range 给定的 CIDR 相同的子网,则 Kuryr 不会创建子网,而只是将现有的子网保持原样。Kuryr 从创建或重用的子网的信息中组合响应。

    预期在使用 Kuryr 驱动程序时,也将使用 Kuryr IPAM 驱动程序。

    如果重用的 Neutron 子网的网关 IP 地址与 --gateway 给定的地址不匹配,Kuryr 仍然返回 Neutron 子网中设置的 IP 地址,并且该命令将因 Docker 对响应的验证而失败。

  2. 用户检查创建的 Docker 网络

    $ sudo docker network inspect foo
    {
        "Name": "foo",
        "Id": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364",
        "Scope": "global",
        "Driver": "kuryr",
        "IPAM": {
            "Driver": "kuryr",
            "Config": [{
                "Subnet": "10.0.0.0/16",
                "IPRange": "10.0.0.0/24",
                "Gateway": "10.0.0.1"
            }]
        },
        "Containers": {}
        "Options": {
            "com.docker.network.generic": {
                "neutron.net.uuid": "25495f6a-8eae-43ff-ad7b-77ba57ed0a04"
            }
        }
    }
    

    用户可以看到命令中给定的 Neutron uuid 存储在 Docker 的存储中,并且可以通过检查网络来查看。

  3. 用户启动一个容器并将其附加到网络

    $ CID=$(sudo docker run --net=foo -itd busybox)
    

    此过程与 Kuryr devref 中描述的现有逻辑相同。libnetwork 调用 /IpamDriver.RequestAddress/NetworkDriver.CreateEndpoint,然后 /NetworkDriver.Join。适当的可用 IP 地址将通过 Kuryr 从 Neutron 返回,并在网络的子网上创建一个具有该 IP 地址的端口。

  4. 用户终止容器

    $ sudo docker kill ${CID}
    

    此过程与 Kuryr devref 中描述的现有逻辑也相同。libnetwork 调用 /IpamDriver.ReleaseAddress/NetworkDriver.Leave,然后 /NetworkDriver.DeleteEndpoint

  5. 用户删除网络

    $ sudo docker network rm foo
    

    当使用现有的 Neutron 网络创建 Docker 网络时,它将被标记,以便在删除操作期间,Neutron 网络不会被删除。目前,如果使用现有的 Neutron 网络,与其关联的子网(无论是预先存在的还是新创建的)也将被保留。在未来,我们可能会考虑标记子网本身或网络(包含子网信息)来决定是否应删除子网。

挑战

参考