嵌入式Linux容器技术

嵌入式Linux容器技术

一、Linux容器技术

  1. Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。

  2. LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与传统虚拟化技术相比,它的优势在于:

    (1)与宿主机使用同一个内核,性能损耗小;

    (2)不需要指令级模拟;

    (3)不需要即时(Just-in-time)编译;

    (4)容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;

    (5)避免了准虚拟化和系统调用替换中的复杂性;

    (6)轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。

    总结:Linux Container是一种轻量级的虚拟化的手段。

  3. Linux Container提供了在单一可控主机节点上支持多个相互隔离的server container同时执行的机制。Linux Container有点像chroot,提供了一个拥有自己进程和网络空间的虚拟环境,但又有别于虚拟机,因为lxc是一种操作系统层次上的资源的虚拟化。

  4. LXC与docker的关系

(1)Docker并不是LXC的替代品,Docker的底层就是使用了LXC来实现的。LXC将Linux进程沙盒化,使得进程之间相互隔离,并且能够控制各
进程的资源分配。

(2)在LXC的基础之上,Docker提供了一系列更强的功能。

二、嵌入式Linux容器

Linux主流的容器包括LXC和Docker,其中LXC是Linux原生的轻量化的容器技术。Docker基于LXC实现,但是,Docker的主要应用场景是云服务
器,其功能十分的强大,但是,其对于嵌入式Linux开发平台的支持可能不那么友好。balenaOS号称对Docker进行了精简,使其可以可靠的运行
于嵌入式Linux环境中。它基于Yocto框架开发,systemd作为init系统。相比较而言,LXC更为轻量化,对于系统资源的要求更低,所以,其天然
的适于嵌入式Linux环境。不过,(balenaOS)docker和LXC各有千秋,需要深度体验之后,才能得出最后的结论。

三、体验容器

3.1 LXC

3.1.1硬件环境

  • allwinner T3
  • Cortex-A7 四核
  • 1G RAM
  • Ubuntu Core 18.04(Linux kernel 3.10.108)

3.1.2 LXC安装

系统要求:

  • 硬性要求:

    1. glibc、libc、uclib中的一种C库
    2. Linux kernel >= 2.6.32
  • lxc-attach额外要求:

    1. Linux kernel >= 3.8
  • 非特权容器额外要求:

    1. libpam-cgfs,cgmanager或其他CGroup管理器为非特权CGroups操作配置系统
    2. 最新版本的shadow,包括newuidmap和newgidmap
    3. Linux kernel >= 3.12
  • 推荐库:

    1. libcap (to allow for capability drops)
    2. libapparmor (to set a different apparmor profile for the container)
    3. libselinux (to set a different selinux context for the container)
    4. libseccomp (to set a seccomp policy for the container)
    5. libgnutls (for various checksumming)
    6. liblua (for the LUA binding)
    7. python3-dev (for the python3 binding)

Ubuntu环境下,LXC的安装十分的简单,只需一个命令就可以完成LXC的安装,包括其依赖的所有库文件:

	$sudo  apt-get  install  lxc

3.1.3 创建非特权容器

无特权容器是最安全的容器。那些使用uid和gid的映射来为容器分配一系列uid和gids。这意味着容器中的uid 0(root)实际上就像容器外的uid 100000。因此,如果出现问题并且攻击者设法逃离容器,他们将发现自己拥有与无人用户一样多的权利。

不幸的是,这也意味着不允许以下常见操作:

  • 安装大多数文件系统
  • 创建设备节点
  • 针对映射集之外的uid / gid的任何操作

注:,因为本次测试的Ubuntu Core环境的内核版本为3.10.108,所以,系统不支非特权容器。

3.1.4 创建特权容器

**注:**下面创建的容器为特权容器,即,容器通过root创建和启动。

