docker资源限制

docker资源限制

一、容器底层技术

Docker底层技术包括:namespace主要是隔离作用,cgroups主要是资源限制,联合文件主要用于镜像分层存储和管理。

1.1 namespace

namespace(命名空间)是将内核的全局资源做封装,使得每个namespace都有一份独立的资源,因此不同的进程在各自的namespace内对同一种资源的使用不会互相干扰。

  1. UTS namespace提供了主机名和域名的隔离,这样每个容器就拥有独立的主机名和域名了,在网络上就可以被视为一个独立的节点,在容器中对hostname的命名不会对宿主机造成任何影响。

  2. IPC namespace实现了进程间通信的隔离,包括常见的几种进程间通信机制,如信号量,消息队列和共享内存。

  3. PID namespace完成的是进程号的隔离,同样的一个进程在不同的PID Namespace里面可以拥有不同的PID。

  4. Mount namespace是用来隔离各个进程看到的挂载点视图。在不同namespace中的进程看到的文件系统层次是不一样的。

  5. User namespace主要是隔离用户的用户组ID。也就是说,一个进程的User ID和Group ID在User namespace内外可以是不同的。

  6. Network namespace是用来隔离网络设备,IP地址端口等网络栈的namespace。Network namespace可以让每个容器拥有自己独立的网络设备(虚拟的),而且容器内的应用可以绑定到自己的端口,每个namespace内的端口都不会互相冲突。

1.2 cgroups

cgroups是control groups的缩写,最初由Google的工程师提出,后来被整合进Linux内核。cgroups是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:CPU、内存、IO等)的机制。在默认情况下,Docker容器并不会对容器内部进程使用的内存大小进行任何限制。对于直接使用docker的用户而言,这非常危险。如果哪个业务容器出现了内存泄露,那么它可能会危害到整个主机系统,导致业务应用容器所在的主机出现OOM。

创建一个新容器,并使用-m限制容器能够使用的内存大小。

复制代码
 [root@ldh ~]# docker run -itd --name mycentos -m 200M centos:7 
 6a08a1b30273319401e7c213ffa054457cb7c3988c9119ad9871d1abf56dcccc

随着容器的创建启动,在/sys/fs/cgroup/mermor/docker目录中,Linux会创建该容器的cgroup目录,目录中包含了对容器所使用资源的限制。

复制代码
 [root@ldh ~]# ls /sys/fs/cgroup/memory/docker/6a08a1b30273319401e7c213ffa054457cb7c3988c9119ad9871d1abf56dcccc
 cgroup.clone_children           memory.kmem.tcp.max_usage_in_bytes  memory.oom_control
 cgroup.event_control            memory.kmem.tcp.usage_in_bytes      memory.pressure_level
 cgroup.procs                    memory.kmem.usage_in_bytes          memory.soft_limit_in_bytes
 memory.failcnt                  memory.limit_in_bytes               memory.stat
 memory.force_empty              memory.max_usage_in_bytes           memory.swappiness
 memory.kmem.failcnt             memory.memsw.failcnt                memory.usage_in_bytes
 memory.kmem.limit_in_bytes      memory.memsw.limit_in_bytes         memory.use_hierarchy
 memory.kmem.max_usage_in_bytes  memory.memsw.max_usage_in_bytes     notify_on_release
 memory.kmem.slabinfo            memory.memsw.usage_in_bytes         tasks
 memory.kmem.tcp.failcnt         memory.move_charge_at_immigrate
 memory.kmem.tcp.limit_in_bytes  memory.numa_stat
 ​
 [root@ldh ~]# cat /sys/fs/cgroup/memory/docker/6a08a1b30273319401e7c213ffa054457cb7c3988c9119ad9871d1abf56dcccc/memory.kmem.limit_in_bytes
 9223372036854771712

在/sys/fs/cgroup/目录中还包含其他的资源限制

复制代码
 [root@ldh ~]# ls /sys/fs/cgroup
 blkio  cpuacct      cpuset   freezer  memory   net_cls,net_prio  perf_event  systemd
 cpu    cpu,cpuacct  devices  hugetlb  net_cls  net_prio          pids

二、容器资源限制

2.1 资源管理

每个容器在运行时,都需要内存、CPU、IO等资源,用户可以根据需求为容器分配资源。对于容器而言,容器中的资源大小与docker主机资源大小是一致的,因为它们都共享同一个内核。如果运行多个容器,某个容器在运行过程中异常占用大量的资源,那么势必会对其他容器造成影响。

构建stress镜像,stress是一个容器压力测试工具,也能帮助我们学习docker的资源限制

复制代码
 [root@ldh ~]# docker pull ubuntu:trusty
复制代码
 [root@ldh ~]# vim Dockerfile
 FROM ubuntu:trusty
 RUN apt-get update && apt-get install -y stress
 ENTRYPOINT ["/usr/bin/stress","--verbose"]
复制代码
 [root@ldh ~]# docker build -t stress .
复制代码
 [root@ldh ~]# docker images
 REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
 stress        latest    591eb7e16cd1   21 seconds ago   214MB
 ......

2.2 内存限制

容器资源限制参数说明

