【Docker】之 Namespace 和 Cgroups

零、简介(容器其实是一种特殊的进程而已)


为什么使用容器?

容器虚拟化可以更高效地构建应用,也更容易管理维护。

左图是虚拟机的工作原理,右图是Docker,所示:

在这里插入图片描述

容器的核心技术是CgroupNamespace,在此基础上还有一些其他工具共同构成容器技术。

容器是宿主机上的进程

  1. 容器技术通过 Namespace 实现资源隔离
  2. 通过Cgroup实现资源控制
  3. 通过rootfs实现文件系统隔离
  4. 容器引擎自身的特性来管理容器的生命周期

补充:
Docker早期其实就相当与LXC的管理引擎,LXCCgroup的管理工具,CgroupNamespace的用户空间管理接口。
Namespace是Linux内核在task_struct中对进程管理的基础机制。



一、Namespace 资源隔离


开发Namespace的主要目的之一:实现轻量级的虚拟化服务

资源隔离,就会想到chroot命令,通过它可以实现文件系统隔离。

如图:

在这里插入图片描述


(1)6种 Namespace 隔离

容器需要6种基本隔离:

如图:
在这里插入图片描述

  1. IPC进程间通信,通过共享内存的方式实现。如果两个进程能直接通过IPC互访,那就不是隔离了,原始的Linux ENV中不同的进程都是可以直接通过IPC通信
  2. 进程树和文件系统树,进程两种形式存在,一种是用户空间的INIT,一种是从属于某一进程。子进程由父进程创建、终止和回收。INIT结束之前,需要终止本用户空间所有的进程(PID映射)。
  3. 用过用户来运行某一个进程(User)。每一个用户空间都需要自己的root,伪装一个root用户[不能处理别的用户空间的内容,比如删除文件],对应在宿主机上只是一个普通的用户。
  4. Mount,文件挂载系统,cd /usr/bin/ 和 宿主机对比。发现是独立的文件系统
  5. UTS-hostname
  6. Networknetstat -an | grep 22

(2)Namespace 操作

Namespace的操作,主要是通过 clonesetnsunshare 这三个系统调用来完成。

  1. clone 可以用来创建新的 Namespace
  2. unshare 调用的进程会被放进新的 Namespace
  3. setns 将进程放到已有的 Namespace

查询当前进程的 Namespace

donald@donald-pro:~$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 donald donald 0 Apr 22 00:00 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 donald donald 0 Apr 22 00:00 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 donald donald 0 Apr 22 00:00 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 donald donald 0 Apr 22 00:00 net -> 'net:[4026532009]'
lrwxrwxrwx 1 donald donald 0 Apr 22 00:00 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 donald donald 0 Apr 22 00:00 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 donald donald 0 Apr 22 00:00 user -> 'user:[4026531837]'
lrwxrwxrwx 1 donald donald 0 Apr 22 00:00 uts -> 'uts:[4026531838]'
donald@donald-pro:~$ 


二、Cgroup


CgroupLinux 内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:CPU、内存、IO等等)的机制

Cgroup有一套进程分组框架,不同资源由不同的子系统控制。
一个子系统就是一个资源控制器,比如 CPU子系统就是控制 CPU时间分配的一个控制器。

通过 Linux 的命名空间为新创建的进程隔离了文件系统、网络与宿主机器之间的进程互相隔离,但是命名空间并不能够为我们提供物理资源上的隔离,比如 CPU 或者 内存,如果在同一台机器上运行了多个彼此以及宿主机器一无所知的 [容器],这些容器却共同占用了宿主机的物理资源。

在这里插入图片描述

Linux上安装了Docker,你就会发现所有子系统的目录下都有一个名为 docker的目录。

cpu.cfs_quota_us文件中的内容能够对CPU的使用作出限制。

