认识Docker底层原理:Linux内核的Namespace、Cgroup和UnionFS

5 篇文章 0 订阅
2 篇文章 0 订阅

The underlying technology

Docker is written in the Go programming language and takes advantage of several features of the Linux kernel to deliver its functionality. Docker uses a technology called namespaces to provide the isolated workspace called the container. When you run a container, Docker creates a set of namespaces for that container.

Docker使用一种名为命名空间的技术来提供被称为容器的隔离工作空间。当您运行一个容器时,Docker会为该容器创建一组命名空间。

These namespaces provide a layer of isolation. Each aspect of a container runs in a separate namespace and its access is limited to that namespace.

这些命名空间提供了一层隔离。容器的每个方面都在一个独立的命名空间中运行,其访问权限仅限于该命名空间。

Docker容器技术的核心架构建立在Linux内核提供的三大关键技术之上:Namespace、Cgroup和UnionFS。这些技术共同确保了容器在隔离性、资源管理和文件系统效率方面的高效运作。Namespace通过创建隔离的环境,为容器提供了独立的网络、文件系统、用户空间和进程空间。Cgroup则通过资源限制和监控,确保了对容器资源使用的精细控制。而UnionFS作为一种创新的文件系统技术,通过层叠文件系统结构,不仅提高了存储效率,还实现了镜像的快速分发和容器的只读性与写入隔离。

Namespace

Linux Namespaces是Linux内核提供的一种资源隔离方案。Namespaces之间的资源相互独立。通过使用Namespace,进程可以拥有独立的资源副本,如网络、文件系统等,从而实现不同进程间的资源隔离。目前Linux中提供七种namespace。

