LinuX Containers

LXC

什么是LXC

LXC 是 Linux 内核包含功能的用户空间接口。通过强大的API和简单的工具,它使Linux用户可以轻松创建和管理系统或应用程序容器。

LXC(LinuX Containers)Linux容器,一种操作系统层虚拟化技术,为Linux内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享API来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得Linux用户可以容易的创建和管理系统或应用容器。

在Linux内核中,提供了cgroups功能,来达成资源的隔离。它同时也提供了名称空间隔离的功能,使应用程序看到的操作系统环境被区隔成独立区间,包括进程树,网络,用户id,以及挂载的文件系统。但是cgroups并不一定需要启动任何虚拟机。

LXC利用cgroups与名称空间的功能,提供应用软件一个独立的操作系统环境。LXC不需要Hypervisor这个软件层,软件容器(Container)本身极为轻量化,提升了创建虚拟机的速度。

而Docker本质来说不是容器,而是容器的管理工具,最初的Docker也是基于LXC实现的。

总而言之:LXC是一种操作系统层虚拟化技术,为Linux内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器,内含应用软件本身的代码,以及所需要的操作系统核心和库。

LXC关键技术点

  • chroot,根切换,从容器内的角度来看,仿佛真的有自己的根树
  • namespaces:名称空间,负责将资源隔离,比如pid,网络,mnt,user,uts等
  • CGroups:控制组,负责控制资源的分配

LXC解决什么问题
通过上面的介绍,我们知道容器(6个名称空间)和cgroups组合即可实现完整并且保证隔离的容器环境。但是控制名称空间和cgroups都是系统调用,又有多少人能掌握呢? 于是LXC出现了,LXC就是让用户可以轻松地创建和管理系统或应用程序容器

特征

当前 LXC 使用以下内核功能来包含进程:

  • 内核命名空间(ipc、uts、mount、pid、network 和 user)
  • Apparmor 和 SELinux 配置文件
  • 安全策略
  • Chroots(使用pivot_root)
  • 内核功能
  • C组(对照组)

LXC 容器通常被视为介于 chroot 和完整虚拟机之间的中间部分。LXC的目标是创建一个尽可能接近标准Linux安装的环境,但不需要单独的内核。

部署LXC

//安装一个epel源
[root@lxc ~]# yum -y install epel-release


//安装LXC软件包和依赖包
[root@lxc ~]# 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的虚拟化功能所需的服务器端守护程序。 需要针对特定驱动程序的管理程序。

//启动服务
[root@lxc ~]# systemctl start lxc libvirtd
[root@lxc ~]# systemctl status lxc
● lxc.service - LXC Container Initialization and Autoboot Code
   Loaded: loaded (/usr/lib/systemd/system/lxc.service; disabled; vendor preset: disabled)
   Active: active (exited) since 三 2021-12-01 01:32:39 CST; 1min 29s ago
  Process: 4674 ExecStart=/usr/libexec/lxc/lxc-autostart-helper start (code=exited, status=0/SUCCESS)
  Process: 4667 ExecStartPre=/usr/libexec/lxc/lxc-devsetup (code=exited, status=0/SUCCESS)
 Main PID: 4674 (code=exited, status=0/SUCCESS)
    Tasks: 0
   Memory: 0B
   CGroup: /system.slice/lxc.service

12月 01 01:32:08 lxc.localdomain systemd[1]: Starting LXC Container Initialization and.....
12月 01 01:32:08 lxc.localdomain lxc-devsetup[4667]: Creating /dev/.lxc
12月 01 01:32:08 lxc.localdomain lxc-devsetup[4667]: /dev is devtmpfs
12月 01 01:32:08 lxc.localdomain lxc-devsetup[4667]: Creating /dev/.lxc/user
12月 01 01:32:39 lxc.localdomain lxc-autostart-helper[4674]: Starting LXC autoboot conta… ]
12月 01 01:32:39 lxc.localdomain systemd[1]: Started LXC Container Initialization and ...e.
Hint: Some lines were ellipsized, use -l to show in full.