donald@donald-pro:/sys/fs/cgroup$ ll
total 0
drwxr-xr-x 15 root root 380 Apr 22 18:05 ./
drwxr-xr-x  9 root root   0 Apr 22 18:05 ../
dr-xr-xr-x  4 root root   0 Apr 22 18:05 blkio/
lrwxrwxrwx  1 root root  11 Apr 22 18:05 cpu -> cpu,cpuacct/
lrwxrwxrwx  1 root root  11 Apr 22 18:05 cpuacct -> cpu,cpuacct/
dr-xr-xr-x  4 root root   0 Apr 22 18:05 cpu,cpuacct/
dr-xr-xr-x  2 root root   0 Apr 22 18:05 cpuset/
dr-xr-xr-x  5 root root   0 Apr 22 18:05 devices/
dr-xr-xr-x  3 root root   0 Apr 22 18:05 freezer/
dr-xr-xr-x  2 root root   0 Apr 22 18:05 hugetlb/
dr-xr-xr-x  4 root root   0 Apr 22 18:05 memory/
lrwxrwxrwx  1 root root  16 Apr 22 18:05 net_cls -> net_cls,net_prio/
dr-xr-xr-x  2 root root   0 Apr 22 18:05 net_cls,net_prio/
lrwxrwxrwx  1 root root  16 Apr 22 18:05 net_prio -> net_cls,net_prio/
dr-xr-xr-x  2 root root   0 Apr 22 18:05 perf_event/
dr-xr-xr-x  4 root root   0 Apr 22 18:05 pids/
dr-xr-xr-x  2 root root   0 Apr 22 18:05 rdma/
dr-xr-xr-x  5 root root   0 Apr 22 18:05 systemd/
dr-xr-xr-x  5 root root   0 Apr 22 18:05 unified/
donald@donald-pro:/sys/fs/cgroup/cpu/docker$ ll
total 0
drwxr-xr-x 3 root root 0 Apr 25 14:28 ./
dr-xr-xr-x 5 root root 0 Apr 25 14:28 ../
drwxr-xr-x 2 root root 0 Apr 25 14:28 c988e6a0567ccc350b18e3e2eb96cfe0dbff4edd202ab4132012916b019c2904/
-rw-r--r-- 1 root root 0 Apr 25 14:28 cgroup.clone_children
-rw-r--r-- 1 root root 0 Apr 25 14:28 cgroup.procs
-r--r--r-- 1 root root 0 Apr 25 14:28 cpuacct.stat
-rw-r--r-- 1 root root 0 Apr 25 14:28 cpuacct.usage
-r--r--r-- 1 root root 0 Apr 25 14:28 cpuacct.usage_all
-r--r--r-- 1 root root 0 Apr 25 14:28 cpuacct.usage_percpu
-r--r--r-- 1 root root 0 Apr 25 14:28 cpuacct.usage_percpu_sys
-r--r--r-- 1 root root 0 Apr 25 14:28 cpuacct.usage_percpu_user
-r--r--r-- 1 root root 0 Apr 25 14:28 cpuacct.usage_sys
-r--r--r-- 1 root root 0 Apr 25 14:28 cpuacct.usage_user
-rw-r--r-- 1 root root 0 Apr 25 14:28 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Apr 25 14:28 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Apr 25 14:28 cpu.shares
-r--r--r-- 1 root root 0 Apr 25 14:28 cpu.stat
-rw-r--r-- 1 root root 0 Apr 25 14:28 notify_on_release
-rw-r--r-- 1 root root 0 Apr 25 14:28 tasks
donald@donald-pro:/sys/fs/cgroup/cpu/docker/c988e6a0567ccc350b18e3e2eb96cfe0dbff4edd202ab4132012916b019c2904$ sudo docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                    NAMES
c988e6a0567c        mobz/elasticsearch-head:5   "/bin/sh -c 'grunt s…"   5 months ago        Up 3 minutes        0.0.0.0:9100->9100/tcp   loving_albattani

# 配额,-1 表示不限额
donald@donald-pro:/sys/fs/cgroup/cpu/docker/c988e6a0567ccc350b18e3e2eb96cfe0dbff4edd202ab4132012916b019c2904$ cat cpu.cfs_quota_us 
-1



三、容器的创建过程


(1)系统调用clone创建新进程,拥有自己的Namespace

该进程拥有自己的:pidmountusernetipcuts namespace

root@docker:~# pid = clone(fun, stack, flags, clone_arg);

(2)将pid写入cgroup子系统,就受到 cgroup 子系统的控制

root@docker:~# echo$pid > /sys/fs/cgroup/cpu/tasks
root@docker:~# echo$pid > /sys/fs/cgroup/cpuset/tasks
root@docker:~# echo$pid > /sys/fs/cgroup/bikio/tasks
root@docker:~# echo$pid > /sys/fs/cgroup/memory/tasks
root@docker:~# echo$pid > /sys/fs/cgroup/devices/tasks
root@docker:~# echo$pid > /sys/fs/cgroup/feezer/tasks

(3)通过 pivot_root 系统调用

通过 pivot_root 系统调用,使进程进入一个新的 rootfs,之后通过 exec系统调用在新的NamespaceCgrouprootfs 中执行 /bin/bash

fun() {
  pivot_root("path_of_rootfs/", path);
  exec("/bin/bash");
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值