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