Docker内存芭蕾:优雅调整容器内存的极限艺术

devtools/2025/2/25 23:11:58/

title: “💾 Docker内存芭蕾:优雅调整容器内存的极限艺术”
author: “Cjs”
date: “2025-2-23”
emoji: “🩰💥📊”

当你的容器变成内存吸血鬼时…


🚀 完美内存编排示范

📜 智能内存管家脚本

#!/bin/bash
# memory_balancer_v3.sh# 定义容器列表和对应的内存分配比例(总可用内存的百分比)
containers=("container-1" "container-2" "container-3" "container-4" "container-5")
percentages=(10 20 30 20 20)# 获取系统总内存
TOTAL_MEM=$(free -b | awk '/Mem:/{print $2}')# 设置安全缓冲为总内存的20%
SAFETY_BUFFER=$((TOTAL_MEM * 20 / 100))# 计算可用内存(总内存 - 安全缓冲)
AVAILABLE_MEM=$((TOTAL_MEM - SAFETY_BUFFER))# 日志文件路径
LOG_FILE="memory_balancer.log"# 格式转换函数:字节转GB
bytes_to_gb() {echo "scale=2; $1 / 1024 / 1024 / 1024" | bc
}# 格式转换函数:字节转MB
bytes_to_mb() {echo "scale=0; $1 / 1024 / 1024" | bc
}for i in "${!containers[@]}"; docontainer=${containers[$i]}percentage=${percentages[$i]}# 计算内存限制mem_limit=$(( AVAILABLE_MEM * percentage / 100 ))swap_limit=$(( mem_limit * 150 / 100 ))# 获取旧内存设置old_mem=$(docker inspect $container --format '{{.HostConfig.Memory}}' 2>/dev/null || echo "0")old_swap=$(docker inspect $container --format '{{.HostConfig.MemorySwap}}' 2>/dev/null || echo "0")# 转换单位用于显示total_mem_gb=$(bytes_to_gb $TOTAL_MEM)old_mem_mb=$(bytes_to_mb $old_mem)new_mem_mb=$(bytes_to_mb $mem_limit)new_swap_mb=$(bytes_to_mb $swap_limit)# 执行内存更新if docker update --memory="$mem_limit" --memory-swap="$swap_limit" $container >/dev/null 2>&1; thenstatus="Success"# 记录到日志文件echo "$(date +'%Y-%m-%d %H:%M:%S') | Status: $status | Container: $container | TotalMem: ${total_mem_gb}GB | OldMem: ${old_mem_mb}MB | NewMem: ${new_mem_mb}MB | NewSwap: ${new_swap_mb}MB" | tee -a $LOG_FILEelsestatus="Failed"# 错误信息也记录到日志echo "$(date +'%Y-%m-%d %H:%M:%S') | Status: $status | Container: $container | Error: Memory update failed" | tee -a $LOG_FILEfi
done

🛠️ 部署自动化

  1. 创建脚本
sudo vim /usr/local/bin/memory_balancer.sh  
# 粘贴上述脚本内容后保存 记得修改你的容器名字 以及如何分配内容哦
  1. 赋予执行权限
sudo chmod +x /usr/local/bin/memory_balancer.sh
  1. 配置定时任务
sudo crontab -e  # 使用root权限编辑cron

添加以下内容:

# 每分钟检测一次,Docker运行时生效
* * * * * if [ $(systemctl is-active docker) = "active" ]; then /usr/local/bin/memory_balancer.sh >> /var/log/memory_balancer.log 2>&1; fi
  1. 查看执行日志
tail -f /var/log/memory_balancer.log  # 实时监控调整记录


🔍 脚本功能详解

代码片段功能说明可视化比喻
free -b精确获取物理内存字节数🕵️♂️ 内存侦探
SAFETY_BUFFER计算保留20%内存应对突发流量🚧 安全气囊
docker update命令动态调整运行中容器的内存限制🎚️ 内存调音师
cron定时任务每分钟自动优化内存分配⏰ 内存生物钟

💡 高阶技巧:智能扩展

