容器虚拟化基础之NameSpace

 “只想从这无边的寂寞中逃出来。”


一、什么是虚拟化、容器化?

物理机:实际的服务器或者计算机。

        这是相对于虚拟机而言的对实体计算机的称呼,物理机提供虚拟机以硬件环境,有时候也称为"宿主"或"寄主"。

虚拟机: 指通过软件模拟的具有完整硬件系统功能的、运行在一个 "完全隔离环境" 中的完整计算机系统。

虚拟化:  是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。在一台计算机上,同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率。

容器化:容器化是一种虚拟化技术,又称操作系统层虚拟化。这种技术将 "操作系统内核" 虚拟化,可以允许用户空间软件实例(instances)被分割成几个独立的单元,在内核中运行,而不是只有一个单一实例运行。

        这个软件实例,也被称为是一个容器(containers)。对于每一个容器拥有者都认为他们使用的服务器程序是自己一个人专用、独享的。容器技术是虚拟化的一种,docker 是现今容器技术的事实标准。

        简单举例比喻:物理机就好比你的庄园,其中的房子、喷泉、花园都是你独享的,别人访问不到,也享受不到。


 

        相反,虚拟机就像开发商的一块楼盘。一栋栋单元楼对应一户户人家,它们之间是隔离的!但其中的小区设施、花园都是共享的,所有户主都可以使用。

        容器就好比 1 个房子里面,开辟出来一个又一个的胶囊公寓共享这套房子的卫生间、共享厨房、共享 WiFi,只有衣服、电脑等私人物品是你自己的。

 


二、为什么需要虚拟化、容器化? 

        从上述举的现实生活中的例子来看,虚拟化、容器化的主要目的是资源隔离。那么资源隔离有什么大的收益吗?

① 资源利用率高

        将利用率较低的服务器资源进行整合,用更少硬件资源运行更多业务降低 IT 支出和
运维管理成本。

        例如: 尽管你的庄园很大,非常得富丽堂皇,可是如果你是一个人住或者几个人住,土地的使用率肯定是不高的,但你付出的维护成本一定大于那栋栋楼盘。

② 环境标准化

        一次构建,随处执行。实现执行环境的标准化发布,部署和运维。由于开发环境、测试环境、生产环境不一致,导致有些bug 并未在开发过程中被发现。由此,确保了应用运行环境一致性
后也就会减少这类恼人问题的出现。

③ 资源弹性伸缩                

        根据业务情况,动态调整计算、存储、网络等硬件及软件资源。例如开售楼盘,你可以一次性开售完,也可以先开售几个观察观察情况,可是你一旦卖出了庄园,就真的再也没有了。 

容器化扩展优点:

④ 差异化环境提供

        虚拟化技术可以将一台计算机虚拟为多台逻辑计算机,也就是说多台虚拟机可以配备不同的执行环境。

 ⑤ 沙箱安全

        为避免不安全或不稳定软件对系统安全性、稳定性造成影响,可使用虚拟化技术构建虚拟执行环境。因为虚拟化技术构建虚拟执行环境具有隔离性,不会影响别人在该服务器上部署的进程、服务。

⑥ 容器对比虚拟机更轻量,启动更快

        传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运
行于宿主内核,无需启动完整的操作系统。大大的节约了开发、测试、部署的时间。

⑦ 维护和扩展容易

        Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
        


三、 虚拟化实现方式        

        学过操作系统的友子应该对 应用程序执行环境分层很熟悉:                

 

(1) 虚拟化常见类别

虚拟机:

        存在于 ”硬件层和操作系统层间” 的虚拟化技术,虚拟机通过“伪造”一个硬件抽象接口,将一个操作系统以及操作系统层以上的层嫁接到硬件上,实现和真实物理机几乎一样的功能。
        比如,我这台机器上面有一个VMWare软件,可以在WIndows系统上使用Linux Centos7虚拟机。

容器:

        存在于 "操作系统层和函数库层" 之间的虚拟化技术。容器通过“伪造”操作系统的接口,将函数库层以上的功能置于操作系统上。

        简单来说,如果虚拟机是把整个操作系统封装隔离,从而实现跨平台应用的话。那么容器
则是把一个个应用单独封装隔离,从而实现跨平台应用。所以容器体积比虚拟机小很多,理论上占用资源更少。        

JVM 之类的虚拟机:

        存在于 "函数库层和应用程序" 之间的虚拟化技术。 Java 虚拟机同样具有跨平台特性,所谓跨平台特性实际上也就是虚拟化的功劳。对下通过不同的版本适应不同的操作系统函数库,对上提供统一的运行环境交给程序和开发者,使开发者能够调用不同操作系统的函数库。
 

(2) 常见虚拟化实现

主机虚拟化(虚拟机)实现:

        主机虚拟化的原理是通过在物理服务器上安装一个虚拟化层来实现。这个虚拟化层可以在物理服务器和客户操作系统之间建立虚拟机,使得它们可以独立运行。

        从软件框架的角度上,根据虚拟化层 "直接位于硬件之上" 还是在 "一个宿主操作系统之
上",将虚拟化划分为 Type1 和 Type2。

        Type1 类的虚拟Hypervisor直接运行在硬件之上,没有宿主机操作系统,Hypervisor 直接控制硬件资源和客户机。Type2 类的Hypervisor运行在一个宿主机操作系统之上,作为宿主机操作系统中的一个应用程序,客户机就是在宿主机操作系统上的一个进程。

注: Hypervisor是一种系统软件,它充当 计算机硬件和虚拟机 之间的中介,负责有效地分配和利用由各个虚拟机使用的硬件资源,这些虚拟机在物理主机上单独工作,因此,Hypervisor 也称为虚拟机管理器。         

 

容器虚拟化实现:

        容器虚拟化实现原理: 容器虚拟化,有别于主机虚拟化,是 “操作系统层” 的虚拟化。需要通过 namespace(命名空间)进行各程序的隔离,加上 cgroups进行资源的控制,以此来进行虚拟化。


三、容器虚拟化基础之NameSpace

        到这里我们总算步入正题,以上都是介绍了很多概念性的东西,当然这也是理解Docker技术的基础。

(1) 什么是Namespace(命名空间)?

        你没看错,Linux系统中也有Namespace命名空间。C++中也有命名空间也是以相同的英文单词namespace,只不过它是为了保证类域名不污染的作用。那么Linux中的Namespace是啥的呢?

        namespace 是 Linux 内核用来隔离内核资源的方式。通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源放在同一namespace中。
        Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前namespace里的进程,对其他 namespace 中的进程没有影响。

(2) namepaces参数

        Linux 提供了多个 API 用来操作 namespace,它们是 clone()、 setns() 和 unshare() 函
数,为了确定隔离的到底是哪项 namespace,在使用这些 API 时,通常需要指定一些调用参数。

namespace系统调用给参数被隔离的全局系统资源
UTSCLONE_NEWUTS主机名和域名
IPCCLONE_NEWIPC信号量、消息队列、共享内存
PIDCLONE_NEWPID进程编号
NetWorkCLONE_NEWNET网络设备、网络栈、端口等
MountCLONE_NEWNS文件系统挂在点
UserCLONE_NEWUSER用户和用户组

以上命名空间在容器环境下的隔离效果:

● UTS:每个容器能看到自己的 hostname,拥有独立的主机名和域名

● IPC:同一个 IPC namespace 的进程之间能互相通讯,不同的 IPC namespace 之间不能通信。

● PID:每个 PID namespace中的进程可以有其独立的 PID,每个容器可以有其PID为1的root进程。

● Network:每个容器用有其独立的网络设备, IP 地址, IP 路由表, /proc/net 目录,端口号。

● Mount:每个容器能看到不同的文件系统层次结构。

● User:每个 container 可以有不同的 user 和 group id。

想想如何进行隔离呢?

① 首先容器进程与进程之间需要隔离,所以需要 PID 隔离。

② 首先容器 A 进程不能读取容器 B 进程通讯内容需要隔离信号量等,所以需要 IPC隔离。

③ 首先容器 A 进程不能读取容器 B 进程的文件,所以需要 Mount 隔离。

④ Docker 允许用户在主机和容器间共享文件夹,同时不需要限制容器的访问权限,这就容易让容器突破资源限制。 需要借助用户空间来完成用户之间的隔离。

四、空间隔离实战

(1) 基础知识

dd命令详解:

        Linux下的dd命令用于读取、转换并输出数据。dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。

