一、Linux容器技术
- Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。
- LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与传统虚拟化技术相比,它的优势在于:
(1)与宿主机使用同一个内核,性能损耗小;
(2)不需要指令级模拟;
(3)不需要即时(Just-in-time)编译;
(4)容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;
(5)避免了准虚拟化和系统调用替换中的复杂性;
(6)轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。
总结:Linux Container是一种轻量级的虚拟化的手段。
- Linux Container提供了在单一可控主机节点上支持多个相互隔离的server container同时执行的机制。Linux Container有点像chroot,提供了一个拥有自己进程和网络空间的虚拟环境,但又有别于虚拟机,因为lxc是一种操作系统层次上的资源的虚拟化。
- 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安装
系统要求:
- 硬性要求:
- glibc、libc、uclib中的一种C库
- Linux kernel >= 2.6.32
- lxc-attach额外要求:
- Linux kernel >= 3.8
- 非特权容器额外要求:
- libpam-cgfs,cgmanager或其他CGroup管理器为非特权CGroups操作配置系统
- 最新版本的shadow,包括newuidmap和newgidmap
- Linux kernel >= 3.12
- 推荐库:
- libcap (to allow for capability drops)
- libapparmor (to set a different apparmor profile for the container)
- libselinux (to set a different selinux context for the container)
- libseccomp (to set a seccomp policy for the container)
- libgnutls (for various checksumming)
- liblua (for the LUA binding)
- 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
未完待续 。。。。。。