# 添加邮件报警功能(需安装mailutils)
MEM_USAGE=$(docker stats --no-stream --format "{{.MemUsage}}" app | cut -d'/' -f1)
if [[ $MEM_USAGE > 85% ]]; thenecho "警告!app容器内存使用率超过85%" | mail -s "内存警报" admin@example.com
fi# 根据时间动态调整(上班时间分配更多资源)
if [[ $(date +%H) -ge 9 && $(date +%H) -lt 18 ]]; then# 日间模式:增加20%内存
else# 夜间模式:减少30%内存
fi


🚨 注意事项

  1. 容器名称适配
    替换脚本中的appdb为你的实际容器

  2. 安全缓冲区调整
    敏感应用可增加安全比例(修改20为更高数值)

  3. 路径问题
    确保cron环境中能识别docker命令(建议使用绝对路径/usr/bin/docker

  4. 权限管理
    如果使用非root用户,需将用户加入docker组:

sudo usermod -aG docker $USER

(保持原文后续内容不变,仅替换最后预告部分)

🐾 下期预告
《等我bug》🕵️♂️
(关注不迷路,我们一起成为容器内存侦探!🔍)


http://www.ppmy.cn/devtools/162671.html

相关文章

传统的自动化行业的触摸屏和上位机,PLC是否会被取代?

传统的自动化行业的触摸屏和上位机是否会被取代? 在工业自动化领域,触摸屏和上位机长期扮演着核心角色,尤其在污水处理、化工生产等场景中,它们通过实时数据采集、逻辑控制、报警联动等功能,保障了生产设备的稳定运行…

【R安装包报错】在conda环境下用R语言命令安装R包报错

报错如下: gnu/include/c/11.2.0/ctime:80:11: error: ‘timespec_get’ has not been declared in ‘::’ 80 | using ::timespec_get; | ^~~~~~~~~~~~ 修改 报错原因:如果使用的是conda安装的g,可能与系统库不兼容。尝试 切换到系统默认编…

DeepSeek 全面分析报告

引言 DeepSeek 是一款由中国人工智能初创公司 DeepSeek 开发的大型语言模型 (LLM),于 2025 年 1 月发布,迅速成为全球人工智能领域的一匹黑马。DeepSeek 不仅在性能上可与 OpenAI、Google 等巨头的模型相媲美,而且其训练成本和运行效率都显著…

15-贪心算法

一,定义 贪心算法的核心思想 贪心算法的特点是: 局部最优:在每一步选择中,都选择当前看起来最好的选项。 不可回退:一旦做出选择,就不再回头重新考虑。 希望全局最优:通过一系列局部最优的选…

Eureka、ZooKeeper 和 Nacos 之间的对比

Eureka、ZooKeeper 和 Nacos 都是分布式系统中常用的服务注册与发现工具,但它们的定位、功能和适用场景有所不同。作为一名开发者,理解它们之间的对比有助于选择合适的技术栈。以下从多个维度进行详细比较: 1. 基本概述 Eureka 来源&#xff…

开源一款I2C电机驱动扩展板-FreakStudio多米诺系列

总线直流电机扩展板 原文链接: FreakStudio的博客 摘要 设计了一个I2C电机驱动板,通过I2C接口控制多个电机的转速和方向,支持刹车和减速功能。可连接16个扩展板,具有PWM输出、过流过热保护和可更换电机驱动芯片。支持按键控制…

Redis存在线程安全吗?为什么?

Redis 在设计和使用层面具备较高的线程安全性,下面从多个方面详细阐述其线程安全特性及原因。 Redis 单线程模型下的线程安全 Redis 在处理网络请求时采用单线程模型(Redis 6.0 之前核心网络 I/O 和命令执行都是单线程,Redis 6.0 引入了多线…

escape SQL中用法

select * from tablename where username like %#%% escape # 这个的意思就是,escape指定字符#,#字符后面的第一个字符被认为是普通字符 查询示例2 查询username字段中包含[的数据也是一样,即: select * from tablename where us…