参数 作用
-m,--memory="<数字>\<单位\>" 内存使用限制。数字需要使用整数,对应的单位是b,k,m,g中的一个。最小取值是4M。
--memory-swap="<数字>\<单位\>" 总内存使用限制(物理内存+交换分区),对应的单位是b,k,m,g中的一个。
--memory-reservation="<数字>\<单位\>" 内存软限制。数字需要使用正整数,对应的单位是b,k,m,g中的一个。
--kernel-memory="<数字>\<单位\>" 内核内存限制。数字需要使用正整数,对应的单位是b,k,m,g中的一个。最小取值是4M。
--oom-kill-disable=false 内存耗尽时是否杀掉容器。
--memory-swappiness="" 调节容器内存使用交换分区的选项,取值为0和100之间的整数(含0和100)。
--oom-score-adj 容器被OOM killer杀死的优先级,范围是-1000,1000,默认为0。

容器对内存的使用限制一般会使用-m或者--memory,这个参数仅限制对物理内存的使用

复制代码
 [root@ldh ~]# docker run -it --name a1 --rm -m 50M stress:latest --vm 1 --vm-bytes 30M

在容器中也可以使用swap,这就需要用到--memory-swap参数,--memory-swap是指容器所用的物理内存加swap的总和,需要配合-m使用。

复制代码
 [root@ldh ~]# docker run -it --name a1 --rm -m 50M --memory-swap=100M stress --vm 1 --vm-bytes 70M

Memory reservation是一种软性限制,用于节制容器内存使用

复制代码
 [root@ldh ~]# docker run -it -m 100M --memory-reservation 50M centos:7

我们可以通过设置--oom-kill-disable选项来禁止OOM killer杀死容器内进程

复制代码
 [root@ldh ~]# docker run -it -m 100M --oom-kill-disable centos:7

2.3 CPU限制

常用的容器CPU限制参数如表:

参数 作用
-c,--cpu-shares=0 CPU份额(相对权重)
--cpu-period=0 完全公平算法中的period值
--cpu-quota=0 完全公平算法中的quota值
--cpiset-cpus="<数字>" 限制容器使用的CPU核(0-3,0,1)
--cpuset-mems="" 限制容器使用的内存节点,该限制仅仅在NUMA系统中生效。

创建两个容器a1和a2,a1的cpu权重为512,a2的cpu权重为1024,同时将docker主机上的cpu全部占满。

复制代码
 [root@ldh ~]# docker run -it --name a1 --rm -c 512 stress --cpu 4
复制代码
 [root@ldh ~]# docker run -it --name a2 --rm -c 1024 stress --cpu 4
复制代码
 [root@ldh ~]# top
 top - 15:29:53 up  6:00,  4 users,  load average: 6.01, 1.99, 
 Tasks: 141 total,   9 running, 132 sleeping,   0 stopped,   0 
 %Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,
 KiB Mem :  4026372 total,  2868276 free,   274404 used,   8836
 KiB Swap:  4194300 total,  4193532 free,      768 used.  34171
 ​
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM 
  13281 root      20   0    7312     96      0 R  71.1  0.0 
  13283 root      20   0    7312     96      0 R  66.4  0.0 
  13284 root      20   0    7312     96      0 R  66.4  0.0 
  13282 root      20   0    7312     96      0 R  65.8  0.0 
  13203 root      20   0    7312     96      0 R  33.6  0.0 
  13202 root      20   0    7312     96      0 R  32.6  0.0 
  13204 root      20   0    7312     96      0 R  32.2  0.0 
  13205 root      20   0    7312     96      0 R  31.9  0.0
 ​

2.4 Block IO限制

Block IO限制常用参数如表:

参数 作用
--blkio-weight=0 块设备IO相对权重,取值在10与1000之间的整数(包含10和1000)。
--blkio-weight-device="设备名称:权重值" 指定的块设备的IO相对权重。
--device-read-bps="<设备路径>:<数字>:\<单位\>" 限制对某个设备的读取速率,数字需要使用正整数,单位是kb,mb,或者gb中的一个。
--device-write-bps="<设备路径>:<数字>:\<单位\>" 限制对某个设备的写速率,数字需要使用正整数,单位是kb,mb,或者gb中的一个。
--device-read-iops="<设备路径>:<数字>" 限制对某个设备每秒IO的读取速率,数字需要使用正整数。
--device-write-iops="<设备路径>:<数字>" 限制对某个设备每秒IO的写速率,数字需要使用正整数。
相关推荐
一个天蝎座 白勺 程序猿12 小时前
KingbaseES数据库归档重做日志文件管理:从配置到运维的实战指南
运维·数据库·oracle·kingbasees·金仓数据库
分布式存储与RustFS16 小时前
镜像仓库的层别堆本地盘:用 RustFS 给 Docker Registry 当 S3 后端
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
陈希12316 小时前
Linux 防火墙配置实战:firewalld、iptables 与云安全组
linux·运维·服务器
@兽血沸腾17 小时前
Windows系统安装Jenkins部署应用至远程Windows服务器操作指南
运维·服务器·jenkins
闲云自留地1 天前
K8s 的记忆大脑!ETCD 集群部署、etcdctl 命令与备份恢复全通关
容器·kubernetes·etcd
讯捷蓝达1 天前
戴尔R720xd服务器卡死在 “Configuring Memory...Done“,换了内存还是卡?问题根本不在内存
运维·服务器
爱和冰阔落1 天前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
lisanmengmeng1 天前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮1 天前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
上火的金鱼妹1 天前
k8s生产实际问题排查(网关,数据库读写等)
运维·服务器