检查系统是否满足容器使用要求

[root@lxc ~]# lxc-checkconfig
Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-3.10.0-862.el7.x86_64
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
newuidmap is not installed
newgidmap is not installed
Network namespace: enabled
Multiple /dev/pts instances: enabled

--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
Bridges: enabled
Advanced netfilter: enabled
CONFIG_NF_NAT_IPV4: enabled
CONFIG_NF_NAT_IPV6: enabled
CONFIG_IP_NF_TARGET_MASQUERADE: enabled
CONFIG_IP6_NF_TARGET_MASQUERADE: enabled
CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled

--- Checkpoint/Restore ---
checkpoint restore: enabled
CONFIG_FHANDLE: enabled
CONFIG_EVENTFD: enabled
CONFIG_EPOLL: enabled
CONFIG_UNIX_DIAG: enabled
CONFIG_INET_DIAG: enabled
CONFIG_PACKET_DIAG: enabled
CONFIG_NETLINK_DIAG: enabled
File capabilities: enabled

Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig


创建LXC主机

//查看当前系统中可用的LXC模板容器
[root@lxc ~]# 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


//使用centos模板
[root@lxc ~]#  lxc-create -t centos -n test2
Host CPE ID from /etc/os-release: cpe:/o:centos:centos:7
Checking cache download in /var/cache/lxc/centos/x86_64/7/rootfs ... 
Cache found. Updating...
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.ustc.edu.cn
 * extras: mirrors.ustc.edu.cn
 * updates: mirrors.ustc.edu.cn
No packages marked for update
已加载插件:fastestmirror
正在清理软件源: base extras updates
0 package 文件已移除
Update finished
Copy /var/cache/lxc/centos/x86_64/7/rootfs to /var/lib/lxc/test2/rootfs ... 
Copying rootfs to /var/lib/lxc/test2/rootfs ...
sed:无法读取 /var/lib/lxc/test2/rootfs/etc/init/tty.conf:没有那个文件或目录
Storing root password in '/var/lib/lxc/test2/tmp_root_pass'
正在终止用户 root 的密码。
passwd: 操作成功
sed:无法读取 /var/lib/lxc/test2/rootfs/etc/rc.sysinit:没有那个文件或目录
sed:无法读取 /var/lib/lxc/test2/rootfs/etc/rc.d/rc.sysinit:没有那个文件或目录

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/test2/tmp_root_pass'


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/test2/rootfs passwd

        
//lxc主机所生成的文件默认路径在/var/lib/lxc/主机名/目录下

[root@lxc ~]# tree /var/lib/lxc/test2/ -L 1 
/var/lib/lxc/mytest1/
├── config			#配置文件
├── rootfs			#根目录
└── tmp_root_pass	#root密码

1 directory, 2 files

启动主机

[root@lxc ~]# chroot /var/lib/lxc/test2/rootfs/ passwd
更改用户 root 的密码 。
新的 密码:
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@lxc ~]# lxc-start -n test2
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 Swap.
[  OK  ] Started Dispatch Password Requests to Console Directory Watch.
[  OK  ] Reached target Local Encrypted Volumes.
[  OK  ] Reached target Remote File Systems.
[  OK  ] Created slice Root Slice.
[  OK  ] Created slice User and Session Slice.
[  OK  ] Listening on /dev/initctl Compatibility Named Pipe.
[  OK  ] Created slice System Slice.
[  OK  ] Created slice system-getty.slice.
[  OK  ] Reached target Slices.
[  OK  ] Listening on Delayed Shutdown Socket.
[  OK  ] Listening on Journal Socket.
         Mounting Huge Pages File System...
         Starting Journal Service...
         Starting Read and set NIS domainname from /etc/sysconfig/network...
         Mounting POSIX Message Queue File System...
[  OK  ] Started Forward Password Requests to Wall Directory Watch.
[  OK  ] Reached target Paths.
         Starting Remount Root and Kernel File Systems...
