容器基础Namespace和Cgroups

隔离-Namespace

Namespace-进程空间 可以区分容器内进程和宿主机进程的PID ,Mount 、NetWork

容器是一组有着自己Namespace 参数 的 进程、目录、文件 ,容器本身是一组特殊的进程;

Docker内的进程,是运行在宿主机伤的进程,但是是被Namespace 隔离的,所以dokcer内的PID还是从1开始。

  • 举个例子就明白了: 宿主机 PID 和 容器内的PID 1 分别是:
user   PID   cmd
root   1     /usr/lib/systemd/systemd --switched-root --system --deserialize 21
# 容器内
root   1     /bin/bash

实际上,容器内的这个 PID=1 的进程,是我在run docker 时候 的启动命令,也就是docker内启动的 bash 。

  • 再举个例子 ,docker top 3192c11550eb 这个命令可以查看 3192c11550eb 这个 docker 在宿主机的 PID 。
root                10343               2360                0                   Jan15               ?                   00:01:30            /workspace/macco-img/macco-img

而同样的 对应这个 docker 中 这个实际进程 的PID是多少呢?

[[email protected] /]# ps -ef |grep /workspace/macco-img/macco-img
root     10851  4601  0 Jan15 ?        00:01:30 /workspace/macco-img/macco-img

可以看到 ,和宿主机的 PID 并没有关联 ,所以说:容器中的进程和外部是 “隔离”的。

可以说 Docker里面的进程是没有上过历史课的进程 ,是脱离了历史行程的自以为是新的进程。

某位伟人 :一个人的命运啊,当然要靠自我奋斗,但是也要考虑到历史的行程 。

容器 其本质还是运行在宿主机上的一组进程,所以用的还是宿主机的内核,所以在低版本主机上无法 run 高版本的 容器, windows 上无法运行 linux 容器, 在windows上运行 linux 容器,是通过 Hyper-V 支持,借助于 docker-machine ,相当于是在 linux 内核的虚拟机上运行的容器,所以还是建立在linux内核之上 。 所以mac/windows上面的 linuxdocker 还是一个虚拟机 。

容器的限制- Cgroups

  • 概念:
    一个子系统目录加上一组资源限制文件的组合 ,对于docker 这样的容器项目来说,只需要在每个子系统下面,为每个容器创建一个控制组——创建一个新的目录,然后在启动容器进程之后,把这个进程的 PID(容器中隔离Namespace 的PID) 填写到对应控制组的 tasks 文件中。
    cgroups目录和docker对应.jpg
    cgroups为docker添加的子系统限制目录
    为进程设置资源限制 ,挂起进程,恢复进程、优先级、审计

  • 功能:
    CPU子系统 /proc 文件系统

    blkio ,为块设备设定 I/O 限制,一般用于磁盘等设备;

    cpuset,为进程分配单独的CPU 核和对应的内存节点;

    memory ,为进程设定内存使用的限制;

    注意这里的限制,是限制使用的上限

举个例子,/proc 文件系统 ,默认设置容器内存为4G ,但使用命令查出容器的内存是远远大于4G ,所以会导致 容器内 jvm oom 的问题

Ending -天真可爱的 容器

天真可爱的 容器Namespace 欺骗,以为自己是一个独立的系统,其实只是宿主机上的 一组进程 ;更过分的是,其实这一组进程只是宿主机衍生的一个进程 fork 的N个进程。
以为自己是一个独立的系统,所以无拘无束,其实却被 Cgroups 限制 ,可以通过宿主机的 /proc 限制具体容器的内存,CPU带宽等; 容器运行着一个进程,和这个进程相依为命,共同存亡