[ English | Indonesia | Deutsch | 日本語 ]

コンピュートノードの故障とメンテナンス

コンピュートノードは、予期せずクラッシュしたり、メンテナンスのために再起動が必要になったりすることがときどきあります。

計画メンテナンス

ソフトウェアやハードウェアのアップグレードなど、計画されたメンテナンスのために、コンピュートノードを再起動する必要があれば、以下の手順を実行します。

  1. 新規 VM のノードへのスケジューリングを無効化し、理由をコメントにします。

    # openstack compute service set --disable --disable-reason \
    maintenance c01.example.com nova-compute
    
  2. すべてのホストのインスタンスがノードからいなくなっていることを確認します。

    • クラウドが共有ストレージを使用している場合:

      1. 移動する必要のあるインスタンスの一覧を取得します。

        # openstack server list --host c01.example.com --all-projects
        
      2. すべてのインスタンスを 1 つずつマイグレーションします。

        # openstack server migrate <uuid> --live c02.example.com
        
    • 共有ストレージを使用していない場合、次のように実行します。

      # openstack server migrate <uuid> --live --block-migration c02.example.com
      
  3. nova-compute サービスを停止します。

    # stop nova-compute
    

    Puppet などの構成管理システムを使って、 nova-compute サービスが確実に実行されているようにしている場合、 init ファイルを一時的に移動します。

    # mkdir /root/tmp
    # mv /etc/init/nova-compute.conf /root/tmp
    # mv /etc/init.d/nova-compute /root/tmp
    
  4. コンピュートノードをシャットダウンし、メンテナンスを実行し、ノードをオンラインに戻します。

  5. nova-compute サービスを起動します。

    # start nova-compute
    

    コマンドを取り消すことにより nova-compute を再有効化できます。

    # mv /root/tmp/nova-compute.conf /etc/init
    # mv /root/tmp/nova-compute /etc/init.d/
    
  6. ノードへの仮想マシンのスケジュールを有効化します。

    # openstack compute service set --enable c01.example.com nova-compute
    
  7. インスタンスを元のコンピュートノードにマイグレーションすることもできます。

コンピュートノードの再起動後

コンピュートノードを再起動した場合、まず正常に起動していることを検証します。これには、nova-compute サービスの動作を確認することが含まれます。

# ps aux | grep nova-compute
# status nova-compute

AMQP サーバーに正常に接続できることも確認します。

# grep AMQP /var/log/nova/nova-compute.log
2013-02-26 09:51:31 12427 INFO nova.openstack.common.rpc.common [-] Connected to AMQP server on 199.116.232.36:5672

コンピュートノードが正常に実行された後、そのコンピュートノードでホストされているインスタンスはどれも動作していないので、そのコンピュートノードにおいてホストされているインスタンスを処理する必要があります。ユーザーや顧客に対する SLA によっては、各インスタンスを開始し、正常に起動していることを確認する必要がある場合もあるでしょう。

インスタンス

以下のコマンドを実行して、コンピュートノードにホストしているインスタンスの一覧を作成できます。

# openstack server list --host c01.example.com --all-projects

一覧を取得した後、各インスタンスを起動するために openstack コマンドを使用できます。

# openstack server reboot <server>

注釈

予期せずシャットダウンしたときは、ブートに問題があるかもしれません。たとえば、インスタンスがルートパーティションにおいて fsck を実行する必要があるかもしれません。もしこうなっても、これを修復するためにダッシュボード VNC コンソールを使用できます。

インスタンスがブートしなければ、つまりブートしようとしても virsh list がインスタンスを表示しなければ、コンピュートノードにおいて以下のとおり実行します。

# tail -f /var/log/nova/nova-compute.log

再び openstack server reboot コマンドを実行してみてください。インスタンスがなぜブートできないかについて、エラーメッセージを確認すべきです。

多くの場合、エラーが libvirt の XML ファイル (/etc/libvirt/qemu/instance-xxxxxxxx.xml) の何かになります。以下のコマンドを実行することにより、インスタンスを再起動するのと同時に、強制的に XML ファイルを再作成できます:

# openstack server reboot --hard <server>

故障したインスタンスからの検査とデータ復旧

