LXC容器部署總結筆記


經過一段時間對lxc容器部署的實踐和理解,階段性總結如下:

對於arm,按LXC提供工具的正常的流程:

   checkconfig:配置內核,使lxc-checconfig的所有項變綠色。(其實lxc-checkconfig只是一個對內核.config壓縮包進行檢查的腳本)

    create:使用template,從模板的發行版(如alpine,ubuntu)的官網鏡像源下載對應的rooft,放到/var或者/usr/local/var目錄;

    start:將rootfs mount到/usr/local/lib目錄,建立必要的網絡服務(因此在此之前先建立虛擬網橋服務);

對於csky:

   checkconfig:因為rootfs里沒有包含congfig.gz文件,可以手動打包然后運行lxc-checkconfig檢查;

    create:因為生態問題,目前發行版的鏡像源還不支持arch=csky,因此需要手動將rootfs和config放置到指定目錄,然后通過lxc-ls確認;

    start:基本和arm一致,會碰到因為工具鏈和rootfs支持不完善導致的問題,具體見下面的詳細筆記;

 

==========   詳細筆記  =========

1. LXC 容器部署(imx6

LXCLinux Container容器,是一種內核虛擬化技術,可以提供輕量級的虛擬化,以便隔離進程和資源。Linux容器功能是基於 cgroups Namespace 來實現的. 所以要了解 Linux 容器必須先了解 cgroup Namespace

1.1 虛擬機環境

1.1.1 安裝LXC服務

1apt-get install lxc。

2lxc-checkconfig,檢查當前Linux內核支持LXC的情況。要是一切都已被啟用,內核對LXC的支持已准備就緒。

1.1.2 使用LXC

1、lxc-create -n lxc-ubuntu -t ubuntu:

-n指定容器名

-t 指定模板名,這里必須為ubuntu。

其中配置模板在/usr/share/

默認創建與本地主機同一版本號和同一架構的最小Ubuntu安裝系統容器存儲在/var/lib/lxc/<container-name>,根文件系統則位於/var/lib/lxc/<container-name>/rootfs。LXC創建過程中下載的所有程序包則緩存在/var/cache/lxc里面

2、 lxc-ls --fancy:查看容器列表,

 

3、lxc-start -n lxc-ubuntu:啟動lxc容器。后面加-F  可以把啟動過程放在前台,會打印更多的調試信息。

4、brctl show lxcbr0 :確認容器的接口(vethSS7RB5)自動連接到LXC的內部網橋(lxcbr0

 

5、lxc-console -n lxc-ubuntu:登入容器的控制台,提示需要輸入用戶名和密碼,默認都是ubuntu,退出控制台使用exit

6、lxc-stop -n lxc-ubuntu:停止容器,注意需要在另一個終端輸入。

1.1.3 遇到過的問題:

1、在虛擬機上重新start容器時:不知道是之前使用了destroy,還是強制關閉虛擬機了,lxc-start的時候提示“lxc_ovs_attach_bridge: 1817 Failed to attach "lxcbr0" to openvswitch bridge "vethDSDW29"”,通過ifconfig發現lxcbr0網卡沒有了,通過apt-get卸載,重新安裝才解決。dpkg --listapt-get --purge remove 包名(--purge是可選項,寫上這個屬性是將軟件及其配置文件一並刪除)

 

1.2 Imx6目標板環境

1.2.1 編譯lxc

下載lxc2.0.0版本

1、設置環境變量:

. /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa9hf-neon-poky-linux-gnueabi

利用nxp自帶的環境變量配置腳本,設置當前環境變量:CCLDLIB

2、配置檢查:./configure --build=x86_64-linux --host= --target=arm-poky-linux --bindir=/home/cql/imx6/lxc-2.0.0/bin。檢查通過后會執行

. /configure相關概念

--build=編譯該軟件所使用的平台

--host=該軟件將運行的平台

--target=該軟件所處理的目標平台

3、編譯make

4、安裝:make install

5、將生成的工具集打包通過ssh放到目標板:scp -r lxc_bin root@192.168.199.102:/usr/sbin/lxc_bin

6、執行lxc-checkconfig看內核還缺哪些服務,如下如所示,需要將內核的對應配置打開,重新編譯內核。

 

1.2.2 配置內核

根據lxc-checkconfig的運行結果,查看當前內核還差哪些服務,根據服務重新配置內核。

1、執行make menuconfig。如果虛擬機缺少ncurses,需要先安裝apt-get install libncurses5-dev。

2、如果在menuconfig中搜索不到選項的關鍵字,需要查看lxc-checkconfig腳本代碼,確認錯誤打印的實際條件。

1.2.3 編譯內核

1make menuconfig

如果提示make menuconfig   fatal error ncurses.h;是因為缺少圖形化動態庫ncurses;通過apt-get install libncurses5-dev解決。又提示:recipe for target  'script/kconfig/dochecklx;重啟虛擬機解決。

2make distclean

3make imx_v7_defconfig

4make zImage 提示:make /bin/sh: 1: lzop: not found,虛擬機缺少lzop壓縮工具,使用apt-get install lzop后解決

5make dtbs

6make modules

1.2.4 構建容器

1、將模板拷貝到目標板:scp  -r templates/ root@192.168.199.228:/usr/local/share/lxc/。並設置可執行權限。

2、將配置文件從lxc-2.0.0/config/templates拷貝到目標板:scp  -r config/templates/* root@192.168.199.228:/usr/local/share/lxc/config/

3、lxc工具集拷貝到目標板:scp  ../bin/* root@192.168.199.129:/sbin/

4、將動態庫拷貝到目標板:scp  src/lxc/liblxc.so root@192.168.199.129:/usr/local/lib;並創建軟連接:ln -s /usr/local/lib/liblxc.so /usr/lib/liblxc.so.1。后面工具集使用的需要用到軟連接。

5、修改/usr/local/share/lxc/template/lxc-xxx編輯模板:將fetch函數wget超時增加到100

6、創建容器:lxc_create -n lxc0 -t alpine

7、啟動容器:lxc-start -n lxc0  -o /dev/stdout -l debug -F。

8、查看lxc版本:lxc-device --version

9、

1.2.5 重要目錄說明:

1、容器的模板路勁:/usr/local/share/lxc/templates。不同的lxc版本路徑有變化,這個對應的是lxc2.0.0,比如筆者虛擬機上lxc2.0.11的目錄是/usr/local/share/lxc/templates。通過閱讀模板腳本可以看到其他目錄的差異。

2、容器的文件系統路徑:/usr/local/var/lib/lxc$(lxcname)/rootfs,虛擬機是:/var/lib/lxc/$(lxcname)/rootfs/

3、容器的配置文件路徑:/usr/local/var/lib/lxc$(lxcname)/config,虛擬機是:/var/lib/lxc/$(lxcname)/config

4、

1.2.6 遇到過的問題:

1、配置lxc編譯腳本的時候:./configure一直有問題,cannot find crt1.o”等各種錯誤,config.log上看是鏈接出錯,反復調整CC--build--host--target還是沒有效果,最后還是使用nxp的環境變量腳本更方便一些。

2、編譯內核前配置的時候:make menuconfig,提示“fatal error ncurses.h”;是因為缺少圖形化動態庫ncurses;通過apt-get install libncurses5-dev解決。又提示:recipe for target  'script/kconfig/dochecklx;重啟虛擬機解決。

3、創建容器的時候,lxc-create -n lxc0 -t alpine -l debug提示:lxc-create: utils.c: get_template_path: 1427 Permission denied - bad template: alpine。查看模板的路徑和內容均確認是正確的。因為template文件是腳本,需要可執行權限,chmod 777 /usr/local/share/lxc/templates/*,提高權限,解決。

4、創建lxc容器的時候:lxc-create -n lxc0 -t alpine,提示“wget: server returned error: HTTP/1.1 400 Bad Request”,直接使用wget工具測試“wget http://www.bai.com”,發現是可以下載網頁的,但是使用wget https://alpinelinux.org/keys/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub,是不行的,提示相同的錯誤。應該是wget軟件問題,去https://www.busybox.net/查看busybox的版本發布說明,wget在筆者使用的busybox_1.27.2這個版本之后確實有修復wget的問題。

5、繼續創建容器:提示sha256sum: WARNING: 1 computed checksum did NOT match”。直接使用sha256sum相應的.pub文件,確實有問題,查看文件內容,和虛擬機相應文件對比,明顯不對,應該是之前wget下載錯誤導致,刪除.pub,解決。

6、繼續創建容器:提示下載apk_tool超時,再次創建的時候直接解壓apk_tool失敗,想起alpine的模板腳本的fetch函數里配置的是wget -T 10,超時時間可能不夠,修改超時時間到100,解決。

7、創建容器的時候,提示錯誤:lxc-create: utils.c: get_template_path: 1340 Permission denied - bad template: alpine”。閱讀代碼發現是access錯誤,應是沒有權限,給templatesconfig都加上操作權限,解決。

8、啟動容器的時候:提示lxc-start 20200714015606.656 ERROR    lxc_start - start.c:lxc_spawn:1093 - failed initializing cgroup support”,放開調試打印:lxc-start -n lxc0  -o /dev/stdout -l debug -Flxc-start 20200714041349.939 ERROR    lxc_cgfs - cgfs.c:do_setup_cgroup_limits:1993 - No such file or directory - Error setting devices.deny to a for lxc0”。官網查到應該是2.0.0的版本對不支持systemd的內核有bug,這個在后面的版本中有修復。通過在/etc/fstab文件中加入掛載信息解決:

cgroup               /sys/fs/cgroup         cgroup     defaults              0  0

重啟后系統會自動掛載文件系統。

9、Linux內核配置文件打包在/proc/config.gz

 

 

 

 

 

 

1. LXC容器部署(csky)

1.1 編譯lxc

1、設置環境變量:. /opt/csky-toolchain/environment-setup-csky。利用通用的環境變量配置腳本,設置當前環境變量:CCLDLIB

2、配置檢查:/configure --build=x86_64-linux --host=csky-abiv2-linux --target=csky-abiv2-linux --bindir=/home/cql/fuxi_h/lxc-2.x.x/bin

--build=編譯該軟件所使用的平台

--host=該軟件將運行的平台

--target=該軟件所處理的目標平台

3、編譯make

4、安裝:make install

5、執行lxc-checkconfig看內核還缺哪些服務,如下如所示,需要將內核的對應配置打開,重新編譯內核。

1.2 內核配置

1、將默認配置覆蓋到../obj/.config,在內核目錄執行:make ARCH=csky CROSS_COMPILE=/opt/csky-toolchain/bin/csky-linux-gnuabiv2- O=../obj/ fx6evb_defconfig

2、根據上面lxc-checkconfig的檢測結果配置內核:Make ARCH=csky  O=../obj/ menuconfig。(注:配置CONFIG_NF_NAT_IPV4 需要先打開 NF_CONNTRACK,其他的根據宏名稱搜索即可)

3、編譯內核並把內核和roofs一起打包到imagemake ARCH=csky CROSS_COMPILE=/opt/csky-toolchain/bin/csky-abiv2-linux- CONFIG_INITRAMFS_SOURCE=/home/cql/fuxi_h/rootfs/work/fx6/tmp_fs O=../obj -j8

1.3 創建容器

   因為通過模板來創建lxc的時候,需要從發行版官網下載和arch相對應的鏡像,cksy的生態不健全,各個發行版還不支持csky,所以不能使用lxc_create -n lxc0 -t alpine來創建容器。

手動將rootfsconfig文件拷貝到/usr/local/var/lib/lxc/lxcXXX/或者/var/lib/lxc/lxcXXX目錄下(自己編譯的庫liblxc.so.1.0.0使用的前者路徑,虛擬機和默認的liblxc.so.l.6.0使用的是后者,具體什么原因還確定),這個時候就可以通過lxc-ls看看有沒有lxcXXX

環境構建:

1mount -t cgroup none /root/cgroupfs(目錄可以隨意,這樣在/proc/1/cgroup文件才有內容)

2、執行lxc-net,創建虛擬網橋,通過ifconfig確認網橋lxcbr0是否OK

1.4 啟動容器

1、輸入命令lxc-start -n lxc0 -l debug  -o /tmp/lxclog12

1.5 進入容器

1、lxc-attach -n lxc0

2、

1.6 退出容器

鍵入exit即可退出容器

1.7 配置網絡

1.7.1 主機網絡配置:

1、配置dns:更改/etc/resolv.confsearch lan nameserver 192.168.199.1

2、重啟網絡服務:/etc/init.d/S40network restart。

3、確認能ping通外網:ping www.baidu.com

1.7.2 容器網絡配置:

1、修改啟動腳本/et/init.d/rcS

/sbin/ifconfig eth0 10.0.3.100 netmask 255.255.255.0

/sbin/route add default gw 10.0.3.1 eth0

2、重啟容器:驗證可以ping通外網。

1.8 遇到過的問題

1## Booting kernel from Legacy Image at 00080000 ...

   Image Name:   fx6-kernel-iamge

   Image Type:   CSKY Linux Kernel Image (uncompressed)

   Data Size:    10435776 Bytes = 10 MiB

   Load Address: 00080000

   Entry Point:  00080000

   Verifying Checksum ... Bad Data CRC

ERROR: can't get kernel image!

==》內核大小超過了扇區大小,檢查uboot的配置和dd命令的大小。

Uboot查看分區大小:pr;修改內核分區大小命令:env set flash_kernel_size 0x900000。

==》使用浙大的rootfsrcS替換南網自制的,實現啟動。

 

2lxc-start: lxc0: cgroups/cgroup.c: cgroup_init: 54 Failed to initialize cgroup driver

==cg_hybrid_init函數中需要訪問read_file("/proc/1/cgroup");內核的這個文件是空的,導致lxc start異常退出。

a.meuconfig:General setup-->Control Group support下選擇你們想要的cgroup

b.重新編譯,啟動,在shell界面把cgroup掛載到一個目錄(path/dir)下,即運行命令mount -t cgroup none path/dir

c.就能/proc/1/cgroup文件中看到內容了

3lxc-start: lxc0: storage/dir.c: dir_mount: 198 No such file or directory - Failed to mount "/var/lib/lxc/lxc-busybox/rootfs" on "/usr/local/lib/lxc/rootfs"

==》在/var路勁中配置rootfs路徑,lxc啟動會將這個目錄mount/usr目錄。

4lxc-start lxc0 19700101001039.724 ERROR    conf - conf.c:lxc_allocate_ttys:1001 - No such file or directory - Failed to create tty 0

lxc-start lxc0 19700101001039.728 ERROR    conf - conf.c:lxc_create_ttys:1102 - Failed to allocate ttys

==》參考lxc源碼自帶的重新openpty.c文件實現openpty函數

4conf - conf.c:setup_caps:2567 - unknown capability sys_module

lxc-start lxc0 19700101005037.568 ERROR    conf - conf.c:lxc_setup:3806 - Failed to drop capabilities

==》在lxc_setup函數中屏蔽掉setup_caps

根本原因分析:configure腳本通過檢查工具鏈是否包含libcap相關的庫和頭文件來決定是否在config.h中打開宏HAVE_LIBCAP,如果這個宏沒有打開,將會導致了setup_caps的匹配失敗。

 

待優化解決方案:構建工具鏈的時候需要開啟libcap選項,因為默認使用動態庫,rootfs也需要libcap.so.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM