Docker容器生产实践1——永远设置容器内存限制

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 背景在默认情况下,docker容器并不会对容器内部进程使用的内存大小进行任何限制。对于PaaS系统而言,或者对于直接使用docker的用户而言,这非常危险。

背景

在默认情况下,docker容器并不会对容器内部进程使用的内存大小进行任何限制。对于PaaS系统而言,或者对于直接使用docker的用户而言,这非常危险。如果哪个业务容器,出现了内存泄漏;那么它可能会危害到整个主机系统,导致业务app容器所在的主机出现oom。本文将介绍着眼于docker对内存资源的使用,解释背后的原理。同时也给出k8s上如何配置内存限制的方法。

docker run、create时刻对容器使用内存大小进行限制

-m硬限制容器使用的内存

通过下面参数可以为容器设置一个内存使用量硬大小,当超出这个大小时刻,linux系统会根据配置设置决定是否进入oom-killer状态。
docker run --name zxy-docker -m 1g -it busybox bash
单位为:b,k,m和g
如果设置了-m参数,通常情况下如果容器使用内存量超过了设置的硬水线,那么linux的oom-killer触发,它将根据oom-score对容器内部进程进行oom kill。但是不影响宿主机上其他进程。

--oom-kill-disable

这个参数设置一定需要在容器run或者create过程中使用了-m参数才可以设置。设置了-m参数,如果容器使用内存超限了,那么oom-kill将触发。如果设置了--oom-kill-disable,那么容器不会oom,但是此时容器内部申请内存的进程将hang,直到他们可以申请到内存(容器内其他进程释放了内存)
绝对不要在没有使用-m的时候设置--oom-kill-disable 因为这会影响到宿主机的oom-killer

背后的原理

docker 设置容器的-m是通过设置memory cgoup的memory.limit_in_bytes实现的。在没有设置-m的时候这个值为-1,表示容器使用的内存不受限制。
例如:
`bash>docker run --name zxy-memorylimit -it -m 1g docker-build:12.06 bash
bash>docker inspect zxy-memorylimit|grep -i pid
“Pid”:24360

bash>cat /proc/24360/cgroup|grep memory
9:memory:/docker/xxxxx
bash>cd /sys/fs/cgroups/memory/docker/xxxx
bash> cat memory.limit_in_bytes
1073741824`

--oom-kill-disable参数实际设置的就是这是了同级目录之下的memory.oom_control,设置此参数就相当于做了如下动作
bash> echo 1 >memory.oom_control
对linux memory cgroup感兴趣的朋友可以参考:
https://segmentfault.com/a/1190000008125359 一文

--memory-reservation 软限制容器使用的内存

在上一节中,我们介绍了-m硬限制容器使用的内存资源。一旦设置了这个-m参数,那么容器内进程使用量超过这个数值,就会被杀或者hang住。docker还提供了一种soft limit就是--memory-reservation,单位和-m一致。当设置了这个参数以后,如果宿主机系统内存不足,有新的内存请求时刻,那么linux会尝试从设置了此参数的容器里回收内存,回收的办法就是swap了。那么如果此容器还在继续使用内存,那么此容器会遇到很大的性能下降
通常实践是设置--memory-reservevation 的值小于-m的值。

背后的原理

和-m参数一致,此参数docker也是借助于memory cgroup的memory.soft_limit_in_bytes 实现。

其他内存资源参数

  • --memory-swap
    配置容器可以设置的swap大小。此值为-m值加上能达到的swap区大小,例如--memory-swap = 500M
    -m =300M,意味着真正的swap大小可以的到200M。默认情况下容器可以得到最大swap大小为-m参数设置的两倍,此参数设置为0,为无效参数。如果--m和--memory-swap相等,相当于关闭容器的swap。值-1表示swap大小为不限
  • --memory-swappiness
    配置容器的swappiness属性,从0到100。0表示无论何种情况下都不要启动swap,100表示只要有可能就启动swap。
    此参数和系统的
    /proc/sys/vm/swappiness
    含义一致,不过它设置的容器所在memory cgroup的swappiness。
    默认情况下容器的此值继承自主机侧的swappiness配置。对于centos系统和ubuntu系统,内存充裕可以设置为10.
    swappiness设置的是匿名页(anonymous page,也就是malloc和mmap以map_anonymous方式申请的内存)是否愿意交换出去

docker做了什么

