首页 >运维 >Docker >docker对哪些资源进行隔离

docker对哪些资源进行隔离

青灯夜游
青灯夜游原创
2022-01-28 15:35:514360浏览

docker进行隔离的资源:1、文件系统;2、网络(Network);3、进程间的通信;4、针对权限的用户和用户组;5、进程内的PID和宿主机的PID;6、主机名与域名等。

docker对哪些资源进行隔离

本教程操作环境:linux5.9.8系统、docker-1.13.1版、Dell G3电脑。

Docker容器的本质

docker容器的本质是宿主机上的一个进程。

Docker通过namespace实现了资源隔离,通过cgroups实现了资源限制,通过*写时复制机制(copy-on-write)*实现了高效的文件操作。

linux的namespace机制

namespace 机制提供一种资源隔离方案。

PID,IPC,Network等系统资源不再试全局性的,而是属于某个特定的Namespace.

每个namespace下的资源对于其他的namespace下的资源是透明的,不可见的。

Linux 内核实现namespace的一个主要目的就是实现轻量级虚拟化(容器)服务,在同一个namespace下的进程可以感知彼此的变化,而对外界的进程一无所知,以达到独立和隔离的目的。

namespace可以隔离哪些

一个容器要想与其他容器互不干扰需要能够做到:

  • 文件系统需要是被隔离的

  • 网络也是需要被隔离的

  • 进程间的通信也要被隔离

  • 针对权限,用户和用户组也需要隔离

  • 进程内的PID也需要与宿主机中的PID进行隔离

  • 容器也要有自己的主机名

有了以上的隔离,我们认为一个容器可以与宿主机和其他容器是隔离开的。

恰巧Linux 的namespace可以做到这些。

namespace 隔离内容 系统调用参数
UTS 主机名与域名 CLONE_NEWUTS
IPC 信号量、消息队列和共享内存 CLONE_NEWIPC
Network 网络设备、网络栈、端口等 CLONE_NEWNET
PID 进程编号 CLONE_NEWPID
Mount 挂载点(文件系统) CLONE_NEWNS
User 用户和用户组 CLONE_NEWUSER

UTS namespace

UTS (UNIX TIme-sharing System) namespace 提供了主机和域名的隔离,这样每个Docker容器就可以拥有独立的主机名和域名,在网络上可以被视作一个独立的节点,而不是宿主机上的一个进程。
Docker中,每个镜像基本都以自身提供的服务名称来命名hostname,且不会对宿主机产生任何影响。

IPC namespace

进程间通信(Inter-Process Communication,IPC)设计的IPC资源包括常见的信号量、消息队列和共享内存。
申请IPC资源就申请了一个全局唯一的32位ID。
IPCnamespace中包含了系统IPC标识符以及实现POSIX消息队列的文件系统。
在同一个IPC namespace中的进程彼此可见,不同的namespace中的进程则互不可见。

PID namespace

PID namespace的隔离非常实用,他对进程PID重新编号,即两个不同namespace下的进程可以拥有相同的PID,每个PID namespace都有自己的计数程序。
内核为所有的PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace。新创建的PIDnamespace被称为child namespace,而原先的PID namespace就是新创建的PID namespace的child namespace,而原来的PID namespace就是新创建的PID namespace的 parent namespace。
通过这种方式,不同的PID namespace会形成=一个层级体系,所属的父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响。但是子节点确看不到父节点PID namespace中的任何内容。

mount namespace

mount namespace通过隔离文件系统挂载点对隔离文件系统提供支持。
隔离后,不同的mount namespace中的文件结构发生变化也互不影响。

network namespace

network namespace主要提供了关于网络资源的隔离,包括网络设备,IPv4,IPv6协议栈、IP路由表、防火墙、/proc/net目录、/sys/class/net目录、套接字等。

user namespace

user namespace隔离了安装相关的标识符和属性

namespace的操作

