https://github.com/lxc/lxc
LXC是Linux containers的简称,操作系统级别的虚拟化技术。它可以在操作系统层次上为进程提供的虚拟的执行环境。一个虚拟的执行环境被称为一个容器(container)。可以为容器绑定特定的cpu和memory节点,分配特定比例的cpu时间、IO时间,限制可以使用的内存大小(包括内存和是swap空间),提供device访问控制,提供独立的namespace(网络、pid、ipc、mnt、uts)。
容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不需要指令级模拟,也不需要即时编译。容器可以在核心 CPU 本地运行指令,而不需要任何专门的解释机制。此外,也避免了准虚拟化(paravirtualization)和系统调用替换中的复杂性。
lxc-version 用于显示系统LXC的版本号(可以通过此命令判断系统是否安装了lxc)
用法:lxc-version
例如:lxc-version
lxc-checkconfig 用于判断linux内核是否支持LXC
用法:lxc-checkconfig
例如:lxc-checkconfig
lxc-create用于创建一个容器
用法:lxc-create -n name [-f config_file]
-n 后面跟要创建的容器名字 例如:-n foo
-f 后面跟容器配置文件的路径
注:1.采用lxc-create创建的容器,在停止运行后,不会被销毁,要采用lxc-destroy命令才能销毁
2.容器命令空间是全局的,系统中不允许存在重名的容器,如果-n 后面跟一个已经存在的容器名,创建会失败
例如:lxc-create –n foo –f foo.conf
lxc-execute 用于在一个容器执行应用程序
用法: lxc-execute -n name [-f config_file] [ -s KEY=VAL ]command
-n 后面跟容器名字(容器名字用于管理容器)例如:-n foo
-f 后面跟容器配置文件的路径(如果没有配置文件,可以直接用-s指定配置选项,如果什么都没有,系统采用默认策略)例如:-f foo.conf
-s 后面跟配置键值对 例如:lxc.cgroup.cpu.shares=512
command 为要执行的命令 例如:/bin/bash
注:1.如果容器还不存在,lxc-execute会自动创建一个,容器停止运行后会被自动销毁
2.用lxc-execute启动应用程序,配置优先级如下:
如果指定-f选项,那么之前创建容器(如果容器是已存在的)的配置文件不会被使用
如果没有指定-f选项,那么将采用之前创建容器(如果容器已存在)的配置文件
如果指定-s选项,则在命令行中的配置键值对会覆盖配置文件(无论之前的还是-f指定的)相同配置
例如:lxc-execute –n foo –s lxc.cgroup.cpu.shares=512 /bin/bash
lxc-start 用于在容器中执行给定命令
用法:lxc-start -n name [-f config_file] [-c console_file] [-d] [-s KEY=VAL]
[command]
-d 将容器当做守护进程执行
-f 后面跟配置文件
-c 指定一个文件作为容器console的输出,如果不指定,将输出到终端
-s 指定配置
例如:lxc-start -n foo -f foo.conf -d /bin/bash
注:1.如果容器还不存在,lxc-start会自动创建一个,容器停止运行后会被自动销毁
2.lxc-start配置优先级与lxc-execute相同
3.lxc-start 与lxc.execute的异同:
lxc-start 和 lxc-execute都可以在容器中启动进程,区别在于lxc-start直接创建进程,lxc-execute先创建lxc-init进程,然后在lxc-init中fork一个进程来执行。
The orphan process group and daemon are not supported by this command,
use the lxc-execute command instead.
If no command is specified, lxc-start will use the default "/sbin/init"
command to run a system container.
4.lxc-start用于在容器启动system,lxc-execute用于在容器执行应用程序
lxc-kill 发送信号给容器中的第一个用户进程(容器内部进程号为2的进程)
用法:lxc-kil -n name SIGNUM
-n 后面跟容器名
SIGNUM 信号 (此参数可选,默认SIGKILL)
例如:lxc-kill -n foo
lxc-stop 用于停止容器中所有的进程
用法:lxc-stop -n name
-n后面跟要停止的容器名
例如:lxc-stop –n foo
lxc-destroy 用于销毁容器
用法:lxc-destroy -n name
-n后面跟要停止的容器名
例如: lxc-destroy –n foo
lxc-cgroup 用于获取或调整与cgroup相关的参数
用法:lxc-cgroup -n name subsystem value
-n 后面跟要调整的容器名
例如: lxc-cgroup -n foo devices.list
lxc-cgroup -n foo cpuset.cpus "0,3"
lxc-info 用户获取一个容器的状态
用法:lxc-info -n name
-n后面跟操作的容器名
例如: lxc-info –n foo
注:容器的状态有:STARTING RUNNING STOPPING STOPPED ABORTING
lxc-monitor 监控一个容器状态的变换,当一个容器的状态变化时,此命令会在屏幕上打印出容器的状态
用法:lxc-monitor -n name
例如:lxc-monitor -n foo
lxc-ls 列出当前系统所有的容器
用法:lxc-ls
例如:lxc-ls
lxc-ps 列出特定容器中运行的进程
用法:lxc-ps
例如:lxc-ps -n foo
更多的命令介绍可以再man page获得
http://manpages.ubuntu.com/manpages/lucid/man7/lxc.7.html
安装
sudo apt-get install lxc
查看系统模板
ls /usr/share/lxc/templates/
lxc-alpine lxc-centos lxc-fedora lxc-oracle
lxc-altlinux lxc-cirros lxc-gentoo lxc-plamo
lxc-archlinux lxc-debian lxc-openmandriva lxc-sshd
lxc-busybox lxc-download lxc-opensuse lxc-ubuntu
创建系统
要花费很多时间
sudo lxc-create -t ubuntu -n zqw
启动
sudo lxc-start -n zqw -d
显示lxc创建的系统
sudo lxc-ls
通过控制台进入系统
sudo lxc-console -n zqw, 就可以在系统内执行shell啦
停止
lxc-stop -n zqw
通过配置文件进入系统
lxc.tty = 4
lxc.pts = 1024
lxc.rootfs = ROOTFS
lxc.arch = ARCH
lxc.cgroup.devices.deny = a
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
lxc.cgroup.devices.allow = c 254:0 rwm
lxc.mount.entry=proc ROOTFS/proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry=sysfs ROOTFS/sys sysfs defaults 0 0
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = GUESTLINK
lxc.network.ipv4 = GUESTIP/24
lxc.network.ipv4.gateway = auto
lxc.utsname = gitian
sudo lxc-start -n gitian -f gitian-builder/var/lxc.config
sudo lxc-attach -n gitian -f gitian-builder/var/lxc.config
) 安装lxc工具包
2) 检查内核是否支持lxc容器
如果输出所有项均为enbale状态,则表明内核支持lxc容器,否则需重新编译内核打开相应功能项。
3) 通过shell在容器中运行一个程序(超级用户下)
a) 在当前目录下编译配置文件conf.txt,其内容为:
#Simplest lxc configuration
lxc.utsname = name
b) 挂载cgroup
c) 输入如下shell命令
d) 输出结果为
hello world
4) 编辑/etc/fstab,使得在系统启动时自动挂载cgroup
3 lxc工具集
3.1 创建和销毁容器
3.1.1 lxc-create
lxc-create -n name [-f config_file] [ -t template]
创建一个系统对象来存储配置和用户信息,该对象保存/usr/local/var/lib/lxc(注意该目录为版本相关的,不同版本的lxc可能不同)目录下,name为其标示符。如果配置文件未指定,则系统会支持默认的资源隔离:PID,sysv IPC和挂载点。
例如:
创建容器test,可在/usr/local/var/lib/lxc目录下发现创建了目录test,该文件中包含了默认的配置文件config
3.1.2 lxc-destroy
lxc-destroy -n name
销毁一个名称为name的容器,主要删除在/usr/local/var/lib/lxc中相应的文件,注意一定要在容器处于STOPPED状态时才能销毁容器.
例如:
销毁容器test.
3.2 在容器中运行与结束应用
3.2.1 lxc-execute和lxc-start
a) lxc-execute -n name [-f config_file] [-s EKY=VAL] command
在指定的容器name中运行由command指定的命令。如果容器name未创建,则lxc-execute使用指定的配置文件创建容器name。该命令通过中间进程lxc-init来启动需要运行的命令,并且lxc-init在创建命令后会等待该命令执行结束。因此lxc-init进程的pid为1,运行的命令的pid为2。
b) lxc-start -n name [-f config_file] [-s KEY=VAL] command
lxc-start在指定容器name中运行command指定的命令。注意lxc-start不支持孤儿进程组和守护进程,且如果command未指定,则会运行/sbin/init命令。
例如:
注意,lxc-create用于在容器中运行一个应用,而lxc-start则用于在容器中运行一个系统。
3.2.2 lxc-stop
lxc-stop -n name
终止容器name的运行。
例如:
3.3 lxc-console
如果创建容器时候配置了tty,可通过如下命令连接到tty
lxc-console -n test -t 3 #连接到容器test的3号tty上。
3.4 冻结和解冻容器
3.4.1 lxc-freeze
lxc-freeze -n name
冻结所有在容器name中运行的程序,此处冻结是指挂起所有在指定容器中运行的程序。必须显式的使用lxc-ufreeze命令解除冻结。
#lxc-freeze -n foo #冻结容器foo中运行的所有程序
3.4.2 lxc-unfreeze
lxc-unfreeze -n name
解除容器name的冻结状态.
#lxc-ufreeze -n foo #将foo中冻结的程序恢复运行。
注意:该功能需要内核打开相应的功能!
3.5 获取容器的信息
3.5.1 lxc-ls
列出系统中存在的所有容器,选项和ls命令相同。
3.5.2 lxc-info
lxc-info -n name
列出容器name的运行信息:输出格式如下:
name is stopped
name is running
3.5.3 lxc-ps
显示特定容器的pids,选项和ps相同,为内置的ps
3.5.4 lxc-netstat
显示指定容器的网络状态,该命令建立在命令netstat之上,因此接受于netstat相同的参数。
3.5.5 lxc-cgroup
lxc-cgroup -n name subsystem [value]
显示或者设置与控制组相关联的子系统的值,如果value未指定则显示其值,否则设定相应子系统的值。
例如:
lxc-cgroup -n foo devices.list #显示允许容器foo使用的设备列表
lxc-cgroup -n foo cpuset.cpus “0,3” #将处理器0和3分配给容器foo
3.6监控容器
3.6.1 lxc-monitor
lxc-monitor -n name
监控指定容器的状态,其中名称为正则表达式。
例如:
lxc-monitor -n ‘foo|bar’ #监控容器foo和bar
lxc-monitor -n ‘.’ #监控所有容器
lxc-monitor -n ‘[f|b].’ #监控所有名称以f或b开始的容器
3.6.2 lxc-wait
lxc-wait -n name -s states
等待容器到达某一状态,然后退出,其中states可为若干状态.
例如:
lxc-wait -n foo ‘RUNNING’ #等待容器到RUNNING状态
lxc-wait -n foo ‘RUNNING|STOPPED’ #等待容器到达RUNNING或者STOPPED状态
注意:容器的状态分为:STOPPED, STARTING ,RUNNING, STOPPING, ABORTING.
3.6.3 lxc-kill
lxc-kill -n name SIGNUM
lxc-kill将信号SIGNUM发送给容器中的第一个进程。
例如:
lxc-kill -n foo 2 #向foo中第一个进程发送SIGINT信号
注意:如果使用lxc-execute运行的命令,信号首先发送给lxc-init,然后lxc-init将该信号传递给运行的第二个进程。如果发送的信号使得lxc-init进程终止,那么该信号不会传递给运行的第二个进程,并且导致容器中得应用结束运行。
4 lxc配置
每个lxc容器都对应于一个配置文件,该文件可在使用lxc-create、lxc-execute和lxc-start命令时指定,如果通过lxc-create创建的容器,则会在/var/lib/lxc/container-name/config中保存该配置。配置信息包括:主机名、网络、cgroup信息等。lxc配置文件中每一行采用key=val的形式,每行保存一个配置项。注释以#开头。
4.1 配置主机名
lxc.utsname = foo #配置主机名为foo
4.2 配置容器使用的虚拟化网络
lxc.network.type: 指定容器使用的虚拟化网络类型,该域一般为新的网络配置的开始,其可能值为:
值 类型
empty 创建仅有回路接口的网络
veth 创建一个对等网络,该网络的一端分配给容器,另一端与lxc.network.link指定的网桥连接。如果未指定网桥,端设备会被创建但是不会连接到任何网桥上。在默认情况下lxc会对容器外的网络设备选择一个名字,但是可以通过lxc.network.veth.pair选项来指定。
vlan 创建一个由lxc.network.link指定的虚拟局域网接口(网卡)分配给容器,vlan的标识符可由lxc.network.vlan.id指定。
phys 将由lxc.network.link指定的已经存在的接口(网卡)分配给容器。
macvlan 创建一个macvlan接口,该接口和由lxc.network.link指定的接口相连接。
lxc.network.flags:指定网络将要执行的动作,可选值为:
on:激活接口
down:关闭接口
lxc.network.link:指定用于进行真实网络通信的接口(网卡)。
lxc.network.name:指定网络接口的名称,在默认情况下,接口名称是动态分配的。
lxc.network.hwaddr:指定虚拟网络接口(虚拟网卡)的MAC地址,在默认情况下,该值自动分配。
lxc.network.ipv4:指定分配给虚拟网卡的ipv4地址。
lxc.network.ipv6:指定分配给虚拟网卡的ipv6地址。
4.3 容器伪终端和系统控制台
lxc.pts:如果该项被设置,容器将要拥有一个新的伪终端,并且该终端为容器所私有。该值指定了该伪终端可拥有的最大实例数。
lxc.console:指定控制台输出文件的路径
lxc.tty:指定容器可得到的tty数量,注意在inittab中getty的数量不能超过指定的值。
4.4 挂载点
lxc.mount:指定包含挂载信息的文件,该文件内容采用fstab格式。fstab格式如下:
spec file type options dump pass
spec:所需加载文件系统所在的设备或远程文件系统。
file:文件系统的挂载点。
type:文件系统类型.
options:加载文件系统的参数。
dump:文件系统转储频率,若不需转储则为0.
pass:启动时扫描文件系统的顺序。根文件系统为1,其他为2,若启动时无需扫描则为0.
如下是一个典型的fstab文件:
none /lxc/rootfs.fedora/dev/pts devpts defaults 0 0
none /lxc/rootfs.fedora/proc proc defaults 0 0
none /lxc/rootfs.fedora/sys sysfs defaults 0 0
lxc.mount.entry: 指定一个挂载点,该行采用fstab格式。
4.5 根文件系统
lxc.rootfs:指定容器的根文件系统,若该项未指定,则采用和主机相同的根文件系统。
例如:
lxc.rootfs=/lxc/test/rootfs
lxc.rootfs.mount:指定调用pivot_root前lxc.rootfs绑定点,一般情况下使用默认值即可。
备注:pivot_root改变根文件系统,格式为:pivot_root new_root put_old。pivot_root将当前进程的根文件系统移动到目录put_old下,并使得new_root作为新的根文件系统。
lxc.pivotdir:指定原始根文件系统在lxc.rootfs下的支点(pivot)。
4.6 控制组配置
4.6.1 控制组CPU配置
lxc.cgroup.cpu.shares:该组的CPU时间份额,默认情况下该值为1024。通过将该值修改为较大值,则该组会获得更多的CPU时间,否则,该组获得的CPU时间会相对较少。比如系统中仅存在控制组A和B ,这两个组中cpu.shares的值分别为1024和2048,则A获得1/3的CPU时间,B获得2/3的时间。注意,子控制组获得CPU时间份额不能超过其父控制组的CPU时间份额。
lxc.cgroup.cpu.rt_period_us:该项指定了控制组CUP资源分配的周期,以防止某些任务一直占用CPU资源。该项以微秒为单位。
lxc.cgroup.cpu.rt_runtime_us :定义了在CUP资源分配周期内控制组中连续占用的CPU资源的时间长度,时间以微秒为单位。比如CUP资源分配周期为5s,控制组连续占用最长时间为4s,则rt_period_us = 5000000,rt_runtime_us=4000000。
4.6.2 块设备配置
lxc.cgroup.blkio.weight:指定当前组块设备优先级权重,权重允许的范围为100~1000.
在控制组中另外只读的项:
blkio.time:控制组中指定使用块设备的时间(毫秒),格式为:major:minor times,其中前两个域为主从设备号,第三个域为时间。
blkio.sectors:组传输的扇区数,格式为:major:minor sectors,其中前两个域为主从设备号,第三个域为传输的扇区数。
4.6.3 CUP计数信息(非配置信息)
在控制组中cpu时间统计信息项:
cpuacct.stat:显示CPU时间信息,显示信息包括两个部分:user和system,分别为用户态和内核态运行的时间。
cpuacct.usage:显示控制组中进程消耗的cpu时间统计。可通过向该文件中写入0来清空时间计数。
cpuacct.usage_percpu:显示控制组中每个cpu时间统计。
4.6.4 CPU集合配置
lxc.cgroup.cpuset.cpus:在cpuset中得cpu列表。列表中cpu从0开始编号,如果系统中存在100个cpu那么cpu的编号为0~99.
例如:
lxc.cgroup.cpuset.cpus = 0-9 #将0到9号CPU分配给该组
lxc.cgroup.cpuset.cpus = 0,3,4-6 #将0,3,4,5,6号CPU分配给该组
注意:该项指定的CPU集合必须为父cpu集合的子集。
lxc.cgroup.cpuset.mems:分配给该cpuset的内存节点列表,例如:
lxc.cgroup.cpuset.mems = 0,1 #将内存节点0和1分配给该组
lxc.cgroup.cpuset.memory_migrate: 如果该项设置为真,当将一个任务连接到新的cpuset时,任务所在前cpuset中分配给该任务的页也被迁移到新的cpuset中,并且尝试确保页所在节点列表的相对位置不变。比如,分配给任务的某一页在前cpuset内存节点中的第二个节点中,则迁移时会尝试将其放到新的cpuset内存节点列表中第二个内存节点中。此外,如果设定了该项,当cpuset中的内存节点列表(cpuset.mems)发生变化时,分配给任务的页被迁移到新的内存节点列表的节点中。
lxc.cgroup.cpuset.cpu_exclusive:cpuset中cpu独占标记,只有在父cpuset设定该项后,子cpuset才可设置该项。当设定该项后,除了祖先和后代cpuset外,lxc.cgroup.cpuset.cpus指定的cpu不允许出现在任何其他cpuset的cpu列表中。
lxc.cgroup.cpuset.mem_exclusive:cpuset中内存节点独占标记。配置规则和lxc.cgroup.cpuset.cpu_exclusive相同。
lxc.cgroup.cpuset.memory_hadwall:该项指定内核分配内存页和缓存数据时是否仅限于从分配给cpuset的内存节点中分配。在默认情况下,该项是关闭的,内核分配的内存页和缓存由多个用户所共享。
lxc.cgroup.cpuset.memory_spread_page和lxc.cgroup.cpuset.memory_spread_slab:这两项控制内核应该从什么地方分配文件系统和相关内核数据结构所需的页。如果lxc.cgroup.cpuset.memory_spread_page项为真,那么内核倾向于在发生缺页的任务允许使用的所有内存节点中均匀的分配内存;否则,会倾向于在任务运行的节点上分配内存。在默认情况下,这两项是关闭的。
例如:
lxc.cgroup.cpuset.memory_spread_page = 1 # 打开spread page cache功能
lxc.cgroup.cpuset.memory_spread_slab = 0 # 关闭spread slab cache功能
lxc.cgroup.cpuset.sched_load_balance:如果设定该项为真,内核会对整个cpuset中得所有CPU进行负载平衡调度。
注意:如果两个重叠的cpuset均打开了该项,那么它们必须在同一个调度域中。
lxc.cgroup.cpuset.sched_relax_domain_level:请求内核改变进行负载平衡时的CPU搜索范围,如果lxc.cgroup.cpuset.sched_load_balance为假,则该项不起作用。其可选等级如下:
-1 : no request. use system default or follow request of others.
0 : no search.
1 : search siblings (hyperthreads in a core).
2 : search cores in a package.
3 : search cpus in a node [= system wide on non-NUMA system]
( 4 : search nodes in a chunk of node [on NUMA system] )
( 5 : search system wide [on NUMA system] )
4.6.5 设备白名单
lxc.cgroup.devices.allow:将设备添加到白名单中。
lxc.cgroup.devices.deny:将设备从白名单中删除。
当前控制组中的白名单列表可从devices.list中得到,白名单列表的每个入口包含四个域,其形式如下:
type major:minor access
其中type可选值为:a , c , b ,a表示所有设备,c为字符设备,b为块设备。
major和minor为设备的主从设备号,用整数或者表示所有设备。
access为访问权限的结合r(读),w(写)和m(mknod)。
例如:
c 1:3 mr #允许对/dev/null进行读和mknode操作。
a *: rwm #允许对所有设备进行读写和mknode操作。
4.6.6 内存配置
lxc.cgroup.memory.limit_in_bytes:当前组的内存使用的最大数。
例如:
lxc.cgroup.memory.limit_in_bytes = 4096 #设定内存限制为4094字节
lxc.cgroup.memory.limit_in_bytes = 4K #设定内存限制为4K
lxc.cgroup.memory.limit_in_bytes = 256M #设定内存限制为256M
lxc.cgroup.memory.limit_in_bytes = 1G #设定内存限制为1G字节
lxc.cgroup.memory.limit_in_bytes = -1 #设定内存为无限制
lxc.cgroup.memory.memsw.limit_in_bytes:设定当前组中内存+对换空间的限制,设定方式和lxc.cgroup.memory.limit_in_bytes相同,但需保证lxc.cgroup.memory.limit_in_bytes <= lxc.cgroup.memory.memsw.limit_in_bytes.
lxc.cgroup.memory.soft_limit_in_bytes:设定内存软限制,这使得系统更大程度上的共享内存,当系统检测到内存争用和短缺时,控制组的内存限制被退回到软限制,防止导致其他控制组饥饿的发生。设定该值时一般要小于硬限制,否则该值会被硬限制所覆盖。
lxc.cgroup.memory.use_hierarchy:打开内存的层次记账功能,注意如果父控制组已经打开该功能,则子控制组对该项的设置将不起作用。
lxc.cgroup.memory.swappiness:设定控制组的对换区的大小,在默认情况下为60。可选值为0~100。
内存子系统其他报告信息项:
memory.stat:显示内存使用的统计信息。
memory.usage_in_bytes:报告当前容器中应用使用的内存量(字节)。
memory.memsw.usage_in_bytes:报告当前容器使用的内存+对换空间的总量。
memory.max_usage_in_bytes:报告容器中内存使用量的最大值。
memory.memsw.max_usage_in_bytes:报告内存+对换空间的最大使用量。
memory.failcnt:应用使用内存数量达到memory.limit_in_bytes的次数。
memory.memsw_failcnt:应用使用内存+对换空间数量达到memory.memsw.limit_in_bytes的次数。
4.6.7 冷冻配置
lxc.cgroup.freezer.state:挂起或者恢复控制组中的任务,其可选值如下:
FROZEN:挂起控制组中得任务
THAWED:恢复控制组中任务的运行。
在配置文件中配置该项为FROZEN可使得应用在容器开始运行的状态为挂起状态。在默认情况下该值设定为THAWED。注意,无法向处于冷冻状态的控制组中添加任务。
4.6.8 网络通信配置
net_cls子系统通过对网络包进行标记从而使得linux流量控制器(tc)识别网络报来自于那个特定的控制组,从而获得该网络包的优先级。
lxc.cgroup.net_cls.classid:该值指示了当前控制组的类别句柄(handle),该值采用十六进制表示。句柄的格式如下:0xAAAABBBB其中AAAA是十六进制主ID号,BBBB是十六进制从ID号,比如0x100001表示10:1(iproute2工具集使用十六进制表示句柄ID)。此处设定的为linux流量控制器中的类标识符。具体可参考TC相关信息。
4.6.9 权限配置
如果容器作为超级用户运行,指定其可放弃的权限。
lxc.cap.drop:指定容器放弃的权限。该行指定了一些用空格分隔的权限。权限的格式为相应权限定义除去CAP_前缀后的小写形式,比如CAP_SYS_MODULE使用sys_module指定,通过指定sys_chroot可剥夺容器中所有进程进行chroot的权限,附录7.3中显示容器放弃的执行权限,注意,被剥夺的权限不能被恢复,即使root也没有权限来恢复被剥夺的权限,只能重启系统或者重新运行容器并将相应配置选项移除。
例:
lxc.cap.drop = sys_module mknod setuid net_raw
lxc.cap.drop = mac_override
lxc.cap.drop = sys_chroot
4.6.10 其他配置项
notify_on_release:当该项被打开时,在控制组最后一个程序结束时,内核执行由release_agent指定的程序。在默认情况下该项是关闭的。
release_agent:保存控制组中最后一个程序结束运行时执行的程序的路径,该项只在根控制组中出现。
5 连接容器实例
5.1 运行Fedora基本安装虚拟机
1)安装febootstrap工具
yum install febootstrap
2) 生成fedora基本安装系统
mkdir /lxc
cd /lxc
febootstrap fedora-13 rootfs.fedora
在rootfs.fedora目录下生成了基本安装的fedora13系统。
3) 基本安装文件不能直接在linux容器使用,需做如下修改:
1、由于udev不在lxc容器中运行,首先需要人工创建需要的设备,编写脚本如下:
#!/bin/bash
ROOT=$(pwd)
DEV=${ROOT}/dev
if [ $ROOT = ‘/’ ]; then
printf “\033[22;35m\nDO NOT RUN ON THE HOST NODE\n\n”
tput sgr0
exit 1
fi
if [ ! -d $DEV ]; then
printf “\033[01;33m\nRun this script in rootfs\n\n”
tput sgr0
exit 1
fi
rm -rf ${DEV}
mkdir ${DEV}
mknod -m 666 ${DEV}/null c 1 3
mknod -m 666 ${DEV}/zero c 1 5
mknod -m 666 ${DEV}/random c 1 8
mknod -m 666 ${DEV}/urandom c 1 9
mkdir -m 755 ${DEV}/pts
mkdir -m 1777 ${DEV}/shm
mknod -m 666 ${DEV}/tty c 5 0
mknod -m 666 ${DEV}/tty0 c 4 0
mknod -m 666 ${DEV}/tty1 c 4 1
mknod -m 666 ${DEV}/tty2 c 4 2
mknod -m 666 ${DEV}/tty3 c 4 3
mknod -m 666 ${DEV}/tty4 c 4 4
mknod -m 600 ${DEV}/console c 5 1
mknod -m 666 ${DEV}/full c 1 7
mknod -m 600 ${DEV}/initctl p
mknod -m 666 ${DEV}/ptmx c 5 2
exit 0
保存到/usr/local/bin/lxc-config中,并添加可执行权限。
chmod u+x /usr/local/bin/lxc-config
切换到rootfs.fedora下运行该脚本:
cd /lxc/rootfs.fedora
/usr/local/bin/lxc-config
2、配置rootfs.fedora
cp /etc/resolv.conf /lxc/rootfs.fedora/etc
chroot /lxc/rootfs.fedora /bin/bash
#挂载proc , sys, /dev/pts
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts
#添加一些应用
yum update
yum -y reinstall glibc-common
yum install httpd php-mysql mysql-server nano openssh-clients vim
#在/下添加一些必要的文件
touch /etc/fstab
rm /etc/mtab
ln -s /proc/mounts /etc/mtab
#卸载proc ,sys和/dev/pts
umount -t proc none /proc
umount -t sysfs none /sys
umount -t devpts none /dev/pts
#设定根密码
passwd
3、根文件系统配置
编辑/lxc/rootfs.feodar/etc/sysconfig/init文件,将最后一行改为:
ACTIVE_CONSOLES = /dev/tty[1-4]
编辑/lxc/rootfs.fedora/etc/rc.sysinit将下行注释掉:
/sbin/start_udev
编辑/lxc/rootfs.fedora/etc/sysconfig/network添加如下两行:
NETWORKING=yes
HOSTNAME=fedora
4、创建lxc配置文件/lxc/config.fedora
lxc.utsname = fedora
lxc.tty = 4
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.name = eth0
lxc.network.mtu = 1500
lxc.network.ipv4 = 192.168.0.65/24
lxc.rootfs = /lxc/rootfs.fedora
lxc.mount = /lxc/fstab.fedora
lxc.cgroup.devices.deny = a
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
lxc.cgroup.devices.allow = c 254:0 rwm
5、创建fstab文件/lxc/fstab.fedora
none /lxc/rootfs.fedora/dev/pts devpts defaults 0 0
none /lxc/rootfs.fedora/proc proc defaults 0 0
none /lxc/rootfs.fedora/sys sysfs defaults 0 0
/etc/resolv.conf /lxc/rootfs.fedora/etc/resolv.conf none bind 0 0
6、删除不必要的init脚本
删除/lxc/rootfs.fedora/etc/init目录下,除下述文件外的所有文件:
rc.conf
start-ttys.conf
tty.conf
将rc.conf和start-ttys.conf第一行修改为
start on startup
将rc.conf中最后一行的
exec /etc/rc.d/rc $RUNLEVEL
修改为:
exec /etc/rc.d/rc.fedora
创建/lxc/rootfs.fedora/etc/rc.d/rc.fedora
#!/bin/bash
route add default gw 192.168.1.1
/etc/init.d/rsyslog start &
/etc/init.d/iptables start &
/etc/init.d/sshd start &
/etc/init.d/mysqld start &
/etc/init.d/httpd start &
将其属性设置为可执行:
chmod u+x /lxc/rootfs.fedora/etc/rc.d/rc.fedora
删除/lxc/rootfs.fedora/etc/init.d目录下除下述文件外的所有文件:
httpd
iptables
mysqld
rsyslog
sshd
4) 创建linux容器
创建网桥:
brctl add br0
brctl setfd br0 0
brctl addif br0 eth0
ifconfig br0 192.168.74.130 up #此处应为本机IP地址
ifconfig eth0 0.0.0.0 up
route add -net default gw 192.168.74.2 br0 #设置网关
创建容器
lxc-create -f /lxc/config.fedora -n fedora
运行容器
lxc-start -n fedora #lxc-start在未指定运行的命令的情况下默认执行init程序
连接到该容器,你会看到登陆界面:
lxc-console -n fedora
注意:在登陆后需用根用户添加网关才能联网:
route add -net default gw 192.168.74.2 eth0
6 网络流量配置
6.1 lxc运行虚拟机网络流量配置
linux容器通过内核流量控制子系统(traffic control subsystem)对流量进行限制,配置文件中lxc.net_cls.classid指示了流量控制器中类的标示。现在采用基于容器IP地址的方法,使用如下脚本利用TC工具创建HTB队列规则,tc命令的使用可参考附录和参考部分:
Shell代码 收藏代码
#!/bin/bash
#remove all classful qdisc first
tc qdisc del dev eth0 root
#create root htb qdisc, specify all unclassified packet into subclass 4
tc qdisc add dev eth0 root handle 1:0 htb default 4
#create subclasses
tc class add dev eth0 parent 1:0 classid 1:2 htb rate 256kbps ceil 512kbps prio 0
tc class add dev eth0 parent 1:0 classid 1:3 htb rate 128kbps ceil 256kbps prio 1
tc class add dev eth0 parent 1:0 classid 1:4 htb rate 64kbps ceil 128kbps prio 2
#attach a sfq qdisc for each leaf class
tc qdisc add dev eth0 parent 1:2 handle 2: sfq perturb 5
tc qdisc add dev eth0 parent 1:3 handle 3: sfq perturb 5
tc qdisc add dev eth0 parent 1:4 handle 4: sfq perturb 5
#attach filters to root htb qdisc
tc filter add dev eth0 protocol ip parent 1:0 u32 match ip src 192.168.74.10 flowid 1:2
tc filter add dev eth0 protocol ip parent 1:0 u32 match ip src 192.168.74.30 flowid 1:3
tc filter add dev eth0 protocol ip parent 1:0 u32 match ip src 192.168.74.130 flowid 1:4
注意,此处根据IP地址将数据包放置到不同的class中,也可采用其他的filter来实现不同的分类规则。u32过滤器可根据数据包的信息对数据包进行归类。此外,本章中容器通过配置桥接来进行网络通信,对于其他的链接网络的形式尚未进行测试。
6.2 利用classid进行流量控制
在linux控制组中net_cls子系统通过对网络包打标记classid来表示属于不同控制组的网络包。linux系统中流量控制系统可根据该标记来对控制组的网络包进行控制。注意,net_cls子系统并不是通过修改网络包来打标记的,当网络包通过协议栈的过程中,通过当前的进程上下文来的到控制组信息,进而获得当前网络包的classid,因此,如果网络包被包过滤器处理之前被重新调度,那么就无法获得该包的classid!因此,对于采用6.1中网桥方式进行网络通信的方式,运行fedora虚拟机时无法采用classid对网络包进行分类管理。下面给出了一个简单的利用classid进行网络流量限制的配置脚本,使用的cgroup过滤器,根据网络包进程上下文中得到的classid对网络包进行分类。
Shell代码 收藏代码
#!/bin/bash
dev=eth0
tc qdisc del dev $dev root
tc qdisc add dev $dev parent root handle 10: htb
tc class add dev $dev parent 10: classid 10:1 htb rate 1mbps ceil 1mbps
tc class add dev $dev parent 10:1 classid 10:2 htb rate 256kbps ceil 256kbps
tc class add dev $dev parent 10:1 classid 10:3 htb rate 256kbps ceil 256kbps
tc class add dev $dev parent 10:1 classid 10:4 htb rate 512kbps ceil 1mbps
tc qdisc add dev $dev parent 10:2 handle 2:0 pfifo
tc qdisc add dev $dev parent 10:3 handle 3:0 pfifo
tc qdisc add dev $dev parent 10:4 handle 4:0 pfifo
tc filter add dev $dev parent 10: protocol ip prio 1 handle 10: cgroup
7 附录和参考
7.1 brctl命令简介
该命令用于建立、维护和检查Ethernet网桥在Linux内核中的配置,如下是该命令的简要使用:
brctl addbr
brctl delbr
brctl addif
brctl delif
brctl setfd
a)在接口eth0上创建一个htb qdisc,其句柄为1:0,未分类数据包发送给类1:12
tc qdisc add dev eth0 root handle 1: htb default 12
b)为qdisc创建htb类以及子类
tc class add dev eth0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 60kbps ceil 100kbps
c)为qdisc添加filter,假设A用户的IP地址为1.2.3.4
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4 ip dprot 80 0xFFFF flowid 1:10
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4 flowid 1:11
上面第一行指定A的www服务的包发到类1:10,第二行指定其他包发给类1:11
d)为每个leaf class添加队列(可选)
tc qdisc add dev eth0 parent 1:10 handle 20: pfifo limit 5
tc qdisc add dev eth0 parent 1:11 handle 30: pfifo limit 5
tc qdisc add dev eth0 parent 1:12 handle 40: pfifo limit 10
7.3 超级用户权限
在linux2.2内核开始将超级用户的权限分为若干独立的子权限,每个子权限可独立的禁止或者打开,注意,一旦剥夺了根用户的某一权限,那么除非重启系统,否则无法恢复该权限。下面对这些权限进行简单的介绍:
CAP_CHOWN:允许改变文件的所有权
CAP_DAC_OVERRIDE:忽略对文件的所有DAC访问限制
CAP_DAC_READ_SEARCH:忽略所有对读、搜索操作的限制
CAP_FOWNER:如果文件属于进程的UID,就取消对文件的限制
CAP_FSETID :允许设置setuid位
CAP_KILL :允许对不属于自己的进程发送信号
CAP_SETGID :允许改变组ID
CAP_SETUID :允许改变用户ID
CAP_SETPCAP :允许向其它进程转移能力以及删除其它进程的任意能力
CAP_LINUX_IMMUTABLE :允许修改文件的不可修改(IMMUTABLE)和只添加(APPEND-ONLY)属性
CAP_NET_BIND_SERVICE: 允许绑定到小于1024的端口
CAP_NET_BROADCAST:允许网络广播和多播访问
CAP_NET_ADMIN:允许执行网络管理任务:接口、防火墙和路由等。
CAP_NET_RAW :允许使用原始(raw)套接字
CAP_IPC_LOCK :允许锁定共享内存片段
CAP_IPC_OWNER: 忽略IPC所有权检查
CAP_SYS_MODULE: 插入和删除内核模块
CAP_SYS_RAWIO:允许对ioperm/iopl的访问
CAP_SYS_CHROOT:允许使用chroot()系统调用
CAP_SYS_PTRACE:允许跟踪任何进程
CAP_SYS_PACCT:允许配置进程记帐(process accounting)
CAP_SYS_ADMIN:允许执行系统管理任务:加载/卸载文件系统、设置磁盘配额、开/关交换设备和文件等。
CAP_SYS_BOOT:允许重新启动系统
CAP_SYS_NICE:允许提升优先级,设置其它进程的优先级
CAP_SYS_RESOURCE:忽略资源限制
CAP_SYS_TIME:允许改变系统时钟
CAP_SYS_TTY_CONFIG:允许配置TTY设备
CAP_MKNOD:允许使用mknod()系统调用
CAP_LEASE:Allow taking of leases on files
7.4 cgroup模块编写
lxc建立在cgroup的基础上,在2.6.35以上内核中支持将控制组子系统通过模块的形式加入到内核中,本节演示了如何编写一个控制组子系统模块。在当前的内核中支持的子系统的最大个数为unsigned long类型的bit位数,当前的子系统个数为8个。编写简单过程如下:
1) 定义struct cgroup_subsys结构
C代码 收藏代码
struct cgroup_subsys sample = {
.create = sample_create,
.destroy = sample_destroy,
.populate = sample_populate,
.module = THIS_MODULE,
};
struct cgroup_subsys结构定义了控制组子系统结构,其中主要包含了一些控制组子系统接口和一些属性信息,其中create和destory接口必须定义,这两个接口实现了创建和销毁控制组子系统状态对象。
2) 定义子系统状态结构,该结构中必须要包含struct cgroup_subsys_state结构已便于编程处理.
C代码 收藏代码
struct cgroup_hello_state {
struct cgroup_subsys_state css;
int helloid;
/其他相关信息/
};
3) 定义一个全局变量只是hello子系统的id,记录系统分配给子系统的编号,以便于后面编程处理.
int hello_subsys_id ;
4) 定义子系统在控制组目录中的控制文件接口.
C代码 收藏代码
struct cftype cft[]={
{
.name = “hello”,
.read_u64 = sample_read_u64,
.write_u64 = sample_write_u64,
},
}
struct cftype结构定义了控制文件的处理句柄以及相关名称和属性信息,在这里仅仅实现文件的读写句柄.
5) 实现接口。
完整的代码如下:
C代码 收藏代码
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/cgroup.h>
MODULE_LICENSE(“Dual BSD/GPL”);
/控制组子系统结构/
struct cgroup_hello_state{
struct cgroup_subsys_state css;
int helloid;
/其他状态信息/
};
int hello_subsys_id;
static struct cgroup_subsys_state cgrp_create(struct cgroup_subsys *ss,struct cgroup *cgrp);
static void cgrp_destroy(struct cgroup_subsys *ss,struct cgroup * cgrp);
static int cgrp_populate(struct cgroup_subsys *ss,struct cgroup * cgrp);
static void cgrp_attach(struct cgroup_subsys *ss,struct cgroup * cgrp,struct cgroup *old_cgrp,struct task_struct *task);
/定义控制组子系统结构*/
struct cgroup_subsys cgroup_hello_subsys ={
.name = “hello”,
.create = cgrp_create,
.destroy = cgrp_destroy,
.populate = cgrp_populate,
.attach = cgrp_attach,
.module = THIS_MODULE,
};
static void cgrp_attach(struct cgroup_subsys *ss,struct cgroup * cgrp,struct cgroup *old_cgrp,struct task_struct *task){
printk(KERN_ALERT “%s:%d\n”,func,task->pid);
}
static inline struct cgroup_hello_state *cgrp_hello_state(struct cgroup *cgrp){
return container_of(cgroup_subsys_state(cgrp,hello_subsys_id),struct cgroup_hello_state,css);
}
static struct cgroup_subsys_state cgrp_create(struct cgroup_subsys *ss,struct cgroup *cgrp){
struct cgroup_hello_state *cs;
cs = kmalloc(sizeof(cs),GFP_KERNEL);
if(!cs)
return ERR_PTR(-ENOMEM);
printk(KERN_ALERT “%s\n”,func);
return &cs->css;
}
static void cgrp_destroy(struct cgroup_subsys *ss,struct cgroup * cgrp){
kfree(cgrp_hello_state(cgrp));
}
static u64 read_helloid(struct cgroup cgrp,struct cftype *cft);
static int write_helloid(struct cgroup *cgrp,struct cftype *cft, u64 val);
/控制文件操作对象结构/
struct cftype ss_files[]={
{
.name = “hello”,
.read_u64 = read_helloid,
.write_u64 = write_helloid,
},
};
/创建本子系统的控制文件*/
static int cgrp_populate(struct cgroup_subsys *ss,struct cgroup *cgrp){
return cgroup_add_files(cgrp,ss,ss_files,ARRAY_SIZE(ss_files));
}
static u64 read_helloid(struct cgroup *cgrp, struct cftype *cft){
printk(KERN_ALERT “%s:%s\n”,func,cft->name);
return cgrp_hello_state(cgrp)->helloid;
}
static int write_helloid(struct cgroup *cgrp,struct cftype *cft,u64 val){
printk(KERN_ALERT “%s:%s\n”,func,cft->name);
cgrp_hello_state(cgrp)->helloid = (int)val;
return 0;
}
static int hello_init(void){
int ret;
printk(KERN_ALERT “Hello,world\n”);
ret = cgroup_load_subsys(&cgroup_hello_subsys);
if(ret)
goto out;
hello_subsys_id = cgroup_hello_subsys.subsys_id;
printk(KERN_ALERT “subsys id:%d\n”,hello_subsys_id);
out:
return ret;
}
static void hello_exit(void){
cgroup_unload_subsys(&cgroup_hello_subsys);
printk(KERN_ALERT “Goodbye, cruel world\n”);
}
module_init(hello_init);
module_exit(hello_exit);
LXC的安装包在CentOS的epel源有提供的,使用官网的epel源需要安装一个软件包
yum -y install epel-release #这个软件包里包含epelyum源和GPG的配置
1
安装LXC软件包和依赖包
yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup libvirt
lxc #主程序包
lxc-templates #lxc的配置模板
bridge-utils #网桥管理工具
lxc-libs #lxc所需的库文件
libcgroup #cgroup是为Linux内核提供任务聚集和划分的机制,通过一组参数集合将一些任务组织成一个或多个子系统。
libvirt #管理Linux的虚拟化功能所需的服务器端守护程序。 需要针对特定驱动程序的管理程序。
注:如果要创建debian系列的主机需要再安装一个软件包:debootstrap
可以修改/etc/default/grub文件,使用update-grub重新生成规则。
GRUB_CMDLINE_LINUX_DEFAULT=”cgroup_enable=memory quiet”
在config文件中可以如下限定:
lxc.cgroup.memory.limit_in_bytes = 512M #限定内存
lxc.cgroup.cpuset.cpus = 0 #限定可以使用的核
lxc.cgroup.blkio.throttle.read_bps_device = 8:0 100 #读取速率限定
lxc.cgroup.blkio.throttle.write_bps_device = 8:0 100 #写入速率限定
lxc.cgroup.blkio.throttle.read_iops_device = 8:0 100 #读取频率限定
lxc.cgroup.blkio.throttle.write_iops_device = 8:0 100 #写入频率限定
myhost2 login: root #使用默认用户root
Password: #密码和myhost1的相同
-n,–name #容器的主机名
-f,–config #指定配置文件以配置容器的虚拟化和隔离功能
-t template #调用模板脚本,可执行模板脚本的完整路径也可以作为参数传递。 “none”可用于强制lxc-create跳过rootfs创建。
-B backingstore #指定根文件储存路径的文件系统,可选:dir、lvm、loop、btrfs、zfs、best ,默认为dir,如果是dir可以使用–dir指定lxc主机的根在宿主机的存储路径。
-P, –lxcpath #自定义容器路径。默认值为/var/lib/lxc。
-o, –logfile #输出创建过程到一个日志文件中。
-l, –logpriority #将日志优先级设置为LEVEL,默认优先级为ERROR
– #向template传递参数查看可选参数:lxc-create -t TEMPLATE -h,常用参数如下
-n,–name #容器标识符
-p,–path #指定容器根的创建路径,默认/var/lib/lxc/容器名/
-c,–clean #清除缓存
-R,–release #指定Centos的发行版本
–fqdn #用于DNS和系统命名的完全域名(FQDN)
–repo #指定创建容器是使用的yum源,这个是redhat系统的参数
-a,–arch #指定容器的架构,可选i686,x86_64
lxc-destroy
用法:lxc-destroy {-n name} [-f]
选项:-f, –force #强制删除
lxc-start
用法:lxc-start {-n name} [-f config_file] [-c console_device] [-L console_logfile] [-d] [-F] [-p pid_file] [-s KEY=VAL] [-C] [–share-[net|ipc|uts] name|pid] [command]
选项:
-n #指定容器名
-d, –daemon #后台运行
-F #前台运行,默认选项
-p, –pidfile #创建一个保存了pid的文件
-f, –rcfile #指定配置文件以配置容器的虚拟化和隔离功能。覆盖现有配置文件。
c, –console #指定一个前台运行容器的终端。不指定默认为当前终端。
-L, –console-log #把容器控制台输入保存到一个文件中。
-C, –close-all-fds #如果任何文件描述符被继承,关闭它们。 如果未指定此选项,则lxc-start将退出而失败。 注意:–daemon意味着–close-all-fds。
–share-net name|pid #从其他容器继承网络名称空间。
–share-ipc #从其他容器继承IPC命名空间。
–share-uts #从其他容器继承UTS命名空间。
lxc-autostart
选项:
-r,–reboot #重启容器
-s,–shutdown #设置定时关闭容器,使用-t 设置关闭时间。
-k,–kill #关闭容器
lxc-stop
选项:
-r,–reboot #重启容器
-k,–kill #关闭容器,默认选项
–nokill #挂起容器
–nolock #此选项避免使用任何API lxc锁定。
lxc-info
选项:
-s #显示状态
-p #显示pid
-i #显示IP地址
-S #显示内存使用
-H #显示原始数值
lxc-console
-t #指定连接的tty
lxc-clone
-o,–orig #要克隆的原始容器的名称
-n #新容器的名称
-p, –lxcpath #原始容器的系统文件路径,不选使用系统默认路径
-P, –newpath #新容器的系统文件路径
-K, –keepname #保留原容器的主机名
-M, –keepmac #使用和原容器相同的mac地址
lxc-checkconfig #检查当前内核lxc支持
lxc-config
lxc-monitor
lxc-top #容器统计信息
lxc-usernsexec #以root用户身份在容器内运行任务
可以使用-m 选项指定用户的uid以该用户的身份运行命令
lxc-freeze #冻结容器内运行的所有进程。
lxc-unfreeze #解冻容器内运行的所有进程。
lxc-execute #在指定的容器内运行指定的命令。
lxc-wait
lxc-snapshot #创建,列出和还原容器快照。
快照文件默认保存在var /lib/lxc-snaps/容器名
1
-c,–comment file #将文件中的注释信息和快照关联
-d,–destroy #删除快照
-L,–list #列出所有快照
-C #显示快照注释信息
-r #恢复快照
newname #恢复快照时用于指定容器的名称。可选参数 ,如果没有给出任何名称,则原始容器将被破坏,并且恢复的容器将占据其位置。
注意:在aufs,overlayfs或zfs支持的快照的情况下,删除原始快照是不可能的。
lxc-cgroup
lxc-cgroup在相应子系统的容器cgroup中获取或设置状态对象(例如,’cpuset.cpus’)的值(例如,’cpuset’)。 如果没有指定[value],则显示状态对象的当前值; 否则设置。注意lxc-cgroup不会检查状态对象是否对运行的内核有效,或者对应的子系统包含在任何已安装的cgroup层次结构中
lxc-cgroup {-n name} {state-object} [value]
lxc-unshare
可用于在一组克隆的命名空间中运行任务。 此命令主要用于测试目的。 尽管它的名字,它始终使用克隆而不是非共享创建新的任务与新的命名空间。 除了测试内核回归之外,这应该没有区别。
-s namespaces #指定要附加到的命名空间
-u user #指定新任务应该成为的用户标识
-H hostname #在新容器中设置主机名。只有设置了UTSNAME命名空间才允许。
-i interfacename #将命名的界面移动到容器中。仅当NETWORK命名空间被设置时才允许。您可以多次指定此参数以将多个接口移动到容器中。
-d #守护程序,退出前不要等待容器退出
-M #在容器中挂载默认文件系统(/ proc / dev / shm和/ dev / mqueue)。如果设置MOUNT命名空间,则只有al-lowed。
lxc-attach
lxc-attach在由name指定的容器内运行指定的命令。 容器lxc-attach在名称指定的容器内运行指定的命令。 容器必须已经运行。 如果未指定命令,则将在容器内查找运行lxc-attach的用户的当前默认shell,然后执行。 如果容器内没有这样的用户,或容器没有工作的nsswitch机制这将失败。
选项:
-n,–name #容器的名称
-a, –arch #指定内核运行的架构
DEVICE=”eth0”
BOOTPROTO=”static”
HWADDR=””
NM_CONTROLLED=”yes”
ONBOOT=”yes”
TYPE=”Ethernet”
IPADDR=””
NETMASK=””
GATEWAY=””
DNS1=””
BRIDGE=”br0” #把eth0添加到br0
创建配置文件ifcfg-br0,并重启网络
[root@CentOS7.3 ~]#cat ifcfg-br0
DEVICE=”br0” #设备名字,必须和BRIDGE=“”里的相同
TYPE=”Bridge” #指定类型为网桥
NOBOOT=”yes”
BOOTPROTO=”static”
IPADDR=”” #网桥的管理地址
NETMASK=”255.255.255.0”
GATEWAY=””
DNS1=””
DELAY=”0” #监控流量里的mac地址
查看所有网桥
[root@CentOS7.3 ~]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.5404a6a7ff6c no eth0
通过命令配置,临时生效。
[root@CentOS7.3 ~]#brctl addbr br0
[root@CentOS7.3 ~]#brctl addif br0 eth1
[root@CentOS7.3 app]#ifconfig br0 172.16.200.33/16 up
[root@CentOS7.3 app]#ip add del dev eth1 172.16.252.71/16
监听端口 :tcp/5000
默认用户名 :admin
密码 :admin
yum -y install python-flask git #安装软件包
git clone https://github.com/lxc-webpanel/LXC-Web-Panel.git #克隆软件包
cd LXC-Web-Panel #进入软件目录
python lwp.py #使用python运行
https://linuxcontainers.org/lxc/manpages/man1/lxc-start.1.html
XEN和KVM实现了真正的虚拟化方案;LXC确切来说应该是资源隔离(namespace),并不能提供完整的物理隔离功能。
XEN虚拟化是相对于KVM来说更加成熟的虚拟化方案,像AWS、Azure等公有云都是使用的XEN作为虚拟化方案;而随着最近几年KVM的发展以及KVM较好的性能,国内的部分虚拟化厂商开始选择KVM作为新的虚拟化方案,像百度、Intel中国、阿里云等开始逐步向KVM迁移。
LXC通过资源隔离和命名空间实现了伪虚拟化功能,由于LXC较高的性能和不彻底的隔离,越来越多的应用到私有云上。