欢迎光临
我们一直在努力

Docker基础——Docker简介和namespace空间隔离

目录

 Docker 简介

什么是虚拟化、容器化

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

容器虚拟化实现

容器虚拟化实现原理

容器虚拟化基础之 NameSpace

什么是 Namespace(命名空间)

空间隔离实战

基础知识

dd 命令详解

mkfs 命令详解

df 命令详解

mount 命令详解

unshare命令详解 


 Docker 简介

什么是虚拟化、容器化

物理机:实际的服务器或者计算机。相对于虚拟机而言的对实体计算机的称呼。物理机提供给虚拟机以硬件环境,有时也称为“寄主”或“宿主”。

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

容器化:容器化是一种虚拟化技术,又称操作系统层虚拟化(Operating system level virtualization),这种技术将操作系统内核虚拟化,可以允许用户空间软件实例(instances)被分割成几个独立的单元,在内核中运行,而不是只有一个单一实例运行。这个软件实例,也被称为是一个容器(containers)。对每个实例的拥有者与用户来说,他们使用的服务器程序,看起来就像是自己专用的。容器技术是虚拟化的一种。docker 是现今容器技术的事实标准。

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

我们从上面的历史发展来看,虚拟化和容器化的最主要目的就是资源隔离,随着资源隔离的实现逐渐也带来了更大的收益。

资源利用率高

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

环境标准化

一次构建,随处执行。实现执行环境的标准化发布,部署和运维。开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。

资源弹性伸缩

根据业务情况,动态调整计算、存储、网络等硬件及软件资源

差异化环境提供

同时提供多套差异化的执行环境,限制环境使用资源。比如我的服务一个以来 Ubuntu 操作系统,一个服务依赖 CentOS 操作系统,但是没有预算购买两个物理机,这个时候容器化就能很好的提供多种不同的环境。

沙箱安全

为避免不安全或不稳定软件对系统安全性、稳定性造成影响,可使用虚拟化技术构建虚拟执行环境。

比如我在容器里面执行 rm -rf /* 不会把整个服务器搞死,也不影响其他人部署的程序使用。

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

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

docker 不需要虚拟内核,所以启动可以更快,相当于 windows 的开机时间省去了。

维护和扩展容易

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。比如 docker hub 提供了很多镜像,各个系统的一个命令就可以拿到了,研发也可以自己定制镜像分享给各个产品

容器虚拟化实现

容器虚拟化实现原理

容器虚拟化,有别于主机虚拟化,是操作系统层的虚拟化。通过 namespace 进行各程序的隔离,加上 cgroups 进行资源的控制,以此来进行虚拟化。

容器虚拟化基础之 NameSpace

什么是 Namespace(命名空间)

namespace 是 Linux 内核用来隔离内核资源的方式。通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。

Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前namespace 里的进程,对其他 namespace 中的进程没有影响。

Linux 提供了多个 API 用来操作 namespace,它们是 clone()、setns() 和 unshare() 函数,为了确定隔离的到底是哪项 namespace,在使用这些 API 时,通常需要指定一些调用参数:CLONE_NEWIPC、CLONE_NEWNET、CLONE_NEWNS、CLONE_NEWPID、CLONE_NEWUSER、CLONE_NEWUTS 和CLONE_NEWCGROUP。如果要同时隔离多个 namespace,可以使用 | (按位或)组合这些参数

举例说明

三年一班的小明和三年二班的小明,虽说他们名字是一样的,但是所在班级不一样,那么,在全年级排行榜上面,即使出现两个名字一样的小明,也会通过各自的学号来区分。对于学校来说,每个班级就相当于是一个命名空间,这个空间的名称是班级号。班级号用于描述逻辑上的学生分组信息,至于什么学生分配到 1 班,什么学生分配到2 班,那就由学校层面来统一调度。

namespace 系统调用参数 被隔离的全局资源
IPC

CLONE_NEWIPC

进程间通信
Mount

CLONE_NEWNS

文件系统挂载点
UTS

CLONE_NEWUTS

主机名域名
PID

CLONE_NEWPID

进程编号
Network

CLONE_NEWNET

网络设备
User

CLONE_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

空间隔离实战

我需要知道隔离的能力其实并不是Docker实现的,而是我们的操作系统实现的

基础知识
dd 命令详解

语法:dd option

参数:

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

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

ibs=bytes:一次读入 bytes 个字节,即指定一个块大小为 bytes 个字节。

obs=bytes:一次输出 bytes 个字节,即指定一个块大小为 bytes 个字节。

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)字符补齐。

–help:显示帮助信息

–version:显示版本信息


dd命令演示


mkfs 命令详解

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

语法:

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

参数:

  • -t fstype:指定要建立何种文件系统;如 ext3,ext4
  • filesys :指定要创建的文件系统对应的设备文件名;
  • blocks:指定文件系统的磁盘块数。
  • -V : 详细显示模式
  • fs-options:传递给具体的文件系统的参数

mkfs演示


df 命令详解

Linux df(英文全拼:disk free) 命令用于显示目前在 Linux 系统上的文件系统磁盘使用情况统计。

语法:

df  [OPTION]…  [FILE]…

参数

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

df命令演示:

-T:


mount 命令详解

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

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

挂载的实质是为磁盘添加入口(挂载点)

mount 常见用法:

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: 挂载点的目录

mount命令演示:

我们将刚刚格式化的test.img文件挂载到我们的testmount文件中,用df可以查看我们成功的挂载,我们就可以通过在这个目录中进行读写,就是对挂载的磁盘或文件进行读写


unshare命令详解 

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

语法:

unshare [options]  program  [arguments]

常用参数:

参数 含义

-i, –ipc

不共享 IPC 空间

-m, –mount

不共享
Mount
空间

-n, –net

不共享
Net
空间

-p, –pid

不共享
PID
空间

-u, –uts

不共享
UTS
空间

-U, –user

不共享用户

-V, –version

版本查看

–fork

执行
unshare
的进程
fork
一个新的子进程,

在子进程里执行 unshare
传入的参数。

–mount-proc

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

unshare命令演示:

1 、PID隔离

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

init
进程

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

–fork 新建了一个 bash 进程,是因为如果不建新进程,新的 namespace 会用 unshare 的 PID 作为新的空间的父进程,而这个 unshare 进程并不在新的 namespace 中,所以会报个错 Cannot allocate memory

mount-proc 是因为 Linux 下的每个进程都有一个对应的 /proc/PID 目录,该目录包含了大量的有关当前进程的信息。 对一个 PID namespace 而言,/proc 目录只包含当前namespace 和它所有子孙后代 namespace 里的进程的信息。创建一个新的 PIDnamespace 后,如果想让子进程中的 topps 等依赖 /proc 文件系统的命令工作,还需要挂载 /proc 文件系统。而文件系统隔离是 mount namespace 管理的,所以 linux特意提供了一个选项–mount-proc 来解决这个问题。如果不带这个我们看到的进程还是系统的进程信息,或者根本看不到系统的相关信息

unshare之后:

unshare之前:

2、mount隔离

我们首先创建一个空白的镜像文件

然后执行mount隔离

再当前窗口进行mount隔离

我们再挂载点中进行写操作

我们去另一个bash中查看当前文件下的是否有内容,发现并没有内容,所以我们的确实完成了mout隔离

赞(0)
未经允许不得转载:171主机测评 » Docker基础——Docker简介和namespace空间隔离
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址