Docker资源隔离(namespace,cgroups)

news2024/9/25 13:17:18

一、概述

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

3.1、namespace的操作

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

3.2、clone()

  • 使用clone() 来创建一个独立namespace的进程,是最常见的做法,也是Docker使用namespace最基本的方法。
  • clone() 是 Linux 系统调用fork() 的一种更通用的实现方式,可以通过flags来控制使用多少功能。

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

$ docker ps
$ docker exec -it host2-c10 hostname
# f057b4b03eb8就是docker ID
$ ps -ef|grep f057b4b03eb8
$ ls -l /proc/3571/ns

img

中括号内的为namespace号。如果两个进程指向的namespace号相同,那么说明它们在同一个namespace

设置link的作用是,即便该namespace下的所有进程都已经结束,这个namespace也会一直存在,后续的进程可以加入进来。

3.4、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并接受参数。

3.5、unshare()

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

3.6、fork() 系统调用

fork并不属于namespace的API

3.7、使用Namespace进行容器的隔离有什么缺点呢?

  • 最大的缺点就是隔离不彻底,其它进程会跟docker抢占资源,虽然可以通过cgroups限制docker使用的资源,但是限制不了其它进程使用docker的资源。
  • 在Linux内核中,有很多资源和对象是不能被Namespace化的,最典型的例子是:时间即如果某个容器修改了时间,那整个宿主机的时间都会随之修改

四、通过Linux的 cgroups控制docker进程资源

1)cgroups简介

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

2)查看docker cgroups

