06 docker-namespace&Cgroups

Docker利用namespace提供进程、网络、文件系统的隔离,创建独立的容器环境。containerd是容器运行时管理工具,与Dockerdaemon协作管理容器生命周期。cgroups用于限制和控制容器的资源使用,如CPU、内存。每个容器有自己的pidnamespace,确保进程隔离,同时通过cgroups实现资源配额,确保主机和容器的安全性。

目录

Docker文档:

namespace学习视频:

namespace

namespace:

问题:

docked - docker daemon

containerd

unshare

Namespace总结

Cgroups总结


Docker文档:

What Are Namespaces and cgroups, and How Do They Work? - NGINX

Docker Docs: How to build, share, and run applications | Docker Documentation

什么是命名空间和 cgroups,它们是如何工作的?- 金克斯 (nginx.com)

namespace学习视频:

Linux中的namespace与cgroup

namespace

namespace:

Docker使用了一种称为namespace的技术来提供独立的工作空间(workspace)称为容器(contaiiner),当你运行一个容器时,Docker会创建一组该容器的namespaces。

这些namepaces提供了一层隔离,Docker 引擎使用namespaces,在linux下执行以下操作:

进程隔离、管理网络接口、 ipc管理进程间通信资源(对于共享内存)、管理文件系统,文件系统挂载、Unix分时系统用来隔离内核和版本信息。

问题:

开启一个容器(ctf)和一个宿主机(host) ,在宿主机host上,是user用户且userid是1000,在容器中,是ctf用户,userid也是1000。

 当我们在容器下创建一个文件:在容器中归ctf所有,在host中查看归user所有

为什么会出现同样的userid,不同的名字呢?

在容器下执行watch “ps ax” 去查看正在运行的进程列表(watch是每两秒查看一次命令输出)

去host下执行ps ax查看正在运行进程列表:

在容器中pid是79,在host中是12675?这也证明容器不是虚拟机。(宿主机和容器之间有一定成程度的隔离,在容器中看不到宿主机进程)

使用pstree -p查看进程树:

 linux执行原理就是,有一个init进程,使用syscalls来clone和frok自己,然后执行新的子进程,最终其中一个子进程将成为你使用的shell。 

从树中可以看到我们在容器中执行的watch在containerd子进程中:

containerd是systemd启动的服务 , 一个标准容器运行时,它来管理其宿主机系统的完整容器生命周期。

docked - docker daemon

         docker daemon(守护进程)运行在后台,并负责管理和监控 Docker 容器的生命周期,处理容器的创建、运行、停止、删除等操作。Docker daemon 监听来自 Docker 客户端的请求,并根据请求执行相应的操作,如拉取镜像、启动容器、管理容器网络等。它还负责管理容器的存储和文件系统,并与主机操作系统进行交互,提供容器运行环境。

dockerd监听客户端请求

containerd

它负责管理和执行容器的生命周期,处理容器的创建、启动、停止和删除等操作。

使用strace跟踪和调试进程的系统调用和信号,它可以捕获程序在运行过程中与操作系统进行的系统调用以及接收到的信号,帮助开发者诊断和分析程序的运行情况。

 containerd运行runc才能真正启动容器。

调用unshare的runc子线程

unshare

创建新的命名空间,并将容器进程放入该命名空间中运行

容器内的进程可以在自己的命名空间中独立运行,与宿主系统和其他容器隔离开

允许进程解除其当前与其他进程共享的部分执行上下文的关联

取消共享进程ID的namespace以便调用进程有一个新的pid,其子进程的namespace不与任何先前存在的进程共享,调用进程不回移动到新的namespace,调用进程创建的第一个子进程id为1,并在新的namespace中的身份为init(1)

         取消共享进程ID的namespace以便调用进程有一个新的pid,其子进程的namespace不与任何先前存在的进程共享,调用进程不会移动到新的namespace,调用进程创建的第一个子进程id为1,并在新的namespace中的身份为init(1)

 在namespace中有新的pid

runc进程已经变成这个容器中的init,已经变成这个容器中namespace的init进程

 这是pidnamespace,还有其他的namespace:

 

 Docker只是围绕这个unshare namespace特性的一个花哨的接口,containerd和runc只是与所有这些交互的组件,最后归结为这些系统调用,他们告诉内核,请伪造fake一个新的进程id或net。

        在容器内部和外部使用相同的是内核,并且可以选择在主机和容器之间取消共享和不取消共享,与虚拟机不同,需要小心不要向容器暴露太多,会造成危险。

Namespace总结

         命名空间是Linux内核中一个功能,也是容器运用的基础。命名空间提供了一层隔离、docker利用多种类型命名空间(进程、还有网络、还有文件系统)来提供容器所需的隔离,既能实现不影响主机系统,又能实现可移植的功能,容器在其单独的命名空间中运行,权限也限制在这个命名空间当中。

        命名空间的关键功能是它们将进程彼此隔离。

        linux系统在创建容器的时候,就会有一个pid的命名空间,这个PID就是进程的序号,编号。建立一个namspace,就会对进程进行pid编个号码,每个命名空间里的pid编号都是从NO1开始。就是一个进程命名空间里只能看到自己个这个空间里的进程,看不到别的namespace里面的进程。如果有另外一个容器,那么它也会有自己的一个pid namespace,这两个空间之间都看不到对方的进程。

        除了pid namespace还有比如network space负责隔离不同的网络环境,mount namespace可以隔离文件系统,还有系统进程通信、hostanme、user共计6种。

        有了namespace,才能让我们隔离出一个个容器,这一个个小系统,小的独立的计算机。

Cgroups总结

        有了一个个小的计算机,但是计算机中的配置不知道。

        有两个版本,V1和V2,目前正在用的还是v1较多。这个东西可以对特有的各种进程做各种计算机资源的限制,比如cpu、内存、io、等等的,有资源限制、优先级控制、记录状态,控制进程状态的功能。

        Cgroups,就是可以对一个或者一些进程的分配计算机资源,消耗啥的进行一系列限制。

        通过各种不同的子系统限制不同的资源,每个子系统都能沟限制一种资源,就各司其职,相关的进程我给你分配一个相关的控制组,然后通过树结构管理。每个控制组有自己的相关资源控制参数。启动容器进程后,把这个进程pid写到对应的控制组的文件里可以起到限制作用。

Cgroups主要包括两部分:subsystem、hierarchy。Subsystem就是一个内核模块,就是用来调度资源,还有限制使用时间等具体待探究,hierarchy,相当于一颗cgroup树,树上的每个节点就是一个进程组,每棵树会有零到多个subsystem。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值