docker做的工作实际上是由runc完成的,docker 创建的hostconfig.json文件(也就是oci接口文件)中,有如下字段描述-m,--memory-reservation等内存资源限制参数:
memory MemoryReservation MemorySwap MemorySwappiness

docker生产实践

  • 永远需要设置-m
  • 不要轻易设置--oom-kill-disable,memory-swappiness,memory-swap和memory-reservation,因为一半情况下,你不太容易理解它们真正如何作用于系统。

k8s如何使用docker限制内存的参数

下文节选自https://mp.weixin.qq.com/s/j2FfqUHSRTzczNcfPuwRQw

K8s资源限制是通过每个容器containerSpec的resources字段进行设置的,它是v1版本的ResourceRequirements类型的API对象。每个指定了"limits"和"requests"的对象都可以控制对应的资源。目前只有CPU和内存两种资源。大多数情况下,deployment、statefulset、daemonset的定义里都包含了podSpec和多个containerSpec。这里有个完整的v1资源对象的yaml格式配置:
`resources:
requests:
cpu: 50m
memory: 50Mi
limits:
cpu: 100m
memory: 100Mi

`

其中limits节限制memory设置的就是docker 容器的-m,而且k8s仅仅使用了-m参数其他参数都没有使用。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6天前
|
人工智能 运维 并行计算
函数计算产品使用问题之如何设置来人为限制内存的使用
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
函数计算产品使用问题之如何设置来人为限制内存的使用
|
14天前
|
前端开发 安全 数据库
Web架构&前后端分离站&Docker容器站&集成软件站&建站分配
Web架构&前后端分离站&Docker容器站&集成软件站&建站分配
|
6天前
|
缓存 Java
《JVM由浅入深学习九】 2024-01-15》JVM由简入深学习提升分(生产项目内存飙升分析)
《JVM由浅入深学习九】 2024-01-15》JVM由简入深学习提升分(生产项目内存飙升分析)
11 0
|
1天前
|
Java API Docker
使用Spring Boot和Docker进行容器化部署
使用Spring Boot和Docker进行容器化部署
|
2天前
|
安全 关系型数据库 开发者
Docker Compose凭借其简单易用的特性,已经成为开发者在构建和管理多容器应用时不可或缺的工具。
Docker Compose是容器编排利器,简化多容器应用管理。通过YAML文件定义服务、网络和卷,一键启动应用环境。核心概念包括服务(组件集合)、网络(灵活通信)、卷(数据持久化)。实战中,编写docker-compose.yml,如设置Nginx和Postgres服务,用`docker-compose up -d`启动。高级特性涉及依赖、环境变量、健康检查和数据持久化。最佳实践涵盖环境隔离、CI/CD、资源管理和安全措施。案例分析展示如何构建微服务应用栈,实现一键部署。Docker Compose助力开发者高效驾驭复杂容器场景。
9 1
|
2天前
|
存储 监控 安全
Docker Compose:轻松实现容器编排的利器
【7月更文挑战第2天】 1. **基础与概念**:服务(多容器实例)、网络(灵活通信)、卷(数据持久化)和配置(安全管理)。 2. **实战指南**:安装Compose,编写`docker-compose.yml`文件,启动应用,并介绍依赖、环境变量、健康检查和数据持久化。 3. **最佳实践**:环境隔离、CI/CD集成、资源管理、日志监控、安全策略及案例分析,展示完整应用栈搭建。
12 1
|
5天前
|
弹性计算 Serverless 调度
《阿里云产品四月刊》—享道出行:容器弹性技术驱动下的智慧出行稳定性实践(3)
阿里云瑶池数据库云原生化和一体化产品能力升级,多款产品更新迭代
|
7天前
|
jenkins 持续交付 开发者
利用Docker容器化部署应用的实战指南
【6月更文挑战第27天】本文详述Docker应用部署,涵盖Docker基本概念、安装、镜像制作及运行。通过编写Dockerfile构建镜像,使用`docker build`、`run`、`push`及`stop`命令管理。集成CI/CD工具如Jenkins,实现自动化构建、测试和部署,提升开发效率与部署质量。Docker助力轻量级、可移植的微服务架构。
|
11天前
|
NoSQL Redis Docker
使用 Docker Compose 接管现有容器的文档
使用 Docker Compose 接管现有容器的文档
25 2
|
14天前
|
Cloud Native 安全 Docker
云上攻防-云原生篇&Docker安全&系统内核&版本&CDK自动利用&容器逃逸
云上攻防-云原生篇&Docker安全&系统内核&版本&CDK自动利用&容器逃逸