[ English | 日本語 | Deutsch | Indonesia ]

计算节点故障和维护

有时,计算节点会意外崩溃,或者由于维护原因需要重启。

计划维护

如果由于计划维护(例如软件或硬件升级)需要重启计算节点,请执行以下步骤:

  1. 禁用将新的虚拟机调度到该节点,可以选择性地提供原因注释

    # 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. 逐个迁移所有实例

        # 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 控制台可能会显示启动失败或内核崩溃错误消息。这可能是 VM 本身文件系统损坏的迹象。如果您需要恢复文件或检查实例的内容,可以使用 qemu-nbd 挂载磁盘。

警告

如果您访问或查看用户的内容和数据,请先获得批准!

要访问实例的磁盘 (/var/lib/nova/instances/instance-xxxxxx/disk),请执行以下步骤:

  1. 使用 virsh 命令挂起实例。

  2. 将 qemu-nbd 设备连接到磁盘。

  3. 挂载 qemu-nbd 设备。

  4. 检查后卸载设备。

  5. 断开 qemu-nbd 设备。

  6. 恢复实例。

如果您不遵循最后三个步骤,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 的内容,它对应于实例磁盘的第一个分区。

    要检查辅助或临时磁盘,如果您希望同时挂载主盘和辅助盘,请使用替代挂载点

    # 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
    

实例之间的浮动 IP 地址管理

在使用 Public_AGILE 网络的弹性云环境中,每个实例都有一个可公开访问的 IPv4 和 IPv6 地址。它不支持 OpenStack 浮动 IP 地址的概念,这些地址可以轻松地附加、删除和传输到实例之间。但是,可以使用包含 IPv4 和 IPv6 地址的 neutron 端口来解决此问题。

创建一个可重用的端口

  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. 如果您知道将分配给 IP 地址的完全限定域名 (FQDN),请使用相同的名称分配端口

    $ 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 选项创建一个新的实例。

在删除实例之前分离端口时,检索 IP 地址

以下过程是检索 IP 地址的一种可能的解决方法,当实例已删除并且端口仍然附加时:

  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

请确保实例已成功启动并且处于登录屏幕上,然后再执行上述操作。

完全计算节点故障

计算节点可能以云控制器可能发生故障的方式发生故障。主板故障或其他类型的硬件故障可能导致整个计算节点离线。当发生这种情况时,在该计算节点上运行的所有实例将不可用。就像云控制器故障一样,如果您的基础设施监控未检测到故障的计算节点,您的用户会因为他们丢失的实例而通知您。

如果计算节点发生故障并且在几个小时内(或根本无法)修复,如果您使用共享存储来存储 /var/lib/nova/instances,则可以重新启动托管在该故障节点上的所有实例。

为此,通过在 nova 数据库上运行以下查询来生成托管在该故障节点上的实例 UUID 列表:

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

接下来,更新 nova 数据库以指示以前托管在 c01.example.com 上的所有实例现在都托管在 c02.example.com 上

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

如果您使用的是 Networking 服务 ML2 插件,请更新 Networking 服务数据库以指示以前托管在 c01.example.com 上的所有端口现在都托管在 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 包含两种类型的目录。

第一种是 _base 目录。它包含从 glance 缓存的所有基本镜像,用于在该计算节点上启动的每个唯一镜像。以 _20(或不同的数字)结尾的文件是临时的基本镜像。

其他目录标题为 instance-xxxxxxxx。这些目录对应于在该计算节点上运行的实例。内部文件与 _base 目录中的一个文件相关。它们本质上是基于差异的文件,仅包含从原始 _base 目录所做的更改。

/var/lib/nova/instances 中的所有文件和目录都具有唯一的名称。_base 中的文件对于它们所基于的 glance 镜像具有唯一的标题,并且目录名称 instance-xxxxxxxx 对于该特定实例具有唯一的标题。例如,如果您将 /var/lib/nova/instances 上的所有数据从一个计算节点复制到另一个计算节点,您不会覆盖任何文件或损坏具有相同唯一名称的镜像,因为它们本质上是相同的文件。

虽然这种方法未记录或受支持,但您可以在计算节点永久离线但您本地存储实例时使用它。