docker--namesp和cgroups

发布于:2023-01-22 ⋅ 阅读:(10) ⋅ 点赞:(0) ⋅ 评论:(0)

注:底层隔离和限制都是内核空间完成的

1.namesprece

1.1dicker的底层隔离机制

就是让进程只能看到与自己相关的一部分资源,进程之间感受不到对方的存在,具体实现就是将一个或者多个相关进程放在一个namespece里面,linux 的namespace就是对全局资源的一种封装隔离,使得处于不同Namespace的进程拥有独立的全局系统资源,改变一个Namespace中的系统资源只会影响当前Namespace里的进程,对其他Namespace中的进程没有影响。

1.2docker进行隔断的方式

如图所示,docker上运行nginx容器对于宿主机来说就是启动了一个进程

容器程序本身被隔离了,容器内部只能看到自己内部的进程

这就是namesprece技术

1.3 有哪些namespace

图解:

Docker容器实战(六) - Docker是如何实现隔离的?_JavaEdge的技术博客_51CTO博客

2. 限制容器

1.1cgroups

Docker实现CPU、内存、网络的限制均通过cgroups实现。Cgroups还能够对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。

[root@localhost _data]# docker run --name sc-nginx-3 --cpu-shares 10 -m 10000000 -d -p 9091:80 nginx
010ece46546644af999a6ff38da2d7450301ce75fcf708610588ebb82a36d200
[root@localhost _data]# docker inspect sc-nginx-3
......
    "Isolation": "",##隔离
            "CpuShares": 10,
            "Memory": 10000000,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,

--cpu-shares 10 这里是把cpu资源无论多大多划分为1000份,数字是多少就占1000份中的多少份,最小为2

--cpus decimal 可以使用的cpu核心的数量

--cpuset-cpus string 允许可以在哪个cpu核心使用

-m 10000000 这里是限制了内存使用情况,最小为6MB

容器的进程达到内存和cpu限制时,为了防止容器被kill,会去kill容器里面的进程

可以看到将超过内存大小的进程杀死了

容器只是一种特殊的进程,一个正在运行的Docker容器,就是一个启用了多个Linux Namespace的应用进程,而该进程能够使用的资源量,则受Cgroups限制。即​​容器是一个“单进程”模型​​。

由于一个容器本质就是一个进程,用户的应用进程实际上就是容器里PID=1的进程,也是其他后续创建的所有进程的父进程。

这意味着,在一个容器,无法同时运行两个不同应用,除非你能事先找到一个公共的PID=1的程序充当两个不同应用的父进程,这也解释了为何很多人会用​​systemd​​或​​supervisord​​这样的软件代替应用本身作为容器的启动进程。

容器本身设计就是希望容器和应用能同生命周期,这对容器的编排很重要。否则,一旦出现类似于“容器是正常运行的,但是里面的应用早已经挂了”的情况,编排系统处理起来就非常麻烦了。

跟Namespace的情况类似,Cgroups对资源的限制能力也有很多不完善的地方,被提及最多的就是/proc文件系统的问题。

如果在容器里执行top,会发现它显示的信息是宿主机的CPU和内存数据,而不是当前容器的。造成这个问题的原因就是,/proc文件系统并不知道用户通过Cgroups给这个容器做了什么样的资源限制,即:/proc文件系统不了解Cgroups限制的存在。

参考

Linux资源管理之cgroups简介 - 美团技术团队

Docker容器实战(六) - Docker是如何实现隔离的?_JavaEdge的技术博客_51CTO博客