大致的流程是在宿主进程中创建网卡,然后移动到容器进程的网络命名空间,最后在容器进程的网络命名空间设置网卡的各种参数如mac、ip、gateway等。

一、宿主进程

见start.c文件的lxc_spawn函数

ret = lxc_netns_set_nsid(handler->nsfd[LXC_NS_NET]);
    if (ret < 0)
        SYSWARN("Failed to allocate new network namespace id");
    else
        TRACE("Allocated new network namespace id");

    /* Create the network configuration. */
    if (handler->ns_clone_flags & CLONE_NEWNET) {
        ret = lxc_create_network(handler);
        if (ret < 0) {
            ERROR("Failed to create the network");
            goto out_delete_net;
        }

        ret = lxc_network_send_to_child(handler);
        if (ret < 0) {
            ERROR("Failed to send veth names to child");
            goto out_delete_net;
        }
    }

lxc_netns_set_nsid函数

通过上面的lxc_try_preserve_namespaces方法解析出容器网络命名空间标识文件的fd

lxc_create_network函数

int lxc_create_network(struct lxc_handler *handler)
{
    int ret;

    if (handler->am_root) {
        ret = lxc_create_network_priv(handler);
        if (ret)
            return -1;

        return lxc_network_move_created_netdev_priv(handler);
    }

    return lxc_create_network_unpriv(handler);
}

→lxc_create_network_priv
→→netdev_conf[netdev->type](handler, netdev)
→→→instantiate_macvlan

//随机生成网卡设备名称
lxc_ifname_alnum_case_sensitive

//创建macvlan虚拟网卡设备mcXXXXXX
//核心方法
lxc_macvlan_create

//将创建的网卡设备mcXXXXXX名称存储起来
netdev->created_name

//获取新创建的网卡设备的ifindex值
netdev->ifindex = if_nametoindex(peer);

→lxc_network_move_created_netdev_priv
→→lxc_netdev_move_by_index(netdev->ifindex, pid, netdev->name)

通过netlink将创建的网卡设备移动至容器的网络命名空间

参数1:netdev->ifindex,即新建的网卡的ifindex值。
参数2:pid,即容器进程pid.
参数3:即容器配置文件配置的网卡名称

原理是通过netlink的接口,通过pid操作容器的命名空间,通过ifindex建立联系,将新建的网卡设备移动到了容器的网络命名空间。

lxc_network_send_to_child函数

容器进程通过lxc_network_recv_from_parent方法获取宿主进程的网卡名称

二、容器进程

见conf.c的lxc_setup函数

if (handler->ns_clone_flags & CLONE_NEWNET) {
        ret = lxc_setup_network_in_child_namespaces(lxc_conf,
                                &lxc_conf->network);
        if (ret < 0)
            return log_error(-1, "Failed to setup network");

        ret = lxc_network_send_name_and_ifindex_to_parent(handler);
        if (ret < 0)
            return log_error(-1, "Failed to send network device names and ifindices to parent");
    }

lxc_setup_network_in_child_namespaces函数

ret = netdev_ns_conf[netdev->type](netdev);
if (!ret)
    ret = lxc_network_setup_in_child_namespaces_common(netdev);

→netdev_ns_conf
→→instantiate_ns_macvlan (通过网卡名称获取ifindex值)
→lxc_network_setup_in_child_namespaces_common
设置网卡设备的mac地址,ip地址、网关等参数,但是设备创建存疑(怀疑是宿主进程创建的那个设备,因为ifindex,但是没有找到两者之间的联系。)


0 条评论

发表回复

您的电子邮箱地址不会被公开。