美文网首页程序员
[原创] 移植LXC容器到高通MDM9607设备上的测试过程

[原创] 移植LXC容器到高通MDM9607设备上的测试过程

作者: 赵国开 | 来源:发表于2017-12-09 16:56 被阅读0次

    1 沙盒介绍


    沙盒是用来隔离运行中程序的一种安全机制,通常是为了缓解系统的故障或者软件缺陷的传递。比如可以用来执行未测试或者不信任的程序/代码,这样就可以把对操作系统的危害隔离开来。从提供一个高度控制环境角度来说,可以把沙盒看作是一种虚拟化的特殊例子。沙盒的实现方式有很多实现,如:

    • 类似jail,主要实现网络访问控制, 文件系统命名空间限制。
    • 虚拟机来仿真一个完整的主机,在虚拟机上常规的操作系统可以从真实的硬件上启动和运行。
    • seccomp是linux内核自带的一个沙盒。如果启用 seccomp 将只允许调用 write(), read(), exit(), sigreturn() 系统调用。
    • 还有很多其他实现具体可以参考
      维基百科上的介绍

    2 沙盒选型


    本次基于虚拟化来实现沙盒机制,可供选择的项目有下面这些:

    image.png
    具体可以参考维基百科上的介绍
    下面简要介绍一些项目:

    2.1 chroot

    可以改变当前运行进程和他的子进程显示的目录。运行在这个环境的程序只能访问它自己的目录,不能访问外面的目录。但是他的功能很简单,如上图所示,除了对文件系统的部分隔离之外,其他的特性都是不能用的(红色)。

    2.2 docker

    是Docker公司开发的的一个软件容器,可以运行在多种操作系统上,linux/MAC/windows等。它是操作系统层级的虚拟化,在操作系统层提供了抽象和自动化的一个虚拟化。Docker功能很丰富如上图所示,很多特性可用(绿色)。Docker很强大被集成到很多商业的基础工具中比如:
    Amazon Web Services, Ansible,CFEngine,Chef,Google Cloud Platform, IBM Bluemix,HPE Helion Stackato, Jelastic,Jenkins,Kubernetes,Microsoft Azure,OpenStack Nova,OpenSVC,Oracle Container Cloud Service,Puppet,Salt,Vagrant,and VMware vSphere Integrated Containers.

    2.3 LXC

    LXC是Linux containers的简称,是一种基于容器的操作系统层级的虚拟化技术。LXC功能很丰富如上图所示,很多特性可用(绿色)。LXC是利用Linux内核安全特性而设计的一个用户层接口,他是一个完全开源的项目。通过提供强大的API接口和一些简单的工具,它使linux用户很容易创建和管理系统/应用级的容器。lxc有这些特点:

    • 虚拟化开销小(LXC的诸多特性基本由内核提供,而内核实现这些特性只有极少的花费)。
    • 快速部署。利用LXC来隔离特定应用,只需要安装LXC,即可使用LXC相关命令来创建并启动容器来为应用提供虚拟执行环境。传统的虚拟化技术则需要先创建虚拟机,然后安装系统,再部署应用。

    具体介绍可以参考官网

    2.4 方案确定

    根据chroot,docker,lxc技术特点,功能,开发难度,最终选择lxc容器作为沙盒进行移植开发(Chroot太简单,docker又比较复杂。LXC开发难度适中,系统开销低等,功能基本能满足安全需求)。

    3 lxc开发介绍


    开发调试环境
    1)硬件使用搭载高通MDM9607 MCU的设备
    2)交叉编译工具:oecore-x86_64-armv7a-vfp-neon-toolchain-nodistro.0.sh

    Lxc包含内核层和用户层(用户层包括工具和库)。在用户层工具可以直接通过命令行来实现容器,也可以使用对应的库自己编码对容器相关操作进行使用(提供了函数调用接口)。

    3.1 内核配置

    LXC需要内核一些模块的支持,需要把相关的内核选型选上,具体可以参考
    官网man手册

    • 内核版本要求:Linux kernel >= 2.6.32
    $bitbake -c menuconfig linux-quic
    
    image.png
    Control Group support
    全部选上
    image.png
    Checkpoint/restore support
    选上
    image.png
    Namespaces support
    全部选上
    image.png
    Support multiple instances of devpts
    选上
    image.png
    MAC-VLAN support
    Virtual ethernet pair device
    选上
    image.png
    802.1d Ethernet Bridging
    选上
    • 我在我的编译环境下只能通过下面的方式才能编译成功,其他方法试过都不行。完成相关操作之后把.config保存起来,比如我这边是
    $cp apps_proc/poky/build/tmp-glibc/work/mdm9607-oe-linux-gnueabi/linux-quic/git-r5/build/.config ~/.
    $bitbake linux-quic  -c cleanall 
    $cp ~/.config  kernel/msm-3.18/arch/arm/configs/L170YX_defconfig
    $./buildL170YXSHIP app
    

    3.2 lxc源码库编译

    重新开一个终端,不然和之前bitbake的编译环境会有冲突。
    Lxc项目最新的源码可以到https://github.com/lxc/lxc下载
    1)下载源码:

    $git clone https://github.com/lxc/lxc.git
    

    2)配置交叉编译的环境,我的是:

    $source ~/local/environment-setup-armv7a-vfp-neon-oe-linux-gnueabi 
    

    3)配置编译
    我的编译目录是/home/zgk/lxc/lxc

    $cd /home/zgk/lxc/lxc
    $make maintainer-clean
    $./autogen.sh
    $./configure --prefix=/home/zgk/lxc/test --host=arm-oe-linux-gnueabi --target=arm-oe-linux-gnueabi --build=x86_64-linux
    $make
    $sudo make install
    

    备注:

    • configure的命令行变量--prefix指定最终编译结果的输出,需要指定一下方便打包下载到设备;--host指定编译后的源码运行的环境;--target目标类型;--build编译的环境。
    • Git直接clone现在下载下来的是stable-2.1的分支版本,我有checkout到stable-1.1分支版本进行编译并下载到设备上进行测试无法测试成功,从出错结果查看可能是我们交叉编译环境配置参数有些问题不适合该版本,有尝试调整了一些编译参数,无果最终放弃测试。

    4)编译结果打包

     $tar cf test.tar test
    

    3.3 设备上环境配置

    把编译好的内核镜像mdm9607-boot.img烧录到设备上之后。可以对设备使用容器环境进行配置。
    1)安装路径配置
    我在主机编译环境中是把相关的编译结果放在/home/zgk/lxc/test位置。如果你使用lxc工具默认配置的话最好,也把test.tar放到该目录下。

    #mkdir -p /home/zgk/lxc
    #adb push test.tar /home/zkg/lxc
    #tar xf test.tar
    

    结果会自动解压到test目录

    • 备注:如果根目录被挂载成只读的,需要重新挂载为可读写的,才能在上面操作
    #mount -o rw,remount /
    

    2)配置环境变量
    增加动态库搜索路径和可执行程序的搜索路径

    #export LD_LIBRARY_PATH=/home/zgk/lxc/test/lib:$LD_LIBRARY_PATH
    #export PATH=/home/zgk/lxc/test/bin:$PATH
    

    3)为容器配置网络
    我这边是根据现有设备环境直接进行配置,仅提供一个参考

    #ifconfig lo up
    #ifconfig rndis0 0.0.0.0
    #ifconfig bridge0 172.16.90.184
    #brctl setfd bridge0 0
    #route add default gw 172.16.90.1 bridge0
    

    4)cgroup节点挂载

    #mkdir -p /cgroup
    #mount -t cgroup cgroup /cgroup
    

    5)检查容器的环境
    看是否已经配置好了

    #lxc-checkconfig
    

    输出无红色的说明容器运行基本环境已经配置好了,下面是我这边配置完检查的结果:

    --- Namespaces ---
    Namespaces: enabled
    Utsname namespace: enabled
    Ipc namespace: enabled
    Pid namespace: enabled
    User namespace: enabled
    newuidmap is not installed
    newgidmap is not installed
    Network namespace: enabled
    Multiple /dev/pts instances: enabled
    --- Control groups ---
    Cgroups: enabled
    
    Cgroup v1 mount points:
    /cgroup
    
    Cgroup v2 mount points:
    
    Cgroup v1 systemd controller: /home/zgk/lxc/test/bin/lxc-checkconfig: line 158: printf \033[1;31m: not found
    
    Cgroup v1 freezer controller: /home/zgk/lxc/test/bin/lxc-checkconfig: line 165: printf \033[1;31m: not found
    
    Cgroup v1 clone_children flag: enabled
    Cgroup device: enabled
    Cgroup sched: enabled
    Cgroup cpu account: enabled
    Cgroup memory controller: enabled
    
    --- Misc ---
    Veth pair device: enabled, not loaded
    Macvlan: enabled, not loaded
    Vlan: missing
    Bridges: enabled, not loaded
    Advanced netfilter: enabled, not loaded
    CONFIG_NF_NAT_IPV4: enabled, not loaded
    CONFIG_NF_NAT_IPV6: missing
    CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
    CONFIG_IP6_NF_TARGET_MASQUERADE: missing
    CONFIG_NETFILTER_XT_TARGET_CHECKSUM: missingCONFIG_NETFILTER_XT_MATCH_COMMENT: missing
    FUSE (for use with lxcfs): missing
    
    --- Checkpoint/Restore ---
    checkpoint restore: enabled
    CONFIG_FHANDLE: missing
    CONFIG_EVENTFD: enabled
    CONFIG_EPOLL: enabled
    CONFIG_UNIX_DIAG: missing
    CONFIG_INET_DIAG: enabled
    CONFIG_PACKET_DIAG: missing
    

    3.4 容器使用简介

    安装完之后设备的/home/zgk/lxc/test/bin目录有下面工具可以使用:

    lxc-attach 
    lxc-copy           
    lxc-ls            
    lxc-unshare   
    lxc-autostart      
    lxc-create         
    lxc-monitor    
    lxc-update-config  
    lxc-cgroup         
    lxc-destroy        
    lxc-snapshot       
    lxc-usernsexec     
    lxc-checkconfig    
    lxc-device         
    lxc-start          
    lxc-wait           
    lxc-checkpoint     
    lxc-execute        
    lxc-stop
    lxc-config        
    lxc-freeze         
    lxc-top            
    lxc-console        
    lxc-info           
    lxc-unfreeze
    

    工具的使用可以参考https://linuxcontainers.org/lxc/manpages/
    1)创建容器

    #lxc-create -n foo -f ./lxc.conf -t none
    

    -n指定容器的名字
    -f指定容器的配置文件,不指定的话就会使用默认的配置
    -t指定使用什么模板,我这里不使用模板
    我这里的配置文件lxc.conf内容如下:

    lxc.uts.name = virtfoo
    lxc.net.0.type = veth
    lxc.net.0.flags = up
    lxc.net.0.link = bridge0
    lxc.net.0.ipv4.address = 172.16.90.20/24
    lxc.net.0.name = rndis0
    lxc.rootfs.path = /
    

    lxc.rootfs.path指定容器根文件系统的目录,不指定的话和操作系统是共享根目录的,我这里只是测试就把它设成和操作系统是同一的,如果实际要安全考虑需要指定容器自己的根文件系统的目录。容器里面的程序只能访问该指定目录下的文件,之外的无法访问。
    2)启动容器

    #lxc-start -n foo
    

    3)在容器中运行自己的程序
    我这边自己写了个测试程序hello。

    #lxc-attach -n foo ./hello
    

    4)查询容器的状态

    #lxc-info -n foo
    

    5)停止容器

    #lxc-stop -n foo
    

    6)销毁容器

    #lxc-destroy -n foo
    

    7)通过API接口进行调用

    • lxccontainer.h里面定义了提供给C语言调用的API接口。在我的环境下是在目录/home/zgk/lxc/test/include/lxc/
    • 具体的实现在目录/home/zgk/lxc/test/lib/下,有静态库和动态库看开发需要进行选择liblxc.so/liblxc.la
    • 样例代码可以参考官网https://linuxcontainers.org/lxc/documentation

    参考文献


    [1] https://en.wikipedia.org/wiki/Operating-system-level_virtualization#IMPLEMENTATIONS
    [2] https://en.wikipedia.org/wiki/Seccomp
    [3] https://en.wikipedia.org/wiki/Chroot
    [4] https://www.ibm.com/developerworks/linux/library/l-lxc-containers/
    [5] http://www.linuxcertif.com/man/7/lxc/
    [6] http://www.cnblogs.com/lisperl/tag/%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF/
    [7] https://www.ibm.com/developerworks/cn/linux/l-lxc-containers/
    [8] https://www.ibm.com/developerworks/cn/linux/theme/virtualization/
    [9] https://github.com/lxc/lxc

    相关文章

      网友评论

        本文标题:[原创] 移植LXC容器到高通MDM9607设备上的测试过程

        本文链接:https://www.haomeiwen.com/subject/rdtpixtx.html