zaki work log

作業ログやら生活ログやらなんやら

[ESXi / Ansible] ssh接続してvmi-cmdを使ったVM操作が可能かお試し

ESXiのsshを有効にすると、ssh接続できる。

f:id:zaki-hmkc:20200910214002p:plain

Copyright (C) Microsoft Corporation. All rights reserved.

新しいクロスプラットフォームの PowerShell をお試しください https://aka.ms/pscore6

PS C:\Users\zaki> ssh root@192.168.0.2
The authenticity of host '192.168.0.2 (192.168.0.2)' can't be established.
RSA key fingerprint is SHA256:niylnBGGHVs8r24g52aq1czc6JKg4MDvqpeGjbHikQk.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.2' (RSA) to the list of known hosts.
Password:
The time and date of this login have been sent to the system logs.

WARNING:
   All commands run on the ESXi shell are logged and may be included in
   support bundles. Do not provide passwords directly on the command line.
   Most tools can prompt for secrets or accept them from standard input.

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.
[root@localhost:~] uname -a
VMkernel localhost.naru.jp-z.jp 6.5.0 #1 SMP Release build-8294253 Apr 17 2018 19:05:39 x86_64 x86_64 x86_64 ESXi
[root@localhost:~] ls
altbootbank      dev              local.tgz        proc             store            usr              vmupgrade
bin              etc              locker           productLocker    tardisks         var
bootbank         lib              mbr              sbin             tardisks.noauto  vmfs
bootpart.gz      lib64            opt              scratch          tmp              vmimages
[root@localhost:~]

この通り、ESXiのweb画面でログインするときのアカウントでsshできる。

[root@localhost:~] which python
/bin/python
[root@localhost:~] python --version
Python 3.5.3

Pythonインタプリタも入っている。

よし、Ansibleで何かできるかな。

ssh接続してlsする

inventory

becomeでrootになるのではなく、初めからrootでssh接続したいので、ansible_userを指定する。
パスワードはtext/plainでの記述に気にしないならansible_passwordで書いてもよい。
またはansible-vaultを使った暗号化という手もある。

今回は手っ取り早く、inventoryには記載なし、実行時に-kインタラクティブに入力とする。

[esxi]
host ansible_host=192.168.0.2 ansible_user=root

playbook

ESXiホスト上でls -lして結果をdebugで表示してみる。

- hosts: esxi
  gather_facts: false
  tasks:
  - name: exec command
    command: /bin/ls -l
    register: result

  - name: result
    debug:
      msg: "{{result.stdout}}"

実行結果

(2.9) [zaki@cloud-dev get-vmlist]$ ansible-playbook -i inventory.ini playbook.yml -k
SSH password: 

PLAY [esxi] *****************************************************************************************************

TASK [exec command] *********************************************************************************************
[WARNING]: No python interpreters found for host host (tried ['/usr/bin/python', 'python3.7', 'python3.6',
'python3.5', 'python2.7', 'python2.6', '/usr/libexec/platform-python', '/usr/bin/python3', 'python'])
changed: [host]