いくつかのシナリオでは、インスタンスが実行中であるにも関わらず、SSH 経由でアクセスできず、あらゆるコマンドに反応がありません。VNC コンソールがブート失敗やカーネルパニックのエラーメッセージを表示している可能性があります。これは仮想マシン自身においてファイルシステム破損の意味する可能性があります。ファイルを復旧したりインスタンスの中身を調査したりする必要があれば、qemu-nbd を使ってディスクをマウントできます。

警告

ユーザーのコンテンツやデータを参照したい場合、まず許可を得ましょう。

インスタンスのディスク (/var/lib/nova/instances/instance-xxxxxx/disk) にアクセスするには、以下の手順を実行します。

  1. virsh コマンドを使用して、インスタンスを一時停止します。

  2. qemu-nbd デバイスをディスクに接続します。

  3. qemu-nbd デバイスをマウントします。

  4. 検査後にディスクをアンマウントします。

  5. qemu-nbd デバイスを切断します。

  6. インスタンスを再開します。

最後の手順 3 つを省略すると、OpenStack Compute がインスタンスを管理できなくなります。OpenStack Compute により発行されるすべてのコマンドに対する応答が失敗し、シャットダウンしているように見えます。

ディスクファイルをマウントすると、それにアクセスでき、ファイルとディレクトリ構造を持つ通常のディレクトリのように取り扱えます。しかしながら、どのファイルの編集も操作もしないことをお薦めします。なぜなら、それにより アクセス制御リスト (ACL) が変更されたり、起動できるインスタンスが起動できなくなる場合があるからです。ACL は、アカウントがファイルやディレクトリーにどの操作を実行できるのか判断するために使用されます。

  1. virsh コマンドを使用してインスタンスを一時停止します。内部 ID を記録します。

    # virsh list
    Id Name                 State
    ----------------------------------
     1 instance-00000981    running
     2 instance-000009f5    running
    30 instance-0000274a    running
    
    # virsh suspend 30
    Domain 30 suspended
    
  2. 次のコマンドを使用しサーバIDをリスト化することで、各インスタンスのIDを見つけてください。

    # openstack server list
    +--------------------------------------+-------+---------+-----------------------------+------------+
    | ID                                   | Name  | Status  | Networks                    | Image Name |
    +--------------------------------------+-------+---------+-----------------------------+------------+
    | 2da14c5c-de6d-407d-a7d2-2dd0862b9967 | try3  | ACTIVE  | finance-internal=10.10.0.4  |            |
    | 223f4860-722a-44a0-bac7-f73f58beec7b | try2  | ACTIVE  | finance-internal=10.10.0.13 |            |
    +--------------------------------------+-------+---------+-----------------------------+------------+
    
  3. qemu-nbd デバイスをディスクに接続します。

    # cd /var/lib/nova/instances/instance-0000274a
    # ls -lh
    total 33M
    -rw-rw---- 1 libvirt-qemu kvm  6.3K Oct 15 11:31 console.log
    -rw-r--r-- 1 libvirt-qemu kvm   33M Oct 15 22:06 disk
    -rw-r--r-- 1 libvirt-qemu kvm  384K Oct 15 22:06 disk.local
    -rw-rw-r-- 1 nova         nova 1.7K Oct 15 11:30 libvirt.xml
    # qemu-nbd -c /dev/nbd0 `pwd`/disk
    
  4. qemu-nbd デバイスをマウントします。

    qemu-nbd デバイスはインスタンスのディスクの個々のパーティションを別々のデバイスとしてエクスポートしようとします。たとえば、ディスクが vda で、ルートパーティションが vda1 の場合、qemu-nbd はそれぞれ /dev/nbd0/dev/nbd0p1 としてデバイスをエクスポートします。

    # mount /dev/nbd0p1 /mnt/
    

    これで /mnt の中身にアクセスできます。これは、インスタンスのディスクの 1 番目のパーティションに対応します。

    セカンダリディスクや一時ディスクを調査する際に、プライマリディスクとセカンダリディスクを同時にマウントしたければ、別のマウントポイントを使用してください。

    # umount /mnt
    # qemu-nbd -c /dev/nbd1 `pwd`/disk.local
    # mount /dev/nbd1 /mnt/
    # ls -lh /mnt/
    total 76K
    lrwxrwxrwx.  1 root root    7 Oct 15 00:44 bin -> usr/bin
    dr-xr-xr-x.  4 root root 4.0K Oct 15 01:07 boot
    drwxr-xr-x.  2 root root 4.0K Oct 15 00:42 dev
    drwxr-xr-x. 70 root root 4.0K Oct 15 11:31 etc
    drwxr-xr-x.  3 root root 4.0K Oct 15 01:07 home
    lrwxrwxrwx.  1 root root    7 Oct 15 00:44 lib -> usr/lib
    lrwxrwxrwx.  1 root root    9 Oct 15 00:44 lib64 -> usr/lib64
    drwx------.  2 root root  16K Oct 15 00:42 lost+found
    drwxr-xr-x.  2 root root 4.0K Feb  3  2012 media
    drwxr-xr-x.  2 root root 4.0K Feb  3  2012 mnt
    drwxr-xr-x.  2 root root 4.0K Feb  3  2012 opt
    drwxr-xr-x.  2 root root 4.0K Oct 15 00:42 proc
    dr-xr-x---.  3 root root 4.0K Oct 15 21:56 root
    drwxr-xr-x. 14 root root 4.0K Oct 15 01:07 run
    lrwxrwxrwx.  1 root root    8 Oct 15 00:44 sbin -> usr/sbin
    drwxr-xr-x.  2 root root 4.0K Feb  3  2012 srv
    drwxr-xr-x.  2 root root 4.0K Oct 15 00:42 sys
    drwxrwxrwt.  9 root root 4.0K Oct 15 16:29 tmp
    drwxr-xr-x. 13 root root 4.0K Oct 15 00:44 usr
    drwxr-xr-x. 17 root root 4.0K Oct 15 00:44 var
    
  5. 調査を完了すると、マウントポイントをアンマウントし、qemu-nbd デバイスを解放します。

    # umount /mnt
    # qemu-nbd -d /dev/nbd0
    /dev/nbd0 disconnected
    
  6. virsh を使用して、インスタンスを再開します。

    # virsh list
    Id Name                 State
    ----------------------------------
     1 instance-00000981    running
     2 instance-000009f5    running
    30 instance-0000274a    paused
    
    # virsh resume 30
    Domain 30 resumed
    

