1 Linux Containers概述
1.1 简介
LXC(Linux Containers),即Linux容器,是一种操作系统层级的虚拟化技术,为Linux内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。通过统一的命名空间(Namespace)和共享API来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得Linux用户可以容易的创建和管理系统或应用容器。
作为一个开源容器平台,Linux 容器项目(LXC)提供了一组工具、模板、库和语言绑定。LXC 采用简单的命令行界面,可改善容器启动时的用户体验。LXC 提供了一个操作系统级的虚拟化环境,可在许多基于 Linux 的系统上安装。在 Linux 发行版中,可能会通过其软件包存储库来提供 LXC。
在Linux内核中,container 技术的核心还是linux 内核的cgroup chroot namespace 技术:其提供了cgroups功能来达成资源的隔离;它同时也提供了命名空间隔离的功能,使应用程序看到的操作系统环境被区隔成独立区间,包括进程树、网络、用户id、以及挂载的文件系统;但是cgroups并不一定需要启动任何虚拟机。
LXC利用cgroups与命名空间的功能,为应用软件提供一个相对独立的操作系统环境。LXC不需要Hypervisor这个软件层,软件容器(Container)本身极为轻量化,提升了创建虚拟机的速度。
而Docker本质来说不是容器,而是容器的管理工具,最初的Docker也是基于LXC实现的。
下图是LXC与KVM技术的比较,KVM的优点是一个物理机上可以跑多个操作系统(Guest-OS),然后在每个操作系统运行应用,通过这种方式实现应用的隔离。而使用LXC技术直接可以在Host-OS的基础上实现隔离的。这就是LXC的优势--运行快。但是,如果有两个应用一个是在windows运行的,一个是在linux上运行的,这时只能使用KVM技术来实现了。
1.2 LXC关键技术点
linux contains 的技术是linux 内核的代码,并非Docker 开发出来的,Docker或者其他的虚拟化容器都是基于LXC 的技术,在基础的lxc 上包了一层代码,让LXC 更简单、更友好,更加好推广,LXC 的三个技术:
- chroot: 创建一个虚拟的根目录文件系统,实质还是调用底层的文件系统,不过是建立一个虚拟的、可以跟其他容器的虚拟文件系统相互隔离、但共享底层的文件系统;
- namespace : 命名空间可以提供一个进程相互隔离的独立网络空间,不同的容器间进程pid可以相同,进程并不冲突影响,但可以共享底层的计算和存储(cpu mem);
- cgroups: 实现了对容器的资源分配和限制,比如给容器1分配10core 30G 内存,那这个容器最多用这么大的资源;如果内存超过30G ,会启动swap,效率降低,也可能会被调度系统给kill掉。
1.2.1 namespace
Linux Namespaces机制提供一种资源隔离方案。PID,IPC,Network等系统资源不再是全局性的(在Linux2.6内核以前是全局的),而是属于特定的Namespace。每个Namespace里面的资源对其他Namespace都是透明的。namespace是container中使用到的重要技术之一,是对系统资源的操作上的隔离。使Guest-OS1的操作对Guest-OS2无法产生影响。
当然namespace的实现还在完善中,下面是3.8以上的内核实现的namespace:
1.2.2 Mount namespace
Mount namespace是对挂载的文件系统布局进行隔离。图中显示在Namespace1中的进程看到的文件系统的挂载方式是一致的,但是在Mount Namespace2中看到的是一另一种情况:
1.2.3 IPC namespace
进程间通讯,处于同一namespace下的进程才可以进行进程间通信。
1.2.4 NET namespace
NET NAMESPACE实现网络协议栈上的隔离,在自己的namespace中对网络的设置只能在本namespace中生效。
1.2.5 PID namespace
进程ID,我们通过fork来创建进程时可以为每个进程指定命名空间。linux下的进程关系是一棵树,所以有了父命名空间和子名字空间之分。
在namespace2创建的P2进程有两个pid。第一个是在父命名空间的下的它的PID号,一个是在自己空间下的PID号。之所以有父pid号是因为P2最终还是在父命名空间下运行的,而为进程指定命名空间是为了让P2和P3实现隔离。
1.2.6 USER namespace
User namespace中使用到了map转换,由于container并不是真正的虚拟化,所以在Guest-OS中创建的root用户会被映射到Host-OS中的普通用户中去。
下图中的例子中,root用户在自己的namespace下创建了一个文件,那这个文件的所有者ID应该是0,当时在磁盘上存的时候文件UID会被转换为kuid,并且所有者ID为1000。想说名一点是在Guest-OS下你是个root用户,但是在Host-OS你只不过被转为一个普通用户而已。因为我们知道在Host-OS下已经有一个root用户了。
1.2.7 system API/ABI
linux下的proc目录是对整个系统状态的描述,用户可以通过查看proc目录来了解当前的系统状态。在proc目录下有很多数字,这些数字对应的是系统创建的进程ID,以前我们说进程是看不见摸不着的,但是通过proc目录我们的确可以看到一些关于进程的信息。
每个进程下有个ns目录,在目下记录了该进程使用的到namespace:
1.2.8 clone函数的使用
clone函数是系统的API,是用于创建进程的。我们常用到的fork函数其实底层调用的是clone函数。在使用clone函数的可以为其指定namespace。下面是一个指定IPC名字空间的例子。
p2会运行在新的IPC namespace中,其他namespace会从P1继承下来
1.2.9 unshare函数
unshare函数用于修改当前的进程的namespace的信息。比如更换当前进程的namespace等等。
1.2.10 setns函数
将当前进程的namespace设置为另一进程的namespace。
1.2.11 chroot
chroot 全称是change to root,其中root 是根目录的意思,也就是改变(linux 根目录是/,也可以理解为设置)一个程序运行时参考的根目录的位置。
chroot 机制因为安全问题才被引入的,但是在LXC 中却启动了举足轻重的作用,因为chroot 机制可以指定虚拟根目录,让不同的容器在不同的根目录下工作:
- 不同的容器进程参考的根目录不同,相互直接不影响;
- 不同的容器因为共享linux 底层的文件系统,所以容器集成os的功能,实现轻量级!
1.2.12 cgroups (control groups)
cgroups (control groups) 是linux 内核提供的一种可以分配给单个进程和多个进程资源,并可以对cpu、mem(io、disk、traffic 现在应该还不支持)进行精细化控制。比如一台处理机有32core 128G内存,这台机器设置最多跑6个application(进程):1个进程申请 8core 20G,1个进程申请16core 64G,1个进程申请 2core 8G 等等,这些都可以通过cgroups 进行按需分配(前提是机器还有资源),如果这台机器没有那调度系统会分配其他的处理机器。
cgroups 为每种可以精细化控制的资源定义了一个子系统,典型的子系统如下:
- cpu 子系统: 主要限制进程cpu的使用率(也可以理解为限制分配给cpu的core,最终限制是cpu 利用率的限制;比如一共32core 分配4core ,那这个进程cpu 最大占用率 = 12.5%,所以一个进程可以申请< 1core,因为最后是转换成比率来控制的;
- cpuacct 子系统:统计每个进程cpu 使用率的报告,如果达到预定的上限,可以采取一定的措施;
- cpuset 子系统:可以为进程分配单独的cpu节点或者mem节点,可以理解为为进程分配指定的额cpu占有率,就是精细化控制cpu资源;
- memery 子系统:可以限制进程memery 最大的使用量;
- blkio 子系统:可以限制进程访问的块设备io;
- device 子系统:可以控制访问的设备;
- net_cls 子系统:标记cgroups 中的网络数据包,然后可以使用tc模块(traffice control) 系统对数据包进行控制;比如namespace NET 的可以通过这个系统让namespace 内进程可以独立进行网络通信,功能类似于自己单独的网卡、单独的带宽;
- freezer 子系统,可以stop或者start cgroups 管理的进程,就是监控进程的状态,如果设置了一直是start状态,就去确定环境是否是ok,如果ok就启动服务;
- ns子系统: 可以控制cgroup的进程访问不同的namespace,这个配合namespace的功能实现容器的隔离效果;
1.2.13 container管理工具
1.3 LXC架构
1.4 LXC常用命令
- lxc-checkconfig
检查系统环境是否满足容器使用要求;
- lxc-create
创建lxc容器;
格式:lxc-create -n NAME -t TEMPLATE_NAME
- lxc-start
启动容器;
格式:lxc-start -n NAME -d
- lxc-info
查看容器相关的信息;
格式:lxc-info -n NAME
- lxc-console
附加至指定容器的控制台;
格式:lxc-console -n NAME -t NUMBER
- lxc-stop
停止容器;
- lxc-destory
删除处于停机状态的容器;
- lxc-snapshot
创建和恢复快照;
- 退出容器方式:<Ctrl a q>
参考链接
LXC-Linux Container 简介 - DockOne.io
什么是 Linux 容器(LXC)?一文带你快速了解容器技术 - 红帽
Docker和LXC两者是什么?有什么区别吗?
LXC的介绍 - 被罚站的树 - 博客园
LXC 入门笔记 - 知乎
LXC简单介绍与使用_十五十六的博客-CSDN博客_lxc
如何实现自己的linux container? - Docker - 操作系统 - 深度开源
Linux 容器的使用 - wang_yb - 博客园
linux 容器(LXC) 第1章 LXC 简介_caoshuming_500的博客-CSDN博客_linux lxc
linux 容器(LXC) 第2章 chroot_caoshuming_500的博客-CSDN博客
linux 命令分析之 chroot 的原理_longyu_wlz的博客-CSDN博客_chroot原理
linux 容器(LXC) 第4章 cgroups_caoshuming_500的博客-CSDN博客
《重识云原生系列》专题索引:
- 第一章——不谋全局不足以谋一域
- 第二章计算第1节——计算虚拟化技术总述
- 第二章计算第2节——主流虚拟化技术之VMare ESXi
- 第二章计算第3节——主流虚拟化技术之Xen
- 第二章计算第4节——主流虚拟化技术之KVM
- 第二章计算第5节——商用云主机方案
- 第二章计算第6节——裸金属方案
- 第三章云存储第1节——分布式云存储总述
- 第三章云存储第2节——SPDK方案综述
- 第三章云存储第3节——Ceph统一存储方案
- 第三章云存储第4节——OpenStack Swift 对象存储方案
- 第三章云存储第5节——商用分布式云存储方案
- 第四章云网络第一节——云网络技术发展简述
- 第四章云网络4.2节——相关基础知识准备
- 第四章云网络4.3节——重要网络协议
- 第四章云网络4.3.1节——路由技术简述
- 第四章云网络4.3.2节——VLAN技术
- 第四章云网络4.3.3节——RIP协议
- 第四章云网络4.3.4节——OSPF协议
- 第四章云网络4.3.5节——EIGRP协议
- 第四章云网络4.3.6节——IS-IS协议
- 第四章云网络4.3.7节——BGP协议
- 第四章云网络4.3.7.2节——BGP协议概述
- 第四章云网络4.3.7.3节——BGP协议实现原理
- 第四章云网络4.3.7.4节——高级特性
- 第四章云网络4.3.7.5节——实操
- 第四章云网络4.3.7.6节——MP-BGP协议
- 第四章云网络4.3.8节——策略路由
- 第四章云网络4.3.9节——Graceful Restart(平滑重启)技术
- 第四章云网络4.3.10节——VXLAN技术
- 第四章云网络4.3.10.2节——VXLAN Overlay网络方案设计
- 第四章云网络4.3.10.3节——VXLAN隧道机制
- 第四章云网络4.3.10.4节——VXLAN报文转发过程
- 第四章云网络4.3.10.5节——VXlan组网架构
- 第四章云网络4.3.10.6节——VXLAN应用部署方案
- 第四章云网络4.4节——Spine-Leaf网络架构
- 第四章云网络4.5节——大二层网络
- 第四章云网络4.6节——Underlay 和 Overlay概念
- 第四章云网络4.7.1节——网络虚拟化与卸载加速技术的演进简述
- 第四章云网络4.7.2节——virtio网络半虚拟化简介
- 第四章云网络4.7.3节——Vhost-net方案
- 第四章云网络4.7.4节vhost-user方案——virtio的DPDK卸载方案
- 第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现
- 第四章云网络4.7.6节——virtio-blk存储虚拟化方案
- 第四章云网络4.7.8节——SR-IOV方案
- 第四章云网络4.7.9节——NFV
- 第四章云网络4.8.1节——SDN总述
- 第四章云网络4.8.2.1节——OpenFlow概述
- 第四章云网络4.8.2.2节——OpenFlow协议详解
- 第四章云网络4.8.2.3节——OpenFlow运行机制
- 第四章云网络4.8.3.1节——Open vSwitch简介
- 第四章云网络4.8.3.2节——Open vSwitch工作原理详解
- 第四章云网络4.8.4节——OpenStack与SDN的集成
- 第四章云网络4.8.5节——OpenDayLight
- 第四章云网络4.8.6节——Dragonflow
- 第四章云网络4.9.1节——网络卸载加速技术综述
- 第四章云网络4.9.2节——传统网络卸载技术
- 第四章云网络4.9.3.1节——DPDK技术综述
- 第四章云网络4.9.3.2节——DPDK原理详解
- 第四章云网络4.9.4.1节——智能网卡SmartNIC方案综述
- 第四章云网络4.9.4.2节——智能网卡实现
- 第六章容器6.1.1节——容器综述
- 第六章容器6.1.2节——容器安装部署
- 第六章容器6.1.3节——Docker常用命令
- 第六章容器6.1.4节——Docker核心技术LXC
- 第六章容器6.1.5节——Docker核心技术Namespace