TASK [result] ***************************************************************************************************
ok: [host] => 
  msg: |-
    total 725
    lrwxrwxrwx    1 root     root            49 Aug  8 09:19 altbootbank -> /vmfs/volumes/5d0f317f-6bd852f3-5e45-fcdbf5dfbc4f
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 bin
    lrwxrwxrwx    1 root     root            49 Aug  8 09:19 bootbank -> /vmfs/volumes/a65abe71-c4f310cb-9086-addf2d180ac6
    -r--r--r--    1 root     root        505734 Apr 18  2018 bootpart.gz
    drwxr-xr-x   13 root     root           512 Sep 10 10:54 dev
    drwxr-xr-x    1 root     root           512 Aug  8 09:27 etc
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 lib
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 lib64
    -r-x------    1 root     root         15842 Aug  8 09:06 local.tgz
    lrwxrwxrwx    1 root     root             6 Aug  8 09:19 locker -> /store
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 mbr
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 opt
    drwxr-xr-x    1 root     root        131072 Sep 10 10:54 proc
    lrwxrwxrwx    1 root     root            23 Aug  8 09:19 productLocker -> /locker/packages/6.5.0/
    lrwxrwxrwx    1 root     root             4 Apr 18  2018 sbin -> /bin
    lrwxrwxrwx    1 root     root            49 Aug  8 09:19 scratch -> /vmfs/volumes/5d8faab9-e7f59692-e859-1c697a00ef17
    lrwxrwxrwx    1 root     root            49 Aug  8 09:19 store -> /vmfs/volumes/5d8faab2-9eb79d0c-7790-1c697a00ef17
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 tardisks
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 tardisks.noauto
    drwxrwxrwt    1 root     root           512 Sep 10 10:54 tmp
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 usr
    drwxr-xr-x    1 root     root           512 Aug  8 09:19 var
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 vmfs
    drwxr-xr-x    1 root     root           512 Aug  8 09:18 vmimages
    lrwxrwxrwx    1 root     root            18 Apr 18  2018 vmupgrade -> /locker/vmupgrade/

PLAY RECAP ******************************************************************************************************
host                       : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(2.9) [zaki@cloud-dev get-vmlist]$ 

VM一覧を取得してファイルに出力

上記のssh接続してlsをベースに実行するコマンドを変更。
実行するのはvim-cmd vmsvc/getallvms

普通に実行するとこんな感じ。

[root@localhost:~] vim-cmd vmsvc/getallvms
Vmid              Name                                                 File                                          Guest OS       Version   Annotation
1      example                       [datastore1] example/example.vmx                                            centos7_64Guest    vmx-13
103    k8s-master03.esxi.jp-z.jp     [WDS100T2B0A] k8s-master03.esxi.jp-z.jp/k8s-master03.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13
105    k8s-worker04.esxi.jp-z.jp     [WDS100T2B0A] k8s-worker04.esxi.jp-z.jp/k8s-worker04.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13
106    cloud-dev                     [WDS100T2B0A] cloud-dev_1/cloud-dev_1.vmx                                   centos7_64Guest    vmx-13
107    desktop                       [WDS100T2B0A] desktop/desktop.vmx                                           ubuntu64Guest      vmx-13
108    desktop2                      [WDS100T2B0A] desktop2/desktop2.vmx                                         ubuntu64Guest      vmx-13
11     test.vm                       [WDS100T2B0A] test.vm/test.vm.vmx                                           centos7_64Guest    vmx-13    test vm
111    restricted-rhel7              [WDS100T2B0A] restricted-rhel7/restricted-rhel7.vmx                         rhel7_64Guest      vmx-13
13     debian-desktop                [WDS100T2B0A] debian-desktop/debian-desktop.vmx                             debian10_64Guest   vmx-13
23     windows                       [WDS100T2B0A] windows8x64/windows8x64.vmx                                   windows8_64Guest   vmx-13
25     okd-manager.esxi.jp-z.jp      [WDS100T2B0A] okd-manager.esxi.jp-z.jp/okd-manager.esxi.jp-z.jp.vmx         centos7_64Guest    vmx-13
26     okd-master.esxi.jp-z.jp       [WDS100T2B0A] okd-master.esxi.jp-z.jp/okd-master.esxi.jp-z.jp.vmx           centos7_64Guest    vmx-13
27     okd-node1.esxi.jp-z.jp        [WDS100T2B0A] okd-node1.esxi.jp-z.jp/okd-node1.esxi.jp-z.jp.vmx             centos7_64Guest    vmx-13
28     okd-node2.esxi.jp-z.jp        [WDS100T2B0A] okd-node2.esxi.jp-z.jp/okd-node2.esxi.jp-z.jp.vmx             centos7_64Guest    vmx-13
33     minikube.jp-z.jp              [WDS100T2B0A] minikube.jp-z.jp/minikube.jp-z.jp.vmx                         centos7_64Guest    vmx-13
45     manager-dev                   [WDS100T2B0A] manager-dev/manager-dev.vmx                                   centos7_64Guest    vmx-13
51     desktop-ubuntu                [WDS100T2B0A] desktop-ubuntu/desktop-ubuntu.vmx                             ubuntu64Guest      vmx-13
53     desktop-centos                [WDS100T2B0A] desktop-centos/desktop-centos.vmx                             centos7_64Guest    vmx-13
54     registry                      [WDS100T2B0A] registry/registry.vmx                                         centos7_64Guest    vmx-13
62     okd4-manager.esxi.jp-z.jp     [WDS100T2B0A] okd4-manager.esxi.jp-z.jp/okd4-manager.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13
69     okd4-bootstrap.esxi.jp-z.jp   [WDS100T2B0A] okd4-bootstrap.esxi.jp-z.jp/okd4-bootstrap.esxi.jp-z.jp.vmx   coreos64Guest      vmx-13
7      manager.local.jp-z.jp         [WDS100T2B0A] manager.local.jp-z.jp/manager.local.jp-z.jp.vmx               centos7_64Guest    vmx-13
70     okd4-master0.esxi.jp-z.jp     [WDS100T2B0A] okd4-master0.esxi.jp-z.jp/okd4-master0.esxi.jp-z.jp.vmx       coreos64Guest      vmx-13
71     okd4-master1.esxi.jp-z.jp     [WDS100T2B0A] okd4-master1.esxi.jp-z.jp/okd4-master1.esxi.jp-z.jp.vmx       coreos64Guest      vmx-13
72     okd4-master2.esxi.jp-z.jp     [WDS100T2B0A] okd4-master2.esxi.jp-z.jp/okd4-master2.esxi.jp-z.jp.vmx       coreos64Guest      vmx-13
73     okd4-worker0.esxi.jp-z.jp     [WDS100T2B0A] okd4-worker0.esxi.jp-z.jp/okd4-worker0.esxi.jp-z.jp.vmx       coreos64Guest      vmx-13
74     okd4-worker1.esxi.jp-z.jp     [WDS100T2B0A] okd4-worker1.esxi.jp-z.jp/okd4-worker1.esxi.jp-z.jp.vmx       coreos64Guest      vmx-13
75     pxe-sample                    [WDS100T2B0A] pxe-sample/pxe-sample.vmx                                     centos7_64Guest    vmx-13
77     win10-offline                 [WDS100T2B0A] win10-offline/win10-offline.vmx                               windows9_64Guest   vmx-13
78     restricted-centos             [WDS100T2B0A] restricted-centos/restricted-centos.vmx                       centos7_64Guest    vmx-13
91     k8s-master01.esxi.jp-z.jp     [WDS100T2B0A] k8s-master01.esxi.jp-z.jp/k8s-master01.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13
92     k8s-worker01.esxi.jp-z.jp     [WDS100T2B0A] k8s-worker01.esxi.jp-z.jp/k8s-worker01.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13
95     esxi-host                     [WDS100T2B0A] esxi-host/esxi-host.vmx                                       vmkernel65Guest    vmx-13
96     k8s-master02.esxi.jp-z.jp     [WDS100T2B0A] k8s-master02.esxi.jp-z.jp/k8s-master02.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13
97     k8s-worker02.esxi.jp-z.jp     [WDS100T2B0A] k8s-worker02.esxi.jp-z.jp/k8s-worker02.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13
98     k8s-worker03.esxi.jp-z.jp     [WDS100T2B0A] k8s-worker03.esxi.jp-z.jp/k8s-worker03.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13
99     k8s-manager.esxi.jp-z.jp      [WDS100T2B0A] k8s-manager.esxi.jp-z.jp/k8s-manager.esxi.jp-z.jp.vmx         centos7_64Guest    vmx-13

j2テンプレート

template.j2で作成。
内容はこれだけ。

{{ result.stdout }}

playbook

- hosts: esxi
  gather_facts: false
  tasks:
  - name: exec command
    command: vim-cmd vmsvc/getallvms
    register: result

  - name: create vm list file
    template:
      src: template.j2
      dest: getallvms.log
    delegate_to: localhost

ポイントはdelegate_tolocalhostを指定していること。
これが無いと、ESXiホスト上にtemplateを使ってファイル生成してしまう。

実行結果

(2.9) [zaki@cloud-dev get-vmlist]$ ansible-playbook -i inventory.ini playbook.yml -k
SSH password: 

PLAY [esxi] *****************************************************************************************************

TASK [exec command] *********************************************************************************************
[WARNING]: No python interpreters found for host host (tried ['/usr/bin/python', 'python3.7', 'python3.6',
'python3.5', 'python2.7', 'python2.6', '/usr/libexec/platform-python', '/usr/bin/python3', 'python'])
changed: [host]

TASK [create vm list file] **************************************************************************************
changed: [host]

PLAY RECAP ******************************************************************************************************
host                       : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(2.9) [zaki@cloud-dev get-vmlist]$ 
(2.9) [zaki@cloud-dev get-vmlist]$ head -3 getallvms.log 
Vmid              Name                                                 File                                          Guest OS       Version   Annotation
1      example                       [datastore1] example/example.vmx                                            centos7_64Guest    vmx-13              
103    k8s-master03.esxi.jp-z.jp     [WDS100T2B0A] k8s-master03.esxi.jp-z.jp/k8s-master03.esxi.jp-z.jp.vmx       centos7_64Guest    vmx-13              
(2.9) [zaki@cloud-dev get-vmlist]$ 

delegate_toを使わないのであれば、command実行はESXi、template実行はローカルと、タスクを分けるのが一番手っ取り早い。 ただしその場合はregisterの値はESXiのホストグループ側にセットされるのでホスト変数を参照する必要がある。

具体的にはテンプレートでは{{ hostvars[groups.esxi[0]].result.stdout }}みたいな感じで取り出せる。

zaki-hmkc.hatenablog.com

また、localhostをターゲットにする場合は、CentOS7でpip3の場合だとPythonインタプリタの指定とinventoryでlocalhost指定が必要かもしれないので注意。

write系処理

無償ライセンスのESXiだとwrite系APIが使えないため、VMのon/offとかもできないんだけど、このvim-cmdであれば可能。

  • poweron

    [root@localhost:~] vim-cmd vmsvc/power.on 78 Powering on VM:

  • poweroff

    [root@localhost:~] vim-cmd vmsvc/power.off 78 Powering off VM:

  • shutdown (要VMware Tools)

    [root@localhost:~] vim-cmd vmsvc/power.shutdown 45

みたいな感じ。(引数はリストで得られるVmid)

ただ、処理に必要なこのVmidを取り出したりするために、それなりのテキスト処理をグリグリやる必要があるので「AnsibleのターゲットホストにESXiを指定してsshで接続してshell/commandでがんばる」のはかなりの力技になりそう。

力技なのはかわりないけれど、playbookがスッキリするという点ではモジュール作成の題材にすると良さげ。

ちなみにやろうとしてたのは、ESXiのアップデートをAnsibleで自動化できないかなーというもの。
コマンド実行するくらいであればこの延長でできそうだけど、「onの状態のVMをすべてシャットダウン」とかはグリグリしないとだめかも。


エラーと対処

fatal: [host]: FAILED! => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  cmd: /bin/ls -l
  msg: '[Errno 38] Function not implemented'
  rc: 38
$ ansible --version
ansible 2.9.10
  config file = /home/zaki/src/ansible-vmware/ssh/get-vmlist/ansible.cfg
  configured module search path = ['/home/zaki/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/zaki/.local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

以上の環境で発生。
検索してみると、以下のissueを発見

github.com

どうやらバージョンの組み合わせ固有の現象っぽい。。 現時点の2.9系最新であるAnsible 2.9.13に更新すると解消。

ESXiシェルのログ

[監視]->[ログ]->[/var/log/shell.log]で確認できる。

f:id:zaki-hmkc:20200910214153p:plain


参考情報

kb.vmware.com

qiita.com

キレイにまとまったリファレンス情報が見当たらない。。