lxc安装完成之后,可以使用lxc-checkconfig检测Linux内核是否支持容器。

	$ lxc-checkconfig

	--- Namespaces ---
	Namespaces: enabled
	Utsname namespace: enabled
	Ipc namespace: enabled
	Pid namespace: enabled
	**User namespace: missing**
	Network namespace: enabled
	Multiple /dev/pts instances: enabled
	
	--- Control groups ---
	Cgroups: enabled
	
	Cgroup v1 mount points: 
	/sys/fs/cgroup/systemd
	/sys/fs/cgroup/blkio
	/sys/fs/cgroup/cpuset
	/sys/fs/cgroup/devices
	/sys/fs/cgroup/perf_event
	/sys/fs/cgroup/cpu,cpuacct
	/sys/fs/cgroup/memory
	/sys/fs/cgroup/freezer
	
	Cgroup v2 mount points: 
	
	
	Cgroup v1 clone_children flag: enabled
	Cgroup device: enabled
	Cgroup sched: enabled
	Cgroup cpu account: enabled
	Cgroup memory controller: enabled
	Cgroup cpuset: enabled
	
	--- Misc ---
	Veth pair device: enabled, loaded
	Macvlan: enabled, not loaded
	Vlan: enabled, not loaded
	Bridges: enabled, loaded
	Advanced netfilter: enabled, not loaded
	CONFIG_NF_NAT_IPV4: enabled, loaded
	CONFIG_NF_NAT_IPV6: enabled, not loaded
	CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
	CONFIG_IP6_NF_TARGET_MASQUERADE: enabled, not loaded
	CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled, loaded
	CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded
	FUSE (for use with lxcfs): enabled, not loaded
	
	--- Checkpoint/Restore ---
	checkpoint restore: enabled
	CONFIG_FHANDLE: enabled
	CONFIG_EVENTFD: enabled
	CONFIG_EPOLL: enabled
	CONFIG_UNIX_DIAG: enabled
	CONFIG_INET_DIAG: enabled
	CONFIG_PACKET_DIAG: enabled
	CONFIG_NETLINK_DIAG: enabled
	File capabilities: 
	
	Note : Before booting a new kernel, you can check its configuration
	usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

该命令会根据内核的.config文件,检测内核对于容器的支持情况。

lxc-create用于创建一个容器,lxc在创建一个容器时,提供了很多模板,这些模板的位置:/usr/share/lxc/templates/目录下。

	sudo lxc-busybox  lxc-download  lxc-local  lxc-oci

下面,通过lxc-download,创一个distribution为Ubuntu,release为bionic,并且arch为armhf的容器:

	sudo lxc-create -n c1 -t download

上面的命令用于创建一个名为c1的容器,键入该命令后,其会提示输入系统、系统的版本、架构等参数,之后,lxc会下载对应的容器的rootfs。rootfs下载的时间可能比较长,其下载成功之后,说明容器已经下载成功了。rootfs的目录位于:/var/lib/lxc/c1目录,其包括一个config配置文件和rootfs系统。

通过lxc-ls可以看到系统中已经部署了c1容器,lxc-info可以查看c1当前的运行状态。

lxc-start用于启动一个容器,具体参数可以通过lxc-start -h查看。

    sudo lxc-start -n c1 -o logfile -d

问题

1.apparmor配置问题

	  1 lxc-start c1 20190812055509.777 ERROR    apparmor - lsm/apparmor.c:apparmor_process_label_set:223 - If you really want to start this container, set
	  2 lxc-start c1 20190812055509.812 ERROR    apparmor - lsm/apparmor.c:apparmor_process_label_set:224 -lxc.apparmor.allow_incomplete = 1
	  3 lxc-start c1 20190812055509.822 ERROR    apparmor - lsm/apparmor.c:apparmor_process_label_set:225 - in your container configuration file
	  4 lxc-start c1 20190812055509.842 ERROR    sync - sync.c:__sync_wait:62 - An error occurred in another process (expected sequence number 5)
	  5 lxc-start c1 20190812055509.908 ERROR    lxccontainer - lxccontainer.c:wait_on_daemonized_start:842 - Received container state "ABORTING" instead of "RUNNING"
	  6 lxc-start c1 20190812055509.953 ERROR    lxc_start - tools/lxc_start.c:main:330 - The container failed to start
	  7 lxc-start c1 20190812055509.970 ERROR    lxc_start - tools/lxc_start.c:main:333 - To get more details, run the container in foreground mode
	  8 lxc-start c1 20190812055509.984 ERROR    lxc_start - tools/lxc_start.c:main:336 - Additional information can be obtained by setting the --logfile and --logpriority options
	  9 lxc-start c1 20190812055509.577 ERROR    start - start.c:__lxc_start:1939 - Failed to spawn container "c1"