语法:

dd option        

参数作用
if=文件名;of=文件名

输入文件名,默认为标准输入。即指定源文件.

输出文件名,默认为标准输出。即指定目的文件.

ibs\obs\bs = bytes一次读入\输出\读入与输出 bytes 个字节.
cbs=bytes一次转换 bytes 个字节,即指定转换缓冲区大小.
skip=blocks从 输入 文件开头跳过 blocks 个块后再开始复制.
seek=blocks从 输出 文件开头跳过 blocks 个块后再开始复制.
count=blocks仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数.
conv=<关键字>

关键字可以有以下 11:

▪ conversion:用指定的参数转换文件。
▪ ascii:转换 ebcdic 为 ascii
▪ ebcdic:转换 ascii 为 ebcdic
▪ ibm:转换 ascii 为 alternate ebcdic
▪ block:把每一行转换为长度为 cbs,不足部分用空格填充
▪ unblock:使每一行的长度都为 cbs,不足部分用空格填充
▪ lcase:把大写字符转换为小写字符
▪ ucase:把小写字符转换为大写字符
▪ swap:交换输入的每对字节
▪ noerror:出错时不停止
▪ notrunc:不截短输出文件
▪ sync:将每个输入块填充到 ibs 个字节,不足部分用空(NUL)字符补齐。

示例1: 生成一个镜像文件        

/dev/zero:是一个特殊的文件,当你读它的时候,它会提供无限的空字符。

bs: 8k = 8 * 1024

count: 块数 该文件的最终大小为 count * bs ≈ 80M

示例2: 将一个文件里的字符转为大写字符        

 

mkfs命令详解:

        用于在设备上创建 Linux 文件系统,俗称格式化,比如我们使用 U 盘的时候可以格式化。
语法:

mkfs [-V] [-t fstype] [fs-options] filesys [blocks]

参数作用
-V详细显示模式
-t fstype指定要建立何种文件系统,例如ext3,ext4 
fs -options传递给具体文件系统的参数
filesys指定创建文件系统的文件名
blocks指定文件系统的磁盘块数

示例: 格式化镜像文件为ext4

  

df命令详解:

        df 命令用于显示目前在 Linux 系统上的文件系统磁盘使用情况统计。

语法

df [option] ... [file] ...

常见参数作用

-a\--all

包含所有的具有 0 Blocks 的文件系统.
-h, --human-readable使用人类可读的格式(预设值是不加这个选项的...).
-H, --si 同-h相像但是用 1000 为单位而不是用 1024.
-t, --type=TYPE限制列出文件系统的 TYPE.
-T, --print-type显示文件系统的形式.

 示例:查看磁盘使用情况\磁盘的系统类型 

mount 命令详解:

        mount 命令用于加载文件系统到指定的加载点,此命令的也常用于 "挂载光盘" ,使我们可以访问光盘中的数据,因为你将光盘插入光驱中, Linux 并不会自动挂载,必须使用mount 命令来手动完成挂载。 

        Linux 系统下不同目录可以 ”挂载不同分区和磁盘设备” ,它的目录和磁盘分区是分离的,可以自由组合(通过挂载)。不同的目录数据可以跨越不同的磁盘分区或者不同的磁盘设备。

         挂载的实质是为磁盘添加入口。

语法

mount [-l]

mount [-t vfstype] [-o options] device dir        

常见参数作用
-l显示已加载的文件系统列表
-t加载文件系统类型支持常见系统类型的 ext3,ext4,iso9660,tmpfs,xfs 等,大部分情况可以不指定, mount 可以自己识别
-o options

主要用来描述设备或档案的挂接方式:

        loop:用来把一个文件当成硬盘分区挂接上系统
        ro:采用只读方式挂接设备

        rw:采用读写方式挂接设备

device要挂接(mount)的设备
dir挂载点的目录

示例: 将镜像文件挂载到 /mnt/目录下,需要确保挂载的目录是存在的

unshare 命令详解:        

        unshare 主要能力是使用与父程序不共享的名称空间运行程序。

语法

unshare [options] program [arguements]

