目录
Docker容器的本质
linux的namespace机制
强大内核工具cgroups
首页 运维 Docker docker对哪些资源进行隔离

docker对哪些资源进行隔离

Jan 28, 2022 pm 03:35 PM
docker

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

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1662
14
CakePHP 教程
1419
52
Laravel 教程
1311
25
PHP教程
1262
29
C# 教程
1234
24
docker怎么退出容器 docker怎么退出容器 Apr 15, 2025 pm 12:15 PM

退出 Docker 容器的四种方法:容器终端中使用 Ctrl D 快捷键容器终端中输入 exit 命令宿主机终端中使用 docker stop <container_name> 命令宿主机终端中使用 docker kill <container_name> 命令(强制退出)

docker内的文件怎么拷贝到外面 docker内的文件怎么拷贝到外面 Apr 15, 2025 pm 12:12 PM

Docker 中将文件拷贝到外部主机的方法:使用 docker cp 命令:执行 docker cp [选项] <容器路径> <主机路径>。使用数据卷:在主机上创建目录,在创建容器时使用 -v 参数挂载该目录到容器内,实现文件双向同步。

docker怎么启动容器 docker怎么启动容器 Apr 15, 2025 pm 12:27 PM

Docker 容器启动步骤:拉取容器镜像:运行 "docker pull [镜像名称]"。创建容器:使用 "docker create [选项] [镜像名称] [命令和参数]"。启动容器:执行 "docker start [容器名称或 ID]"。检查容器状态:通过 "docker ps" 验证容器是否正在运行。

docker怎么重启 docker怎么重启 Apr 15, 2025 pm 12:06 PM

重启 Docker 容器的方法:获取容器 ID(docker ps);停止容器(docker stop <container_id>);启动容器(docker start <container_id>);验证重启成功(docker ps)。其他方法:Docker Compose(docker-compose restart)或 Docker API(参考 Docker 文档)。

docker容器名称怎么查 docker容器名称怎么查 Apr 15, 2025 pm 12:21 PM

可以通过以下步骤查询 Docker 容器名称:列出所有容器(docker ps)。筛选容器列表(使用 grep 命令)。获取容器名称(位于 "NAMES" 列中)。

docker怎么启动mysql docker怎么启动mysql Apr 15, 2025 pm 12:09 PM

在 Docker 中启动 MySQL 的过程包含以下步骤:拉取 MySQL 镜像创建并启动容器,设置根用户密码并映射端口验证连接创建数据库和用户授予对数据库的所有权限

docker怎么创建容器 docker怎么创建容器 Apr 15, 2025 pm 12:18 PM

在 Docker 中创建容器: 1. 拉取镜像: docker pull [镜像名] 2. 创建容器: docker run [选项] [镜像名] [命令] 3. 启动容器: docker start [容器名]

docker怎么更新镜像 docker怎么更新镜像 Apr 15, 2025 pm 12:03 PM

更新 Docker 镜像的步骤如下:拉取最新镜像标记新镜像为特定标签删除旧镜像(可选)重新启动容器(如果需要)

See all articles