通过分析日志,可知需要在容器的配置文件里,添加一条"lxc.apparmor.allow_incomplete = 1"。c1容器的配置文件为/var/lib/lxc/c1/config,将这一条配置添加到config末尾。

完成如上步骤之后,再次启动容器c1,仍然没有启动成功,错误日志为:

	  1 lxc-start c1 20190812034836.659 ERROR    lsm - lsm/lsm.c:lsm_process_label_set_at:174 - No such file or directory - Failed to set AppArmor label "lxc-container-default"
	  2 lxc-start c1 20190812034836.659 ERROR    apparmor - lsm/apparmor.c:apparmor_process_label_set:245 - Failed to change apparmor profile to lxc-container-default
	  3 lxc-start c1 20190812034836.660 ERROR    sync - sync.c:__sync_wait:62 - An error occurred in another process (expected sequence number 5)
	  4 lxc-start c1 20190812034836.660 ERROR    lxccontainer - lxccontainer.c:wait_on_daemonized_start:842 - Received container state "ABORTING" instead of "RUNNING"
	  5 lxc-start c1 20190812034836.661 ERROR    lxc_start - tools/lxc_start.c:main:330 - The container failed to start
	  6 lxc-start c1 20190812034836.662 ERROR    lxc_start - tools/lxc_start.c:main:333 - To get more details, run the container in foreground mode
	  7 lxc-start c1 20190812034836.662 ERROR    lxc_start - tools/lxc_start.c:main:336 - Additional information can be obtained by setting the --logfile and --logpriority options
	  8 lxc-start c1 20190812034836.719 ERROR    start - start.c:__lxc_start:1939 - Failed to spawn container "c1"

分析日志,AppArmor找不到 "lxc-container-default"配置文件。AppArmor是Linux内核提供的下类似于SeLinux的安全模块,Ubuntu默认
支持该功能。但是,Ubuntu Core默认并不支持apparmor_status和apparmor_parser工具,而且系统中自带的profile配置文件很少,可以
通过可以通过sudo apt-get install apparmor-profiles进行安装,上面的apparmor_status、apparmor_parser工具也会一并安装。

apparmor profile安装完成之后,需要重启apparmor,启动方法如下:

	Start : sudo /etc/init.d/apparmor start
	Stop : sudo /etc/init.d/apparmor stop
	reload: sudo /etc/init.d/apparmor reload
	Show status: sudo /etc/init.d/apparmor status

通过sudo lxc-info -n c1可以查看,容器的运行状态:

	sudo lxc-info -n c1
	
	Name:           c1
	State:          RUNNING
	PID:            2993
	IP:             10.0.3.81
	CPU use:        1.87 seconds
	BlkIO use:      18.83 MiB
	Memory use:     22.02 MiB
	KMem use:       0 bytes
	Link:           vethLWC02H
	 TX bytes:      1.04 KiB
	 RX bytes:      1.12 KiB
	 Total bytes:   2.16 KiB

可以看到当前c1容器当前的系统资源使用率。

通过lxc-attach命令,可以得到一个与容器进行交互的shell,例如

   sudo lxc-attach -n c1

attach成功之后,会进入到一个shell终端,

	#root@c1:

可以通过lxc-attach执行容器中任何命令,例如:

	sudo lxc-attach -n c1 ls
	sudo lxc-attach -n c1 top

可以将APP打包成deb,然后将deb拷贝到容器rootfs的适当的位置,最后,通过lxc-attach命令执行进行deb的安装。

	sudo lxc-attach -n c1 -- dpkg -i /home/ubuntu/app.deb  //安装app.deb
	sudo lxc-attach -n c1 -- dpkg  -r /home/ubuntu/app.deb //卸载app.deb

该终端提供了Ubuntu几乎所有的功能,例如,apt,但是,该Ubuntu却是以容器的方式运行与Ubuntu Core物理主机下的。

最后,lxc-stop可以关闭容器,lxc-destroy删除容器相关的一切配置文件,包括rootfs。

3.2 LXD

未完待续 。。。 。。。

3.3 BalenaOS

未完待续 。。。。。。

发布了119 篇原创文章 · 获赞 125 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/linux_embedded/article/details/99436441