参数作用
i,--ipc不共享ipc空间
-m,--mount不共享Mount空间
-n,--net不共享Net空间
-p,--pid不共享PID空间
-u,--uts不共享UTS空间
-U,--user不共享用户
-V,--version版本查看
--fork执行unshare的进程fork一个子进程,在子进程中执行unshare传入的参数

--mount-porc

执行子进程前,将proc挂载过去

 示例: 实现hostname隔离

 

(2) 实战一 PID隔离

         在主机上执行 ps -ef,可以看到进程列表如下,其中启动进程 PID 1 为 init 进程.

        当我们查看该Namespace下的 /proc目录文件是这样的:

        其中记录着大量与当前进程相关进程的信息。

如何实现PID隔离呢?

        我们打开另外一个 shell ,执行下面命令创建一个 bash 进程并且,新建一个 PID Namespace。

unshare --fork --pid --mount-proc /bin/bash

● --fork:新建了一个 bash 进程。如果不建新进程,新的 namespace 会用 unshare的 PID 作为新的空间的父进程(pid=1),但unshare进程并不在新的namespace当中,而是在当前的namespace当中。

● --pid:表示我们的进程隔离的是 pid,而其他命名空间没有隔离。

● mount-proc:Linux 下的每个进程都有一个对应的 /proc/PID,创建一个新的 PID namespace 后,如果想让子进程中的 top、 ps 等依赖 "/proc 文件系统" 的命令工作,就需要挂载 /proc 文件系统。而文件系统隔离是 mount namespace 管理的,所以 linux特意提供了一个选项--mount-proc 来解决这个问题。如果不带这个我们看到的进程还是系统的进程信息。

        执行 ps -ef 查看进程信息,我们可以看到此时进程空间内的内容已经变,而且启动进程也变成了我们的 bash 进程。说明我们已经看不到主机上的进程空间了,我们的进程空间发生了隔离。

        执行 exit 退出进程。

 


(3) 实战二Mount 隔离

        打开一个shell 窗口 A,执行命令, df -h ,查看主机默认命名空间的磁盘挂载情况。


        
        再打开一个新的 shell 窗口 B,执行 Mount 隔离命令:

unshare --mount --fork /bin/bash 

注:--fork\--mount不解释

        在窗口 B 中添加新的磁盘挂载.

dd if=/dev/zero of=fdimage.img bs=8k count=1024   

mkfs -t ext4 ./fdimage.img

 

        在窗口 B 挂载的磁盘中添加文件:

echo "hello world" >> /test/tmpmount/hello.txt

        分别查看窗口 A、B 中的磁盘挂载信息

A:

 

 B:

         查看窗口A、 B中的文件信息

        可以看到窗口 B 中新建的文件和磁盘挂载,并不存在与A窗口,说明我们实现了文件系统的隔离。


本篇到此结束,感谢你的阅读。

祝你好运,向阳而生~

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LXC(Linux Container)容器虚拟化技术是一种轻量级的虚拟化技术,适用于在单个主机上运行多个相互隔离的应用程序。与传统的虚拟机相比,LXC容器更加轻便和高效。 LXC容器虚拟化技术的研究主要集中在几个方面。首先,研究者致力于提高容器的隔离性。通过实现更严格的资源隔离和访问控制机制,可以保证不同容器之间的资源互不干扰,提高安全性和稳定性。 其次,研究者关注于提升容器的性能。通过针对不同应用场景的性能优化,可以提高容器的运行效率和响应速度。例如,使用特定的调度算法来优化容器的CPU、内存和网络资源分配。 此外,研究者还致力于提供更便捷的容器管理工具和技术。例如,开发了一些图形化界面和命令行工具,可以方便地创建、部署和管理容器。同时,为了提高容器的可靠性,研究者还研究了容器的镜像和备份技术,以及容器的自动化部署和扩展技术。 最后,还有一些研究关注于容器的安全性。容器虚拟化技术由于存在共享内核的特点,容器之间存在一定的安全风险。因此,研究者致力于开发能够检测和防御容器安全威胁的技术。例如,通过使用用户命名空间(user namespace)和容器沙盒(container sandbox)等技术,可以增加容器的安全性。 总的来说,LXC容器虚拟化技术的研究方向包括提高容器的隔离性、性能优化、容器管理工具和技术、容器安全性等。通过这些研究,我们可以更好地应用LXC容器技术,提高应用程序的部署效率和资源利用率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值