RouteFlow与LXC学习 ( by quqi99 )

RouteFlow与LXC学习 ( by quqi99 )

作者:张华  发表于:2013-07-27
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明

http://blog.csdn.net/quqi99 )

      开源的基于Openflow的路由虚拟化开源项目,Openflow解决的是交换机上的流表生成和下发的数据平面问题,Routeflow的目的是解决控制平面路由协议及计算的问题。直接上图:

RouteFlow与LXC学习 ( by quqi99 )_第1张图片                         RouteFlow与LXC学习 ( by quqi99 )_第2张图片

   要点:

Quagga用于产生路由表,RouteFlow client用于将路由表和ARP表转换成流表,通过RouteFlow Proxy及Pox下发流表到openflow datapath。全局RouteFlow Server用于存储

    存储VM, PORT, CONTROL, SWITCH的映射关系

  • https://github.com/CPqD/RouteFlow/wiki/Tutorial-1:-rftest1#creating-our-virtual-gateway.
    1, 先VM1 ping VM2
    2, 正常路由之后产生了ARP或者路由表,将由routeflow client将netlink截获送往routeflow server存储VM, PORT, CONTROL, SWITCH的映射关系
    3, routeflow proxy指导openflow controll对openflow datapath下发流表:
       cookie=0x0, duration=204.649s, table=0, n_packets=0, n_bytes=0, idle_timeout=300,priority=32800,ip,dl_dst=12:a1:a1:a1:a1:a1,nw_dst=172.31.2.2 actions=mod_dl_src:12:a1:a1:a1:a1:a1,mod_dl_dst:02:b2:b2:b2:b2:b2,output:2
     cookie=0x0, duration=203.97s, table=0, n_packets=0, n_bytes=0, idle_timeout=300,priority=32800,ip,dl_dst=12:a1:a1:a1:a1:a1,nw_dst=172.31.1.2 actions=mod_dl_src:12:a1:a1:a1:a1:a1,mod_dl_dst:02:b1:b1:b1:b1:b1,output:1
    4, 所以这个routeflow client应该是运行在网络节点上。注意:如果采用mininet来模块switch与host,那么:In RouteFlow a virtual machine represents an OpenFlow switch.
    5, 采用quagga来帮助生成路由时,唯一的区别是:the interfaces configuration is now done through Quagga. https://github.com/CPqD/RouteFlow/wiki/Tutorial-2:-rftest2
    6, 问题的关键是,如果对于neutron dvr,当计算节点变成网络节点之后,就有可能存在一个节点存在多个相同子网的网关。那么似乎只能像kubertenes一样假设一个节点的子网唯一。
    7, 另一个关键问题,quagga对namespace的支持问题
    8, 在一个数据中心内的多个openstack集群,如果跨路由器的话,可以和安装了quagga的l3-agent一起运行iBGP或者OSPF协议
    9, 不同的数据中心的两个Openstack集群的两个l3-agent之间运行eBGP协议,这时内网地址如何与外网地址转换
    10, 如何将路由表转换成转发表。转换规则如下:http://www.my-fire.eu/documents/11433/58820/Route+Flow , 并且这点如何应用到dragonflow中去

    http://changeofelia.info.ucl.ac.be/pmwiki/uploads/SummerSchool/Program/session_007.pdf
    RouteClient收集下列路由和ARP信息:
    Route =IP + MASK [Rede]+IP[Gateway]+Interface
    ARP= IP[Host]+MAC[Host]+Interface

    路由表转换成流表:
    Match: DST_MAC + DST_IP + SUBNET_MASK
    Actions: 
    Re-Write [SRC_MAC (Interface)], Re-Write [DST_MAC (Nexthop)]
    Forward [Port-out(Interface)]

    11, 显然,所有这些数据中心应该受相同的routeflow server收集全局的VM, PORT, CONTROL, SWITCH的拓扑信息,openflow controller可能有多个去为datapath设置流规则。所以routeflow好像是比dragonflow更加通用的解决方案。

    12, ACL ?



安装rfclient的话如下,其他的安装rfcserver等类似。

git clonehttps://github.com/CPqD/RouteFlow.git

sudo yum install make automake gcc gcc-c++kernel-devel git boost-devel boost-program-options boost-threadboost-filesystem iproute-devel openvswitch mongodb pymongo

make rfclient


一个例子见:https://github.com/CPqD/RouteFlow/wiki/Tutorial-1


