嵌入式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

未完待續 。。。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章