Docker 与 K8S学习笔记(六)—— 容器的资源限制

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 我们在启动Docker容器时,默认情况下容器所使用的资源是没有限制的,这样就会存在部分特别耗资源的容器会占用大量系统资源,从而导致其他容器甚至整个服务器性能降低,为此,Docker提供了一系列参数方便我们对容器的CPU、内存、IO等进行限制。为了方便演示,我们这里使用progrium/stress镜

Docker 与 K8S学习笔记(六)—— 容器的资源限制


我们在启动Docker容器时,默认情况下容器所使用的资源是没有限制的,这样就会存在部分特别耗资源的容器会占用大量系统资源,从而导致其他容器甚至整个服务器性能降低,为此,Docker提供了一系列参数方便我们对容器的CPU、内存、IO等进行限制。为了方便演示,我们这里使用progrium/stress镜像,这个镜像内置一个压力测试工具,通过它我们可以很方便进行实验。首先我们拉取此镜像:


$ sudo docker pull progrium/stress
Using default tag: latest
latest: Pulling from progrium/stress
Image docker.io/progrium/stress:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
a3ed95caeb02: Pull complete
871c32dbbb53: Pull complete
dbe7819a64dd: Pull complete
d14088925c6e: Pull complete
58026d51efe4: Pull complete
7d04a4fe1405: Pull complete
1775fca35fb6: Pull complete
5c319e267908: Pull complete
Digest: sha256:e34d56d60f5caae79333cee395aae93b74791d50e3841986420d23c2ee4697bf
Status: Downloaded newer image for progrium/stress:latest
docker.io/progrium/stress:latest


一、容器内存限制


与操作系统类似,容器可使用的内存包括两部分:物理内存,Swap交换空间,因此Docker通过以下两个参数对内存资源进行限制:


  • -m或--memroy:设置内存使用限额

  • --memory-swap:设置内存和交换空间总大小,如果只设置-m而不设置此参数,则默认内存和交换空间总大小是-m的两倍


例如我们按如下配置启动容器:我们设置内存为200M,内存与Swap总共300M,那么Swap就是100M。


sudo docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M


这里我们对stress进行设置:


--vm 1:启动一个工作线程


--vm-bytes:每个工作线程分配280M内存


$ sudo docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 293601280 bytes
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 293601280 bytes
stress: dbug: [7] allocating 293601280 bytes ...


我们可以看到stress容器启动后不断在申请内存,释放内存,由于我们设置--vm-bytes 280M,所以它每次会申请280M内存空间,大家可能会注意到,容器启动后有一段告警信息:


WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.


这是因为我这边宿主机使用Ubuntu,在Ubuntu上默认是没有开启Swap限制的,这样就会导致容器的swap限制不生效,为了解决这个问题,我们需要先修改/etc/default/grub file 文件:


$ sudo vim /etc/default/grub file


添加如下内容:


GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"


使用 sudo update-grub 更新系统的GRUB,并重启系统。


$ sudo update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/50-curtin-settings.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.15.0-159-generic
Found initrd image: /boot/initrd.img-4.15.0-159-generic
Found linux image: /boot/vmlinuz-4.15.0-158-generic
Found initrd image: /boot/initrd.img-4.15.0-158-generic
Found linux image: /boot/vmlinuz-4.15.0-156-generic
Found initrd image: /boot/initrd.img-4.15.0-156-generic
Found linux image: /boot/vmlinuz-4.15.0-154-generic
Found initrd image: /boot/initrd.img-4.15.0-154-generic
done


OK,解决了这个问题后我们继续内存限额的实现,我们这次将vm-bytes设置为310M,看看会有什么样的效果:


$ sudo docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 325058560 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 7 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 0s


我们可以看到,当线程每次申请的内存大于300M的时候会stress线程报错,容器退出。


二、容器的CPU限制


默认情况下,所有容器都可以平等使用宿主机的CPU而没有限制,Docker提供-c或--cpu-share参数用于设置容器的CPU权重,如果不指定则默认为1024。与内存限制不同,-c设置的并不是容器使用CPU的核的数量,而是相对的权重值,某个容器最终能分配到的CPU资源取决于它的cpu share占所有容器cpu share总和的比例,也就是说-c可以决定容器CPU优先级。


我们首先启动containerA,cpu share为1024:


$ sudo docker run --name containerA -it -c 1024 progrium/stress --cpu 2
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [8] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [9] forked


接着启动containerB,cpu share为512:


$ sudo docker run --name containerB -it -c 512 progrium/stress --cpu 2
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [8] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [9] forked


PS:注意我们要确保stress容器能够将host的cpu拉满这样才能确保实验效果,所以大家在实验时要注意看自己的宿主机CPU有多少个,例如我的机器cpu为2,所以在启动stress容器时--cpu也设置为2。


我们在宿主机上通过top命令能够明显看出效果:containerA消耗的CPU是containerB的两倍:


 

分类: 容器技术

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3天前
|
存储 Kubernetes 对象存储
部署DeepSeek但GPU不足,ACK One注册集群助力解决IDC GPU资源不足
借助阿里云ACK One注册集群,充分利用阿里云强大ACS GPU算力,实现DeepSeek推理模型高效部署。
|
1月前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
224 93
|
4天前
|
网络协议 API Docker
Docker+consul容器服务的更新与发现
通过本文的介绍,我们详细探讨了如何结合Docker和Consul来实现容器服务的更新与发现。通过Consul的服务注册和发现功能,可以高效地管理和监控容器化服务,确保系统的高可用性和可扩展性。希望本文能帮助您在实际项目中更好地应用Docker和Consul,提高系统的可靠性和管理效率。
37 23
|
4天前
|
Ubuntu API 网络虚拟化
ubuntu22 编译安装docker,和docker容器方式安装 deepseek
本脚本适用于Ubuntu 22.04,主要功能包括编译安装Docker和安装DeepSeek模型。首先通过Apt源配置安装Docker,确保网络稳定(建议使用VPN)。接着下载并配置Docker二进制文件,创建Docker用户组并设置守护进程。随后拉取Debian 12镜像,安装系统必备工具,配置Ollama模型管理器,并最终部署和运行DeepSeek模型,提供API接口进行交互测试。
90 15
|
1月前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
157 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
1月前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
62 17
|
1月前
|
弹性计算 运维 Kubernetes
使用ACK Edge统一管理多地域的ECS资源
本文介绍如何使用ACK Edge来管理分布在多个地域的ECS资源。
|
1月前
|
运维 Java 虚拟化
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
117 12
|
1月前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
182 11
|
关系型数据库 UED 开发者
DockOne微信分享(八十七):基于Docker的开发云提高资源利用率的实践
本文讲的是DockOne微信分享(八十七):基于Docker的开发云提高资源利用率的实践【编者的话】Docker的出现,为更简便、更细粒度地对云资源的调控提供了一个强有力的支撑,WeX5开发者云基于Rancher+Docker,在如何提高物理资源利用率的课题上做了一些探索和研究,在保障用户体验良好的前提下,大大提高了物理资源的利用率,有效地降低了运营成本。
2162 0

相关产品

  • 容器服务Kubernetes版