RouteFlow真正要做的事情就是,举个例子:一个物理机上通过ovs连了两个虚机的话,当vm1ping vm2后,物理上通过arp-a命令看就会多出两条arp记录(macip的映射),如:

ubuntu@rfvm1:~$ sudo arp -a
? (172.31.1.2) at 02:b1:b1:b1:b1:b1 [ether] on eth1
? (192.169.1.1) at aa:48:2d:aa:da:41 [ether] on eth0
? (172.31.2.2) at 02:b2:b2:b2:b2:b2 [ether] on eth2 

RouteFlow真正要做的事情就是就根据上述变化的ARP表或者RIB路由表来生成下列的openflowFIB流表

sudo ovs-ofctl dump-flows switch1
...
 cookie=0x0, duration=204.649s, table=0, n_packets=0, n_bytes=0, idle_timeout=300,priority=32800,ip,dl_dst=12:a1:a1:a1:a1:a1,nw_dst=172.31.2.2 actions=mod_dl_src:12:a1:a1:a1:a1:a1,mod_dl_dst:02:b2:b2:b2:b2:b2,output:2
 cookie=0x0, duration=203.97s, table=0, n_packets=0, n_bytes=0, idle_timeout=300,priority=32800,ip,dl_dst=12:a1:a1:a1:a1:a1,nw_dst=172.31.1.2 actions=mod_dl_src:12:a1:a1:a1:a1:a1,mod_dl_dst:02:b1:b1:b1:b1:b1,output:1


最初可以在虚机里运行内部路由协议在一个路由器的下面的同一tenant的同一子网下的机器的东西向流量带来好处,将来也可以在虚机里再分配一个浮动ip后直接参与和外部路由的路由交换从而实现跨数据中心的三层网络SDN化。




LXC容器简介,一种不同于KVM的另类的虚拟化实现方案,容器有效地将由单个OS管理的资源(计算,存储,网络)划分到孤立的组中,与传统的虚拟化相比,这样不需要指令级模拟。避免了虚拟化中系统调用替换中的复杂性。容器是下列两个技术的结合,在chroot的基础上,使用namespace增强chroot环境的隔离性,使之成为有效的容器

  • chroot,linux系统中,根目录就是”/”,但使用chroot可以用任意指定的目录作根目录

  • namespace, 相当于单独的TCP/IP进程,用于网络资源的隔离

通过提供一种创建(创建容器就是将一个名称与一个配置文件关联,lxc-create-n name -f configfile)和进入容器的方式(ssh,VNC (GUI), VT: tty (text),VT:X(GUI),操作系统让应用就像在独立的机器上运行一样,但又能共享很多底层的资源。LXC配置文件的例子如下:

lxc.utsname = my_ssh_container
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 10.0.2.16/24
lxc.network.name = eth0
lxc.mount = ./fstab
lxc.rootfs = ./rootfs

mkdir -p ./rootfs/{bin,dev,etc,lib,lib64,proc,sbin,sys,usr,var}

$ cat./fstab  
/bin /bak/lxc/rootfs/bin none ro,bind 0 0
/sbin /bak/lxc/rootfs/sbin none ro,bind 0 0
/lib /bak/lxc/rootfs/lib none ro,bind 0 0
/lib64 /bak/lxc/rootfs/lib64 none ro,bind 0 0
/etc /bak/lxc/rootfs/etc none ro,bind 0 0
/usr /bak/lxc/rootfs/usr none ro,bind 0 0
/dev /bak/lxc/rootfs/dev none ro,bind 0 0
/dev/pts /bak/lxc/rootfs/dev/pts none ro,bind 0 0
/proc /bak/lxc/rootfs/proc proc defaults 0 0
/sys /bak/lxc/rootfs/sys sysfs defaults 0 0

无论配置文件如何,用LXC工具启动的容器有自己的系统进程视图,以及自己的挂载树和可用的进程间通信(IPC)资源视图。除了这些以外,当一个容器启动时,配置中未提到的任何类型的资源都被认为是与主机共享

一些命令:

创建容器:lxc-create -n name -f configfile

列出容器: lxc-info -n name
显示容器中的进程:lxc-ps
启动系统容器,系统容器类似于虚拟机,但比虚拟机的隔离级别要低:lxc-start -n name init 
启动应用容器,应用容器只是创建一个隔离一个应用程序的单独的名称容间:lxc-execute -n name cmd
发信号到某个容器的所有进程 :lxc-kill -n name -s SIGNAL
暂停,相当于级容器的所有进程发SIGSTOP信号:lxc-freeze -n name
恢复: lxc-unfreeze -n name
停止容器,将杀死容器内的所有进程:lxc-stop -n name




2013.9.29添加:

使用Libvirt管理LXC

1, 定义虚机(/etc/libvirt/lxc/lxc1.xml),相比于qemu虚拟机,lxc不需要设置cdrom、hd等硬件配置,设置信息较少。
$ sudo virsh -c lxc:/// define /bak/lxc/lxc1.xml
$ cat /bak/lxc/lxc1.xml
<domain type='lxc'>
   <name>lxc1</name>
   <memory>512000</memory>
   <vcpu>1</vcpu>
   <cputune>
     <shares>1000</shares>
   </cputune>
   <os>
     <type arch='x86_64'>exe</type>
     <init>/bin/sh</init>

   </os>
   <devices>
     <console type='pty'/>
     <interface type = 'bridge'>
       <source bridge = 'br-phy'/>
       <virtualport type='openvswitch'/>
     </interface>
   </devices>
</domain>

说明,上面只是一个应用容器,和上面不同的地方在于:

1) 执行根文件系统的init脚本

  <os>
    <type arch='x86_64'>exe</type>
    <init>/sbin/init</init>

  </os>

