使用Python脚本自动化管理Docker容器与系统监控
在日常开发与运维中,手动管理Docker容器的生命周期效率较低。本文提供一套基于Python的自动化脚本方案,结合subprocess与psutil库,实现按名启动容器、通过chpasswd修改内部root密码、先stop后rm的安全清理,以及实时采集主机CPU、内存和磁盘使用率。脚本适用于Linux环境,可直接集成至运维平台或定时任务。
自动化管理目标与环境配置
本指南旨在通过Python调用系统指令与硬件监控接口,替代繁琐的命令行操作,统一返回结构化结果以便后续对接。所需运行条件如下:
- 操作系统:Linux(如CentOS、Ubuntu等)
- Docker服务:已安装且处于运行状态
- Python版本:3.6及以上
- 第三方依赖:
psutil(用于系统资源监控)
在安装依赖前请确认当前执行环境具备调用docker命令的权限。若未安装相关包,请先执行:
pip install psutil
第1步:启动指定名称的容器
目的:根据容器名称批量唤醒处于关闭状态的容器,替代交互式敲击命令。
操作入口:终端或Python脚本环境
执行动作:
from subprocess import Popen, PIPE
name = "centos7-novnc3d"
p = Popen(['docker', 'start', name], stderr=PIPE)
_, stderr = p.communicate()
code = stderr.decode("utf-8").strip()
if code == "" or code.startswith(name):
response = {"code": 200, "msg": "success"}
else:
response = {"code": 500, "msg": code}
print(response)
完成判断:控制台输出包含"code": 200即为启动成功。通常docker start成功时标准错误流为空;若返回容器名或报错文本,则说明未找到该容器或容器已在运行状态。
第2步:动态修改容器内 root 密码
目的:在容器初始化或临时调试阶段,快速更新内部用户的登录凭证。
操作入口:终端或Python脚本环境
执行动作:
from subprocess import Popen, PIPE
root_passwd = "NewStrongPass@2024"
name = "centos7-novnc28"
# 构造修改密码的 shell 命令
pass_cmd = f"echo 'root:{root_passwd}' | chpasswd && echo 'success'"
p2 = Popen(['docker', 'exec', '-i', name, '/bin/bash', '-c', pass_cmd],
stdout=PIPE, stderr=PIPE)
stdout, stderr2 = p2.communicate()
# 注意:chpasswd 成功时不会输出到 stderr,需检查 stdout
output = stdout.decode("utf-8").strip()
error = stderr2.decode("utf-8").strip()
if "success" in output or (output == "" and error == ""):
response = {"code": 200, "msg": "root修改密码成功"}
else:
response = {"code": 500, "msg": error or output}
print(response)
完成判断:当stdout中包含success标识,或两者输出均为空时,代表chpasswd指令执行完毕。需注意部分精简型镜像可能未预装相关工具,建议在实际业务镜像中验证基础命令完整性。
第3步:安全停止并删除容器
风险提醒:docker rm为不可逆操作,执行前请务必确认该容器数据已备份或属于废弃状态。生产中建议增加日志记录与二次确认机制。
目的:遵循“先停止再移除”的标准流程,避免强制删除导致的数据丢失或资源悬空。
执行动作:
from subprocess import Popen, PIPE
name = "reverent_matsumoto"
try:
# 停止容器
p_stop = Popen(['docker', 'stop', name], stdout=PIPE, stderr=PIPE)
stdout, stderr = p_stop.communicate()
stop_output = stdout.decode("utf-8").strip()
if stop_output == name: # docker stop 成功会返回容器名
# 删除容器
p_rm = Popen(['docker', 'rm', name], stdout=PIPE, stderr=PIPE)
rm_out, rm_err = p_rm.communicate()
response = {"code": 200, "msg": "删除成功"}
else:
response = {"code": 500, "msg": stderr.decode("utf-8")}
except FileNotFoundError:
response = {"code": 500, "msg": "docker未安装或环境变量缺失"}
print(response)
完成判断:返回{"code": 200, "msg": "删除成功"}即表示容器已彻底清理。必须严格遵循此顺序,跳过stop直接rm除非追加-f参数,否则可能触发权限拒绝或后台残留进程。
第4步:采集主机系统与进程资源状态
目的:实时监控服务器负载,便于评估容器化部署的资源余量或排查性能瓶颈。
执行动作:
import psutil
import os
def bytes2human(n):
"""将字节转换为易读格式"""
symbols = ('KB', 'MB', 'GB', 'TB')
for i, s in enumerate(symbols):
unit = 1 << (i + 1) * 10 # 1KB=1024, 1MB=1024^2...
if n < unit:
return f"{n / (unit // 1024):.2f} {s}"
return f"{n:.2f} B"
# 内存信息
mem_info = psutil.virtual_memory()
disk_usage = psutil.disk_usage('/')
response = {
"code": 200,
"msg": "success",
"data": {
"memory": {
"current_process_memory": bytes2human(psutil.Process(os.getpid()).memory_info().rss),
"total": bytes2human(mem_info.total),
"used": bytes2human(mem_info.used),
"available": bytes2human(mem_info.available),
"free": bytes2human(mem_info.free),
"active": bytes2human(mem_info.active),
"inactive": bytes2human(mem_info.inactive),
"percent": f"{mem_info.percent}%",
"cpu_cores": psutil.cpu_count()
},
"disk_usage": {
"total": bytes2human(disk_usage.total),
"used": bytes2human(disk_usage.used),
"free": bytes2human(disk_usage.free),
"percent": f"{disk_usage.percent}%"
}
}
}
print(response)
完成判断:脚本打印完整JSON字典,其中percent字段直观反映利用率。可通过调整disk_usage('/')的路径参数适配不同挂载点,例如/data或/var。
排错与注意事项
- 命令返回异常:若
Popen抛出FileNotFoundError,请检查系统是否正确安装了Docker CLI及Python解释器路径。 - 容器内命令缺失:修改密码依赖于容器基础镜像是否内置
chpasswd。Alpine或部分定制镜像可能需要替换为passwd命令或通过挂载卷覆盖/etc/shadow文件。 - 权限校验:所有
docker子命令的执行均受宿主机Docker Socket权限控制,建议以具备运维权限的用户运行脚本,或配置sudo免密策略。
简要总结
通过整合subprocess调用Docker指令与psutil监控底层硬件,上述流程构建了一套轻量级的容器生命周期管理方案。它有效规避了人工操作的遗漏风险,并为后续的自动化编排提供了标准化接口。在实际落地前,建议补充完善的日志模块、失败重试逻辑以及严格的账号鉴权机制。以上就是使用Python脚本自动化管理Docker容器的详细内容,更多关于Docker容器运维与Python自动化脚本的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