[  OK  ] Mounted POSIX Message Queue File System.
[  OK  ] Mounted Huge Pages File System.
[  OK  ] Started Journal Service.
[  OK  ] Started Read and set NIS domainname from /etc/sysconfig/network.
[  OK  ] Started Remount Root and Kernel File Systems.
         Starting Rebuild Hardware Database...
         Starting Configure read-only root support...
         Starting Flush Journal to Persistent Storage...
[  OK  ] Reached target Local File Systems (Pre).
<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.
         Starting Load/Save Random Seed...
[  OK  ] Reached target Local File Systems.
         Starting Rebuild Journal Catalog...
         Starting Mark the need to relabel after reboot...
         Starting Create Volatile Files and Directories...
[  OK  ] Started Load/Save Random Seed.
[  OK  ] Started Rebuild Journal Catalog.
[  OK  ] Started Create Volatile Files and Directories.
         Starting Update UTMP about System Boot/Shutdown...
[  OK  ] Started Mark the need to relabel after reboot.
[  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  ] Started Daily Cleanup of Temporary Directories.
[  OK  ] Reached target Timers.
[  OK  ] Listening on D-Bus System Message Bus Socket.
[  OK  ] Reached target Sockets.
[  OK  ] Reached target Basic System.
         Starting OpenSSH Server Key Generation...
         Starting Permit User Sessions...
         Starting LSB: Bring up/down networking...
[  OK  ] Started D-Bus System Message Bus.
         Starting Login Service...
[  OK  ] Started Permit User Sessions.
         Starting Cleanup of Temporary Directories...
[  OK  ] Started Console Getty.
[  OK  ] Reached target Login Prompts.
[  OK  ] Started Command Scheduler.
[  OK  ] Started Cleanup of Temporary Directories.
[  OK  ] Started Login Service.
[  OK  ] Started OpenSSH Server Key Generation.

CentOS Linux 7 (Core)
Kernel 3.10.0-862.el7.x86_64 on an x86_64

test2 login: root   #使用root用户
Password: 			#设置的密码



[root@test2 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fe:1f:bf:1d:7f:f0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.122.44/24 brd 192.168.122.255 scope global dynamic eth0
       valid_lft 3556sec preferred_lft 3556sec
    inet6 fe80::fc1f:bfff:fe1d:7ff0/64 scope link 
       valid_lft forever preferred_lft forever
       
# ping本机       
[root@test2 ~]# ping 192.168.47.140
PING 192.168.47.140 (192.168.47.140) 56(84) bytes of data.
64 bytes from 192.168.47.140: icmp_seq=1 ttl=64 time=0.118 ms
64 bytes from 192.168.47.140: icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from 192.168.47.140: icmp_seq=3 ttl=64 time=0.048 ms

# ping百度
[root@test2 ~]# ping www.baidu.com
PING www.a.shifen.com (14.215.177.39) 56(84) bytes of data.
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=1 ttl=127 time=25.2 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=2 ttl=127 time=47.6 ms
64 bytes from 14.215.177.39 (14.215.177.39): icmp_seq=3 ttl=127 time=69.1 ms

--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 25.209/47.353/69.173/17.950 ms

LXC相关命令

停止lxc主机

[root@lxc ~]# lxc-stop -n test2

克隆主机

[root@lxc ~]# lxc-clone -o test2 -n test3  #把test2克隆为名字为test3
Created container test3 as copy of test2

删除主机

[root@lxc ~]# lxc-destroy -n test2

lxc-create 创建一个系统对象

用法: 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

用法: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
12

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/容器名
选项:
	-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                      #指定内核运行的架构

遇到的报错

请添加图片描述
错误表现

//修改密码死活不成功
[root@lxc ~]# chroot /var/lib/lxc/test/rootfs/ passwd
更改用户 root 的密码 。
新的 密码:
重新输入新的 密码:
passwd: 鉴定令牌操作错误   

使用/var/lib/lxc/test1/tmp_root_pass中的初始密码也登不进去
在这里插入图片描述
解决方案

关闭selinux
[root@lxc ~]# setenforce 0
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值