LXC
简介
在云端技术的领域,虚拟系统扮演了重要的角色,但不管虚拟系统怎样演进,效能如何的提升,不可否认的虚拟系统(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。
KVM和LXC的架构对比
使用
安装一个epel源
[root@localhost ~]# yum -y install epel-release
安装LXC软件包和依赖包
[root@localhost ~]# yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup libvirt perl debootstrap
lxc #主程序包
lxc-templates #lxc的配置模板
bridge-utils #网桥管理工具
lxc-libs #lxc所需的库文件
libcgroup #cgroup是为Linux内核提供任务聚集和划分的机制,通过一组参数集合将一些任务组织成一个或多个子系统。
libvirt #管理Linux的虚拟化功能所需的服务器端守护程序。 需要针对特定驱动程序的管理程序。
注:如果要创建debian系列的主机需要再安装一个软件包:debootstrap
限制LXC可以使用的系统资源
在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 #写入频率限定
启动服务
[root@localhost ~]# systemctl start lxc #启动服务
[root@localhost ~]# 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 2021-12-1 13: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 1 13:09:16 CentOS7.3 systemd[1]: Starting LXC Container Initialization and Autoboot Code...
Sep 1 13:09:16 CentOS7.3 lxc-devsetup[7623]: /dev is devtmpfs
Sep 1 13:09:17 CentOS7.3 lxc-autostart-helper[7625]: Starting LXC autoboot containers: [ OK ]
Sep 1 13:09:17 CentOS7.3 systemd[1]: Started LXC Container Initialization and Autoboot Code.
[root@localhost ~]# systemctl start libvirtd #启动虚拟网络
[root@localhost ~]# lxc-checkconfig #检查配置
创建虚拟机
[root@localhost ~]# 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主机
[root@localhost ~]# lxc-create -t centos -n myhost1
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密码
[root@localhost ~]# tree /var/lib/lxc/myhost1/ -L 1
/var/lib/lxc/myhost1/
├── config #配置文件
├── rootfs #根目录
├── rootfs.dev -> /dev/.lxc/myhost1.83704f3b9569a945
└── tmp_root_pass #root密码
启动主机
[root@localhost ~]# chroot /var/lib/lxc/myhost1/rootfs passwd #修改root初始密码
Changing password for user root.
New password: #输入新密码
Retype new password: #再次输入新密码
passwd: all authentication tokens updated successfully. #修改成功
[root@localhost ~]# 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@localhost ~]# 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@localhost ~]# ll /boot/ #因为lxc共享物理主机的内核,所以lxc主机的/boot目录是空的。
total 0
[root@localhost ~]# passwd #在这里也可以修改root的密码和创建用户。
Changing password for user root.
New password:
[root@localhost ~]# ip a #查看网卡信息
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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.145.195/24 brd 192.168.145.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 <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself
#敲击Ctrl+a然后q,就可以从容器控制台中退出。
[root@localhost ~]# ssh 192.168.145.195 #也可以使用ssh进行连接
root@192.168.145.195's password:
Last login: Sat Sep 1 13:06:58 2021
停止
[root@localhost ~]# lxc-stop -n myhost1
删除
[root@localhost ~]# lxc-destroy -n myhost1