namespace的API包括clone() setns() unshare() 还有/proc下的部分文件
为了确定隔离的是那些namespace,需要指定以下6个参数的一个或多个 | 进行分隔。6个参数就是上面表中提到的CLONE_NEWUTS、CLONE_NEWIPC、CLONE_NEWPID、CLONE_NEWNET、CLONE_NEWUSER

clone()

使用clone() 来创建一个独立namespace的进程,是最常见的做法,也是Docker使用namespace最基本的方法。

int clone(int(*child_func)(void *),void *child_stack,int flags, void *arg);

clone() 是 Linux 系统调用fork() 的一种更通用的实现方式,可以通过flags来控制使用多少功能。
共有20多种CLONE_*的flag,控制clone进程的方方面面。

  1. child_func 传入子进程运行的程序主函数
  2. child_stack 传入子进程使用的栈空间
  3. flags 标识使用哪些CLONE_*标志位,与namespace相关的主要是上面提到的6种。
  4. args 用于传入用户参数

/proc/[pid]/ns

用户可以在/proc/[pid]/ns文件下看到指向不同namespace好的文件。

ls -l /proc/10/ns

在这里插入图片描述

中括号内的为namespace号

如果两个进程指向的namespace号相同,那么说明他们在同一个namespace

设置link的作用是,即便该namespace下的所有进程都已经结束,这个namespace也会一直存在,后续的进程可以加入进来。
把/proc/[pid]/ns目录文件使用 --bind方式挂载也可以达到link的作用

touch ~/utsmount --bind /proc/10/ns/uts ~/uts

setns()

Docker中 使用 docker exec命令在已经运行着的命令执行一个新的命令就需要使用setns() 。
通过setns()系统调用,进程从原来的的namespace加入某个已经存在的namespace
通常为了不影响进程的调用者,也为了使新加入的pid namespace生效,会在setns()函数执行后使用clone() 创建子进程继续执行命令,让原先的进程结束运行。

int setns(int fd, in nstype);
#fd 表示要加入namespace的文件描述符。是一个指向/proc/[pid]/ns目录的文件描述符,打开目录链接可以获得
#nstype 调用者可以检查fd指向的namespace类型是否符合实际要求,该参数为0则不检查

为了把新加入的namespace利用起来,需要引入execve()系列函数,该函数可以执行用户命令,常用的就是调用/bin/bash并接受参数

unshare()

通过unshare() 在原先的进程上namespace隔离
unshare与clone很像,unshare不需要新启动一个进程,在原有的进程上就可以进行使用。
docker并没有使用

fork() 系统调用

fork并不属于namespace的API

强大内核工具cgroups

cgroups是Linux内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源分等级的不同组内,从而为系统资源管理提供一个统一的框架。

cgroups是Linux的另外一个强大的内核工具,有了cgroups,不仅可以限制被namespace隔离起来的资源,还可以为资源设置权重、计算使用量、操控任务(进程或县城)启停等。说白了就是:cgroups可以限制、记录任务组所使用的物理资源(包括CPU,Memory,IO等),是构建Docker等一系列虚拟化管理工具的基石。

cgroups 的作用

cgroups 为不同用户层面的资源管理提供了一个统一接口,从单个的资源控制到操作系统层面的虚拟化,cgroups提供了4大功能。

  • 资源限制
    • cgroups可以对任务使用的资源总额进行限制。
      • 如 设定应用运行时使用的内存上限,一旦超过配额就发出OOM提示
  • 优先级分配
    • 通过分配的CPU时间片数量以及磁盘IO带宽大小,实际上就相当于控制了任务运行的优先级
  • 资源统计
    • cgroups可以统计系统的资源使用量
      • 如CPU使用时长,内存用量等,这个功能非常适用于计费
  • 任务控制
    • cgroups 可以对任务进行挂起、恢复等操作

推荐学习:《docker视频教程

以上是docker对哪些资源进行隔离的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn