当前位置: 首页 > 工具软件 > LXC > 使用案例 >

1.LXC的使用

屠德宇
2023-12-01

1.LXC的使用

1.1简介

LXC为Linux Container的简写。Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与传统虚拟化技术相比,它的优势在于:

(1)与宿主机使用同一个内核,性能损耗小;

(2)不需要指令级模拟;

(3)不需要即时(Just-in-time)编译;

(4)容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;

(5)避免了准虚拟化和系统调用替换中的复杂性;

(6)轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。

总结:Linux Container是一种轻量级的虚拟化的手段。

Linux Container提供了在单一可控主机节点上支持多个相互隔离的server container同时执行的机制。Linux Container有点像chroot,提供了一个拥有自己进程和网络空间的虚拟环境,但又有别于虚拟机,因为lxc是一种操作系统层次上的资源的虚拟化。

1.2.0 前置工作

[root@yyx2 ~]#yum -y install epel-release //配置源
[root@yyx2 ~]# yum -y install net-tools //安装包

1.2 安装LXC

[root@yyx2 ~]# yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup libvirt perl debootstrap //下载lxc及其所需依赖包

1.3 网桥设置

[root@yyx2 ~]# brctl addbr virbr0 && brctl addif virbr0 ens33&&ip addr del dev ens33 192.168.141.128/24&&ifconfig virbr0 192.168.141.128/24 up&&route add default gw 192.168.141.1
//以上五步为同时执行,以免执行过程中导致Xshell断开连接
//addbr virbr0 添加网桥
//brctl addif virbr0 ens33 关联网卡
//ip addr del dev ens33 192.168.141.128/24 删除网卡ip
ifconfig virbr0 192.168.141.128/24 配置网桥ip
//route add default gw 192.168.141.1 设置默认网关
[root@yyx2 ~]# brctl show //查看网桥
bridge name	bridge id		STP enabled	interfaces
virbr0		8000.000c2917d93d	no		ens33
[root@yyx2 ~]# ifconfig //查看网络设备
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::20c:29ff:fe17:d93d  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:17:d9:3d  txqueuelen 1000  (Ethernet)
        RX packets 44304  bytes 61905078 (59.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8987  bytes 608737 (594.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

virbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500 //网桥配置成功
        inet 192.168.141.128  netmask 255.255.255.0  broadcast 192.168.141.255
        inet6 fe80::20c:29ff:fe17:d93d  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:17:d9:3d  txqueuelen 1000  (Ethernet)
        RX packets 352  bytes 70134 (68.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 49  bytes 3894 (3.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

1.4 检查系统

[root@yyx2 ~]# lxc-checkconfig //查看系统是否满足容器使用的要求  都是enabled则可以使用

1.5 创建LXC

[root@yyx2 ~]# lxc-create --name=yyxnb -t /usr/share/lxc/templates/lxc-download //利用模板安装LXC

1.6 启动容器

[root@yyx2]# chroot /var/lib/lxc/myhost1/rootfs/ passwd  //修改初始密码

1.7 常用命令操作

// 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
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                      #指定内核运行的架构

问题汇总

Socket error Event: 32 Error: 10053.
Connection closing...Socket close.

Connection closed by foreign host.

Disconnected from remote host(192.168.141.128:22) at 22:58:19.

Type `help' to learn how to use Xshell prompt.
//断开连接
原因:设置网桥的时候一步一步来的,导致Xshell断开连接。
解决方法:同时运行

Socket error Event: 32 Error: 10053.
Connection closing...Socket close.

Connection closed by foreign host.

Disconnected from remote host(192.168.141.128:22) at 22:58:19.

Type `help' to learn how to use Xshell prompt.
//再次出现这个情况
原因:本机缺少包导致ifconfig命令用不了,而中断命令执行过程
解决方法:去VMware虚拟机里面配置好IP并且安装net-tools包然后运行后续命令

2.容器的工作方式

一个容器由操作系统,用户文件和元数据组成。由此可知,每个容器都根据镜像来生成。这个镜像告诉Docker容器包含什么内容,运行什么程序,以及其他配置信息。

docker image是只读的,当一个容器运行一个镜像时,容器会在Union FS的顶层增加文件层。

运行下面一条执行,执行后会出现下面的信息:

[root@VM_0_5_centos ~]# docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
Trying to pull repository docker.io/library/ubuntu ...
latest: Pulling from docker.io/library/ubuntu
7ddbc47eeb70: Pull complete
c1bbdc448b72: Pull complete
8c3b70e39044: Pull complete
45d437916d57: Pull complete
Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Status: Downloaded newer image for docker.io/ubuntu:latest
root@b2ca7b248b17:/#

docker client 通过run 命令告诉Daemon启动一个新的容器,这个指令至少需要包括:

(1)、需要运行什么image,这里使用的是ubuntu基础镜像
(2)、需要在容器启动是运行什么命令,这里使用的是/bin/bash。是否需要进入应用程序,这里指定 -i -t,表示进入容器交互模式

那么具体到内部的流程是怎么样的呢?

(1)、拉取ubuntu镜像:docker检查本地是否存在ubuntu镜像,如果就自动从docker hub拉取,如果存在就进入下一步。
(2)、创建一个容器:一旦本地存在ubuntu镜像,docker将通过它来创建容器。
(3)、分配文件系统并挂载一个RW层:容器是创建在文件系统中的,并且在其之上增加了一层读写层。由此可以看出容器并不会改变原始的镜像。
(4)、分配网络/桥接模式:创建一个桥接网络接口,使容器可以和本地主机进行通信。
(5)、设置一个IP地址:根据本地网络情况,选取一个可用的IP挂载到容器之上。
(6)、启动一个进程:这里就是/bin/bash
(7)、抓取应用程序的输出:将程序的stdin、stdout、和stderr进行捕捉,这样就可以看到程序的运行情况。至此,就拥有了一个运行的容器。通过容器,可以运行程序,并且进行交互。当程序执行完毕,可以停止和删除程序。

3.CGroup的功能

控制组(CGroups)是Linux内核的一个特性,用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,Docker才能避免多个容器同时运行时的系统资源竞争。

控制组可以提供对容器的内存、CPU、磁盘IO等资源进行限制。

CGroups能够限制的资源有:

  • blkio:块设备IO
  • cpu:CPU
  • cpuacct:CPU资源使用报告
  • cpuset:多处理器平台上的CPU集合
  • devices:设备访问
  • freezer:挂起或恢复任务
  • memory:内存用量及报告
  • perf_event:对cgroup中的任务进行统一性能测试
  • net_cls:cgroup中的任务创建的数据报文的类别标识符

具体来看,控制组提供如下功能:

  • 资源限制(Resource Limitting)组可以设置为不超过设定的内存限制。比如:内存子系统可以为进行组设定一个内存使用上限,一旦进程组使用的内存达到限额再申请内存,就会发出Out of Memory警告
  • 优先级(Prioritization)通过优先级让一些组优先得到更多的CPU等资源
  • 资源审计(Accounting)用来统计系统实际上把多少资源用到合适的目的上,可以使用cpuacct子系统记录某个进程组使用的CPU时间
  • 隔离(Isolation)为组隔离命名空间,这样一个组不会看到另一个组的进程、网络连接和文件系统
  • 控制(Control)挂起、恢复和重启等操作

安装Docker后,用户可以在/sys/fs/cgroup/memory/docker/目录下看到对Docker组应用的各种限制项,包括

[root@yyx2 templates]# cd /sys/fs/cgroup/memory/
[root@yyx2 memory]# ls
cgroup.clone_children           memory.kmem.tcp.limit_in_bytes      memory.pressure_level
cgroup.event_control            memory.kmem.tcp.max_usage_in_bytes  memory.soft_limit_in_bytes
cgroup.procs                    memory.kmem.tcp.usage_in_bytes      memory.stat
cgroup.sane_behavior            memory.kmem.usage_in_bytes          memory.swappiness
init.scope                      memory.limit_in_bytes               memory.usage_in_bytes
machine.slice                   memory.max_usage_in_bytes           memory.use_hierarchy
memory.failcnt                  memory.memsw.failcnt                notify_on_release
memory.force_empty              memory.memsw.limit_in_bytes         release_agent
memory.kmem.failcnt             memory.memsw.max_usage_in_bytes     system.slice
memory.kmem.limit_in_bytes      memory.memsw.usage_in_bytes         tasks
memory.kmem.max_usage_in_bytes  memory.move_charge_at_immigrate     user.slice
memory.kmem.slabinfo            memory.numa_stat
memory.kmem.tcp.failcnt         memory.oom_control

用户可以通过修改这些文件值来控制组限制Docker应用资源。

4.容器的基本概念

容器的本质实际上是一个进程,是一个视图被隔离,资源受限的进程。

容器就是一个视图隔离、资源可限制、独立文件系统的进程集合。所谓“视图隔离”就是能够看到部分进程以及具有独立的主机名等;控制资源使用率则是可以对于内存大小以及 CPU 使用个数等进行限制。容器就是一个进程集合,它将系统的其他资源隔离开来,具有自己独立的资源视图。

容器具有一个独立的文件系统,因为使用的是系统的资源,所以在独立的文件系统内不需要具备内核相关的代码或者工具,我们只需要提供容器所需的二进制文件、配置文件以及依赖即可。只要容器运行时所需的文件集合都能够具备,那么这个容器就能够运行起来。

 类似资料: