Python 运维实战:psutil 监控系统资源 + paramiko 远程管理服务器

张开发
2026/4/20 22:33:21 15 分钟阅读
Python 运维实战:psutil 监控系统资源 + paramiko 远程管理服务器
一、psutil模块psutil模块作用协助我们完成 CPU使用率 、 内存 、磁盘信息、网络等等相关数据的采集1、模块介绍psutil是一个跨平台的 Python 库用于检索系统的运行信息包括 CPU 使用情况、内存状态、磁盘信息、网络统计、进程信息等非常适合运维和系统监控应用。下面是psutil的一些常见用法和应用示例。2、安装psutil前置操作第一步启动VMware中的node1服务器192.168.88.101第二步在PyCharm中创建一个新项目所有配置保持默认不需要调整第三步在项目中找到File菜单-Settings设置-Project关键词菜单-Python Interpreter解析器选择On SSH配置远程解析器填入Linux服务器信息确认指纹单击OK然后输入Linux服务器的密码如下图所示设置系统解析器在Linux服务器的/root目录创建一个day04Project文件夹mkdir-p/root/day04Project然后更改解析器信息注意必须选择系统解析器如果选择虚拟的话里面可以使用的包只有几种需要去下载其他包后才能使用而选择系统默认的解释器里面则大多数包都是有的更改源码上传位注意更改源码上传位置:进入到Linux服务器可以通过以下命令安装psutildnf install python3-pip-y pip install psutil-i https://pypi.tuna.tsinghua.edu.cn/simple 注 pip install 软件包名称安装软件-i 指定镜像源说白了就是从哪里下载软件 https://pypi.tuna.tsinghua.edu.cn/simple清华镜像源3、官方文档官方地址https://github.com/giampaolo/psutil4、获取CPU使用情况获取CPU使用率importpsutil# 获取 CPU 总使用率1 秒间隔cpu_usagepsutil.cpu_percent(interval1)print(CPU usage:,cpu_usage,%)常见运行报错解决方案获取每个核心的 CPU 使用率[第一个核心使用率第二个核心使用率第三个核心使用率第四个核心使用]importpsutil# 获取每个核心的CPU使用率foriinrange(psutil.cpu_count()):print(CPU usage of core,i,:,psutil.cpu_percent(interval1,percpuTrue)[i],%)5、获取内存使用情况字节Bytes /1024 KB千字节 /1024 MB兆字节 /1024 GBimportpsutil# 获取物理内存信息memory_infopsutil.virtual_memory()print(Total memory:,memory_info.total//(1024**2),MB)print(Used memory:,memory_info.used//(1024**2),MB)print(Memory usage:,memory_info.percent,%)获取交换内存信息import psutil# 获取交换内存信息swap_info psutil.swap_memory()print(Total swap:,swap_info.total//(1024**2),MB)print(Used swap:,swap_info.used//(1024**2),MB)print(Swap usage:,swap_info.percent,%)6、获取磁盘使用情况import psutil# 获取磁盘分区partitions psutil.disk_partitions()# disk_partitions() 获取磁盘的所有分区forpartition in partitions: print(fDevice: {partition.device}, Mountpoint: {partition.mountpoint}, Filesystem: {partition.fstype})# 获取指定分区的使用情况disk_usage psutil.disk_usage(/)print(Total disk space:,disk_usage.total//(1024**3),GB)print(Used disk space:,disk_usage.used//(1024**3),GB)print(Disk usage:,disk_usage.percent,%)获取磁盘IOIInputOOutput磁盘IO指的是系统对磁盘设备进行数据读写的过程主要包括读取操作从磁盘中读取数据到内存。写入操作将数据从内存写入到磁盘。磁盘IO性能通常受磁盘硬件、文件系统类型、RAID配置和磁盘缓存的影响。常见指标IOPSInput/Output Operations Per Second每秒处理的IO操作数量。吞吐量磁盘每秒处理的数据量如MB/s或GB/s。比如一块SSD的读写速度标称为 3.5 GB/s表示它每秒可以读取或写入3.5GB的数据。计算磁盘的IOPSimportpsutilimporttime# 第一次采样disk_io_1psutil.disk_io_counters()time.sleep(1)# 等待1秒# 第二次采样disk_io_2psutil.disk_io_counters()# 计算吞吐量 (MB/s)read_bytes_diffdisk_io_2.read_bytes-disk_io_1.read_bytes write_bytes_diffdisk_io_2.write_bytes-disk_io_1.write_bytes read_mb_sread_bytes_diff/(1024*1024)# 转换为MB/swrite_mb_swrite_bytes_diff/(1024*1024)# 转换为MB/s# 计算IOPSread_iopsdisk_io_2.read_count-disk_io_1.read_count write_iopsdisk_io_2.write_count-disk_io_1.write_countprint(f读取吞吐量:{read_mb_s:.2f}MB/s)print(f写入吞吐量:{write_mb_s:.2f}MB/s)print(f读取IOPS:{read_iops})print(f写入IOPS:{write_iops})---------------------------------------------------------------------------psutil.disk_io_counters()返回一个对象包含以下关键属性指标 read_bytes从磁盘读取的总字节数。 write_bytes写入磁盘的总字节数。 read_count读取操作的次数可用于计算IOPS。 write_count写入操作的次数。运行结果读取吞吐量: 15.75 MB/s 写入吞吐量: 8.20 MB/s 读取IOPS: 1200 写入IOPS: 600理论值参考吞吐量HDD顺序读写约100-200 MB/sSATA SSD500-550 MB/s或NVMe SSD3-7 GB/sIOPSHDD100-200 IOPSSATA SSD1万-10万IOPS或NVMe SSD10万-100万IOPS7、获取网络信息获取网络I/O统计网络IO指的是系统通过网络接口进行数据收发的过程主要包括接收操作从网络中接收数据包。发送操作通过网络发送数据包。带宽单位时间内网络传输的数据量如Mbps或Gbps。延迟网络数据包从源到目标的时间。吞吐量实际传输的数据量通常小于带宽上限。普及一个概念千兆带宽1Gb/s注意这里b是小写的Gb/s表示 Gigabit per second千兆比特每秒1 Gb 10亿比特10^9 bits。GB/s表示 Gigabyte per second吉字节每秒1 GB 10亿字节10^9 Bytes。关键区别1 Byte字节 8 bits比特所以 1 GB/s 8 Gb/s。所以千兆带宽的理论传输速度约为125MB/s百兆带宽理论传输速度约为12.5MB/simportpsutil# 获取网络流量统计net_iopsutil.net_io_counters()print(Bytes sent:,net_io.bytes_sent)print(Bytes received:,net_io.bytes_recv)-----------------------------------------------psutil.net_io_counters()返回一个命名元组包含系统所有网络接口如Wi-Fi、以太网的累计网络IO统计数据 主要指标 bytes_sent系统发送的总字节数上传流量。 bytes_recv系统接收的总字节数下载流量。 其他指标包括 packets_sent发送的数据包数。 packets_recv接收的数据包数。 errin/errout接收/发送的错误数。 dropin/dropout接收/发送丢弃的数据包数。获取网络IO吞吐量import psutil import time# 第一次采样net_io_1 psutil.net_io_counters()time.sleep(1)# 等待1秒# 第二次采样net_io_2 psutil.net_io_counters()# 计算吞吐量 (MB/s)bytes_sent_diff net_io_2.bytes_sent-net_io_1.bytes_sent bytes_recv_diff net_io_2.bytes_recv-net_io_1.bytes_recv send_mb_s bytes_sent_diff/(1024*1024)# 转换为MB/srecv_mb_s bytes_recv_diff/(1024*1024)# 转换为MB/sprint(f发送吞吐量: {send_mb_s:.2f} MB/s)print(f接收吞吐量: {recv_mb_s:.2f} MB/s)获取网路接口网卡如lo网卡、ens33/ens160/eth0地址信息import psutil net_if_addrs psutil.net_if_addrs()forinterface_name,interface_addresses in net_if_addrs.items(): print(f接口名称: {interface_name})print(f接口地址: {interface_addresses[0].address})小结网络信息采集通常采集两个方面网络IO使用net_io_counters与 网卡信息使用net_if_addrs8、psutil运维场景:获取cpu使用率监控CPU使用率,超过80%(阈值)就发给邮件给运维前置知识点:https://docs.python.org/3.9/library/smtplib.htmlimport psutil import smtplibfromemail.mime.text import MIMETextfromemail.header import Header# 设置邮箱地址和授权码from_addr 你的邮箱to_addr 目标邮箱auth_code 你的邮箱授权码# 早期版本都是使用的是邮箱密码有安全隐患现在使用的都是授权码不能登录邮箱只能用于邮件发送# 获取 CPU 使用率cpu_percent psutil.cpu_percent()# 判断 CPU 使用率是否超过阈值ifcpu_percent 80:# 构造邮件内容subject 警报高 CPU 使用率message CPU 使用率超过 80%当前使用率为 {}%.format(cpu_percent)# 使用 MIMEText 创建邮件对象指定编码为 UTF-8plain代表纯文本msg MIMEText(message,plain,utf-8)msg[Subject] Header(subject,utf-8)msg[From] from_addr# 用于显示的发件人msg[To] to_addr# 用于显示的收件人# 建立 SMTP 连接server smtplib.SMTP(smtp.163.com)server.login(from_addr,auth_code)# 发送邮件server.sendmail(from_addr,to_addr,msg.as_string())server.quit()测试在linux端下载一个压力测试工具 yun install stress-ng -y;接着输入命令进行测试stress-ng --cpu n --timeout 60sn表示虚拟机机子的CPU核心数n可以是4或者6…60秒表示把CPU压力满的时间为60s60s之后就恢复正常了小结整个案例一共使用了3个模块检查系统CPU信息psutil、发送邮件email另外特别注意邮件发送时使用的密码并不是邮件密码而是邮件授权码二、paramiko模块目标paramiko主要用于实现远程登录、文件上传与下载功能1、模块介绍paramiko模块支持以加密和认证的方式连接远程服务器。可以实现远程文件的上传,下载或通过ssh远程执行命令。Linux上写shell脚本远程ssh操作处理密码有两种方法:ssh-keygen实现免密操作这样远程连接不用输入密码 ssh 192.168.88.102 touch /tmp/123expect自动应答处理密码#!/bin/bash# 删除 .ssh/known_hosts 中的旧记录以便每次登录都需要确认sed-i/^192.168.88.102/d/root/.ssh/known_hosts# 使用 expect 自动化 SSH 登录expect EOF spawn ssh 192.168.88.102# 执行 SSH 登录expect(yes/no)?# 等待出现 yes/no 确认提示sendyes\n# 发送 yes 确认expectpassword:# 等待输入密码提示send123\n# 输入密码expect]# 等待登录成功提示符sendtouch /tmp/123\n# 登录成功后执行命令sendexit\n# 退出 SSHexpect eof EOF2、安装paramikopip install paramiko-i https://pypi.tuna.tsinghua.edu.cn/simple3、使用paramiko实现远程登录importparamiko# 创建sshclient对象sshparamiko.SSHClient()# 创建一个客户端连接实例ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)# 加了这一句,如果第一次ssh连接要你输入yes,也不用输入了ssh.connect(hostname192.168.88.102,port22,usernameroot,password123456)# 指定连接的ip,port,username,passwordstdin,stdout,stderrssh.exec_command(touch /tmp/file.txt)# 执行一个命令,有标准输入,输出和错误输出# 标准输入可以忽略cor_resstdout.read()# 标准输出赋值err_resstderr.read()# 错误输出赋值print(cor_res.decode())# 网络传输是二进制需要decode(我们没有讨论socket编程所以你就直接这样做)print(err_res.decode())# 不管正确的还是错误的输出,都打印出来ssh.close()# 关闭此连接实例在paramiko中ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())用于指定在首次连接到一个新主机时的处理策略。作用自动接受未知主机在首次连接到一个新的主机即known_hosts文件中没有记录的主机时通常会提示确认连接要求输入yes或no。避免手动确认使用AutoAddPolicy后paramiko会自动将未知主机的主机密钥添加到known_hosts文件中而不提示用户手动确认。把以上内容封装为函数# 1. 导入模块importparamiko# 2. 封装函数defssh_exec(hostname,password,cmd,port22,usernameroot):# 创建SSHClient对象sshparamiko.SSHClient()# 允许连接不在know_hosts文件中的主机ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 连接服务器ssh.connect(hostnamehostname,portport,usernameusername,passwordpassword)# 执行命令获取返回结果 标准输入 标准输出1 标准错误2stdin,stdout,stderrssh.exec_command(cmd)# 返回最终的结果print(stdout.read().decode())print(stderr.read().decode())# 关闭SSH连接ssh.close()# 3. 调用函数# ssh_exec(192.168.88.102, 123456, ls /)whileTrue:cmdinput([rootnode2 ~]# )ssh_exec(192.168.88.102,123456,cmd)4、使用paramiko免密远程登录操作node1服务器生成秘钥发送公钥给node2服务器然后才能使用paramiko实现免密登录# ssh-keygen# ssh-copy-id root192.168.88.102import paramiko ssh paramiko.SSHClient()# 创建一个客户端连接实例private_key paramiko.RSAKey.from_private_key_file(/root/.ssh/id_rsa)# 提前先做好ssh等效性(也就是免密登陆)ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)# 加了这一句,如果第一次ssh连接要你输入yes,也不用输入了ssh.connect(hostname192.168.88.102,port22,usernameroot,pkeyprivate_key)# 把password123456换成pkeyprivate_keystdin,stdout,stderr ssh.exec_command(touch /tmp/paramiko.txt)cor_res stdout.read()err_res stderr.read()print(cor_res.decode())print(err_res.decode())ssh.close()5、使用paramiko实现文件上传下载基于账号密码操作import paramiko# 创建传输连接trans paramiko.Transport((192.168.88.102,22))# 参数比较特殊要求必须是一个元组类型# 使用账号密码连接node2服务器trans.connect(usernameroot,password123456)# 创建sftp对象实现文件的上传与下载sftp paramiko.SFTPClient.from_transport(trans)# 下载文件sftp.get(/etc/fstab,/tmp/fstab1)# 把对方机器的/etc/fstab下载到本地为/tmp/fstab(注意不能只写/tmp,必须要命名)# 上传文件sftp.put(/etc/inittab,/tmp/inittab1)# 本地的上传,也一样要命令# 关闭连接trans.close()基于免密操作node1# ssh-keygen# ssh-copy-id root 192.168.88.102编写执行代码import paramiko# 创建传输连接trans paramiko.Transport((192.168.88.102,22))# 使用私钥进行登录验证private_key paramiko.RSAKey.from_private_key_file(/root/.ssh/id_rsa)trans.connect(usernameroot,pkeyprivate_key)# 提前使用ssh-keygen做好免密登录# 创建sftp对象sftp paramiko.SFTPClient.from_transport(trans)# 实现文件的上传与下载sftp.get(/etc/fstab,/tmp/fstab2)sftp.put(/etc/inittab,/tmp/inittab2)trans.close()小结paramiko作用实现远程登录、(上传)、下载、执行远程命令模拟MobaXterm软件等功能paramiko既支持密码登录还支持免密登录

更多文章