NamespaceFlag中文名功能
CgroupCLONE_NEWCGROU控制组可以限制、记录和隔离进程组使用的物理资源
IPCCLONE_NEWIPC进程间通信允许进程间通过共享内存、消息队列和信号量等方式进行通信。
NetWorkCLONE_NEWNET网络命名空间提供了网络设备、网络栈和端口号等的隔离。
MountCLONE_NEWNS挂载命名空间允许在用户空间中挂载和卸载文件系统,而不影响其他进程。
PIDCLONE_NEWPID进程 ID 命名空间允许每个容器拥有独立的进程编号空间。
UserCLONE_NEWUSER用户命名空间允许容器内的用户 ID 和组 ID 与宿主机不同,提供了用户和组的隔离。
UTSCLONE_NEWUTSUTS (UNIX Time-Sharing System)命名空间提供了主机名和域名的隔离。
func init() {
     namespaceList = Namespaces{
          {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt"},
          {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts"},
          {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc"},
          {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user"},
          {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid"},
          {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net"},
     }
}

在Linux操作系统中,创建新进程通常涉及fork等系统调用。fork系统调用负责创建子进程,它会复制父进程的task_struct结构体到子进程。在调用fork时,可以传递多种与命名空间(namespace)相关的参数,这些参数通过标志位(flags)来设置。随后,Linux使用exec系列函数来启动子进程中的新程序。

对于容器技术,由于容器本质上是基于进程的,Docker守护进程(Docker Daemon)在创建容器时,会传递特定的命名空间相关参数。这些参数作为标志位,用于在创建过程中配置命名空间。这样,当容器内的进程开始运行时,它们就会受到命名空间隔离的影响,确保容器拥有独立的系统资源视图和操作环境。

Cgroup

Cgroups(控制组)是 Linux 内核提供的一种资源管理框架,它允许系统管理员限制、监控和隔离一组进程使用的资源。通过 Cgroups,可以有效地控制进程组对 CPU、内存、磁盘 I/O 等资源的访问,确保容器化应用不会消耗过多主机资源。此外,Cgroups 还能够记录进程组的资源使用情况,为资源规划和性能监控提供数据支持。

  1. 资源限制:Cgroups 可以限制进程组可以使用的资源量,如 CPU 时间、内存、磁盘 I/O 等。这有助于防止单个进程或进程组消耗过多资源,从而影响系统上其他进程或应用的性能。
  2. 资源分配:Cgroups 允许管理员为不同的进程组分配资源,确保关键任务获得足够的资源,同时限制非关键任务的资源使用。
  3. 资源监控:Cgroups 提供了监控工具,可以跟踪和记录进程组的资源使用情况,帮助系统管理员了解系统资源的使用模式和性能瓶颈。
  4. 进程隔离:通过将进程分配到不同的 Cgroups,可以实现进程间的隔离,使得一个进程组中的进程无法影响其他进程组。
  5. 层次化管理:Cgroups 支持层次化结构,允许将进程组织成树状结构,方便对具有相似特性的进程进行统一管理。
  6. 系统稳定性:通过限制进程资源使用,Cgroups 有助于提高系统的稳定性和可靠性,防止因资源耗尽导致的系统崩溃。

cgroups已经被自动挂载到/sys/fs/cgroup目录下。

docker run -it --name d1 -c 512 centos

cat /sys/fs/cgroup/cpu/cpu.shares
 docker run -it --name d1 -m 300M --memory-swap 400M centos

启动一个容器限制内存为300M,交换空间为400M

 cat  /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes  //查看确认,单位为bytes
 cat /sys/fs/cgroup/memory/memory.limit_in_bytes 

docker会为该容器在每个子系统目录下创建docker/$container_id目录。这样cgroups就能对该容器的资源进行管理和限制了。

容器镜像提供了容器运行所需的全部依赖文件的“静态快照”,包括应用程序及其依赖环境。尽管镜像是不可变的,但容器运行时可以对其文件进行修改。这种灵活性得益于 UnionFS 技术,它将容器的文件系统与镜像文件系统联合挂载。在容器内部,镜像文件表现为只读(类似于 CD-ROM),而所有的修改都被隔离在容器自己的写入层中,保持镜像本身的不变性。

镜像本身由多个只读层构成,这些层叠加在一起形成了完整的文件系统。每当你基于镜像启动新容器时,系统会在这些只读层之上添加一个新的可写层。容器中的任何文件更改或新增操作都发生在这一层,从而确保了镜像的原始状态得以保留。

UnionFS(联合文件系统)

UnionFS 是一种文件系统服务,允许容器共享宿主机的文件系统,同时可以有自己独立的文件系统层:

  • 联合挂载:UnionFS 可以将多个目录的内容叠加在一起,形成一个统一的文件系统视图。在这个视图中,上层目录的内容会覆盖下层目录中的同名文件或目录。联合视图:UnionFS 通过联合挂载(union mount)的方式,将所有分支堆叠起来,形成一个单一的文件系统视图。优先级:在联合视图中,位于上层的分支会覆盖下层分支中的同名文件或目录。也就是说,如果多个分支中存在同名文件,只有最上层分支中的文件可见。
  • 只读与可写层:通常,基础层被设置为只读,以保持镜像的不变性。当需要写入文件时,更改会被写入一个额外的可写层。多个分支:在 UnionFS 中,数据被组织成多个分支(branch),每个分支可以代表文件系统中的一个层(layer)。只读分支:通常,除了最顶层分支外,其他分支都是只读的。这意味着底层分支中的数据不可更改,从而保持了文件系统的一致性和不可变性。

容器化技术中的应用

  • Docker 镜像:在 Docker 中,镜像由多个只读层组成,每一层代表 Dockerfile 中的一个指令。当容器启动时,一个新的可写层(通常称为容器层)被添加到顶部。
  • 写时复制:当容器需要修改文件时,UnionFS 执行写时复制操作。这意味着只有在文件被修改时,它才会被复制到容器的可写层,保持了存储效率。

UnionFS 为容器提供了文件系统级别的隔离,确保容器内的更改不会影响宿主机或其他容器

  • 53
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值