在云端技术的领域,虚拟系统扮演了重要的角色,但不管虚拟系统怎样
演进,效能如何的提升,不可否认的虚拟系统(Guest OS)对实体系统(Host OS)来说还是沉重的负担。
虚拟系统由早期完全透过软件来模拟硬件的全虚拟化(Full
virtualization),演进到以修改系统(Guest OS)核心的方式,来简化CPU 与外围设备操作指令转译的复杂度,以提 升虚拟系统的效能的半虚拟化(Paravirtualization),一直到目前Linux核心支持的原生虚拟 化技术(Linux Kernel-base Virtual Machine,简称Linux KVM),可以明显的发现,虚拟系 统在发展的过程中,尝试利用各种方式来减轻软件虚拟化的程度,而后期因为硬件(CPU)技术与规格的提升,让CPU直接支持虚拟化技术,加上Linux核心直接内建虚拟化模块,并透过Hypervisor的管理程序,让虚拟化技术以裸机架构(Bare-Metal)的模式来运作,而也由于CPU 与系统核心皆支持虚拟化技术,让虚拟系统的核心命令可以直接通透到实体 计算机的 CPU,以模块化的方式来执行核心指令,以提升运作效能。
话虽如此,即使如Linux KVM利用支持虚拟化技术的实体CPU与系统核心,强化了CPU指令运算的效能,但大部分的周边设备,如网络卡等,却还是要倚赖软件 来(例如QEMU)将其虚拟化之后使用,在实际的应用上也会明显拖累整体系统的效能,尤其是网卡更是明显,所有的虚拟网卡都是以同一张实体网卡来当做对外联系的窗口(如果所有的虚拟网络卡都有对外联机的需求时),这势必会影响原先实体系统的网络
运作,只要虚拟计算机的数量越多,影响的程度就越大。
难道,我们就不能对虚拟系统的效能,有更高的要求吗?当然可以,就是利用Linux Container,这是一套不需要透过虚拟化平台(Hypervisor)来仿真所有的硬件装置,而是直接可以使用实体主机硬件装置的虚拟系统架构,让虚拟化的计算机能达到最大的效能。Linux Container 或称 Linux容器系统,也简称LXC其本身仅提供最低程度虚拟化(硬件)的功能,并利用两个系统管理模块(cgroup与AppArmor),来有效的管理、控制,并隔离虚拟计算机与实体计算机的资源运用,另外,Linux Container并不需要再透过复杂的程序,来解译虚拟计算机与实体计算机之间CPU指令的运算,或是外围装置的虚拟化,简单来说,Linux Container就是可以直接使用实体计算机上的软硬件资源,而最特别的地方,就是Linux Container与实体系统共享相同的核心与函式库。Linux Container这样的技术,是由 IBM所开发,除早期运用在 IBM 的大型主机上面,也存 在一些非 Linux的系统之中,而直到Linux 核心版本为2.6.29之后,才开始支持Linux Container。
yum -y install epel-release #这个软件包里包含epelyum源和GPG的配置
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
在config文件内,写入限定规则。注意,使用内存限定的话,需要在内核参数中加入cgroup_enable=memory
。
可以修改/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 #写入频率限定
systemctl start lxc #启动服务
systemctl status lxc #查看服务状态,如果Active后面显示为active (exited)表示服务已启动,显示为inactive (dead)服务未启动。
● lxc.service - LXC Container Initialization and Autoboot Code
Loaded: loaded (/usr/lib/systemd/system/lxc.service; disabled; vendor preset: disabled)
Active: active (exited) since Sat 2017-09-23 14:09:17 CST; 9min ago
Process: 7625 ExecStart=/usr/libexec/lxc/lxc-autostart-helper start (code=exited, status=0/SUCCESS)
Process: 7623 ExecStartPre=/usr/libexec/lxc/lxc-devsetup (code=exited, status=0/SUCCESS)
Main PID: 7625 (code=exited, status=0/SUCCESS)
CGroup: /system.slice/lxc.service
Sep 23 14:09:16 CentOS7.3 systemd[1]: Starting LXC Container Initialization and Autoboot Code...
Sep 23 14:09:16 CentOS7.3 lxc-devsetup[7623]: /dev is devtmpfs
Sep 23 14:09:17 CentOS7.3 lxc-autostart-helper[7625]: Starting LXC autoboot containers: [ OK ]
Sep 23 14:09:17 CentOS7.3 systemd[1]: Started LXC Container Initialization and Autoboot Code.
systemctl start libvirtd #启动虚拟网络
lxc-checkconfig #检查配置
ls /usr/share/lxc/templates/
lxc-alpine lxc-busybox lxc-debian lxc-gentoo lxc-oracle lxc-ubuntu
lxc-altlinux lxc-centos lxc-download lxc-openmandriva lxc-plamo lxc-ubuntu-cloud
lxc-archlinux lxc-cirros lxc-fedora lxc-opensuse lxc-sshd
lxc-create -t centos -n myhost1 #创建LXC主机,-t 指定模板容器,-n 指定要创建的主机名
Copy /var/cache/lxc/centos/x86_64/7/rootfs to /var/lib/lxc/myhost1/rootfs ...
Copying rootfs to /var/lib/lxc/myhost1/rootfs ... #生成虚拟系统的根,文件默认路径在/var/lib/lxc/myhsot1下
sed: can't read /var/lib/lxc/myhost1/rootfs/etc/init/tty.conf: No such file or directory
Storing root password in '/var/lib/lxc/myhost1/tmp_root_pass'
Expiring password for user root.
passwd: Success
sed: can't read /var/lib/lxc/myhost1/rootfs/etc/rc.sysinit: No such file or directory
sed: can't read /var/lib/lxc/myhost1/rootfs/etc/rc.d/rc.sysinit: No such file or directory
Container rootfs and config have been created.
Edit the config file to check/enable networking setup.
The temporary root password is stored in:
'/var/lib/lxc/myhost1/tmp_root_pass' #这个文件保存了主机的初始root密码
The root password is set up as expired and will require it to be changed
at first login, which you should do as soon as possible. If you lose the
root password or wish to change it without starting the container, you
can change it from the host by running the following command (which will
also reset the expired flag):
chroot /var/lib/lxc/myhost1/rootfs passwd #可以使用这个命令修改初始root密码
注:lxc主机所生成的文件默认路径在/var/lib/lxc/主机名/目录下
tree /var/lib/lxc/myhost1/ -L 1
/var/lib/lxc/myhost1/
├── config #配置文件
├── rootfs #根目录
├── rootfs.dev -> /dev/.lxc/myhost1.83704f3b9569a945
└── tmp_root_pass #root密码
chroot /var/lib/lxc/myhost1/rootfs passwd #修改root初始密码
Changing password for user root.
New password: #输入新密码
Retype new password: #再次输入新密码
passwd: all authentication tokens updated successfully. #修改成功
注:如果在使用中忘记了lxc主机的密码也可以通过这条命令进行重置密码,修改不同lxc主机的密码时应当指向要修改主机目录下的rootfs文件进行修改。
lxc-start -n myhost1
systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
Detected virtualization lxc.
Detected architecture x86-64.
Welcome to CentOS Linux 7 (Core)!
Running in a container, ignoring fstab device entry for /dev/root.
Cannot add dependency job for unit display-manager.service, ignoring: Unit not found.
[ OK ] Reached target Encrypted Volumes.
[ OK ] Reached target Swap.
[ OK ] Created slice Root Slice.
[ OK ] Created slice User and Session Slice.
[ OK ] Listening on Delayed Shutdown Socket.
[ OK ] Reached target Remote File Systems.
[ OK ] Listening on /dev/initctl Compatibility Named Pipe.
[ OK ] Listening on Journal Socket.
[ OK ] Created slice System Slice.
Mounting Huge Pages File System...
Starting Journal Service...
[ OK ] Reached target Slices.
[ OK ] Created slice system-getty.slice.
Mounting POSIX Message Queue File System...
Starting Remount Root and Kernel File Systems...
[ OK ] Mounted POSIX Message Queue File System.
[ OK ] Mounted Huge Pages File System.
[ OK ] Started Remount Root and Kernel File Systems.
Starting Configure read-only root support...
Starting Rebuild Hardware Database...
[ OK ] Reached target Local File Systems (Pre).
Starting Load/Save Random Seed...
[ OK ] Started Load/Save Random Seed.
[ OK ] Started Journal Service.
Starting Flush Journal to Persistent Storage...
<46>systemd-journald[15]: Received request to flush runtime journal from PID 1
[ OK ] Started Flush Journal to Persistent Storage.
[ OK ] Started Configure read-only root support.
[ OK ] Reached target Local File Systems.
Starting Mark the need to relabel after reboot...
Starting Create Volatile Files and Directories...
Starting Rebuild Journal Catalog...
[ OK ] Started Mark the need to relabel after reboot.
[ OK ] Started Rebuild Journal Catalog.
[ OK ] Started Create Volatile Files and Directories.
Starting Update UTMP about System Boot/Shutdown...
[ OK ] Started Update UTMP about System Boot/Shutdown.
[ OK ] Started Rebuild Hardware Database.
Starting Update is Completed...
[ OK ] Started Update is Completed.
[ OK ] Reached target System Initialization.
[ OK ] Listening on D-Bus System Message Bus Socket.
[ OK ] Reached target Sockets.
[ OK ] Reached target Paths.
[ OK ] Reached target Basic System.
Starting LSB: Bring up/down networking...
Starting System Logging Service...
Starting OpenSSH Server Key Generation...
Starting Permit User Sessions...
Starting Login Service...
[ OK ] Started D-Bus System Message Bus.
Starting D-Bus System Message Bus...
[ OK ] Reached target Timers.
[ OK ] Started Permit User Sessions.
Starting Cleanup of Temporary Directories...
[ OK ] Started Console Getty.
Starting Console Getty...
[ OK ] Reached target Login Prompts.
[ OK ] Started Cleanup of Temporary Directories.
[ OK ] Started Login Service.
[ OK ] Started System Logging Service.
[ OK ] Started OpenSSH Server Key Generation.
CentOS Linux 7 (Core)
Kernel 3.10.0-514.el7.x86_64 on an x86_64
myhost1 login: #使用root用户登陆
Password: #输入设置的root密码
[root@myhost1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 100G 4.4G 96G 5% /
devtmpfs 474M 0 474M 0% /dev
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 489M 6.2M 483M 2% /run
tmpfs 489M 0 489M 0% /sys/fs/cgroup
tmpfs 98M 0 98M 0% /run/user/0
[root@myhost1 ~]# ll /boot/ #因为lxc共享物理主机的内核,所以lxc主机的/boot目录是空的。
total 0
[root@myhost1 ~]# passwd #在这里也可以修改root的密码和创建用户。
Changing password for user root.
New password:
[root@myhost1 ~]# ip a #查看网卡信息
1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
6: eth0@if7: mtu 1500 qdisc noqueue state UP qlen 1000
link/ether fe:6b:41:82:2e:32 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.122.53/24 brd 192.168.122.255 scope global dynamic eth0
valid_lft 2940sec preferred_lft 2940sec
inet6 fe80::fc6b:41ff:fe82:2e32/64 scope link
valid_lft forever preferred_lft forever
lxc-start -n myhost1 -d #在启动时添加-d选项可以把主机防止后台有运行
lxc-console -n myhost1 #使用lxc-console 进行连接
Connected to tty 1
Type to exit the console, to enter Ctrl+a itself
#敲击Ctrl+a然后q,就可以从容器控制台中退出。
[root@CentOS7.3 ~]#ssh 192.168.122.53 #也可以使用ssh进行连接
root@192.168.122.53's password:
Last login: Sat Sep 23 06:49:58 2017
[root@myhost1 ~]#
lxc-info -n myhost1 #使用这条lxc-info命令可以查看主机的状态信息
Name: myhost1 #主机名
State: RUNNING #当前状态,RUNNING表示启动,STOPPED表示关闭。
PID: 4409 #lxc主机当前在物理机上的进程号
IP: 192.168.122.53 #主机的IP地址
CPU use: 0.19 seconds #cpu占用时间
BlkIO use: 3.35 MiB #占用BLKIO资源的大小
Memory use: 4.40 MiB #占用物理内存大小
KMem use: 0 bytes #内核虚拟内存
Link: veth2DSU4I
TX bytes: 1.76 KiB #流量相关的信息
RX bytes: 35.69 KiB
Total bytes: 37.45 KiB
lxc-stop -n myhost1
lxc-destroy -n myhost2
[root@CentOS7.3 ~]#lxc-clone -o myhost1 -n myhost2 #把myhost1克隆一份命名为myhost2
Created container myhost2 as copy of myhost1
[root@CentOS7.3 ~]#lxc-start -n myhost2 #启动myhost2
systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
Detected virtualization lxc.
......
CentOS Linux 7 (Core)
Kernel 3.10.0-514.el7.x86_64 on an x86_64
myhost2 login: root #使用默认用户root
Password: #密码和myhost1的相同
用法: lxc-create {-n name} [-f config_file] {-t template} [-B backingstore] [-- template-options]
选项
-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 {-n name} [-f]
选项:-f, --force #强制删除
用法: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命名空间。
选项:
-r,--reboot #重启容器
-s,--shutdown #设置定时关闭容器,使用-t 设置关闭时间。
-k,--kill #关闭容器
选项:
-r,--reboot #重启容器
-k,--kill #关闭容器,默认选项
--nokill #挂起容器
--nolock #此选项避免使用任何API lxc锁定。
选项:
-s #显示状态
-p #显示pid
-i #显示IP地址
-S #显示内存使用
-H #显示原始数值
-t #指定连接的tty
-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
快照文件默认保存在var /lib/lxc-snaps/容器名
-c,--comment file #将文件中的注释信息和快照关联
-d,--destroy #删除快照
-L,--list #列出所有快照
-C #显示快照注释信息
-r #恢复快照
newname #恢复快照时用于指定容器的名称。可选参数 ,如果没有给出任何名称,则原始容器将被破坏,并且恢复的容器将占据其位置。
注意:在aufs,overlayfs或zfs支持的快照的情况下,删除原始快照是不可能的。
lxc-cgroup在相应子系统的容器cgroup中获取或设置状态对象(例如,'cpuset.cpus')的值(例如,'cpuset')。 如果没有指定[value],则显示状态对象的当前值; 否则设置。注意lxc-cgroup不会检查状态对象是否对运行的内核有效,或者对应的子系统包含在任何已安装的cgroup层次结构中
lxc-cgroup {-n name} {state-object} [value]
可用于在一组克隆的命名空间中运行任务。 此命令主要用于测试目的。 尽管它的名字,它始终使用克隆而不是非共享创建新的任务与新的命名空间。 除了测试内核回归之外,这应该没有区别。
-s namespaces #指定要附加到的命名空间
-u user #指定新任务应该成为的用户标识
-H hostname #在新容器中设置主机名。只有设置了UTSNAME命名空间才允许。
-i interfacename #将命名的界面移动到容器中。仅当NETWORK命名空间被设置时才允许。您可以多次指定此参数以将多个接口移动到容器中。
-d #守护程序,退出前不要等待容器退出
-M #在容器中挂载默认文件系统(/ proc / dev / shm和/ dev / mqueue)。如果设置MOUNT命名空间,则只有al-lowed。
lxc-attach在由name指定的容器内运行指定的命令。 容器lxc-attach在名称指定的容器内运行指定的命令。 容器必须已经运行。 如果未指定命令,则将在容器内查找运行lxc-attach的用户的当前默认shell,然后执行。 如果容器内没有这样的用户,或容器没有工作的nsswitch机制这将失败。
选项:
-n,--name #容器的名称
-a, --arch #指定内核运行的架构
[root@CentOS7.3 ~]#cat ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="static"
HWADDR=""
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
IPADDR=""
NETMASK=""
GATEWAY=""
DNS1=""
BRIDGE="br0" #把eth0添加到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
基于python-flask Web框架开发,为lxc提供一个web管理页面
监听端口 :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运行