在测试和使用openvswitch的时候, 一部分人会使用KVM(kernel virtual machine)创建虚拟机.但KVM需要有一定的硬盘的支持, 还传说需要CPU支持虚拟化. 而也有一部分人使用LXC. LXC是一个轻量级的虚拟化技术, 占用的空间更小, 门槛也更低. 有兴趣的同学可以看一下
http://lxc.sourceforge.net/(需翻墙)
https://help.ubuntu.com/12.04/serverguide/lxc.html
在Mininet中, 开发者也用了类似的方法生成虚拟环境. 在对mininet的代码研究的时候, 我觉得我可以把一些基础的功能捡出来, 然后用C实现. 这一时兴起才有了我编的小程序和这篇总结的文章.
LXC可以生成多种虚拟环境. 实现这么多种虚拟环境依靠的其实就是unshare的方法(shell方法, C方法). 由于ovs只需要网络的虚拟环境, 所以我也只实现了网络虚拟化. 非常庆幸的是LXC的官网上开放了网络虚拟化的代码(需翻墙). 运行这段代码即可为我们的程序造出一个虚拟的网络环境.
下面这行代码用了unshare方法造出一个虚拟网络环境
而下面这行代码用exel族函数在虚拟网络环境中运行我们的程序.
现在, 我们有了一个网络虚拟环境. 将其编译后就可以放着了.
但是我做到这时仍有了一个疑问, 何为”我们的程序”? 显然, “我们的程序”是控制和使用虚拟网络环境的程序. 所以我的答案, 也是最简单的答案是: bash.
接下来是往该bash里写命令来控制虚拟环境. bash会运行在一个进程里, 而往一个进程里写数据当然是用管道最简单. 所以我写了另外一个程序并用管道的方法打开虚拟环境的那个文件, 让其运行起bash. 建立管道的话, Popen()是个好方法, 但不幸的是, C语言中, Popen()建立的管道只能是单向的, 要么只能读数据, 要么只能写数据. 所以, 我只好自己写一个函数建立双向管道. 我参考的方法是:Linux 上实现双向进程间通信管道. 用该方法打开虚拟环境, 然后就可以读写数据来控制该环境了!
下面是我改好后的双向管道函数.
FILE stream; ///< Pointer to the duplex pipe stream
pid_t pid; ///< Process ID of the command
};
struct ProcessInfo dpopen(char *const command[])
{
int fd[2];
pid_t pid;
struct ProcessInfo pi;
FILE *stream;
// 创建管道
socketpair(AF_UNIX, SOCKET_STREAM, 0, fd);
if ( (pid = fork()) == 0) { // 子进程
// 关闭管道的父进程端
close(fd[0]);
// 复制管道的子进程端到标准输出
dup2(fd[1], STDOUT_FILENO);
// 复制管道的子进程端到标准输入
dup2(fd[1], STDIN_FILENO);
// 关闭已复制的读管道
close(fd[1]);
/* 使用exec执行命令 */
execvp(command[0],command);
} else { // 父进程
// 关闭管道的子进程端
close(fd[1]);
stream = fdopen(fd[0], "r+");
if (stream == NULL) {
close(fd[0]);
return;
}
/* Successfully return here */
pi.pid = pid;
pi.stream = stream;
return pi;
}
}
但是, 创建的虚拟环境只有回环口lo, 所以目前该环境即没有对外的网口, 更不可能和外界通信. 解决这个问题的方法是用ip命令.
ip link set <interface> netns <pid>
上面的命令可以用exel族函数在主进程里执行. 其功能是创建一对相连的虚拟网卡, 并把一个放入到虚拟环境里一个留在主机里. 这样就实现了虚拟环境与外界的通信. 如果再把留在主机里的网卡加到ovs的网桥上, 那么虚拟环境就可以连上网桥了.
总结一下过程
1. 将该代码(需翻墙)编译成一个文件, 例如: vm.o
2. 用自己写的双向管道函数打开vm.o, 并把/bin/bash作为参数传入vm.o中
3. 用两个ip命令建立两个相连的网卡并把一个网卡放入虚拟环境中, 使虚拟环境能和外界相连.
4. 将留在主机里的网卡加入到ovs的网桥中, 使虚拟环境连到网桥上
剩下的功能就可以即兴发挥了. 比如可以创建任意数量的虚拟环境, 任意数量的网口等.. Have a good time~
赞~收了~lol