2)在<devices>里可以添加一个根文件系统,这样虚机就可以使用自己的lib,bin等自己的内容了,对于应用容器也可以这样隔离目录但不能隔离根目录(用的就是mount  --bind, 如:mount --bind /tmp/hosts /etc/hosts)。

    <filesystem type='mount' accessmode='passthrough'>
        <source dir='/bak/images/mylinux'/>
        <target dir='/'/>
    </filesystem>

我们可以用下列方法现场做一个根文件系统,

例如linux-0.2.img是一个采用kvm虚机安装的raw格式的镜像,现在将它转成linux内核认识的ext4格式的根文件系统。/mnt/ext4即是我们要用的根。
1), sudo mkdir -p /mnt/{raw,ext4} && sudo mount -o loop linux-0.2.img /mnt/raw
2), dd if=/dev/zero of=linux-0.2.ext4 bs=1M count=22
   mkfs.ext4 linux-0.2.ext4
   sudo mount -o loop linux-0.2.ext4 /mnt/ext4
3), sudo cp -r /mnt/raw/* /mnt/ext4/


2, 命令说明,实际上命令和用操作qemu虚机的一模一样,只不过添加了"-c lxc:///"参数,libvirt默认的是"-c qemu:///"
启动虚机,sudo virsh -c lxc:/// start lxc1
连接虚机,sudo virsh -c lxc:/// console lxc1 ,退出输入“Ctrl+]”。不要使用其他命令退出,如使用“Ctrl+d”,将导致lxc被停止、销毁等。
取消定义, sudo virsh -c lxc:/// undefine lxc1
销毁虚机, sudo virsh -c lxc:/// destroy lxc1

3, 在Virtual Machine Manager图形化界面中操作lxc时,直接创建一个LXC的连接即可。


总结:

从上面我们可以看出,LXC的隔离性做的不大好,它对cpu, memory, network的隔离还好一点,但对存储的隔离不够,尤其对于应用容器,甚至可以从lxc虚机可以访问宿主机的根目录,当然,我们可以自己做一个根文件系统然后使用操作系统容器来隔离。但lxc在这块支持不够啊,全要自己实现,所以还有两个项目docker和dockerlite似乎弥补了这些(我还没来得及看)

       dockerlite 利用 LXC(Linux 容器)实现运行时资源隔离,并利用 Btrfs 文件系统的快照功能完成状态保持和虚拟环境克隆。所谓轻量级虚拟化,也指代操作系统级别的虚拟化,通过内核和用户态进程组的支持,实现的独立网络 IP、进程树等类似虚拟机的隔离运行环境,但是和宿主机运行同样的内核。dockerlite 和另一款用 Go 语言实现的docker的区别有:

  • dockerlite 使用 Shell 脚本实现,而 docker 用 Go。
  • dockerlite 使用 BTRFS 文件系统,而 docker 使用 AUFS。
  • docker 以后台进程方式运行并通过命令行客户端实现操作交互,dockerlite 则无法以后台进程运行。

       docker的主要特性如下:

  • 文件系统隔离:每个进程容器运行在完全独立的根文件系统里
  • 资源隔离:可以使用cgroup为每个进程容器分配不同的系统资源,例如CPU和内存。
  • 网络隔离:每个进程容器运行在自己的网络命名空间里,拥有自己的虚拟接口和IP地址。
  • 写时复制:采用写时复制方式创建根文件系统,这让部署变得极其快捷,并且节省内存和硬盘空间。
  • 日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。
  • 变更管理:容器文件系统的变更可以提交到新的映像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。
  • 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互shell

Docker的使用的大致步骤如下,如果使用dockerlite的话步骤一一对应即可

1, 安装docker, 首先关闭SELinux, 然后使用一个叫 Naresh Kumar制作的docker安装源。
cd /etc/yum.repos.d/
sudo wget -c http://www.hop5.in/yum/el6/hop5.repo
sudo yum install docker-io
docker-io-0.6.2-1.el6.x86_64.rpm                                                                     
lxc-0.9.0-1.el6.x86_64.rpm                                                                              
lxc-libs-0.9.0-1.el6.x86_64.rpm
kernel-ml-aufs-3.10.5-3.el6.x86_64.rpm

2, 启动,
$ sudo docker -d
Loading containers: done.
2013/09/30 10:31:36 WARNING: Your kernel does not support cgroup swap limit.
2013/09/30 10:31:36 Listening for HTTP on /var/run/docker.sock (unix)

3, 下载镜像
   查找镜像,docker search archlinux
$ sudo docker search archlinux
Found 8 results matching your query ("archlinux")
NAME                             DESCRIPTION
schmidh/arch-base                Basic Archlinux installation with base, base-devel, yaourt, packer-color, bash-completion and emacs-nox.  K...
schmidh/cassandra                Archlinux Cassandra installation using JDK 7.25 and Cassandra 1.2.8.
schmidh/immutant                 Archlinux Immutant 1.0.0 installtion with Torquebox overlay, JDK 7.25, Clojure 1.5.1, leiningen 2.
schmidh/clojure                  Archlinux with Clojure and ClojureScript under Oracle JDK 7.25.
schmidh/vertx-clj                Archlinux Vert.x 2.0.1 installation with mod-lang-clojure 0.1.
schmidh/redis                    Archlinux Redis 2.6.15 installation.
schmidh/vertx-base               Archlinux Vertx 2.0.1 base installation.
schmidh/vertx-mod-redis          Archlinux Vertx mod-redis installation.

   下载镜像,sudo docker pull schmidh/arch-base ,存储在/var/lib/docker/目录
   查看镜像,docker images

4, 容器操作, 有了镜像之后,就可以使用run命令来创建容器了,它会在容器内部执行。当命令执行完后,容器就会自动被销毁。(注意:只是容器 被销毁了,镜像还在)
   在容器内运行命令,docker run schmidh/arch-base cat /etc/os-release
   查看运行过的容器的状态, docker ps -l
   运行虚机内部的shell, 可使用exit退出shell, docker run -t -i  schmidh/arch-base bash

5,保存操作,无论在容器内做何种操作,原始的镜像都是不会被改变的。只有通过commit命令进行提交,才能把对镜像的修改保存下来。这类似于对虚拟机磁盘做snapshot。
   例如:在刚才的 arch-base 镜像中安装了一个nginx ,然后进行保存:
   docker run schmidh/arch-base  pacman -S --noconfirm nginx
   docker ps -l
   docker commit 80db3f jianingy/arch-nginx
   docker images
   docker run jianingy/arch-nginx /sbin/nginx -v
   docker run schmidh/arch-base /sbin/nginx -v

6, 虚拟机容器无法连接外网, 须保证:
   sudo sysctl -w net.ipv4.ip_forward=1
   sudo iptables -I FORWARD 1 -i docker+ -j ACCEPT


不管怎么说,研究LXC的根本还应该是cgroup, http://www.cnblogs.com/yjf512/p/3298582.html


Reference:

http://cpqd.github.io/RouteFlow/

lxc,http://www.ibm.com/developerworks/cn/linux/l-lxc-containers/

chroot,http://www.ibm.com/developerworks/cn/linux/l-cn-chroot/

RouteFlow PPT, http://changeofelia.info.ucl.ac.be/pmwiki/uploads/SummerSchool/Program/session_007.pdf



你可能感兴趣的:(RouteFlow与LXC学习 ( by quqi99 ))