vsphereClient/vCenterで見られる情報を取得する方法。
ただし、ホスト内部でのコマンド(esxcli)ではなく、SOAP経由で外部から取得する方法。
公式のSDKとしてC#、java、perlがあるけれど、普段慣れてるrubyでやってみる。
実際はSOAPでやりとりしているので、生で書いてもいいけどgemがあったのでこれを利用。
ここではESX単体が対象だけれども、vCenterに同様の手法でアクセスすることも可能。
ただし、その際は複数のESXがvCenter配下に置かれているので、オブジェクトが配列のものは複数のESXの情報が返ってくることに注意。
前準備
SDK
ruby用SDKをインストール
gem install rbvmomi
モノはここ
https://github.com/vmware/rbvmomi
VMwareの人が書いてるようだけどこれって非公式なのかな?
オブジェクトツリー
どんなオブジェクトがあるかはリファレンスから辿れる
5.5用
https://www.vmware.com/support/developer/converter-sdk/conv55_apireference/
4.1用
https://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/index.html
実際にどんな値が入っているかは実機を見た方が早いかも
https://[esx address]/mob/
ユーザ・パスワードは設定したやつで
アクセス方法
SOAPを利用してオブジェクトを取得する。
githubにサンプルがあるけど、独特な部分もあるので概念の説明
ツリーのrootはそのまんま「ServiceInstance」
ServiceInstance -> ServiceContent -> rootFolder -> ...
という構成になっている。
ServiceInstance.CurrentTime
で今の時刻が返ってくるなど、対象のオブジェクトがメソッドを持ってるのがSOAPがSNMPやLDAPと違うところ。
メソッドとプロパティの概念はオブジェクト指向言語を触っていれば理解しやすいけれど、インフラ系のエンジニアにはとっつきにくいかもね。
コード
接続
require 'rbvmomi'
vim = RbVmomi::VIM.connect host: 'foo', user: 'bar', password: 'baz', insecure: true
TLSの検証を無視するようにconnectに「insecure: true」を付与しておく
なお、SOAPの中身が必要であれば
debug: true
を追加するとSOAP(HTTP)の中身が得られる。
rubyが良きに計らってくれすぎて余計なオブジェクトを取得しているかどうかはこれを見ながらコードを修正するのが手っ取り早い。
ホスト情報
ホストオブジェクト(hostSystem)が
ServiceInstance -> ServiceContent -> rootFolder - childEntity[0] -> hostFolder -> childEntity[0] -> host[0]
なので、
hostSystem = vim.root.childEntity[0].hostFolder.childEntity[0].host[0]
で、ホスト情報のオブジェクトまで到達
メモリとCPUの使用量は
hostSystem.summary.quickStats.overallMemoryUsage
hostSystem.summary.quickStats.overallCpuUsage
使用率は↓の実装量から計算
hostInfo.summary.hardware.cpuMhz
hostInfo.summary.hardware.numCpuThreads
hostInfo.summary.hardware.memorySize
※単位に注意
config情報、仮想ハード情報など必要なオブジェクトがあちこちにとっちらかってるので、探し出すのがちょっと大変かも。
VM情報
サンプル
vms = vim.serviceContent.rootFolder.childEntity[0].hostFolder.childEntity[0].host[0].vm
vms.each do |vm|
printf("%s: ", vm.name)
if (vm.runtime.powerState == "poweredOn")
printf("%d %d %d\n",
vm.summary.quickStats.hostMemoryUsage,
vm.summary.quickStats.guestMemoryUsage,
vm.summary.quickStats.overallCpuUsage)
else
printf("power off\n")
end
end
VM単位で探したいときは
vm = vim.serviceContent.rootFolder.childEntity[0].find_vm("vmName")
が簡単。
カウンタ系
ネットワークやストレージなどのカウンタは直接取得できない。perfCounterオブジェクトを経由して取得する。
その他
いろいろイジリ倒しながら悪戦苦闘してみたけれど、ドキュメントを探すよりirbやpry上でメソッドやプロパティを見ながら試行錯誤したほうが速い
や
vim.methods
vim.serviceContent.rootFolder.childEntity[0].hostFolder.childEntity[0].host[0].methods
など。
少なくともオブジェクトのドキュメントもrdocは不親切=3