python3使用pyVmomi获取vCenter中虚拟机cpu/内存信息
说明
文章分享在Linux操作系统中安装python3环境,并通过pyVmomi获取vCenter中运行的虚拟机信息,最后把获取的虚拟机数据存储到数据库中。
前三章为基础环境构建,第四章为脚本代码。
环境
软件列表:
- 操作系统版本:AnolisOS-8.8-x86_64-dvd
- Python版本:Python 3.12.4
- vCenter版本:7.0.3
- 数据库版本:mariadb-server-utils-10.3.35
IP地址规划:
- 192.168.10.222:vCenter1地址
- 192.168.10.223:vCenter2地址
- 192.168.10.188:Python3+Mariadb运行虚拟机
数据库规划:
数据库名:vcenterdb 数据库用户名:vcenterinfo 数据库用户密码:TestVcenter!#123 数据库地址:192.168.10.188
数据库表格规划:
记录ID:id 虚拟机UUID: vm_uuid 虚拟机名:vm_name 虚拟机是否为模板:vm_temp 虚拟机电源状态:vm_power 虚拟机所属宿主机:vm_host 虚拟机所属集群:vm_cluster 虚拟机cpu数量:vm_cpu 虚拟机内存数量:vm_memory 虚拟机cpu使用率,单位MHZ:vm_cpuUsage 虚拟机内存使用率,MB:vm_MemoryUsage 虚拟机vmtools运行状态:rvtools_stat 数据采集时间:import_date
python模块列表:
清单中为作者环境中的所有已安装模块,实际该案例中使用不到这么多。
certifi==2024.2.2 setuptools charset-normalizer==3.3.2 colorama==0.4.6 contourpy==1.2.1 cycler==0.12.1 decorator==5.1.1 docopt==0.6.2 fonttools==4.53.0 formats==0.1.1 future==1.0.0 httpretty==1.1.4 idna==3.7 Jinja2==3.1.3 jsonpatch==1.33 jsonpath-rw==1.4.0 jsonpointer==2.4 kiwisolver==1.4.5 MarkupSafe==2.1.5 matplotlib==3.9.0 numpy==1.26.4 packaging==24.1 pbr==6.0.0 pillow==10.3.0 ply==3.11 prompt_toolkit==3.0.47 pyflakes==3.2.0 Pygments==2.18.0 PyMySQL==1.1.1 pyparsing==3.1.2 python-dateutil==2.9.0.post0 python-redfish==0.4.4 pyvim==3.0.3 pyvmomi==8.0.2.0.1 redfish==3.2.2 redfish-client==0.3.9 redfish_utilities==3.2.8 requests==2.31.0 requests-toolbelt==1.0.0 requests-unixsocket==0.3.0 simplejson==3.19.2 six==1.16.0 tortilla==0.5.0 urllib3==2.2.1 wcwidth==0.2.13 XlsxWriter==3.2.0
一、Python3安装
安装前准备:
- 操作系统配置网络、确保系统能够正常连通互联网、yum源配置完成(本地光盘yum源即可)。
- 下载openssl-1.1.1w.tar.gz 软件离线安装包(https://openssl.org/source/old/1.1.1/openssl-1.1.1w.tar.gz )
- 下载Python-3.12.4.tg离线安装包(https://www.python.org/ftp/python/3.12.4/Python-3.12.4.tgz)
1.1 安装软件依赖包
# yum install gcc vim zlib-devel make zlib-static libzip bash-completion openssl-devel bzip2-devel libzip-devel python3-pyOpenSSL -y # source /etc/profile.d/bash_completion.sh
1.2 安装openssl(可忽略)
安装openssl-1.1.1版本的openssl,在python-3.12版本的python编译安装时提示需要openssl-1.1.1,即使机器上的openssl版本更高。
# mkdir /vm_pack # 把openssl-1.1.1w.tar.gz包上传到/vm_pack目录中 # cd /vm_pack # tar -zxvf openssl-1.1.1w.tar.gz # cd openssl-1.1.1w # ./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl # make # make install # cd /usr/bin/ # mv openssl openssl.bak # ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl # echo 'export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH' >> /etc/bashrc;source /etc/bashrc
1.3 安装python3.12
# mkdir /python3 # 上传Python-3.12.4.tgz到/vm_pack目录中 # cd /vm_pack # tar -zxvf Python-3.12.4.tgz # cd Python-3.12.4 # ./configure --prefix=/python3 --with-openssl=/usr/local/openssl # make # makeinstall
验证python3.12是否安装成功
[root@localhost ~]# /python3/bin/python3 --version Python 3.12.4
1.4 回退openssl
本章节只适用于进行了1.2章节操作后的还原,1.2操作过后yum等功能使用不了,在python3.12安装完成过后手动的把openssl还原。
需要做两个操作:
- 使用之前备份的/usr/bin/openssl.bak替换当前的/usr/bin/openssl。
- 取消掉 LD_LIBRARY_PATH变量。
1、替换openssl文件
# cp -rp /usr/bin/openssl /root/ # cp /usr/bin/openssl.bak openssl
2、取消 LD_LIBRARY_PATH变量
# vim /etc/bashrc export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH # unset LD_LIBRARY_PATH # reboot
二、Python3安装模块
2.1安装python模块离线版
使用pip3安装项目所需的模块,在真实生成场景中的虚拟机经常不具备访问互联网的能力,此时需要在能够访问互联的环境中下构造一套和生产环境一致的环境,下载所需要的包上传至生产环境进行离线安装。
在线安装不叙述。
默认的pip源下载速度比较感人,国内可用如下源:
- 阿里云 http://mirrors.aliyun.com/pypi/simple/
- 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
- 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
- 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
1、下载模块
在/python3/bin/中新建一个名为requirement.txt
注:(文章编写于2024年6月22日)时间久了过后,requirement.txt中记录的模块版本会出现版本不一致导致下载报错,此时把文件中的版本号去掉就行了。
[root@localhost ~]# cat /python3/bin/requirement.txt certifi==2024.2.2 setuptools charset-normalizer==3.3.2 colorama==0.4.6 contourpy==1.2.1 cycler==0.12.1 decorator==5.1.1 docopt==0.6.2 fonttools==4.53.0 formats==0.1.1 future==1.0.0 httpretty==1.1.4 idna==3.7 Jinja2==3.1.3 jsonpatch==1.33 jsonpath-rw==1.4.0 jsonpointer==2.4 kiwisolver==1.4.5 MarkupSafe==2.1.5 matplotlib==3.9.0 numpy==1.26.4 packaging==24.1 pbr==6.0.0 pillow==10.3.0 ply==3.11 prompt_toolkit==3.0.47 pyflakes==3.2.0 Pygments==2.18.0 PyMySQL==1.1.1 pyparsing==3.1.2 python-dateutil==2.9.0.post0 python-redfish==0.4.4 pyvim==3.0.3 pyvmomi==8.0.2.0.1 redfish==3.2.2 redfish-client==0.3.9 redfish_utilities==3.2.8 requests==2.31.0 requests-toolbelt==1.0.0 requests-unixsocket==0.3.0 simplejson==3.19.2 six==1.16.0 tortilla==0.5.0 urllib3==2.2.1 wcwidth==0.2.13 XlsxWriter==3.2.0 [root@localhost ~]#
下载所需软件到到指定目录中
# mkdir /packs
# cd /python3/bin/ # /python3/bin/pip3 download -d /packs -r requirement.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
# echo $?
命令正常运行完成,即echo $? 结果为0,且/packs目录中有刚下载的模块文件。
把刚下载的模块打包成tar.gz文件方便后期传输到其他机器上。
# cd /packs # tar -zcvf python3_mod.tar.gz *
2、离线安装模块
对于离线安装,需要把下载的模块放置到需要安装的主机上,本次环境中不再累述如何解压tar.gz包。
假定我在一台全新的机器把python3_mode.tar.gz包解压到/packs目录中。
# cd /python3/bin/ # /python3/bin/pip3 install --no-index --find-link /packs -r requirement.txt # echo $? 安装完成后不报错,即echo $? 执行结果为0,表示安装完成。
验证模块是否安装成功,进入python3控制台,尝试导入模块,如果正常表示模块安装完成。
[root@localhost ~]# /python3/bin/python3 Python 3.12.4 (main, Jun 21 2024, 18:42:17) [GCC 8.5.0 20210514 (Anolis 8.5.0-10.0.3)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pymysql as mysql >>> from pyVmomi import vim >>> from pyVim.connect import SmartConnect, Disconnect >>> (ctrl + d 退出python控制台)
三、Mariadb数据库配置
3.1安装mariadb
# yum install mariadb* -y # systemctl enable mariadb --now # mysql_secure_installation (根据提示操作)
3.2创建数据库数据
[root@localhost ~]# mysql -uroot #新建数据库 MariaDB [(none)]> create database vcenterdb; #新建账号语句 MariaDB [(none)]> CREATE USER 'vcenterinfo'@'%' IDENTIFIED BY 'TestVcenter!#123'; #授予权限 MariaDB [(none)]> GRANT ALL PRIVILEGES ON vcenterdb.* TO 'vcenterinfo'@'%' WITH GRANT OPTION; #刷新权限 MariaDB [(none)]> FLUSH PRIVILEGES;
设置数据编码
[root@localhost my.cnf.d]# cat /etc/my.cnf # # This group is read both both by the client and the server # use it for options that affect everything # [client-server] # # include all files from the config directory # !includedir /etc/my.cnf.d [mysqld] character-set-server=utf8mb4 [mysql] default-character-set=utf8mb4
[root@localhost my.cnf.d]# systemctl restart mariadb.service
创建表语句
create table vm_info( id int not null auto_increment primary key, vm_uuid varchar(40), vm_name varchar(60), vm_temp char(6), vm_power varchar(10), vm_host varchar(20), vm_cluster varchar(20), vm_cpu varchar(10), vm_memory varchar(10), vm_cpuUsage varchar(10), vm_MemoryUsage varchar(10), rvtools_stat varchar(20), import_date varchar(80) not null );
alter table vm_info convert to character set utf8 collate utf8_unicode_ci;
四、Python脚本
官方文档地址:https://vdc-download.vmware.com/vmwb-repository/dcr-public/6b586ed2-655c-49d9-9029-bc416323cb22/fa0b429a-a695-4c11-b7d2-2cbc284049dc/doc/index.html#linkc73e053404c378354e7517d812eba5f5441a13da;vim.VirtualMachine.html
脚本共由4个函数构成:
- connect_to_vcenter: 通过读取用户给出的vCenter相关信息,与vCenter建立连接。
- get_vm_list: 接收connect_to_vcenter函数的返回值,获取到vCenter中虚拟机的数据并以列表的形式返回。
- generate_sql_lang:接收get_vm_list函数的返回值,把虚拟机各个参数整合成一条一条的sql语句。返回一个列表。
- import_db:接收get_vm_list函数的返回值,逐条执行sql语句。
import ssl import datetime import pymysql as mysql from pyVmomi import vim from pyVim.connect import SmartConnect, Disconnect #静态mysql信息 mysql_user = 'vcenterinfo' mysql_password = 'TestVcenter!#123' mysql_host = '192.168.10.188' mysql_db = 'vcenterdb' # 连接vCneter函数 def connect_to_vcenter(hostname,username,password): try: #忽略ssl证书验证 ssl._create_default_https_context = ssl._create_unverified_context #连接到vCenter service_instance = SmartConnect(host=hostname, user=username, pwd=password) return service_instance except Exception as e: print("connect vCenter faile: ",str(e)) #获取虚拟机列表函数 def get_vm_list(service_instance): try: print("\n开始获取虚拟机数据..........\n\n") vm_info = [] content = service_instance.RetrieveContent() # 获取数据中心 container = content.rootFolder viewType = [vim.VirtualMachine] recursive = True containerView = content.viewManager.CreateContainerView(container, viewType, recursive) # 循环读取每个vm信息,并存储在vm_object字典中,最终追加到vm_info列表中 for vm in containerView.view: resource_usage = vm.summary.quickStats cpu_usage = resource_usage.overallCpuUsage memory_usage = resource_usage.guestMemoryUsage vm_object = { "VMuuid" : vm.config.uuid, "VMname" : vm.name, "IStemp" : vm.config.template, "VMPowerstat": vm.runtime.powerState, "VMcpu" : vm.config.hardware.numCPU, "VMmemry" : vm.config.hardware.memoryMB, "VMCpu_usage" : cpu_usage, "VMMemory_usage" : memory_usage, "Rvtoolstat" : vm.guest.toolsRunningStatus, "VMHost" : vm.runtime.host.name, "VMCluster" : vm.runtime.host.parent.name } vm_info.append(vm_object) return vm_info except Exception as e: print("get vm list faile: ",str(e)) #整合sql语句 def generate_sql_lang(vm_lists): try: print('开始执行sql语句整合..........') #生成时间 current_time = datetime.datetime.now() sql_langs = [] print(f"虚拟机数量: {len(vm_lists)}") for vm_dir in vm_lists: sql_lang = 'insert into vm_info (vm_uuid, vm_name, vm_temp, vm_power, vm_host, vm_cluster, vm_cpu, vm_memory, vm_cpuUsage, vm_MemoryUsage, rvtools_stat, import_date) values ("' + str(vm_dir["VMuuid"]) + '","' + str(vm_dir["VMname"]) + '","' + str(vm_dir["IStemp"]) + '","' + str(vm_dir["VMPowerstat"]) + '","' + str(vm_dir["VMHost"]) + '","' + str(vm_dir["VMCluster"]) + '","' + str(vm_dir["VMcpu"]) + '","' + str(vm_dir["VMmemry"]) + '","' + str(vm_dir["VMCpu_usage"]) + '","' + str(vm_dir["VMMemory_usage"]) + '","' + str(vm_dir["Rvtoolstat"]) +'","' + str(current_time) +'");' #print(sql_lang) sql_langs.append(sql_lang) return sql_langs except Exception as e: print("generate sql lang faile: ", str(e)) #数据存储到mariadb数据库中 def import_db(mysql_user,mysql_password,mysql_host,mysql_db,sql_langs): try: print('开始导入虚拟机信息..........') print(f"导入总数量: {len(sql_langs)}") # 数据入库 # 新建数据库连接 conn = mysql.connect(host=mysql_host, user=mysql_user, password=mysql_password, database=mysql_db) # 新建游标 #print('连接数据库成功。。。。。。。。。。。。') conn_cur = conn.cursor() #print('新建游标成功。。。。。。。。。。。。。') # 执行命令 for sql_sing in sql_langs: #print(sql_sing) conn_cur.execute(sql_sing) # 提交执行 conn.commit() #print("数据插入成功。。。。。。。。。。。。。") # 关闭游标 conn_cur.close() # 关闭数据库连接 conn.close() #print("关闭数据库连接成功。。。。。。。。。。。。。") except Exception as e: print("import db faile: ", str(e)) #定义vc信息list,如果只有一个vc需要采集,只在vc_info列表中保留一个vc的信息即可,如有多个依次添加即可。 vc_info = [{'vcenter_ip':'192.168.10.222','vcenter_user':'administrator@vsphere.local','vcenter_password':'vCenter_pass!#123'},{'vcenter_ip':'192.168.10.223','vcenter_user':'administrator@vsphere.local','vcenter_password':'vCenter_pass!#123'}] #循环操作2个vc for i in vc_info: print(f"{i["vcenter_ip"]} 开始执行程序................") # 新建一个连接到vCenter aa = connect_to_vcenter(i["vcenter_ip"], i["vcenter_user"], i["vcenter_password"]) # 获取虚拟机数据,置入一个列表中 bb = get_vm_list(aa) # 数据获取完成后立马关机vCenter连接 Disconnect(aa) # 使用get_vm_list函数获取到得数据生成sql语句。 cc = generate_sql_lang(bb) # 连接mysql,执行sql语句。 import_db(mysql_user, mysql_password, mysql_host, mysql_db, cc) print(f"{i["vcenter_ip"]} 程序执行完成................")
结果展示