ESXi の設定確認を楽にする方法(SSH + expect)

ESXi の設定確認を楽にする方法(SSH + expect)

ESXi の管理は、基本的に vSphere Client や Web Client を使用します。
また、ESXi へのコマンドをリモート実行する場合は、esxcli (主に vSphereCLI や vMA など)を使用すると思います。

しかし、まれに ESXi に対してSSH でアクセスしたいケースもあると思います。

たとえば、

など。

とくにESXi の台数が多い場合は、個々にSSH ログインするのは大変です。

そんな時の解決法として、Linux サーバから expect コマンドでリモートアクセスをする方法があります。

expect では、接続先サーバの応答をもとにコマンドを自動実行することができます。


今回は expect コマンドを使用して主に参照系のコマンドを実行してみます。

※esxcli コマンドは、vSphereCLI に含まれリモート実行できるので、今回はあえて実行しません。

Linux への expect コマンドインストール

今回は、アクセス元として Oracle Linux 6.2 を使用しています。
Red Hat 6.x 系(Oracle Linux や CentOS も) にはデフォルトでは expect が入っていないので
OS インストール DVD にある RPM ファイルで別途インストールします。

[root@guest192 Packages]# cat /etc/oracle-release
Oracle Linux Server release 6.2

[root@guest192 Packages]# rpm -ivh expect-5.44.1.15-2.el6.x86_64.rpm
警告: expect-5.44.1.15-2.el6.x86_64.rpm: ヘッダ V3 RSA/SHA256 Signature, key ID ec551f03: NOKEY
準備中...       ########################################### [100%]
   1:expect        ########################################### [100%]

[root@guest192 Packages]# which expect
/usr/bin/expect   ★expect コマンドが見つかることを確認。

[root@guest192 Packages]# /usr/bin/expect -v
expect version 5.44.1.15  ★ついでに expect のバージョンも確認。

スクリプトの説明とファイル構成について

今回は、こんなスクリプトを作成してみました。
エラー処理などは特に入れていません。


SSH アクセス先 ESXi のリスト(sv.list)とシェル(get_esxi_info.sh)の2ファイル構成です。

[root@guest192 work]# ls -l
合計 8
-rw-r--r--. 1 root root 638  3月  8 00:45 2013 get_esxi_info.sh
-rw-r--r--. 1 root root  56  3月  8 00:41 2013 sv.list


まず、アクセス先の ESXi を、下記のように sv.list ファイルに書いておきます。

sv.list ファイルの内容

172.16.50.121  ★1列でESXiのアドレスを記載しておく。
172.16.50.122
172.16.50.123

SSH を実行するシェル(get_esxi_info.sh)は下記のような感じで作ってみました。

get_esxi_info.sh ファイルの内容

#!/bin/sh

user=root

pass=<ESXiのrootパスワード>

list=sv.list

prompt=\"\~\ \#\"

cat $list | while read LINE
do
sv=$LINE

expect -c "
  spawn ssh ${user}@${sv}
  expect \"\(yes\/no\)\?\" {
    send \"yes\\r\"
    expect \"Password:\"
    send \"${pass}\\r\"
  } \"Password:\" {
    send \"${pass}\\r\"
  }

expect ${prompt}
send \"uname -n\\r\"
expect ${prompt}
send \"cat /etc/ssh/sshd_config \| grep ^PasswordAuthentication\\n\"
expect ${prompt}
send \"ls /vmfs/volumes/ds_\*\\r\"
expect ${prompt}
send \"exit\\r\"
" > ${sv}.txt
echo "Get ESXi Info : ${sv}"
done


ヒント1

${prompt} の部分は、スクリプト冒頭の
prompt=\"\~\ \#\"
によりESXiのプロンプト文字列「~ #」を表します。

「~ #」が表示されるたびに、次の send より後部分のコマンドが実行されます。

ヒント2

何かコマンドラインを足したい時は、
expect ${prompt}
send \"コマンドライン
\\r\"

の2行をセットで追加します。
ただし、コマンドライン中のスペース文字や記号(「*」や「 | 」など)はエスケープ「\」します。


スクリプトの実行例

実行すると、下記のような感じになります。

ESXi の情報取得が終わるたびに、対象の ESXi のアドレスが表示されます。

[root@guest192 work]# sh get_esxi_info.sh
Get ESXi Info : 172.16.50.121
Get ESXi Info : 172.16.50.122
Get ESXi Info : 172.16.50.123


シェルの実行が終わると、ESXi 毎に情報を取得したファイルが作成されます。

[root@guest192 work]# ls -1
172.16.50.121.txt  ★「ESXiアドレス.txt」 が出力される。
172.16.50.122.txt
172.16.50.123.txt
get_esxi_info.sh
sv.list


ためしに、172.16.50.121.txt を開いてみると
SSH でコマンド実行した時の情報が取れています。

※最初の cat コマンド以下は、すべて「172.16.50.121.txt 」ファイルの中身です。

[root@guest192 work]# cat 172.16.50.121.txt
spawn ssh root@172.16.50.121
Password:
The time and date of this login have been sent to the system logs.

VMware offers supported, powerful system administration tools.  Please
see www.vmware.com/go/sysadmintools for details.

The ESXi Shell can be disabled by an administrative user. See the
vSphere Security documentation for more information.
~ # uname -n  ★実行したコマンドラインもファイルに残る。
sc-esxi501
~ # cat /etc/ssh/sshd_config | grep ^PasswordAuthentication
PasswordAuthentication yes
~ # ls /vmfs/volumes/ds_*  ★データストアに変なファイルが残っていないか見たり。
/vmfs/volumes/ds_local_esxi501:
vm01        vm02        vm03

/vmfs/volumes/ds_nfs131:
DB          lost+found          esxtop_001.log

/vmfs/volumes/ds_nfs132:
ESXi500-201209001.zip  lost+found  vma1
work                   iso


ちなみに、接続できない ESXi があったりすると、

ファイルにも下記のように NG だった様子が出力されます。

[root@guest192 work]# cat 172.16.50.123.txt
spawn ssh root@172.16.50.123
ssh: connect to host 172.16.50.123 port 22: No route to host


おまけ。シェルと作るときに役立ちそうなこと。

1. 初回アクセス対策

Linux から ESXi にアクセスするときも、お決まりの RSA key の質問があり

「yes」と入力する必要があります。

[root@guest192 work]# ssh root@172.16.50.121
The authenticity of host '172.16.50.121 (172.16.50.121)' can't be established.
RSA key fingerprint is 5d:27:66:c5:a6:ea:9b:ca:4a:ab:40:29:59:74:e5:5a.
Are you sure you want to continue connecting (yes/no)?

そこで、今回のシェルでは下記のように expect の条件分岐で

SSH 初回アクセス / 2回以降のアクセスを判断して対処しています。

ちなみに、「\r」 は Enter キーと同義です。

expect \"\(yes\/no\)\?\" {
    send \"yes\\r\"
    expect \"Password:\"
    send \"${pass}\\r\"
  } \"Password:\" {
    send \"${pass}\\r\"
  }

2. エスケープ文字「\」が多い場合の実際のコマンドライン確認

このスクリプトを要約すると
expect -c "xxxxxxx xxxxx" といった expect の使い方をしています。
この場合、expect のサブコマンド(send コマンドなど)で指定されるコマンドラインでは、
「"」を表現するためにエスケープ文字を使用し、「\"」と書く必要があります。
そのため文字列が複雑になり、実際に実行されるコマンドラインがわかりにくくなります。

この場合、echo コマンドを使うと、わかりやすくコマンドラインを確認することができます。

たとえば、下記のように確認します。

[root@guest192 work]# echo expect \"\(yes\/no\)\?\"
expect "(yes/no)?"
[root@guest192 work]# echo prompt=\"\~\ \#\"
prompt="~ #"
[root@guest192 work]# echo send \"ls /vmfs/volumes/ds_\*\\r\"
send "ls /vmfs/volumes/ds_*\r"

このような確認をしながらスクリプトを作成すると、間違いを減らすことができます。

以上、ESXi に SSH アクセスするときの工夫でした。

Version history
Revision #:
1 of 1
Last update:
‎03-07-2013 09:15 AM
Updated by: