Mic_chen

It is not the strongest of the species that survive, nor the most intelligent, but the one most responsive to change

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

经过一段时间对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.

 

posted on 2020-07-31 15:03  Mic_chen  阅读(6072)  评论(0编辑  收藏  举报