インスタンス間の Floating IP アドレスの管理

In an elastic cloud environment using the Public_AGILE network, each instance has a publicly accessible IPv4 & IPv6 address. It does not support the concept of OpenStack floating IP addresses that can easily be attached, removed, and transferred between instances. However, there is a workaround using neutron ports which contain the IPv4 & IPv6 address.

再利用できるポートの作成

  1. Public_AGILE ネットワークにポートを作成します。

    $ openstack port create port1 --network Public_AGILE
    
    Created a new port:
    +-----------------------+------------------------------------------------------+
    | Field                 | Value                                                |
    +-----------------------+------------------------------------------------------+
    | admin_state_up        | UP                                                   |
    | allowed_address_pairs |                                                      |
    | binding_host_id       | None                                                 |
    | binding_profile       | None                                                 |
    | binding_vif_details   | None                                                 |
    | binding_vif_type      | None                                                 |
    | binding_vnic_type     | normal                                               |
    | created_at            | 2017-02-26T14:23:18Z                                 |
    | description           |                                                      |
    | device_id             |                                                      |
    | device_owner          |                                                      |
    | dns_assignment        | None                                                 |
    | dns_name              | None                                                 |
    | extra_dhcp_opts       |                                                      |
    | fixed_ips             | ip_address='96.118.182.106',                         |
    |                       | subnet_id='4279c70a-7218-4c7e-94e5-7bd4c045644e'     |
    |                       | ip_address='2001:558:fc0b:100:f816:3eff:fefb:45fb',  |
    |                       | subnet_id='11d8087b-6288-4129-95ff-42c3df0c1df0'     |
    | id                    | 3871bf29-e963-4701-a7dd-8888dbaab375                 |
    | ip_address            | None                                                 |
    | mac_address           | fa:16:3e:e2:09:e0                                    |
    | name                  | port1                                                |
    | network_id            | f41bd921-3a59-49c4-aa95-c2e4496a4b56                 |
    | option_name           | None                                                 |
    | option_value          | None                                                 |
    | port_security_enabled | True                                                 |
    | project_id            | 52f0574689f14c8a99e7ca22c4eb572                      |
    | qos_policy_id         | None                                                 |
    | revision_number       | 6                                                    |
    | security_groups       | 20d96891-0055-428a-8fa6-d5aed25f0dc6                 |
    | status                | DOWN                                                 |
    | subnet_id             | None                                                 |
    | updated_at            | 2017-02-26T14:23:19Z                                 |
    +-----------------------+------------------------------------------------------+
    
  2. If you know the fully qualified domain name (FQDN) that will be assigned to the IP address, assign the port with the same name:

    $ openstack port create "example-fqdn-01.sys.example.com" --network Public_AGILE
    
    Created a new port:
    +-----------------------+------------------------------------------------------+
    | Field                 | Value                                                |
    +-----------------------+------------------------------------------------------+
    | admin_state_up        | UP                                                   |
    | allowed_address_pairs |                                                      |
    | binding_host_id       | None                                                 |
    | binding_profile       | None                                                 |
    | binding_vif_details   | None                                                 |
    | binding_vif_type      | None                                                 |
    | binding_vnic_type     | normal                                               |
    | created_at            | 2017-02-26T14:24:16Z                                 |
    | description           |                                                      |
    | device_id             |                                                      |
    | device_owner          |                                                      |
    | dns_assignment        | None                                                 |
    | dns_name              | None                                                 |
    | extra_dhcp_opts       |                                                      |
    | fixed_ips             | ip_address='96.118.182.107',                         |
    |                       | subnet_id='4279c70a-7218-4c7e-94e5-7bd4c045644e'     |
    |                       | ip_address='2001:558:fc0b:100:f816:3eff:fefb:65fc',  |
    |                       | subnet_id='11d8087b-6288-4129-95ff-42c3df0c1df0'     |
    | id                    | 731c3b28-3753-4e63-bae3-b58a52d6ccca                 |
    | ip_address            | None                                                 |
    | mac_address           | fa:16:3e:fb:65:fc                                    |
    | name                  | example-fqdn-01.sys.example.com                      |
    | network_id            | f41bd921-3a59-49c4-aa95-c2e4496a4b56                 |
    | option_name           | None                                                 |
    | option_value          | None                                                 |
    | port_security_enabled | True                                                 |
    | project_id            | 52f0574689f14c8a99e7ca22c4eb5720                     |
    | qos_policy_id         | None                                                 |
    | revision_number       | 6                                                    |
    | security_groups       | 20d96891-0055-428a-8fa6-d5aed25f0dc6                 |
    | status                | DOWN                                                 |
    | subnet_id             | None                                                 |
    | updated_at            | 2017-02-26T14:24:17Z                                 |
    +-----------------------+------------------------------------------------------+
    
  3. インスタンスの作成時にポートを使用します。

    $ openstack server create --flavor m1.medium --image ubuntu.qcow2 \
      --key-name team_key --nic port-id=PORT_ID \
      "example-fqdn-01.sys.example.com"
    
  4. インスタンスが適切な IP アドレスを持っていることを検証します。

    +--------------------------------------+----------------------------------------------------------+
    | Field                                | Value                                                    |
    +--------------------------------------+----------------------------------------------------------+
    | OS-DCF:diskConfig                    | MANUAL                                                   |
    | OS-EXT-AZ:availability_zone          | nova                                                     |
    | OS-EXT-SRV-ATTR:host                 | os_compute-1                                             |
    | OS-EXT-SRV-ATTR:hypervisor_hostname  | os_compute.ece.example.com                               |
    | OS-EXT-SRV-ATTR:instance_name        | instance-00012b82                                        |
    | OS-EXT-STS:power_state               | Running                                                  |
    | OS-EXT-STS:task_state                | None                                                     |
    | OS-EXT-STS:vm_state                  | active                                                   |
    | OS-SRV-USG:launched_at               | 2016-11-30T08:55:27.000000                               |
    | OS-SRV-USG:terminated_at             | None                                                     |
    | accessIPv4                           |                                                          |
    | accessIPv6                           |                                                          |
    | addresses                            | public=172.24.4.236                                      |
    | config_drive                         |                                                          |
    | created                              | 2016-11-30T08:55:14Z                                     |
    | flavor                               | m1.medium (103)                                          |
    | hostId                               | aca973d5b7981faaf8c713a0130713bbc1e64151be65c8dfb53039f7 |
    | id                                   | f91bd761-6407-46a6-b5fd-11a8a46e4983                     |
    | image                                | Example Cloud Ubuntu 14.04 x86_64 v2.5 (fb49d7e1-273b-...|
    | key_name                             | team_key                                                 |
    | name                                 | example-fqdn-01.sys.example.com                          |
    | os-extended-volumes:volumes_attached | []                                                       |
    | progress                             | 0                                                        |
    | project_id                           | 2daf82a578e9437cab396c888ff0ca57                         |
    | properties                           |                                                          |
    | security_groups                      | [{u'name': u'default'}]                                  |
    | status                               | ACTIVE                                                   |
    | updated                              | 2016-11-30T08:55:27Z                                     |
    | user_id                              | 8cbea24666ae49bbb8c1641f9b12d2d2                         |
    +--------------------------------------+----------------------------------------------------------+
    
  5. netcat ユーティリティーを使用してポート接続を確認します。

    $ nc -v -w 2 96.118.182.107 22
    Ncat: Version 7.00 ( https://nmap.org/ncat )
    Ncat: Connected to 96.118.182.107:22.
    SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
    

インスタンスからポートの切断

  1. インスタンスに対応するポートを見つけます。例:

    $ openstack port list | grep -B1 96.118.182.107
    
    | 731c3b28-3753-4e63-bae3-b58a52d6ccca | example-fqdn-01.sys.example.com | fa:16:3e:fb:65:fc | ip_address='96.118.182.107', subnet_id='4279c70a-7218-4c7e-94e5-7bd4c045644e' |
    
  2. コマンド openstack port set を利用してインスタンスからポートを削除します。

    $ openstack port set 731c3b28-3753-4e63-bae3-b58a52d6ccca \
    --device "" --device-owner "" --no-binding-profile
    
  3. インスタンスを削除し、--nic port-id オプションを使用して新しいインスタンスを作成します。

Retrieve an IP address when an instance is deleted before detaching a port

The following procedure is a possible workaround to retrieve an IP address when an instance has been deleted with the port still attached:

  1. いくつか neutron ポートを起動します。

    $ for i in {0..10}; do openstack port create --network Public_AGILE \
    ip-recovery; done
    
  2. 失われた IP アドレス向けのポートを確認して、その名前を更新します。

    $ openstack port set 731c3b28-3753-4e63-bae3-b58a52d6ccca \
    --name "don't delete"
    
  3. 必要ないポートを削除します。

    $ for port in $(openstack port list | grep -i ip-recovery | \
    awk '{print $2}'); do openstack port delete $port; done
    
  4. 失われた IP アドレスがまだ見つからない場合、これらの手順をまた繰り返します。

ボリューム

影響するインスタンスもボリュームを接続していた場合、まずインスタンスとボリュームの UUID の一覧を生成します。

mysql> select nova.instances.uuid as instance_uuid,
       cinder.volumes.id as volume_uuid, cinder.volumes.status,
       cinder.volumes.attach_status, cinder.volumes.mountpoint,
       cinder.volumes.display_name from cinder.volumes
       inner join nova.instances on cinder.volumes.instance_uuid=nova.instances.uuid
       where nova.instances.host = 'c01.example.com';

以下のような結果を確認できます:

+--------------+------------+-------+--------------+-----------+--------------+
|instance_uuid |volume_uuid |status |attach_status |mountpoint | display_name |
+--------------+------------+-------+--------------+-----------+--------------+
|9b969a05      |1f0fbf36    |in-use |attached      |/dev/vdc   | test         |
+--------------+------------+-------+--------------+-----------+--------------+
1 row in set (0.00 sec)

次に、ボリュームを手動で切断し、再接続します。ここで X は適切なマウントポイントです。

# openstack server remove volume <instance_uuid> <volume_uuid>
# openstack server add volume <instance_uuid> <volume_uuid> --device /dev/vdX

上記を実行する前に、インスタンスが正常に起動し、ログイン画面になっていることを確認します。

コンピュートノード全体の故障

コンピュートノードは、クラウドコントローラーの障害と同じように故障します。マザーボードや他の種類のハードウェア障害により、コンピュートノード全体がオフラインになる可能性があります。これが発生した場合、そのコンピュートノードで動作中のインスタンスがすべて利用できなくなります。ちょうどクラウドコントローラーが発生した場合のように、インフラ監視機能がコンピュートノードの障害を検知しなくても、インスタンスが失われるので、ユーザーが気づくでしょう。

コンピュートノードが故障し、2〜3時間もしくはそれ以上たっても復旧できないと見込まれる場合、 /var/lib/nova/instances に共有ストレージを使用していれば、故障したノードで動作していたインスタンスをすべて再スタートすることができます。

これを実行するために、nova データベースにおいて以下のクエリーを実行することにより、故障したノードにおいてホストされているインスタンスの UUID の一覧を生成します。

mysql> select uuid from instances
       where host = 'c01.example.com' and deleted = 0;

次に、c01.example.com においてホストされていたすべてのインスタンスが、今度は c02.example.com でホストされることを伝えるために nova データベースを更新します。

mysql> update instances set host = 'c02.example.com'
       where host = 'c01.example.com' and deleted = 0;

If you're using the Networking service ML2 plug-in, update the Networking service database to indicate that all ports that used to be hosted on c01.example.com are now hosted on c02.example.com:

mysql> update ml2_port_bindings set host = 'c02.example.com'
       where host = 'c01.example.com';
mysql> update ml2_port_binding_levels set host = 'c02.example.com'
       where host = 'c01.example.com';

その後、openstack コマンドを使って、c01.example.com にあったすべてのインスタンスを再起動します。起動する際にインスタンスの XML ファイルを再生成します:

# openstack server reboot --hard <server>

最後に、 ボリューム のセクションで説明されているのと同じ方法を用いて、ボリュームを再接続します。

/var/lib/nova/instances

コンピュートノードの故障の話題に関連して、このディレクトリについては説明しておく価値があるでしょう。このディレクトリには、コンピュートノードにホストされているインスタンス用の libvirt KVM のファイル形式のディスクイメージが置かれます。共有ストレージ環境でクラウドを実行していなければ、このディレクトリはコンピュートノード全体で一つしかありません。

/var/lib/nova/instances には 2 種類のディレクトリがあります。

一つ目は _base ディレクトリです。ここには、そのコンピュートノードで起動されたそれぞれのイメージに関して、glance から取得したすべてのベースイメージのキャッシュが置かれます。_20 (または他の番号) で終わるファイルは一時ディスクのベースイメージです。

もう一つのディレクトリは instance-xxxxxxxx という名前です。これらのディレクトリはコンピュートノードにおいて実行中のインスタンスと対応します。中にあるファイルは _base ディレクトリにあるファイルのどれかと関連があります。これらは基本的に、元々の _base ディレクトリからの変更点のみ含む、差分ベースのファイルです。

/var/lib/nova/instances にあるすべてのファイルとディレクトリは一意に名前が付けられています。 _base にあるファイルは元となった glance イメージに対応する一意に名前が付けられています。また、instance-xxxxxxxx という名前が付けられたディレクトリは特定のインスタンスに対して一意にタイトルが付けられています。たとえば、あるコンピュートノードにある /var/lib/nova/instances のすべてのデータを他のノードにコピーしたとしても、ファイルを上書きすることはありませんし、また同じ一意な名前を持つイメージにダメージを与えることもありません。同じ一意な名前を持つものは本質的に同じファイルだからです。

この方法はドキュメントに書かれておらず、サポートされていない方法ですが、コンピュートノードが完全にオフラインになってしまったが、インスタンスがローカルに保存されているときに、この方法を使用できます。