赞
踩
什么是 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 | 系统调用参数 | 被隔离的全局系统资源 | 引入内核版本 |
---|---|---|---|
UTC | CLONE_NEWUTS | 主机名和域名 | 2.6.19 |
IPC | CLONE_NEWIPC | 进程间通信(信号量、消息队列、共享内存) | 2.6.19 |
PID | CLONE_NEWPID | 进程编号 | 2.6.24 |
Network | CLONE_NEWNET | 网络设备、网络栈、端口等 | 2.6.29 |
Mount | CLONE_NEWNS | 文件系统挂载点 | 2.4.19 |
User | CLONE_NEWUSER | 用户和用户组 | 3.8 |
以上命名空间在容器环境下的隔离效果:
想想以下如果我们要隔离两个进程需要怎么办?
(1)首先容器进程与进程之间需要隔离,所以需要 PID 隔离;
(2)首先容器 A 进程不能读取容器 B 进程通讯内容需要隔离信号量等,所以需要 IPC 隔离;
(3)首先容器 A 进程不能读取容器 B 进程的文件,所以需要 Mount 隔离;
(4)首先容器 A 进程不能读取容器 B 进程的 socket,所以需要网络隔离、主机隔离;
(5)Docker 允许用户在主机和容器间共享文件夹,同时不需要限制容器的访问权限,这就容易让容器突破资源限制。需要借助用户空间来完成用户之间的隔离。
通过 namespace 隔离实战我们就会知道隔离能力并不是 docker 提供的,而是操作系统内核
提供的基本能力。
Linux dd 命令用于读取、转换并输出数据。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 种:
示例
# 生成 1 个镜像文件
$ dd if=/dev/zero of=fdimage.img bs=8k count=10240
# 查看镜像文件
$ ls
fdimage.img
#将 testfile_1 文件中的所有英文字母转换为大写,然后转成为 testfile_2 文件
$ echo hello docker > testfile_1
$ dd if=testfile_2 of=testfile_1 conv=ucase
$ cat testfile_1
hello docker
$ cat testfile_2
HELLO DOCKER
用于在设备上创建 Linux 文件系统,俗称格式化,比如我们使用 U 盘的时候可以格式化。
$ mkfs [-V] [-t fstype] [fs-options] filesys [blocks]
-t fstype
:指定要建立何种文件系统;如 ext3,ext4;filesys
:指定要创建的文件系统对应的设备文件名;blocks
:指定文件系统的磁盘块数;-V
: 详细显示模式;fs-options
:传递给具体的文件系统的参数;示例
#将 sda6 分区格式化为 ext4 格式 #$ mkfs -t ext4 /dev/sda6 #格式化镜像文件为 ext4 $ mkfs -t ext4 ./fdimage.img mke2fs 1.42.9 (28-Dec-2013) ./fdimage.img is not a block special device. Proceed anyway? (y,n) y Discarding device blocks: done Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) Stride=0 blocks, Stripe width=0 blocks 20480 inodes, 81920 blocks 4096 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=33685504 10 block groups 8192 blocks per group, 8192 fragments per group 2048 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done
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 -Th
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 909M 0 909M 0% /dev
tmpfs tmpfs 919M 0 919M 0% /dev/shm
tmpfs tmpfs 919M 97M 822M 11% /run
tmpfs tmpfs 919M 0 919M 0% /sys/fs/cgroup
/dev/vda1 ext4 40G 30G 7.4G 81% /
tmpfs tmpfs 184M 0 184M 0% /run/user/1003
mount 命令用于加载文件系统到指定的加载点。此命令的也常用于挂载光盘,使我们可以访问光盘中的数据,因为你将光盘插入光驱中,Linux 并不会自动挂载,必须使用 Linux mount 命令来手动完成挂载。
Linux 系统下不同目录可以挂载不同分区和磁盘设备,它的目录和磁盘分区是分离的,可以自由组合(通过挂载);
不同的目录数据可以跨越不同的磁盘分区或者不同的磁盘设备。挂载的实质是为磁盘添加入口(挂载点)。
$ mount [-l]
$ mount [-t vfstype] [-o options] device dir
常见参数
-l
:显示已加载的文件系统列表;-t
: 加载文件系统类型支持常见系统类型的 ext3,ext4,iso9660,tmpfs,xfs 等,大部分情况可以不指定,mount 可以自己识别;-o options
主要用来描述设备或档案的挂接方式。
device
: 要挂接(mount)的设备;dir
: 挂载点的目录;示例
#将 /dev/hda1 挂在 /mnt 之下。
#$ mount /dev/hda1 /mnt
#将镜像挂载到/mnt/testext4 下面,需要确保挂载点也就是目录存在
sudo mkdir -p /mnt/testext
sudo mount ./fdimage.img /mnt/testext4
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 一个新的子进程,在子进--mount-proc
:执行子进程前,将 proc 优先挂载过去示例
#hostname 隔离
[hxy@hcss-ecs-4c0e dockerTest]$ sudo unshare -u /bin/bash
[root@hcss-ecs-4c0e dockerTest]# hostname test1
[root@hcss-ecs-4c0e dockerTest]# hostname
test1
[root@hcss-ecs-4c0e dockerTest]# exit
exit
[hxy@hcss-ecs-4c0e dockerTest]$ hostname
hcss-ecs-4c0e
在主机上执行 ps -ef,可以看到进程列表如下,其中启动进程 PID 1 为 init 进程;
我们打开另外一个 shell ,执行下面命令创建一个 bash 进程,并且新建一个 PID Namespace:
$ sudo unshare --fork --pid --mount-proc /bin/bash
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 909M 0 909M 0% /dev
tmpfs 919M 0 919M 0% /dev/shm
tmpfs 919M 97M 822M 11% /run
tmpfs 919M 0 919M 0% /sys/fs/cgroup
/dev/vda1 40G 30G 7.4G 81% /
tmpfs 184M 0 184M 0% /run/user/1003
/dev/loop0 74M 1.6M 67M 3% /mnt/testext4
# --mount 表示我们要隔离 Mount 命名空间了
# --fork 表示新建进程
[hxy@hcss-ecs-4c0e dockerTest]$ sudo unshare --mount --fork /bin/bash
[root@hcss-ecs-4c0e dockerTest]# dd if=/dev/zero of=fdimage.img bs=8k count=10240 10240+0 records in 10240+0 records out 83886080 bytes (84 MB) copied, 0.0731584 s, 1.1 GB/s [root@hcss-ecs-4c0e dockerTest]# mkdir -p /data/tmpmount [root@hcss-ecs-4c0e dockerTest]# mkfs -t ext4 ./fdimage.img mke2fs 1.42.9 (28-Dec-2013) ./fdimage.img is not a block special device. Proceed anyway? (y,n) y Discarding device blocks: done Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) Stride=0 blocks, Stripe width=0 blocks 20480 inodes, 81920 blocks 4096 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=33685504 10 block groups 8192 blocks per group, 8192 fragments per group 2048 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done [root@hcss-ecs-4c0e dockerTest]# mount ./fdimage.img /data/tmpmount/
[root@hcss-ecs-4c0e dockerTest]# echo "Helo world" > /data/tmpmount/hello.txt
[root@hcss-ecs-4c0e dockerTest]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 30G 7.4G 81% /
devtmpfs 909M 0 909M 0% /dev
tmpfs 919M 0 919M 0% /dev/shm
tmpfs 919M 0 919M 0% /sys/fs/cgroup
tmpfs 919M 97M 822M 11% /run
tmpfs 184M 0 184M 0% /run/user/1003
tmpfs 184M 0 184M 0% /run/user/0
/dev/loop0 74M 1.6M 67M 3% /mnt/testext4
/dev/loop1 74M 1.6M 67M 3% /data/tmpmount
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 909M 0 909M 0% /dev
tmpfs 919M 0 919M 0% /dev/shm
tmpfs 919M 97M 822M 11% /run
tmpfs 919M 0 919M 0% /sys/fs/cgroup
/dev/vda1 40G 30G 7.4G 81% /
tmpfs 184M 0 184M 0% /run/user/1003
/dev/loop0 74M 1.6M 67M 3% /mnt/testext4
tmpfs 184M 0 184M 0% /run/user/0
[root@hcss-ecs-4c0e dockerTest]# ll /data/tmpmount/
total 13
-rw-r--r-- 1 root root 11 Apr 23 11:09 hello.txt
drwx------ 2 root root 12288 Apr 23 11:08 lost+found
[root@hcss-ecs-4c0e dockerTest]# cat /data/tmpmount/hello.txt
Helo world
$ ll /data/tmpmount/
total 0
[root@hcss-ecs-4c0e dockerTest]# exit
exit
[hxy@hcss-ecs-4c0e dockerTest]$
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。