$ ls -l /sys/fs/cgroup/*/docker -d

img

3)cgroups子系统介绍

cpu 子系统,主要限制进程的 cpu 使用率。

cpuacct 子系统,可以统计 cgroups 中的进程的 cpu 使用报告。

cpuset 子系统,可以为 cgroups 中的进程分配单独的 cpu 节点或者内存节点。

memory 子系统,可以限制进程的 memory 使用量。

blkio 子系统,可以限制进程的块设备 io。

devices 子系统,可以控制进程能够访问某些设备。

net_cls 子系统,可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制。

freezer 子系统,可以挂起或者恢复 cgroups 中的进程。

ns 子系统,可以使不同 cgroups 下面的进程使用不同的 namespace。

4)cgroups 的作用

1、资源限制

cgroups可以对任务使用的资源(内存,CPU,磁盘等资源)总额进行限制。
如 设定应用运行时使用的内存上限,一旦超过配额就发出OOM提示

2、优先级分配

通过分配的CPU时间片数量以及磁盘IO带宽大小,实际上就相当于控制了任务运行的优先级

3、资源统计

cgroups可以统计系统的资源使用量
如CPU使用时长,内存用量等,这个功能非常适用于计费

4、任务控制

cgroups 可以对任务进行挂起、恢复等操作

5)使用stress工具压测CPU和内存

使用Dockerfile来创建一个基于Centos的stress工具镜像

$ mkdir -p /opt/stress
$ vi /opt/stress/Dockerfile

FROM centos:7
MAINTAINER chen "liugp@tom.com"
RUN yum install -y wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum install -y stress

新建镜像

$ cd /opt/stress/
$ docker build -t centos:stress .

1、内存限制

CPU 限制相关参数

选项描述
–cpuset-cpus=“”允许使用的 CPU 集,值可以为 0-3,0,1
-c,–cpu-shares=0CPU 共享权值(相对权重)
cpu-period=0限制 CPU CFS 的周期,范围从 100ms~1s,即[1000, 1000000]
–cpu-quota=0限制 CPU CFS 配额,必须不小于1ms,即 >= 1000
–cpuset-mems=“”允许在上执行的内存节点(MEMs),只对 NUMA 系统有效

其中–cpuset-cpus用于设置容器可以使用的 vCPU 核。-c,–cpu-shares用于设置多个容器竞争 CPU 时,各个容器相对能分配到的 CPU 时间比例。–cpu-period和–cpu-quata用于绝对设置容器能使用 CPU 时间。

1)创建容器的CPU权重控制

  • 默认情况下,每个docker容器的cpu份额都是1024,单独一个容器的份额是没有意义的,只有在同时运行多个容器时,容器cpu的加权效果才能体现出现。
  • cgroups只在容器分配的资源紧缺时,即需要对容器使用的资源进行限制时,才会生效。因此,无法单纯的根据某个容器的cpu份额来确定有多少cpu资源分配给它,可以通过cpu share参数可以设置容器使用cpu的优先级,比如启动了两个容器及运行查看cpu的cpu的使用百分比

创建两个容器,分别制定不同的权重比

# --cpu-shares 指定使用cpu的权重
# stress -c 指定产生子进程的个数
$ docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10
$ docker run -itd --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10

# 查看
$ docker exec -it cpu512 top
$ docker exec -it cpu1024 top

img
img

分别进入cpu512和cpu1024之后可以看到,%cpu的比例是1:2,符合我们设置的–cpu-shares参数。

2)cpu core控制

对于多核cpu的服务器,docker还可以控制容器运行使用那些cpu内核,以及使用–cpuset-cpus参数,这对于具有多cpu服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。

执行以下命令需要宿主机为双核,表示创建的容器只能使用两个内核/使用哪几个CPU,最终生成cgroup的cpu内核配置如下:

$ docker run -itd --name cpu1 --cpus=2 centos:stress
# 指定使用哪几个cpu(0和3)
$ docker run -itd --name cpu1 --cpuset-cpus="0,3" centos:stress
# 指定使用哪几个cpu(0,1,2),只执行这个行
$ docker run -itd --name cpu1 --cpuset-cpus="0-2" centos:stress

查看

$ docker exec -it cpu1 bash
$ cat /sys/fs/cgroup/cpuset/cpuset.cpus
# 上面是登录到容器上查,其实也可以在宿主机上查,找到容器对应的容器ID
$ docker ps --no-trunc
$ cat /sys/fs/cgroup/cpuset/docker/7ca231149ecb0e06cbabda944697c0787c9a9e1f77565fd001aa978f4b3adede/cpuset.cpus

img

2、内存限制

与操作系统类似,容器可使用的内存包括两部分:物理内存和swap;Docker 默认容器交换分区的大小和内存相同;若没有设置memory和memory-swap选项,则该容器可以使用主机的所有内存,没有限制

内存限制相关的参数

选项描述
-m,–memory内存限制,格式是数字加单位,单位可以为 b,k,m,g。最小为 4M
–memory-swap内存+交换分区大小总限制。格式同上。必须必-m设置的大
–memory-reservation内存的软性限制。格式同上
–oom-kill-disable是否阻止 OOM killer 杀死容器,默认没设置
–oom-score-adj容器被 OOM killer 杀死的优先级,范围是[-1000, 1000],默认为 0
–memory-swappiness用于设置容器的虚拟内存控制行为。值为 0~100 之间的整数
–kernel-memory核心内存限制。格式同上,最小为 4M

1)允许容器最多使用200M的内存和300M的swap

$ docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
#--vm 1 ,代表启动一个内存工作线程
#--vm-bytes 280 M ,代表每个线程可以分配280M内存

2)容器中的进程最多能使用 500M 内存,在这 500M 中,最多只有 50M 核心内存。

docker run -it -m 500M --kernel-memory 50M ubuntu:16.04 /bin/bash

核心内存

核心内存和用户内存不同的地方在于核心内存不能被交换出。不能交换出去的特性使得容器可以通过消耗太多内存来堵塞一些系统服务。

3、磁盘IO配额控制

相对于CPU和内存的配额控制,docker对磁盘IO的控制相对不成熟,大多数都必须在有宿主机设备的情况下使用。主要包括以下参数:

选项描述
–device-read-bps限制此设备上的读速度(bytes per second),单位可以是kb、mb或者gb。
–device-read-iops通过每秒读IO次数来限制指定设备的读速度。
–device-write-bps限制此设备上的写速度(bytes per second),单位可以是kb、mb或者gb。
–device-write-iops通过每秒写IO次数来限制指定设备的写速度。
–blkio-weight容器默认磁盘IO的加权值,有效值范围为10-100。
–blkio-weight-device针对特定设备的IO加权控制。其格式为DEVICE_NAME:WEIGHT

1)Block IO的限制

默认情况下,所有容器平等地读写磁盘,可以通过设置–blkio-weight参数来改变容器block IO的优先级。

$ docker run -it --name container_A --blkio-weight 600 centos:stress
$ cat /sys/fs/cgroup/blkio/blkio.weight

| –blkio-weight-device | 针对特定设备的IO加权控制。其格式为DEVICE_NAME:WEIGHT |

1)Block IO的限制

默认情况下,所有容器平等地读写磁盘,可以通过设置–blkio-weight参数来改变容器block IO的优先级。

$ docker run -it --name container_A --blkio-weight 600 centos:stress
$ cat /sys/fs/cgroup/blkio/blkio.weight

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/354744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jfr引起的一次jvm异常记录

业务生产启动时,20个节点有1-2个节点因为jvm问题出现启动失败,k8s自动重启后正常。在测试环境2个节点下偶现 排查思路: 先拿到hs_err_pid的jvm错误文件找到当前线程和内部错误信息 hs_err_pid 文件分析 当前线程:lettuce的线程…

使用Robot Framework实现多平台自动化测试

目录 前言 1、设计目标 2、架构设计 3、平台实现 4、平台的创新点 5、平台的实施效果 6、总结 重点:配套学习资料和视频教学 前言 基于Robot Framework、Jenkins、Appium、Selenium、Requests、AutoIt等开源框架和技术,成功打造了通用自动化测试…

各数据库数据类型的介绍和匹配

各数据库数据类型的介绍和匹配1. Oracle的数据类型2. Mysql的数据类型3. Sql server的数据类型4. 类型匹配5. Awakening1. Oracle的数据类型 数据类型介绍 VARCHAR2 :可变长度的字符串 最大长度4000 bytes 可做索引的最大长度749; NCHAR :根据字符集而定的固定长度字…

微服务架构的演变

文章目录1.1 系统架构的演变过程1.1.1 单体应用架构1.1.2 垂直应用架构1.1.3 分布式架构1.1.4 SOA架构1.1.5 微服务架构1.2 微服务架构设计原则1.2.1 AKF拆分原则1.2.1.1 X轴扩展(水平复制)1.2.1.2 Y轴扩展(模块拆分)1.2.1.3 Z轴扩…

【SSM】Spring对IoC的实现方式DI详讲

控制反转的一种实现方式——依赖注入一、IoC 控制反转(Overview)依赖注入(DI)- Overview利用 IoC(控制反转)这种思想有什么好处呢?二、依赖注入的方式setter 方式(xml配置中的proper…

Java JSR规范列表

Java JSR规范列表目录概述需求:设计思路实现思路分析1.JSR2.JSR方法3.web service4.Webservice:5.数据处理器拓展实现参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,m…

JavaWeb-连接数据库实现用户登录、注册、修改密码(全代码)

上一篇博客中我通过使用HttpServlet完成一个假登录,这篇博客我将通过JDBC连接数据库,使其实现简单的用户登录、注册以及更改密码一、MySQL:MySQL部分代码:-- ---------------------------- -- Table structure for users -- ----------------…

WSL(ubuntu2204)使用xfce4桌面打不开语言支持及配置WSL服务自启

语言支持报错 在图形桌面或命令行打开语言支持报错:dbus.exceptions.DBusException: org.freedesktop.DBus.Error.FileNotFound: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory itboonelocalhost:/$ sudo /usr/bin/gnome-…

【SCL】1200案例:天塔之光数码管显示液体混合水塔水位

使用scl编写天塔之光&数码管显示&液体混合&水塔水位 文章目录 目录 文章目录 前言 一、案例1:天塔之光 1.控制要求 2.编写程序 3.效果 二、案例2:液体混合 1.控制要求 2.编写程序 三、案例3:数码管显示 1.控制要求 2.编写程序 3…

转载:项目分析信息方法论

转载一篇最近看到的项目分析信息法:如何快速分析项目和如何详细分析项目。 一、如何快速分析项目? 可以从6个点进行分析,分别是:「流量效率,销转效率,交付效率,客单价,毛利率&…

【程序化天空盒】过程记录02:云扰动 边缘光 消散效果

写在前面 写在前面唉,最近筋疲力竭,课题组的东西一堆没做,才刚刚开始带着思考准备练习作品,从去年5月份开始到现在真得学了快一年了,转行学其他的真的好累,,不过还是加油! 下面是做…

zlib压缩原理

数据压缩的本质 去除数据中的冗余信息,对于ABABABABABABAB字样的字符串,AB出现了7次,占用14个字节,如果将该字符串编码为7AB,只占用3个字节。 为什么需要对数据压缩 数据需要存储或者传输,为了节省磁盘空…

ONNXRUNTUIME实例分割网络说明

ONNXRUNTUIME c使用(分割网络)与相关资料(暂记) initiate a env with an id name(使用id名称启动env) create session (创建会话 ) onnxenv -> sessioninputname [“x”] ,outputname [“t”]inputnodedim [[1,1,192,192…

Linux单一服务管理systemctl

基本上systemd这个启动服务机制只有systemctl命令来处理,所以全部的操作都需要使用systemctl systemctl管理单一服务 一般来说服务的启动有两个阶段,一个是开机是否启动,以及现在是否启动 systemctl【command】【unit】 command主要有&…

VS2017+OpenCV4.5.5 决策树-评估是否发放贷款

决策树是一种非参数的监督学习方法,主要用于分类和回归。 决策树结构 决策树在逻辑上以树的形式存在,包含根节点、内部结点和叶节点。 根节点:包含数据集中的所有数据的集合内部节点:每个内部节点为一个判断条件,并且…

mysql详解之innoDB

索引 Mysql由索引组织,所以索引是mysql多重要概念之一。 聚簇索引 InnoDB和MyISAm一样都是采用B树结构,但不同点在于InnoDB是聚簇索引(或聚集索引),将数据行直接放在叶子节点后面。 这里可能存在一个误区&#xff1…

【C语言】编程初学者入门训练(14)

文章目录131. kiki学结构体和指针132. kiki定义电子日历类133. 圣诞树134. 超级圣诞树131. kiki学结构体和指针 问题描述:KiKi学习了结构体和指针,他了解了结构体类型可以定义包含多个不同类型成员,而指针本质是内存地址,是引用数…

【人脸检测】Yolov5Face:优秀的one-stage人脸检测算法

论文题目:《YOLO5Face: Why Reinventing a Face Detector》 论文地址:https://arxiv.org/pdf/2105.12931.pdf 代码地址:https://github.com/deepcam-cn/yolov5-face 1.简介 近年来,CNN在人脸检测方面已经得到广泛的应用。但是许多…

【C++的OpenCV】第一课-opencv的间接和安装(Linux环境下)

第一课-目录一、基本介绍1.1 官网1.2 git源码1.3 介绍二、OpenCV的相关部署工作2.1 Linux平台下部署OpenCV一、基本介绍 1.1 官网 opencv官网 注意:官网为英文版本,可以使用浏览器自带的翻译插件进行翻译,真心不推荐大家去看别人翻译的&am…

过滤器和监听器

1、过滤器Filter 作用是防止SQL注入、参数过滤、防止页面攻击、空参数矫正、Token校验、Session验证、点击率统计等等; 使用Filter的步骤 新建类,实现Filter抽象类;重写init、doFilter、destroy方法;在SpringBoot入口中添加注解…