> 技术文档 > Openstack 云计算秘籍(三)_openstack image list

Openstack 云计算秘籍(三)_openstack image list


原文:annas-archive.org/md5/2ca02d976e2dad8eba9e4b7090f2058d

译者:飞龙

协议:CC BY-NC-SA 4.0

第六章:Glance – OpenStack 镜像服务

在本章中,我们将涵盖以下主题:

  • OpenStack 镜像服务介绍

  • 管理镜像

  • 使用镜像快照

  • 使用镜像元数据

  • 保护镜像

  • 禁用镜像

  • 创建自定义镜像

OpenStack 镜像服务介绍

OpenStack 镜像服务,也称为 Glance,是一个允许用户注册、发现和获取虚拟机镜像,以便在 OpenStack 云中使用的服务。通过 OpenStack 镜像服务提供的镜像可以存储在多种格式和后端位置中,从本地文件系统存储到分布式文件系统,如 OpenStack 对象存储(Swift)和 Ceph。

OpenStack 镜像服务由两个主要组件组成:glance-api服务和glance-registry服务。用户在使用 OpenStack 客户端执行创建、列出、删除或管理镜像等命令时,间接与glance-api服务进行交互。glance-registry服务负责连接后端数据库,并存储或检索镜像。

管理镜像

在 OpenStack 环境中,可以使用openstack命令行工具、Horizon 仪表板或通过 Glance 基于 REST 的 API 直接进行镜像管理。镜像可以直接从互联网获取,或者使用virshvirt-managergrowpartcloud-init等工具创建和操作。自定义镜像创建将在本章后面进行介绍。

上传镜像

在 OpenStack 中创建镜像时,必须提供描述镜像的属性。这些属性包括镜像名称、磁盘格式和容器格式。镜像可以是公共的、私有的,或者在多个项目之间共享。

准备工作

以下示例所需的镜像可以从以下位置下载:

  • Ubuntu: cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-disk1.img

  • CirrOS: download.cirros-cloud.net/0.3.5/cirros-0.3.5-i386-disk.img

注意

随着时间的推移,网络上的镜像位置可能会发生变化,本书中的 URL 可能不可用。您可以自由地将这些示例中的任何 URL 替换为已知且有效的 URL。

上传镜像时,确保您已经正确获取凭证或已通过其他方式正确认证。

上传镜像时,您至少需要以下信息:

  • 镜像名称

  • 磁盘格式

  • 镜像位置

对于我们的第一个示例,将使用以下内容:

  • 镜像名称: COOKBOOK_CIRROS_IMAGE

  • 磁盘格式: qcow2

  • 镜像位置: /tmp/cirros-0.3.5-i386-disk.img

对于我们的第二个示例,将使用以下内容:

  • 镜像名称: COOKBOOK_UBUNTU_IMAGE

  • 磁盘格式: qcow2

  • 镜像位置: /tmp/xenial-server-cloudimg-amd64-disk1.img

如何操作……

在系统上安装 OpenStack 客户端后,我们现在可以通过以下步骤上传镜像:

  1. 将 CirrOS 镜像下载到 /tmp 目录:

    wget https://download.cirros-cloud.net/0.3.5/cirros-0.3.5-i386-disk.img -O /tmp/cirros-0.3.5-i386-disk.img
  2. 上传 CirrOS 镜像:

    openstack image create COOKBOOK_CIRROS_IMAGE \\--disk-format qcow2 \\--file /tmp/cirros-0.3.5-i386-disk.img

    输出将类似于以下内容:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00117.jpeg

    对 Ubuntu 镜像重复执行上述步骤:

  3. 将 Ubuntu 镜像下载到 /tmp 目录:

    wget https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-disk1.img -O /tmp/xenial-server-cloudimg-amd64-disk1.img
  4. 上传 Ubuntu 镜像:

    openstack image create COOKBOOK_UBUNTU_IMAGE \\--disk-format qcow2 \\--file /tmp/xenial-server-cloudimg-amd64-disk1.img

它是如何工作的…

创建镜像的语法如下:

openstack image create IMAGE_NAME \\--disk-format DISK_FORMAT \\--file FILE_LOCATION \\[--public | --private | --shared | --community]

使用 OpenStack 客户端创建镜像时,指定的文件将被上传到 OpenStack 镜像库。镜像库可以是 Glance 配置文件中指定的本地目录或卷,也可以是由 Swift、Ceph、Rackspace Cloud Files 等提供的对象存储。

disk-format 参数定义了镜像使用的虚拟磁盘格式。可选项包括 amiariakivhdvmdkrawqcow2vhdxvdiisoploopqcow2 格式在基于 OpenStack 的云环境中广泛使用,特别是在运行 QEMU/KVM 虚拟化的环境中,它支持较小的镜像文件大小、写时复制(copy-on-write)支持以及各种压缩和加密技术。默认格式为 raw

当将镜像上传到由 Ceph 支持的 Glance 存储时,镜像必须为 raw 格式,否则无法正常工作。可以使用 qemu-img 命令识别镜像的格式,同时该命令也可以用来将镜像从一种格式转换为另一种格式。

下面是一个将 qcow2 格式的镜像转换为 raw 格式的示例:

qemu-img convert -f qcow2 -O raw image.qcow2 image.raw

提示

更多使用 qemu-img 命令的示例可以在 OpenStack 文档中找到:

docs.openstack.org/image-guide/convert-images.html

file 参数定义了镜像文件相对于运行 OpenStack 客户端的位置。OpenStack 客户端将镜像上传到 OpenStack 镜像库,并根据 Glance 中的设置进行存储。

当指定时,--public 选项将镜像标记为所有云中的项目都可以访问。或者,--private 选项将镜像标记为仅创建它的项目可以访问。默认情况下,所有创建的镜像都标记为 shared,并且可以与另一个项目共享。然而,在创建时,镜像只能由创建它的项目看到。--shared--community 选项将在本章后续的 共享镜像 章节中讨论。

列出镜像

要列出 OpenStack 镜像服务库中的镜像,请使用以下 OpenStack 客户端命令:

openstack image list

输出将类似于以下内容:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00118.jpeg

查看镜像详情

可以使用以下 OpenStack 客户端命令查询单个镜像的详细信息:

openstack image show IMAGE_NAME_OR_ID

输出将类似于以下内容:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00119.jpeg

删除镜像

图像可以随时从 OpenStack 图像仓库中删除。但请记住,根据安装的 OpenStack 版本,删除图像可能会对迁移实例的能力产生不利影响。

注意

新版本的 OpenStack(Kilo 之后)不应受到此问题的影响。

准备工作

删除图像时,需要以下信息:

  • 图像名称或 ID

如何操作……

要在 OpenStack 中删除图像,请执行以下命令:

openstack image delete COOKBOOK_CIRROS_IMAGE

如果操作成功,则不会返回任何输出。要验证图像是否已不再可用,可以使用openstack image listopenstack image show命令。

下载图像

存在于 OpenStack 图像仓库中的图像可以在以后下载并传输到其他系统。

准备工作

要从 OpenStack 图像仓库下载图像,您必须拥有访问该图像的权限。下载图像时,至少需要以下详细信息:

  • 图像名称或 ID

  • 下载文件的目标位置

对于我们的示例,将使用以下内容:

  • 图像名称:COOKBOOK_UBUNTU_IMAGE

  • 下载位置:/tmp/my_downloaded_ubuntu_image.qcow2

如何操作……

在我们的系统上安装了 OpenStack 客户端后,我们现在可以使用以下命令从仓库中下载图像:

openstack image save COOKBOOK_UBUNTU_IMAGE \\--file /tmp/my_downloaded_ubuntu_image.qcow2

如果操作成功,则不会返回任何输出。使用ls命令列出已下载的文件:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00120.jpeg

分享图像

当图像为私有时,仅对创建或上传该图像的项目可用。另一方面,当图像为公共时,它对所有项目可用。OpenStack 图像服务提供了一种机制,允许这些私有图像在一部分项目之间共享。这使得在不向所有项目公开的情况下,更好地控制需要存在于不同项目中的图像。

在项目之间共享图像需要以下工作流程:

  • 租户 A 更新图像的共享能力

  • 租户 A 与租户 B 分享图像

  • 租户 B 接受或拒绝共享请求

准备工作

共享图像时,请确保您已通过身份验证为管理员,或是该图像的所有者。共享图像至少需要以下详细信息:

  • 图像名称或 ID

  • 项目名称或 ID

对于我们的示例,ADMIN 项目将与 FINANCE 项目共享图像。将使用以下内容:

  • 图像名称:COOKBOOK_UBUNTU_IMAGE

  • 项目名称:FINANCE

注意

有关如何在 OpenStack 中创建项目的说明,请参见本书的第三章,Keystone – OpenStack 身份服务

如何操作……

在我们的系统上安装了 OpenStack 客户端后,我们现在可以通过以下步骤共享图像:

  1. 使用FINANCE项目中用户的凭证配置环境:

    source finance_openrc
  2. 作为FINANCE项目中的用户,查看所有可用的图片:

    openstack image list

    如果没有可用的图片,输出将类似于以下内容:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00121.jpeg

    注意

    在此环境中,FINANCE项目没有可用的图片。

  3. 现在,使用 ADMIN 项目中用户的凭证配置环境:

    source openrc
  4. 更新 Ubuntu 镜像并使其可共享:

    openstack image set COOKBOOK_UBUNTU_IMAGE --shared

    不会返回任何输出。

  5. 与 FINANCE 项目共享 Ubuntu 镜像:

    openstack image add project COOKBOOK_UBUNTU_IMAGE FINANCE

    输出将类似于以下内容:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00122.jpeg

    注意

    此时,用户应通知FINANCE项目共享尝试并提供图片 ID。在此示例中,图片 ID 为d120a923-5246-4dca-8f52-51a951bffce5

  6. 使用FINANCE项目中用户的凭证重新配置环境:

    source finance_openrc
  7. 接受共享尝试:

    openstack image set d120a923-5246-4dca-8f52-51a951bffce5 --accept

    不会返回任何输出。

  8. 查看所有可用的图片:

    openstack image list

    输出将类似于以下内容:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00123.jpeg

它是如何工作的…

共享图片需要生产者使用openstack image add project命令,消费者使用openstack image set命令。此过程涉及生产者与消费者之间的沟通,超出了 OpenStack API,因为图片 ID 必须在它们之间共享。

生产者使用以下命令启动共享过程:

openstack image add project  

一旦共享,消费者可以使用以下方式接受或拒绝该尝试:

openstack image set  [--accept | --reject | --pending]

注意

将图片标记为pending使该图片在消费项目中不可用,但仍然保留稍后使其可用的可能性。

生产者可以使用以下命令撤销图片的共享:

openstack image remove project  

标记图片为共享的替代方法是将其可见性标记为community,使用--community选项。这允许用户将图片共享给所有项目,但仍然需要消费项目在图片出现在图片列表之前接受该图片。这减少了共享图片用户的管理负担,同时不会无谓地使所有项目的图片列表变得凌乱。

有关共享图片的更多信息,请访问docs.openstack.org/image-guide/share-images.html

使用图片快照

在 OpenStack 中,快照是反映实例在某个时间点状态的图片。快照通常用于备份实例或将实例从一个云迁移到另一个云,并且可以像普通图片一样与其他项目共享。

创建快照

可以使用openstack server image create命令在 OpenStack 中创建快照。

准备就绪

创建快照时,请确保您已作为管理员进行身份验证或是实例的所有者。您将需要以下详细信息:

  • 实例名称或 ID

  • 图片名称

对于我们的示例,将使用以下内容:

  • 实例名称:COOKBOOK_TEST_INSTANCE

  • 图片:COOKBOOK_TEST_SNAPSHOT_20170824

如何操作…

安装 OpenStack 客户端后,我们现在可以使用以下命令创建快照:

openstack server image create \\--name COOKBOOK_TEST_SNAPSHOT_20171016 \\COOKBOOK_TEST_INSTANCE

输出结果将类似于以下内容:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00124.jpeg

它是如何工作的…

图片快照使用以下语法创建:

openstack server image create [--name ] \\[--wait] \\

快照的创建会导致系统将实例的磁盘写入计算节点上的临时文件,并将其上传到 OpenStack 镜像服务作为新的图片。当实例的磁盘位于 Ceph 后端时,快照发生在后端本身,计算节点文件系统不参与其中。生成的快照/图片随后可以用于在同一云中启动新的实例,或者可以下载并复制到离线存储系统或其他云中。

name参数定义了图片存储在镜像库中的名称。

参数定义了从中拍摄快照的实例的名称或 ID。

如果指定了--wait选项,它会强制 OpenStack 在前台执行快照操作,这意味着在任务完成之前,CLI 将无法使用。

使用图片元数据

图片具有被称为元数据的属性,这些属性有助于描述图片及其与其他 OpenStack 组件的关系。应用于图片的元数据可以用于启用其他 OpenStack 服务中的特定功能,或根据 CPU 架构或特性等确定将实例调度到主机的方式,等等。

设置图片元数据

OpenStack 中的图片元数据可以通过openstack image set命令进行操作。--property参数可以用来通过key=value对设置其他属性。

准备工作

在设置图片元数据时,请确保您已认证为管理员或是该图片的所有者。至少需要以下信息:

  • 图片名称或 ID

  • 属性名称和值

在我们的示例中,将使用以下内容:

  • 图片名称:COOKBOOK_UBUNTU_IMAGE

  • 属性名称和值:architecture=m68k, os_distro=ubuntu

如何操作…

安装 OpenStack 客户端后,我们现在可以使用以下命令设置图片元数据:

openstack image set COOKBOOK_UBUNTU_IMAGE \\--property architecture=m68k \\--property os_distro=ubuntu

如果操作成功,则不会返回任何输出。然而,使用openstack image show将显示属性已被设置:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00125.jpeg

它是如何工作的…

在 OpenStack 中设置图片元数据时,属性会影响系统如何处理使用该图片的实例。属性如hypervisor_typearchitecture影响实例如何调度到主机,而其他属性如hw_disk_bushw_cdrom_bus则影响虚拟设备如何连接到实例。

注意

要根据镜像元数据调度实例,请确保在/etc/nova/nova.conf中的enabled_filters列表中包含\'ImagePropertiesFilter\'过滤器。这是大多数 OpenStack 安装的默认设置,包括本书中构建的环境。

在这种环境中,使用要求架构为m68k(Motorola 68000)的修改后镜像引导实例应导致以下错误:

NoValidHost: No valid host was found. There are not enough hosts available.

修改镜像以要求x86_64或完全删除该属性应允许根据其他定义的元数据或环境默认值来安排实例的调度。

在撰写本文时,可以在以下位置找到当前的镜像元数据属性列表:

docs.openstack.org/python-glanceclient/latest/cli/property-keys.html

删除图像元数据

在 OpenStack 中,可以使用openstack image unset命令来删除图像元数据。--property参数可用于取消单个属性的设置。

准备工作

在删除图像元数据时,请确保您已经作为管理员进行了身份验证,或者是镜像的所有者。至少需要以下详细信息:

  • 镜像名称或 ID

  • 属性名称

对于我们的示例,将使用以下内容:

  • 镜像名称:COOKBOOK_UBUNTU_IMAGE

  • 属性名称:architecture

如何操作…

在我们的系统上安装了 OpenStack 客户端后,现在可以使用以下命令取消设置图像元数据:

openstack image unset COOKBOOK_UBUNTU_IMAGE \\--property architecture

如果操作成功,则不返回任何输出。要验证已删除属性,请使用openstack image show命令。

保护图像

与其他 OpenStack 对象类似,图像和快照容易被用户意外删除。默认情况下,图像是不受保护的,这意味着可以随时由项目中的用户删除。以下各节将解释如何保护图像以确保其存活。

保护图像

可以使用openstack image set命令并带有--protected参数来保护图像。

准备工作

在保护镜像时,请确保您已经作为管理员进行了身份验证,或者是镜像的所有者。至少需要以下详细信息:

  • 镜像名称或 ID

对于我们的示例,将使用以下内容:

  • 镜像名称:COOKBOOK_UBUNTU_IMAGE

如何操作…

在我们的系统上安装了 OpenStack 客户端后,现在可以使用以下命令保护图像:

openstack image set COOKBOOK_UBUNTU_IMAGE --protected

如果操作成功,则不返回任何输出。使用openstack image show命令来查看镜像的状态:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00126.jpeg

工作原理…

当在 OpenStack 中保护图像时,用户无法删除该图像。尝试删除受保护的图像将导致类似以下的错误:

Failed to delete image with name or ID \'COOKBOOK_UBUNTU_IMAGE\': 403 Forbidden: Image d120a923-5246-4dca-8f52-51a951bffce5 is protected and cannot be deleted. (HTTP 403)Failed to delete 1 of 1 images.

保护图像是确保由许多用户和项目共享的云中快照和其他特殊图像保持完好的有用步骤。

解除图像保护

可以使用 openstack image set 命令与 --unprotected 参数解除镜像的保护。

准备工作

当解除保护镜像时,确保你已认证为管理员或是镜像的所有者。你至少需要以下信息:

  • 镜像名称或 ID

在我们的示例中,将使用以下内容:

  • 镜像名称:COOKBOOK_UBUNTU_IMAGE

如何操作…

在我们的系统上安装了 OpenStack 客户端后,我们现在可以使用以下命令解除镜像保护:

openstack image set COOKBOOK_UBUNTU_IMAGE --unprotected

如果操作成功,将不返回任何输出。使用 openstack image show 命令查看镜像的状态。

停用镜像

默认情况下,镜像在上传过程完成后即可使用。有时,可能需要停用镜像,以防止用户使用该镜像启动实例,尤其是当镜像可能过时但必须保留用于归档时。

停用镜像

可以使用 openstack image set 命令与 --deactivate 参数停用镜像。

准备工作

停用镜像时,确保你已认证为管理员或是镜像的所有者。你至少需要以下信息:

  • 镜像名称或 ID

在我们的示例中,将使用以下内容:

  • 镜像名称:COOKBOOK_UBUNTU_IMAGE

如何操作…

在我们的系统上安装了 OpenStack 客户端后,我们现在可以使用以下命令停用镜像:

openstack image set COOKBOOK_UBUNTU_IMAGE --deactivate

如果操作成功,将不返回任何输出。使用 openstack image show 命令查看镜像的状态:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00127.jpeg

工作原理…

当镜像在 OpenStack 中被停用时,用户无法使用该镜像启动实例。尝试使用停用镜像启动实例时,将出现类似以下的错误:

Image d120a923-5246-4dca-8f52-51a951bffce5 is not active. (HTTP 400) (Request-ID: req-fb43f34c-982b-4eeb-abb1-76c93ebc2b5f)

停用镜像是确保镜像被保留但无法使用的一个有用步骤。现有的使用该镜像的实例不会受到影响。

激活镜像

停用的镜像可以通过 openstack image set 命令与 --activate 参数重新激活。

准备工作

激活镜像时,确保你已认证为管理员或是镜像的所有者。你至少需要以下信息:

  • 镜像名称或 ID

在我们的示例中,将使用以下内容:

  • 镜像名称:COOKBOOK_UBUNTU_IMAGE

如何操作…

在我们的系统上安装了 OpenStack 客户端后,我们现在可以使用以下命令激活镜像:

openstack image set COOKBOOK_UBUNTU_IMAGE --activate

如果操作成功,将不返回任何输出。使用 openstack image show 命令查看镜像的状态。

创建自定义镜像

用户可以创建各种操作系统的自定义镜像,这些镜像可以在 OpenStack 环境中使用。诸如 cloud-init 之类的工具可以安装在镜像中,以提供一种在实例部署后进行引导的方法。

注意

cloud-init的使用超出了本书的范围。更多信息请参见cloud-init.io

准备就绪

首先,确保你使用的操作系统不是本书中所用的 OpenStack 环境。创建镜像所需的软件包和库可能与当前已安装的软件发生冲突,导致环境损坏。在本示例中,我们将使用配置为 Ubuntu 16.04 LTS 的虚拟机来创建自定义的 CentOS 7 镜像。

注意

配置 Ubuntu 16.04 LTS 操作系统的虚拟机超出了本书的范围。如果需要,也可以使用物理服务器代替虚拟机。

以下软件包是构建镜像所需的主机前置条件:

  • qemu-kvm

  • libvirt-bin

  • virt-manager

使用apt,通过以下命令安装软件包:

sudo apt updatesudo apt install qemu-kvm libvirt-bin virt-manager

如何操作…

在虚拟机内执行以下步骤以创建自定义镜像:

  1. 切换到你的主目录,并创建一个名为ks.cfg的 kickstart 文件,内容如下:

    cd ~/ installtexturl --url http://mirror.rackspace.com/CentOS/7/os/x86_64/lang en_US.UTF-8keyboard usnetwork --onboot yes --bootproto dhcp --noipv6timezone --utc America/Chicagozerombrclearpart --all --initlabelbootloader --location=mbr --append=\"crashkernel=auto\"part / --fstype=ext4 --size=1024 --growauthconfig --enableshadow --passalgo=sha512rootpw openstackfirewall --disableselinux --disabledskipxshutdown%packages@coreopenssh-serveropenssh-clientswgetcurlgitmanvimntp%end%post%end
  2. 创建一个空的 10GB 虚拟磁盘供 CentOS 虚拟机使用:

    sudo qemu-img create -f qcow2 \\/var/lib/libvirt/images/centos-7.qcow2 10G
  3. 执行以下命令以启动 CentOS 操作系统的无人值守安装:

    sudo virt-install --virt-type qemu \\--name centos-7 \\--ram 2048 \\--location=\"http://mirror.rackspace.com/CentOS/7/os/x86_64/\" \\--disk /var/lib/libvirt/images/centos-7.qcow2,format=qcow2 \\--network network=default \\--graphics vnc,listen=0.0.0.0 \\--noautoconsole \\--os-type=linux \\--os-variant=centos7.0 \\--initrd-inject ks.cfg \\--rng /dev/random \\--extra-args=\"inst.ks=file:/ks.cfg console=ttyS0,115200\"

    注意

    如果安装是在启用嵌套虚拟化的虚拟机内进行的,可能需要将virt-typekvm更改为qemu,以便虚拟机正确启动。如果没有嵌套虚拟化,使用kvm能获得更好的性能。

    返回的输出应类似于以下内容:

    Starting install...Retrieving file vmlinuz...  | 5.1 MB 00:00:01Retrieving file initrd.img...  | 41 MB 00:00:07Allocating \'centos-7.0-vm.img\'  | 5.0 GB 00:00:00Creating domain... | 0 B 00:00:00Domain installation still in progress. You can reconnect tothe console to complete the installation process.

    从主机登录到新创建的 CentOS 虚拟机,并使用openstack密码作为root用户登录。要退出控制台会话,请按Ctrl + ]

    virsh console centos-7

    要刷新控制台,请按Enter键。输出将类似于以下内容:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00128.jpeg

    客户机应正在启动,并且将显示实时控制台日志。安装过程是自动化的,可能会根据主机提供的资源而需要一段时间。

    安装完成时,输出将类似于以下内容:

    [ OK ] Reached target Shutdown.dracut Warning: Killing all remaining processesPowering off.[ 3388.611074] Power down.

    控制台会话应结束,你将返回到主机的提示符。

  4. 使用以下命令启动虚拟机:

    sudo virsh start centos-7

    从主机登录到 CentOS 虚拟机,并使用openstack密码作为root用户登录。要退出控制台会话,请按Ctrl + ]

    virsh console centos-7

    要刷新控制台,请按Enter键。输出将类似于以下内容:

    Connected to domain centos-7Escape character is ^]CentOS Linux 7 (Core)Kernel 3.10.0-693.el7.x86_64 on an x86_64localhost login: rootPassword:Last login: Wed Aug 30 09:02:14 on tty1[root@localhost ~]#
  5. 在来宾中,通过以下命令安装epel-releasecloud-init软件包:

    yum -y install epel-releaseyum -y install cloud-init cloud-utils cloud-utils-growpart
  6. 使用文本编辑器,将来宾的cloud.cfg文件(位于/etc/cloud/cloud.cfg)替换为以下内容:

    users:- defaultdisable_root: 1ssh_pwauth: 0locale_configfile: /etc/sysconfig/i18nmount_default_fields: [~, ~, \'auto\', \'defaults,nofail\', \'0\', \'2\']resize_rootfs_tmp: /devssh_deletekeys: 0ssh_genkeytypes: ~syslog_fix_perms: ~cloud_init_modules:- bootcmd- write-files- resizefs- set_hostname- update_hostname- update_etc_hosts- rsyslog- users-groups- sshcloud_config_modules:- mounts- locale- set-passwords- timezone- puppet- chef- salt-minion- mcollective- disable-ec2-metadata- runcmdcloud_final_modules:- rightscale_userdata- scripts-per-once- scripts-per-boot- scripts-per-instance- scripts-user- ssh-authkey-fingerprints- keys-to-console- phone-home- final-messagesystem_info: distro: rhel default_user: name: centos lock_passwd: True shell: /bin/bash sudo: [\"ALL=(ALL) NOPASSWD: ALL\"] paths: cloud_dir: /var/lib/cloud templates_dir: /etc/cloud/templates ssh_svcname: sshd

    注意

    cloud.cfg 的内容是以 YAML 格式构建的,在启动时由 cloud-init 进行解析。在这个示例中,访问实例的默认用户名是 centos,并且没有设置密码。相反,必须使用 SSH 密钥,并将其通过 OpenStack 元数据服务推送到实例。更多信息请参见 第五章, Nova – OpenStack 计算

  7. 确保虚拟机能够通过以下命令与元数据服务进行通信:

    echo \"NOZEROCONF=yes\" >> /etc/sysconfig/network
  8. 使用以下命令删除持久化规则:

    rm -rf /etc/udev/rules.d/70-persistent-net.rules
  9. 删除特定机器的 MAC 地址和 UUID。编辑 /etc/sysconfig/network-scripts/ifcfg-eth0 文件并删除以 HWADDRUUID 开头的行:

    sed -i \'/HWADDR/d\' /etc/sysconfig/network-scripts/ifcfg-eth0sed -i \'/UUID/d\' /etc/sysconfig/network-scripts/ifcfg-eth0
  10. 做出更改后,确保接口配置文件类似于以下内容:

    NAME=\"eth0\"ONBOOT=\"yes\"NETBOOT=\"yes\"IPV6INIT=\"no\"BOOTPROTO=\"dhcp\"TYPE=\"Ethernet\"DEFROUTE=\"yes\"PEERDNS=\"yes\"PEERROUTES=\"yes\"IPV4_FAILURE_FATAL=\"no\"

    注意

    如果您需要支持 IPv6,请相应地修改接口文件,确保使用该镜像的实例能够通过 DHCPv6 或 SLAAC 获取其 IPv6 地址。

  11. 使用以下命令清理各种文件和目录:

    yum clean allrm -rf /var/log/*rm -rf /tmp/*history -c
  12. 在虚拟机内部,使用以下命令干净地关闭虚拟机:

    shutdown -h now

    一旦虚拟机关闭,控制台会话应该结束,您将返回到主机上的提示符。在主机上将位于 /var/lib/libvirt/images/centos-7.qcow2 的磁盘文件传输到您的主目录,在那里它可以被传输出主机并转移到安装了 OpenStack 命令行工具的客户端。使用 OpenStack 客户端,将镜像上传到 OpenStack 镜像库:

    openstack image create MY_CENTOS_IMAGE \\--disk-format qcow2 \\--file ~/centos-7.qcow2

    输出应类似于以下内容:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00129.jpeg

    欲了解有关构建自定义镜像的更多信息,请访问 docs.openstack.org/image-guide/create-images-manually.html

第七章:Cinder – OpenStack 块存储

在本章中,我们将涵盖以下主题:

  • 配置 Cinder 卷服务

  • 创建卷

  • 将卷附加到实例

  • 从实例中分离卷

  • 删除卷

  • 使用卷快照

  • 配置卷类型

  • 启用卷加密

  • 配置卷的服务质量(QoS)

  • 重置卷状态

介绍

当一个基础计算实例被启动时,该实例的数据会存储在计算主机的磁盘上,直到实例运行结束,写入的数据在实例终止后并不持久——这意味着用户请求销毁该实例时,保存在磁盘上的任何数据都会丢失。OpenStack 提供了解决方案。是持久存储,可以附加到你正在运行的 OpenStack 计算实例上;最好的类比是你可以将 USB 驱动器连接到实例。像 USB 驱动器一样,你一次只能将实例附加到一台计算机上。

提示

目前有一个实验性功能,可以将一个卷附加到多个实例。我们在此不予涉及,也不建议目前使用该功能。

OpenStack 块存储项目的代号 Cinder 提供了接口和自动化功能,允许将存储卷连接到 OpenStack 计算实例。OpenStack 块存储与 Amazon 弹性块存储 (EBS) 非常相似——主要区别在于如何将卷呈现给正在运行的实例。在 OpenStack 计算中,一种方法是专门为此目的分配一台服务器,使得可以通过 iSCSI 暴露 LVM 卷组,特别命名为 cinder-volumes。然后通过一个名为 cinder-volume 的 OpenStack 服务,通过 iSCSI 将其呈现给实例。OpenStack 用户通过 Cinder API 与此服务交互。在我们的环境中,Cinder API 服务运行在三个控制节点上,通常这些服务会暴露在负载均衡器后面。本章中的配方使用了这种方法,通过 LVM 和 iSCSI 提供 Cinder 卷。然而,Cinder 支持由商业供应商和开源软件 (OSS) 社区提供的各种第三方存储提供商——例如,Cinder 的一个非常流行的后端提供商(而不是单独一台服务器运行 cinder-volume 服务)是 Ceph

提示

在本章中,“OpenStack 块存储”和“Cinder”这两个术语将交替使用。

配置 Cinder 卷服务

在本配方中,我们将使用 Openstack-Ansible 部署 Cinder 服务。我们假设你的环境已经按照第一章,使用 Ansible 安装 OpenStack中描述的配方进行部署。

准备工作

要使用 LVM 和 iSCSI 的 Cinder 卷,您需要一台(或多台)运行 Ubuntu 16.04 的主机。此外,您还需要确保卷主机可以由您的 Openstack-Ansible 部署主机进行管理。

以下是所需的:

  • 一个具有适当凭据的openrc文件

  • 访问openstack-ansible部署主机

  • 一个专用服务器,用于向实例提供 Cinder 卷:

    • 一个名为cinder-volumes的 LVM 卷组

    • 一个从部署主机可以访问的 IP 地址

如果您使用的是本书附带的实验环境,cinder-volume已部署到具有以下详细信息的主机:

  • cinder-volume API 服务主机 IP:172.29.236.10

  • cinder-volume服务主机 IP:OpenStack 管理调用通过172.29.236.100,存储流量通过172.29.244.100

如何做…

要部署cinder-volume服务,首先我们将创建一个 YAML 文件来描述如何部署 Cinder。然后我们将使用openstack-ansible来部署适当的服务。

要配置运行cinder-volume服务的 Cinder LVM 主机,请在部署主机上执行以下步骤:

  1. 首先,编辑/etc/openstack_deploy/openstack_user_config.yml文件,添加以下行,注意我们同时使用了 API 和存储网络的地址:

    ---storage-infra_hosts: controller-01: ip: 172.29.236.10storage_hosts: cinder-volume: ip: 172.29.236.100 container_vars: cinder_backends: limit_container_types: cinder_volume lvm: volume_group: cinder-volumes volume_driver: cinder.volume.drivers.lvm.LVMVolumeDriver volume_backend_name: LVM_iSCSI iscsi_ip_address: \"172.29.244.100\"

    提示

    可以向storage-infra_hosts部分添加更多节点以匹配您的环境。请注意,我们引用了来自容器网络(172.29.236)的storage_hostsstorage-infra_hosts IP,并且我们将在存储网络(172.29.244)上将实际的 iSCSI 卷呈现给实例。

  2. 现在编辑/etc/openstack_deploy/user_variables.yml文件,添加以下行。此处显示的是 OpenStack-Ansible 部署的默认值;如有必要,请根据您的环境进行编辑:

    ## Cinder iscsicinder_iscsi_helper: tgtadmcinder_iscsi_iotype: fileiocinder_iscsi_num_targets: 100cinder_iscsi_port: 3260
  3. 使用 LVM 时,如我们所做的那样,我们必须告诉 OpenStack-Ansible不要将服务部署到容器中(通过设置is_metal: true)。确保/etc/openstack_deploy/env.d/cinder.yml文件包含以下内容:

    ---container_skel: cinder_volumes_container: properties: is_metal: true
  4. 由于我们在本示例中专门选择使用LVMVolumeDriver服务安装 Cinder,因此我们必须确保设置为运行cinder-volume服务的主机(或主机)在部署 Cinder 之前已创建了一个名为cinder-volumes卷组。执行以下步骤以创建此重要的卷组。以下示例假设有一个额外的磁盘,在/dev/sdb,我们将用作此目的:

    pvcreate /dev/sdbvgcreate cinder-volumes /dev/sdb

    这将返回如下所示的输出:

    Physical volume \"/dev/sdb1\" successfully createdVolume group \"cinder-volumes\" successfully created

    提示

    提示:创建cinder-volumes逻辑卷组VG)仅在我们选择volume_driver类型为cinder.volume.drivers.lvm.LVMVolumeDriver时才需要创建。Cinder 还提供其他后端,这些后端不需要执行此步骤。

  5. 我们现在可以使用openstack-ansible命令部署 Cinder 服务:

    cd /opt/openstack-ansible/playbooksopenstack-ansible os-cinder-install.yml

    请注意,Ansible 的输出在此已被省略。如果成功,Ansible 会报告安装成功,或者向您提供有关失败步骤的信息。

    提示

    您是否使用了多个storage-infra_hosts?这些是 Cinder API 服务器。由于这些服务器位于负载均衡器后面,请确保您已将负载均衡器的 VIP 更新为这些新节点的 IP 地址。Cinder 服务运行在端口8776。如果您使用的是通过 OpenStack-Ansible 安装的 HAProxy,您还必须运行以下命令:

    openstack-ansible haproxy-install.yml
  6. 通过以下检查从 OpenStack 客户端或控制节点上的任何一个实用容器中验证 Cinder 服务是否正在运行,如下所示:

    lxc-attach --name $(lxc-ls -1 | grep util)source openrccinder service-list

    这将返回如下的输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00130.jpeg

它是如何工作的…

为了使用某个主机作为cinder-volume服务器,我们首先需要确保已创建名为cinder-volumes的逻辑卷组(LVM VG)。

提示

提示:您可以将卷组重命名为除cinder-volumes之外的其他名称;然而,重命名的理由非常少。如果确实需要这么做,请确保/etc/openstack_deploy/openstack_user_config.yml中的volume_group:参数与您创建的 LVM 卷组名称匹配。

完成此步骤后,我们将配置我们的 OpenStack-Ansible 部署,指定我们的cinder-volume服务器(如storage_hosts部分所示)以及运行 API 服务的服务器(如storage-infra_hosts部分所示)。然后,我们将使用openstack-ansible将软件包部署到控制节点和我们指定的 Cinder 卷服务器上。

请注意,如果您使用多个网络或 VLAN 段,请相应地配置您的 OpenStack-Ansible 部署。本书中介绍的存储网络应当用于 iSCSI 流量(也就是说,当一个卷附加到一个实例时),并且它与专用于 API 流量和服务间流量的容器网络是分开的。

在我们的示例中,cinder-volume使用 iSCSI 作为将卷附加到实例的机制;然后,openstack-ansible会安装运行 iSCSI 目标所需的软件包。

OpenStack-Ansible 提供了部署任何支持 Cinder 所需的更改的额外好处。这包括在 Keystone 中创建该服务并配置 Nova 以支持卷后端。

创建卷

现在我们已经创建了 Cinder 卷服务,我们可以为我们的实例创建卷。我们将在客户端环境中使用 Python-OpenStack 客户端和python-cinderclient库来执行此操作;因此,我们正在为我们的项目(租户)创建特定的卷。

提示

请参考第二章,OpenStack 客户端,了解更多关于安装和配置 OpenStack 客户端的信息。

准备工作

创建卷需要以下内容:

  • openstack 命令行客户端

  • 一个包含适当凭证的 openrc 文件,适用于当前环境

  • 期望的卷名称

  • 期望的卷大小,以 GiB 为单位

对于我们的示例,以下是这些信息:

  • 卷名称:cookbook.volume

  • 大小:10 GiB

如何操作…

执行以下步骤以创建卷:

我们只需使用以下命令创建卷,然后将其附加到我们的实例:

openstack volume create --size 10 --description \"Cookbook Volume\" cookbook.volume

完成后,命令会返回以下输出:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00131.jpeg

它是如何工作的…

创建卷非常简单。使用 openstack 客户端,我们提供 volume 上下文和 create 操作,语法如下:

openstack volume create --size size_GiB --description \"meaningful description\" volume_name

在这里,volume_name 可以是任何不包含空格的任意名称。

由于我们使用的服务器运行 cinder-volume 服务,我们可以使用常规的 LVM 工具查看 cinder-volumes 上的实际 LVM 卷,如下所示(确保你以 root 用户身份登录到我们指定的存储主机服务器):

lvdisplay cinder-volumes --- Logical volume --- LV Path /dev/cinder-volumes/volume-bb7a7d2c-8069-4924-a18e-8fb398584a5d LV Name volume-bb7a7d2c-8069-4924-a18e-8fb398584a5d VG Name cinder-volumes LV UUID XqZY27-Ei32-EEdC-3UtE-MR6e-2EKw-XCvIGt LV Write Access read/write LV Creation host, time cinder-volume, 2017-09-22 20:25:17 +0000 LV Status  available # open  0 LV Size 10.00 GiB Current LE 2560 Segments  1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 252:2

还有更多…

默认情况下,Cinder 卷像物理磁盘一样工作,即它们一次只能附加到一个实例。然而,对于需要磁盘在多个实例之间共享的工作负载,您可以在创建卷时传递 --multi-attach 标志,使得该卷可以附加到多个实例:

openstack volume create --multi-attach --description \"description\" --size size_GiB volume_name

提示

提醒

该功能相当新,并被视为生产环境中的实验性功能,它并不替代像 NFS 这样的共享存储服务。NFS 支持锁定,允许多个客户端读取和写入同一个挂载点。而多重附加块存储不支持锁定。因此,一个有效的使用场景可能是一个主/从服务的场景,其中数据应仅由一个实例在同一时间写入,但在故障转移时能立即访问数据是有益的。

将卷附加到实例

现在我们有了一个可用的磁盘卷,可以将其附加到任何实例。我们将使用 openstack server volume add 命令来执行此操作。

准备就绪

要将卷附加到实例,您将需要以下内容:

  • openstack 命令行客户端

  • 一个包含适当凭证的 openrc 文件,适用于当前环境

  • 要附加的卷的 名称ID

  • 要附加卷的实例的 名称ID

对于我们的示例,这些值如下:

  • 卷:cookbook.volume

  • 实例:cookbook.test

如何操作…

执行以下步骤,将卷附加到实例上,使用 openstack 客户端:

  1. 首先,列出正在运行的实例,以获取我们实例的 ID:

    openstack server list -c Name -c ID -f table

    下面是一个示例,展示了我们正在运行的实例 cookbook.test

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00132.jpeg

  2. 现在列出可用卷,以获取我们卷的 ID:

    openstack volume list

    这展示了我们需要的卷信息:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00133.jpeg

  3. 使用实例的名称或 ID,我们将按照以下方式将卷附加到实例:

    openstack server add volume cookbook.test cookbook.volume --device /dev/vdc

    当命令成功执行时,不会输出任何内容。

    请注意,--device选项并非始终有效,具体取决于操作系统和镜像类型。执行任何操作之前,始终检查目标实例操作系统为新卷分配了哪个设备。

    提示

    提示:在 OpenStack 中,卷或服务器名称不需要唯一;如果卷和服务器名称不唯一,请使用分配的 ID 代替名称。在前面的示例中,这样也能实现相同的目标:

    openstack server add volume 90654098-477f-417f-b102-453c0f1f9119 daeddd6c-908a-4ea8-8632-d93d198c2621 --device /dev/vdb
  4. 现在我们将在运行中的实例内执行操作。登录到实例并验证卷是否已附加:

    lsblk

    这将列出可供我们实例使用的块设备。在这里,我们可以看到我们的卷作为/dev/vdb已附加,但尚未挂载:

    NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsr0 11:0 1 558K 0 romvda 253:0 0 2.2G 0 disk`-vda1 253:1 0 2.2G 0 part /vdb 253:16 0 10G 0 disk
  5. 我们应该看到10G的空间可供运行中的实例使用。由于这是一个新的卷,就像为系统添加一个全新的磁盘。我们需要先格式化它以供使用,然后将其挂载到文件系统中:

    sudo mkfs.ext4 /dev/vdbsudo mkdir /mnt1sudo mount /dev/vdb /mnt1

    提示

    提示:使用 Cinder 创建的卷是持久存储卷;格式化卷(磁盘)只需要执行一次。如果将来需要将此数据卷重新附加到另一个实例,请不要重新格式化该磁盘!

  6. 我们现在应该看到新附加的磁盘可用在/mnt1

    df -h

    这将显示类似以下的输出:

    Filesystem Size Used Avail Use% Mounted onudev 238M 0 238M 0% /devtmpfs 49M 1.8M 48M 4% /run/dev/vda1 2.1G 843M 1.3G 41% /tmpfs 245M 0 245M 0% /dev/shmtmpfs 5.0M 0 5.0M 0% /run/locktmpfs 245M 0 245M 0% /sys/fs/cgrouptmpfs 49M 0 49M 0% /run/user/1000/dev/vdb 9.8G 23M 9.2G 1% /mnt1

它是如何工作的…

附加一个的 Cinder 卷就像将一个未格式化的 USB 闪存盘插入计算机。当它第一次需要使用时,必须先格式化才能使用。

提示

在后续使用此磁盘(将来连接到其他实例时),您无需执行此格式化步骤。

openstack客户端中,server add volume选项的语法如下:

openstack server add volume instance_ID volume_ID --device /dev/device_ID

instance_ID 是通过openstack server list返回的,我们希望将卷附加到的实例 ID。

volume_ID 是通过openstack volume list返回的卷 ID。

device_ID 是在实例上创建的设备,用于挂载卷。请记住,这个参数有时可以忽略;因此,可以将其视为仅供传递给正在运行的实例的提示。

从实例中卸载卷

通常,Cinder 卷一次只能附加到一个实例。因此,您需要先从一个实例卸载卷,再将其附加到另一个实例。要卸载卷,我们将使用另一个 OpenStack 客户端命令,叫做openstack server remove volume

准备工作

要从实例中卸载卷,您需要以下内容:

  • openstack命令行客户端

  • 带有适当凭据的openrc文件

  • 要卸载的的名称或 ID

  • 要从实例中卸载卷,需要指定实例的名称或 ID

对于我们的示例,值如下:

  • 卷:cookbook.volume

  • 实例:cookbook.test

  • 挂载点:/mnt1

如何操作…

执行以下步骤以使用 openstack 客户端将卷从实例中分离:

  1. 列出正在运行的实例,以获取我们实例的 ID:https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00134.jpeg

  2. 列出我们环境中可用的和in-use的卷:

    openstack volume list

    这将返回类似以下的输出。请注意,提供的信息显示了卷是否正在使用以及它附加到哪个实例:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00135.jpeg

  3. 现在我们需要在运行中的实例内部执行操作。连接到此实例并验证该卷是否已挂载:

    df -h

    这将显示类似以下的输出:

    Filesystem Size Used Avail Use% Mounted onudev 238M 0 238M 0% /devtmpfs 49M 1.8M 48M 4% /run/dev/vda1 2.1G 843M 1.3G 41% /tmpfs 245M 0 245M 0% /dev/shmtmpfs 5.0M 0 5.0M 0% /run/locktmpfs 245M 0 245M 0% /sys/fs/cgrouptmpfs 49M 0 49M 0% /run/user/1000/dev/vdb 9.8G 23M 9.2G 1% /mnt1
  4. 现在卸载/mnt1卷:

    sudo umount /mnt1

    (通过再次运行df -h来验证是否已卸载)。

  5. 退出访客系统后,在 OpenStack 客户端中,使用以下命令将卷从实例中分离:

    openstack server remove volume cookbook.test cookbook.volume
  6. 此命令在成功时不会产生任何输出,因此请再次查看卷列表以验证该卷已从cookbook.test实例中分离:

    openstack volume list

    这表明该卷可用且未附加到任何实例:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00136.jpeg

它是如何工作的…

从实例中分离 Cinder 卷的步骤类似于从计算机中拔出 USB 硬盘的步骤。首先,我们需要将其从实例中卸载,以便操作系统不会因存储的意外移除而报错。接下来,在openstack客户端中,server remove volume选项使用以下语法:

openstack server remove volume instance_name_or_id volume_name_or_id

删除卷

在某个时刻,您将不再需要您已创建的卷。为了永久将它们从系统中删除,使它们不再可用,我们只需从 OpenStack 客户端中调用另一个工具——volume delete选项。

准备工作

删除一个卷,您需要以下内容:

  • openstack 命令行客户端

  • 一个包含适当凭据的 openrc 文件,用于该环境

  • 要删除的的名称或 ID

对于我们的示例,以下是这些值:

  • 卷:cookbook.volume

提示

警告:这将删除卷及其上存储的所有数据,请确保这是您希望执行的正确操作,然后再继续。

只能删除未附加到任何实例的卷。

它是如何工作的…

使用 OpenStack 客户端删除一个卷,请执行以下步骤:

  1. 首先,我们列出可用的卷,以便识别要删除的卷,使用以下命令:

    openstack volume list

    这表明该卷可用且未附加到任何实例:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00137.jpeg

  2. 我们现在将使用卷的名称或 ID 删除该卷,使用以下命令:

    openstack volume delete cookbook.volume

    提示

    此命令在成功时不会产生输出。

    与附加和分离卷类似,可以使用 ID 或名称。最佳实践是使用 ID 以避免出现差异并删除错误的卷。

它是如何工作的…

实际删除卷的方式在很大程度上取决于 Cinder 卷驱动程序。在本章的 配置 Cinder 卷服务 配方中,我们使用了 cinder.volume.drivers.lvm.LVMVolumeDriver。在这种情况下,删除镜像会将 LVM 卷从我们的系统中移除。

还有更多…

OpenStack Cinder 卷可以拍摄快照,在这种情况下,openstack volume delete 命令会产生如下错误消息:

Invalid volume: Volume status must be available or error or error_restoring or error_extending or error_managing and must not be migrating, attached, belong to a group, have snapshots or be disassociated from snapshots after volume transfer. (HTTP 400) (Request-ID: req-2b82e7fc-0cb4-403f-8dd8-35d99a0f6c6c)

要删除一个卷及其所有快照,请在 openstack volume delete 命令中传递 --purge 标志。

提示

小心操作。这是一个单向操作,并且 openstack volume delete 命令不会要求确认。此外,命令成功时不会产生任何输出。

使用卷快照

Cinder 卷 快照 提供了一种非破坏性地复制卷的方法;允许进行原位卷备份。它还启用了更高级的备份功能,并提供了从指定快照或某个时间点启动实例的能力。

在本节中,我们将展示如何创建快照、基于快照挂载卷、刷新快照以及删除指定的快照。

准备工作

使用 Cinder 卷快照时,你将需要以下内容:

  • openstack 命令行客户端

  • 一个带有适当凭据的 openrc 文件,用于当前环境

  • 要删除的 的名称或 ID

如何操作…

要创建快照,卷必须首先从实例中分离:

  1. 首先,列出你当前的卷:https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00138.jpeg

    提示

    如果你希望拍摄快照的卷状态为 in-use,你需要使用本章前面 从实例中分离卷 的配方中的说明将其分离。

  2. 由于我们的卷处于正确的 available 状态,我们将继续使用 openstack volume snapshot create 命令创建卷的快照:

    openstack volume snapshot create --volume cookbook.volume cookbook.snapshot

    这将产生类似如下的输出,显示 creating 状态:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00139.jpeg

  3. 快照完成后,你可以使用本章中的 将卷附加到实例 配方重新附加原始卷并继续操作。

  4. 如果你将快照作为持续测试/验证过程的一部分,或作为备份方案的一部分,你可能希望使用最新数据更新快照。为此,我们使用 cinder snapshot-reset-state,如果成功,命令不会产生任何输出:

    openstack volume snapshot list -c ID -c Name -c Status -f tablecinder snapshot-reset-state cookbook.snapshot

    提示

    请注意使用 cinder 命令行工具,而不是 openstack

  5. 你不能直接使用快照;要将快照作为卷挂载到实例上,首先需要基于该快照创建一个新的卷。为此,执行以下操作:

    openstack volume create --snapshot cookbook.snapshot newcookbook.volume

    这将产生如下输出。请注意所使用的 snapshot_id 和我们未指定大小这一事实:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00140.jpeg

  6. 我们可以通过再次查看卷列表来确认基于快照创建的新的食谱卷现在可用:

    openstack volume list –c Name –c ID –c Status –f table

    这将生成我们卷及其状态的列表:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00141.jpeg

  7. 最后,你希望在某个时候删除快照。为此,请使用 openstack volume snapshot delete 命令,如下所示:

    openstack volume snapshot delete cookbook.snapshot

    使用 openstack volume snapshot list 确认剩余的可用快照列表。

它是如何工作的…

Cinder 卷快照提供了一种灵活的方式来克隆卷进行快照类型备份、附加到其他实例等。我们在这里使用的 cinder snapshot 命令,具体包括 openstack volume snapshot createopenstack volume snapshot listcinder snapshot-reset-stateopenstack volume snapshot delete,指示 cinder 与存储驱动程序一起执行特定的快照操作——创建、列出、更新和删除。快照的具体实现取决于底层驱动程序。

还要注意,你不能直接将快照与实例一起使用。你必须先根据选择的快照创建一个新卷。其语法如下:

openstack volume create --snapshot snapshot_name_or_id new_volume_name

配置卷类型

Cinder 中的卷类型是一个标签或标识符,在创建卷时选择。通常,卷类型对应卷的某些属性,例如 SSDHigh IOPSEncrypted。我们将使用这个与下一个配方一起定义我们 Cinder 服务的更多功能。

准备工作

要创建一个卷类型,你需要以下内容:

  • 一个具有适当凭证的 openrc 文件(你必须是管理员)

  • openstack 命令行客户端

  • 要创建的卷类型名称。在我们的示例中,我们将创建 \"High IOPS\" 卷类型,作为一个虚构的示例类型,指的是专用于高 IOPS 的块存储设备。

如何操作…

我们将使用 openstack volume type 命令来操作 Cinder 卷类型。要创建一个卷类型,请按照以下步骤操作:

  1. 首先,列出现有的卷类型:

    openstack volume type list

    这将返回类似如下的输出。这里我们有安装 LVM 服务时设置的默认值:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00142.jpeg

  2. 创建新的卷类型:

    openstack volume type create --description \"The High IOPS volume type is QOS applied to 500 IOPS\" \"High IOPS\"

    这将返回类似如下的输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00143.jpeg

  3. 通过显示卷类型列表,确认新卷类型是否可用:

    openstack volume type list

    这现在将返回我们额外的卷类型:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00144.jpeg

  4. 在创建卷时使用这个新类型,我们将使用 --type 标志,如下所示:

    openstack volume create --size 10 --type \"High IOPS\" --description \"High IOPS Volume\" highiops.volume
  5. 我们将在输出中验证类型:https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00145.jpeg

它是如何工作的…

openstack volume type create 命令只有一个必填参数,namename 参数允许用户定义不同的卷类型或标识符。虽然通常基于存储的某些属性,如部门、存储后端或 QOS 水平,但由于这些只是标签,只要它们易于理解,名称可以是任意的。

此外,--description 标志可以用来提供有关卷类型的更多细节。--private 标志允许你限制公共访问。--project 标志允许选择性地与其他命名项目共享私有卷类型。

然后,我们将利用这些类型(通过进一步配置 Cinder 来指定与特定卷类型相关联的存储类型),通过在 volume create 命令中使用 --type 标志来实现:

openstack volume create --size size_GiB --description \"meaningful description\" --type \"Type\" volume_name

启用卷加密

Cinder 可以管理卷的 加密,并且加密对客户机是透明的。加密在 卷类型 级别启用。

准备工作

加密可以在创建新的卷类型时启用,也可以添加到没有卷正在使用的现有卷类型中。要启用卷加密,你将需要以下内容:

  • 一个包含适当凭证的 openrc 文件

  • openstack 命令行客户端

  • 卷类型 的名称

  • 加密提供者 的名称

  • 加密控制位置

  • 加密密钥大小

  • 加密算法

对于我们的示例,以下内容将是:

  • 名称:Cookbook Encrypted Volumes

  • 加密提供者:nova.volume.encryptors.luks.LuksEncryptor

  • 加密控制位置:front-end

  • 加密密钥大小:256

  • 加密算法:aes-xts-plain64

注意

你选择的加密特定值将基于你所在环境中可用的内容。本书不讨论这些值的详细内容。

如何操作…

要启用卷加密作为新的卷类型,使用以下命令:

openstack volume type create --description \"LUKS Encrypted volumes\" --encryption-provider nova.volume.encryptors.luks.LuksEncryptor --encryption-control-location front-end --encryption-key-size 256 --encryption-cipher aes-xts-plain64 \"Encrypted\"

然后,我们将在创建卷时使用这个 \"Encrypted\" 卷类型,具体如下:

openstack volume create --size 1 --type \"Encrypted\" --description \"An encrypted volume\" encrypted.volume

它是如何工作的…

卷通过卷类型进行配置,因此,额外的参数会传递给 openstack volume type create

  • --encryption-provider 标志告诉 Cinder 哪个提供者将执行加密。与存储后端类似,提供者有多种可选项。请参阅 OpenStack 文档获取当前的提供者列表。

  • --encryption-control-location 参数告诉 Cinder 加密将在哪里处理。在我们的例子中,front-end 表示 Nova 将处理加密。

  • 接下来,--encryption-key-size 参数指定所用密钥的大小。为了避免影响实验性能,示例中选择了 256。你选择的加密提供者和密码算法将提供具体的建议。

  • 最后,--encryption-cipher 指定使用哪个加密算法。你可以使用 cryptsetup benchmark 来获取可用选项的列表,并了解它们的性能。

配置卷的服务质量 (QoS)

Cinder 提供的另一个功能是能够为卷定义和管理服务类别。与卷加密类似,Cinder 中的 服务质量 (QoS) 是通过卷类型进行配置的。默认情况下,你可以定义最小、最大和突发 IOPS 值。

准备工作

要配置卷的 QoS,您需要以下信息:

  • 一个包含适当凭据的 openrc 文件(您需要是管理员)

  • openstack 命令行客户端

  • 卷类型的名称或 ID

  • QoS 策略的 消费者

  • 以下值:

    • 最小 IOPS

    • 最大 IOPS

    • 突发 IOPS

    注意

    要定义一个最小的 QoS 策略,只需提供三项中的一个(最小、最大和突发)。

对于我们的示例,值如下所示:

  • 名称:High IOPS

  • 消费者:both

  • 最大 IOPS:500

如何操作…

为了使 Cinder 卷使用 QoS,管理员需要执行两个步骤:首先定义规范,其次将规范与卷类型关联。

要创建并分配 QoS 规范,请使用以下步骤:

  1. 首先,列出现有的 QoS 规范:

    openstack volume qos list --print-empty

    目前我们没有定义任何 QoS:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00146.jpeg

  2. 定义一个新的 QoS 规范,内容如下:

    openstack volume qos create --consumer both --property maxIOPS=500 \"High IOPS\"

    这将返回以下输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00147.jpeg

  3. 通过列出可用的 QoS 来确认我们创建的 QoS 规范:

    openstack volume qos list -c Name -c Consumer -c Properties -f table

    这将返回以下输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00148.jpeg

  4. 我们现在将策略与卷类型关联,如下所示:

    openstack volume qos associate \"High IOPS\" \"High IOPS\"

    注意

    成功时,此命令不会产生任何输出。

它是如何工作的…

QoS 规范在 Cinder 中使用 openstack volume qos 一组命令进行定义。创建 QoS 规范时,可以指定 QoS 应用的位置以及设置的值。目前,您可以指定一组静态的最小、最大和突发 IOPS,以及一个可伸缩的 IOPS 集合。

静态值分解如下:

  • 最小 IOPS:这是保证分配给卷的 IOPS 数量

  • 最大值:这是卷的 IOPS 上限

  • 突发 IOPS:这是短时间内的最大 IOPS

伸缩 IOPS 时,定义每增加一个千兆字节的卷大小,静态值的变化量。

重置卷状态

在 OpenStack 云的持续运行过程中,您偶尔会遇到 Cinder 卷卡在某个奇怪状态的问题。在写这章内容时,作者遇到了多个卷在实例从它们启动失败后卡在 attaching 状态的情况。以下是该情况的表现:

openstack volume list -c Name -c Status -f table

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00149.jpeg

注意

这次错误是因为在创建从卷启动部分时,手误造成的!

准备就绪

要重置 Cinder 卷的状态,您需要以下内容:

  • 一个包含适当凭据的 openrc 文件

  • openstack 命令行客户端

  • cinder 命令行客户端

  • 卷的 名称ID

对于以下示例,我们将重置以下卷为可用状态:

  • cookbook.boot.volume

  • cookbook.volume.boot.test

如何操作…

重置 Cinder 卷的状态是通过cinder命令完成的。这里的openstack命令集覆盖了大多数您常用的操作,而cinder命令则提供了额外的管理员功能,如reset-state

提示

由于reset-state命令仅操作数据库,不考虑实际状态,因此在使用时应谨慎。

要重置 Cinder 卷的状态,请执行以下步骤:

  1. 首先,列出你的 Cinder 卷及其状态

    openstack volume list -c Name -c Status -f table

    这将列出 OpenStack 所知道的卷:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00149.jpeg

  2. 使用cinder客户端重置卷的状态:

    cinder reset-state 23e1e006-a753-403c-ad8f-27e98444f71e --state availablecinder reset-state e934c45f-6e2f-431f-8457-7e84f6cee876 --state available

    注意

    当成功时,此命令不会产生任何输出。

  3. 确认新的状态:

    openstack volume list -c Name -c Status -f table

    这将显示状态已重置为available

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00150.jpeg

它是如何工作的…

cinder reset-state命令直接操作cinder数据库,而不考虑卷的实际状态。我们使用的--state标志允许我们更改可能卡在特定状态中的卷的状态。还有两个附加标志,分别允许您更改附件状态和迁移状态:

cinder help reset-stateusage: cinder reset-state [--type ] [--state ] [--attach-status ] [--reset-migration-status] [ ...]

该工具显式地更新cinder数据库中的实体状态。由于它仅涉及数据库更改,因此不会影响实体的真实状态,可能与实际状态不符。在更改为available状态时,这可能导致实体无法使用。

第八章. Swift – OpenStack 对象存储

本章我们将覆盖以下主题:

  • 介绍 – OpenStack 对象存储

  • 创建对象容器

  • 删除对象容器

  • 上传对象

  • 上传大对象

  • 下载对象

  • 删除对象

  • 容器 ACL

介绍 – OpenStack 对象存储

OpenStack 对象存储,也称为 Swift,是一个允许在商品硬件上进行大规模可扩展和高度冗余存储的服务。该服务由 Rackspace 实现,名为 Cloud Files,也类似于 Amazon 的 S3 存储服务,并在 OpenStack 下以类似方式进行管理。通过 OpenStack 对象存储,我们可以存储许多几乎无限大小的对象—仅受限于可用硬件—并根据需要扩展环境以适应我们的存储需求。OpenStack 对象存储的高度冗余特性非常适合用于归档数据(例如日志和备份归档),同时也为 OpenStack Compute 提供了一个存储系统,可用于虚拟机实例镜像。

OpenStack 对象存储的架构是直接而简单的。API 服务运行在控制节点上。然后是 Swift 代理服务,这些服务可以部署到控制节点上,也可以根据需求分布到独立的服务器上,之后是实际存储数据的存储节点。这些存储节点是为随着存储需求增长而进行扩展而设计的服务器。

注意

扩展 Swift 的特性和设计超出了本书的范围。

这里展示了一个典型的简化架构视图:

https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00151.jpeg

本质上,上传或下载对象等请求是通过负载均衡池发送到 API 的,然后数据通过 Swift-Proxy 服务传送到物理存储节点。Swift-Proxy 服务会从终端用户那里获取数据,并将其存储进出。

正如名称所示,OpenStack 对象存储基于所谓的对象操作。对象可以是任何东西,从文件到一个名为完整文件夹和文件名的对象——对 OpenStack 对象存储来说,不管是什么文件名,所有它看到的内容都只是一个单一的对象。对象被存储在 容器 中。一个很好的类比是桶。在桶里,你可以存放任何适合其中的东西,从沙粒到你放在棚子里的工具!

创建对象容器

要开始使用 OpenStack 对象存储,我们必须首先创建一个容器。在这里,容器类似于 Windows 或 Linux 文件目录中的文件夹。然而,容器不能嵌套,尽管在上传存储在这些容器中的对象时,我们可以通过容器和对象名称(伪文件夹)的组合方式创建类似嵌套文件夹结构的深层结构。我们分配给容器和对象的名称类似于标签,允许我们通过在这些标签中使用/字符来将其解释为文件夹结构。

准备就绪

请确保您已登录到正确配置的 OpenStack 客户端,如第二章,OpenStack 客户端,中所述,并且可以作为具有swiftoperator权限的用户访问 OpenStack 环境。

我们将使用在第二章,OpenStack 客户端中创建的developer用户,并使用cookbook4密码;我们还授予此用户swiftoperator权限。

提示

参考第二章,OpenStack 客户端,获取有关设置环境以使用 OpenStack 命令行客户端的详细信息。

如何操作…

要在我们的环境中创建一个 Swift 容器,请按照以下步骤操作:

  1. 要创建一个容器,请执行以下命令:

    openstack container create books
  2. 创建容器后,您将看到以下输出:https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00152.jpeg

  3. 要查看所有可用的容器,请输入以下命令:

    openstack container list

    这将返回类似以下的输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00153.jpeg

  4. 一旦容器创建完成,我们可以通过执行以下命令设置附加的详细信息或元数据

    openstack container set books --property title=cookbooks
  5. 要查看容器详细信息,请输入以下命令:

    openstack container show books

    这将返回以下输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00154.jpeg

  6. 如引言中所述,我们分配给容器和对象的名称很像标签;因此,要在容器中创建一个伪文件夹,请在容器名称中使用/分隔符:

    openstack container create books/chapter1

    这将返回类似以下的输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00155.jpeg

  7. 要查看伪文件夹的详细信息,请通过包含完整的伪文件夹名称执行container show命令:

    openstack container show books/chapter1

    这将提供类似以下的信息:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00156.jpeg

它是如何工作的…

在 OpenStack 对象存储中,具有adminswiftoperator权限的用户可以使用对象存储服务。为此,我们首先必须创建容器,其中将存储对象。容器不能嵌套,但我们可以使用/分隔符在容器名称中创建伪文件夹。要创建容器,请遵循以下命令行语法:

openstack container create container_name

要列出可用容器,请使用以下命令:

openstack container list

我们还可以在每个容器上设置元数据。使用以下命令为容器设置附加信息:

openstack container set container_name --property key=value

可以在每个容器上设置多对元数据。

要查看容器详细信息,请执行以下命令:

openstack container show 

删除对象容器

删除 OpenStack 对象存储容器非常简单。只要它们为空,任何容器都可以被删除。

注意

在此情况下,OpenStack CLI 与 Swift CLI 工具的行为不同。Swift CLI 将删除包括所有内容在内的容器,而 OpenStack CLI 则不会。在本示例中,我们使用的是 OpenStack CLI。

准备就绪

确保您以正确配置的 OpenStack 客户端登录,并作为具有 swiftoperator 特权的用户访问 OpenStack 环境。我们将使用在 第二章 的 Common OpenStack identity tasks 配方中创建的 developer 用户,密码为 cookbook4。我们还为该用户授予了 swiftoperator 特权。

详细设置环境以使用 OpenStack 命令行客户端,请参阅 第二章 的 OpenStack 客户端

如何操作…

要在我们的环境中删除 Swift 容器,请执行以下步骤:

  1. 首先,列出可用容器:

    openstack container list

    这将显示如下输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00153.jpeg

  2. 查看容器详细信息,确保它为空:

    openstack container show books

    这将显示如下输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00157.jpeg

  3. 现在使用以下命令删除容器:

    openstack container delete books

    注意

    此命令不会输出任何内容。

工作原理…

在 OpenStack 对象存储中,用户可以删除空容器。首先,我们必须确保容器为空,方法是查看其详细信息:

openstack container show container_name

然后,使用以下命令删除容器:

openstack container delete container_name

验证容器是否已删除,方法是列出可用容器:

openstack container list

上传对象

一旦我们创建了一个或多个容器,就可以开始向其中上传对象。虽然 OpenStack 对象存储不支持嵌套容器,但我们可以通过对象名称模拟文件夹或文件目录。这与我们在容器名称中使用伪文件夹的类似结构,并且都能实现用户期望的对象存储使用树形结构的最终目标。

准备就绪

确保你已登录到配置正确的 OpenStack 客户端,并且作为具有 swiftoperator 权限的用户可以访问 OpenStack 环境。我们将使用在第二章,OpenStack 客户端,中创建的 developer 用户,密码为 cookbook4;我们也已经授予该用户 swiftoperator 权限。

请参阅第二章,OpenStack 客户端,了解如何设置环境以使用 OpenStack 命令行客户端。

如何操作…

要将对象上传到 OpenStack 对象存储容器,请按照以下步骤操作:

  1. 我们将把 intro.txt 文件上传到 books 容器中:

    openstack object create books intro.txt

    这将产生以下输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00158.jpeg

  2. 通过提供容器名称来列出容器中的对象:

    openstack object list books

    这将产生如下输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00159.jpeg

    注意

    这里的 chapter1 是我们在 创建对象容器 章节中创建的伪文件夹,它显示为一个对象。

  3. 我们可以通过以下方式将对象上传到名为 books/chapter1 的伪文件夹中:

    openstack object create books/chapter1 swift.txt

    这将产生如下输出:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00160.jpeg

  4. 要列出容器中的对象,请对容器名称执行以下操作:

    openstack object list books

    这将列出该容器下可用的对象:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00161.jpeg

  5. 要列出伪文件夹容器中的所有对象,请使用 prefix 标志:

    openstack object list books --prefix chapter1/

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00162.jpeg

    提示

    你可以使用 --prefix 来列出以指定前缀字母开头的任何对象。

  6. 要列出容器中的所有顶级对象,请使用分隔符标志。在此示例中,分隔符为 /

    openstack object list books --delimiter /

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00159.jpeg

  7. 要显示有关对象的信息,请执行以下命令:

    openstack object show books chapter1/swift.txt

    这将显示该对象的信息:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00163.jpeg

它是如何工作的…

为了将文件存储到 OpenStack 对象存储中,对象必须上传到一个容器中。容器不能嵌套;然而,可以使用 / 分隔符创建伪文件夹或伪目录。一旦容器创建完成,你可以使用以下命令上传文件:

openstack object create container_name object_1 [object_2 …]

提示

可以通过一条命令上传多个对象。

要列出上传到容器中的对象,请执行以下命令:

openstack object list container_name

列出容器中的对象时,启用 --prefix--delimiter 标志进行过滤。

注意

默认情况下,将列出最多 10,000 个对象。使用分页或 --all 标志查看超过默认数量的对象。

要查看单个对象的详细信息,请使用以下命令:

openstack object show container_name object_name

注意

在 Swift 中,常规对象的大小有限制。默认情况下,只有 5 GB 或更小的对象可以通过 openstack object create 命令上传。有关如何上传大型对象的详细信息,请参考上传大型对象配方。

上传大型对象

每个 OpenStack 对象存储集群都有一个上传对象大小的限制。通常,该限制为 5 GB,尽管每个集群可以有自己的限制。然而,这并不意味着你只能上传 5 GB 或更小的对象到 OpenStack 对象存储。Swift 通过已经配置和部署的中间件提供大对象支持,通过将大对象拆分成较小的部分来实现。有两种类型的大对象支持:动态和静态。

准备就绪

确保你已经登录到正确配置的 OpenStack 客户端,并且可以作为具有 swiftoperator 权限的用户访问 OpenStack 环境。我们将使用在公共 OpenStack 身份任务配方中创建的 developer 用户,该用户的密码为 cookbook4,同时我们也授予该用户 swiftoperator 权限。

由于 OpenStack CLI 没有通过单独的 OpenStack 项目客户端提供所有必要的功能,我们需要使用 Swift CLI 来完成本配方。请确保你已安装 Swift 命令行客户端。如果没有,请安装:

pip install python-swiftclient

如何操作…

要将大型对象上传到 OpenStack 对象存储容器,请按照以下步骤操作:

  1. 首先,我们可以使用以下命令列出可用的容器:

    swift list

    这会给出我们拥有的容器列表:

    books
  2. 要上传一个大型文件,我们将使用 –S 标志指定对象的分段大小,单位为字节

    swift upload -S 25000 books nova.txt

    这将显示对象被拆分为分段的输出:

    nova.txt segment 1nova.txt segment 0nova.txt segment 5nova.txt segment 2nova.txt segment 3nova.txt segment 4nova.txt

    在这个例子中,分段大小为 25000 字节,我们的 128 K nova.txt 文件在上传到 Swift 集群之前被拆分成了 6 个分段。

  3. 通过列出容器中可用的对象,验证文件是否已上传:

    swift list books

    这显示了我们可用的 nova.txt 文件:

    nova.txt

    尽管文件被拆分成 6 个部分进行上传,但它在 Swift 的 books 容器中显示为一个文件。这些分段会在一个新的容器中单独列出。

  4. 要查看可用的容器,请执行以下命令:

    swift list

    这会为我们提供容器,并自动创建一个新的容器:

    booksbooks_segments

    你会注意到一个新的 books_segments 容器已经自动创建。

  5. 列出 books_segments 容器中的对象,以查看单个对象:

    swift list books_segments

    这显示了我们分段的文件对象:

    nova.txt/1512361523.073429/131024/25000/00000000nova.txt/1512361523.073429/131024/25000/00000001nova.txt/1512361523.073429/131024/25000/00000002nova.txt/1512361523.073429/131024/25000/00000003nova.txt/1512361523.073429/131024/25000/00000004nova.txt/1512361523.073429/131024/25000/00000005

    注意

    请勿单独修改或删除这些对象。

  6. 使用 stat 命令查看 books 容器中已上传对象的详细信息:

    swift stat books nova.txt

    这提供了有关 books 容器中 nova.txt 文件的详细信息:

     Account: AUTH_402e8fe274c143ea91fe905a1b8c7614 Container: books Object: nova.txt Content Type: text/plain Content Length: 131024 Last Modified: Sun, 17 Dec 2017 06:36:32 GMT ETag: \"cd0ef1b80a6261f0b6b7db9efa739938\" Manifest: books_segments/nova.txt/1512361523.073429/131024/25000/Meta Mtime: 1512361523.073429 Accept-Ranges: bytes X-Timestamp: 1513492591.13264 X-Trans-Id: tx4fa6e7a4e53a459a86430-005a3611adX-Openstack-Request-Id: tx4fa6e7a4e53a459a86430-005a3611ad

    查看提供的信息中的 manifest 字段。manifest 字段将包括为各个段创建的 container 详细信息、原始文件大小以及段的大小。

它是如何工作的

由于 OpenStack CLI 在编写本食谱时不支持大文件上传,我们将使用 Swift 命令行客户端。为了将大文件存储到 OpenStack 对象存储中,必须先将对象拆分或分段,然后再上传到容器中。这一分段过程通过在 swift upload 命令中指定 -S 标志来完成:

swift upload -S size_in_bytes container large_object

在上传大文件时,Swift 会自动为上传对象的各个段创建一个新的容器和伪文件夹。各个段可以像常规对象一样列出;但是,请勿直接操作它们。

下载对象

一旦对象上传到容器中,你可能还想下载它们。在本食谱中,我们将向你展示如何将对象下载到本地磁盘。

准备工作

确保你已经登录到正确配置的 OpenStack 客户端,并且能够以具有 swiftoperator 权限的用户身份访问 OpenStack 环境。我们将使用在第二章 OpenStack 客户端 任务中创建的 developer 用户,并使用 cookbook4 密码。我们还为该用户授予了 swiftoperator 权限。

参见第二章 OpenStack 客户端,了解如何设置你的环境以使用 OpenStack 命令行客户端。

如何操作…

要从 Swift 集群下载对象,请执行以下步骤:

  1. 列出容器中的可用对象:

    openstack object list books

    这将列出我们在 books 容器中的对象:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00164.jpeg

  2. 要下载所需的文件,例如 intro.txt,请执行以下命令:

    openstack object save books intro.txt

    注意

    此命令没有输出。文件将保存到当前目录。

  3. 我们还可以下载文件并指定目标文件:

    openstack object save books nova.txt --file /tmp/nova.txt

它是如何工作的…

为了从 OpenStack 对象存储中下载文件,请执行以下命令:

openstack object save container object --file file_name

--file 标志是可选的。如果未指定,将把对象保存到当前目录。

注意

下载大对象时不需要特别处理;同样的命令可以用于大对象和小对象。

删除对象

从 OpenStack 对象存储删除对象相当简单,无论是小文件还是大文件。

准备工作

确保你已经登录到正确配置的 OpenStack 客户端,并且能够以具有 swiftoperator 权限的用户身份访问 OpenStack 环境。我们将使用在第二章,The OpenStack Client 中的 Common OpenStack identity tasks 配方中创建的 developer 用户,密码为 cookbook4。我们也已授予该用户 swiftoperator 权限。

请参考第二章,The OpenStack Client,了解如何设置环境以使用 OpenStack 命令行客户端。

如何操作…

要从 Swift 集群中删除对象,请执行以下步骤:

  1. 列出容器中可用的对象:

    openstack object list books

    这将列出我们 books 容器中的对象:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00164.jpeg

  2. 从容器中删除对象:

    openstack object delete books intro.txt

    注意

    此命令不会输出任何内容。

  3. 删除对象后的 books 容器中的对象列表:

    openstack object list books

    容器列表将显示 intro.txt 不再存在:

    https://github.com/OpenDocCN/freelearn-devops-pt8-zh/raw/master/docs/opstk-cld-comp-cb-4e/img/00165.jpeg

  4. 要删除 所有对象随后删除容器,请执行以下命令:

    openstack container delete -r books

    注意

    此命令不会输出任何内容。

工作原理

为了从 OpenStack 对象存储集群中删除文件,请使用以下命令指定应删除的容器和对象:

openstack object delete container object

使用 -r 标志来删除容器及其所有内容。

容器 ACL

OpenStack 对象存储容器通常由创建它们的用户拥有。然而,通过 Swift 的 ACLs访问控制列表),可以使容器对不同的 OpenStack 用户可访问,或者完全公开。容器的拥有者可以设置特定的读写规则。这些读写规则必须单独设置,并且必须在每个容器上明确启用。容器的拥有者可以将容器设置为完全公开,或根据项目、用户或规则集设置规则。

准备工作

确保你已经登录到正确配置的 OpenStack 客户端,并且能够以具有 swiftoperator 权限和 admin 权限的用户身份访问 OpenStack 环境。我们将使用在第二章,The OpenStack Client 中的 Common OpenStack identity tasks 配方中创建的 developer 用户,密码为 cookbook4。我们也已授予该用户 swiftoperator 权限。

由于 OpenStack CLI 并未提供所有通过各个 OpenStack 项目客户端可用的功能,因此我们需要使用 Swift CLI 来执行此配方。确保你已经安装了 Swift 命令行客户端。如果没有,请安装:

pip install python-swiftclient

如何操作…

要查看和修改容器上的 ACL,请按照以下步骤操作:

  1. 首先,查看容器上的现有 ACL(如果有的话):

    swift stat books

    这将提供关于我们名为 books 的容器的信息:

     Account: AUTH_402e8fe274c143ea91fe905a1b8c7614 Container: books Objects: 3 Bytes: 32764 Read ACL: Write ACL: Sync To: Sync Key: Accept-Ranges: bytes X-Storage-Policy: default Last-Modified: Mon, 18 Dec 2017 06:09:45 GMT X-Timestamp: 1512278405.11522 X-Trans-Id: tx484e741deb754fdb86f7a-005a375e4c Content-Type: text/plain; charset=utf-8X-Openstack-Request-Id: tx484e741deb754fdb86f7a-005a375e4c
  2. 在我们的示例中,还没有设置读或写的 ACL。让我们设置一个 read ACL 使 books 容器 公开

    swift post books --read-acl \".r:*,.rlistings\"

    注意

    此命令没有输出。

  3. 要使 books 容器对所有人 可写,请执行以下操作:

    swift post books --write-acl \"*:*\"

    注意

    此命令没有输出。

  4. 现在再次使用 stat 命令检查 books 容器的详细信息:

    swift stat books

    我们可以看到 Read ACLWrite ACL 字段已经被填充:

     Account: AUTH_402e8fe274c143ea91fe905a1b8c7614 Container: books Objects: 3 Bytes: 32764 Read ACL: .r:*,.rlistings Write ACL: *:* Sync To: Sync Key: Accept-Ranges: bytes X-Trans-Id: txc0d0d64ed54e48989f3f6-005a3760ba X-Storage-Policy: default Last-Modified: Mon, 18 Dec 2017 06:22:56 GMT X-Timestamp: 1512278405.11522 Content-Type: text/plain; charset=utf-8X-Openstack-Request-Id: txc0d0d64ed54e48989f3f6-005a3760ba
  5. 由于操作 世界可写可读 容器并不是一个很好的安全做法,我们可以从容器中删除 ACL。要删除 ACL,可以执行以下命令:

    swift post -r \"\" books
  6. 要删除 ACL,请使用此命令:

    swift post -w \"\" books
  7. 如果你需要与 OpenStack 环境中的其他用户共享容器,可以基于 项目用户 设置权限。在我们的示例中,我们将设置 books 容器的访问权限,使 admin 项目中的所有人都可以读取:

    swift post -r \"admin:*\" books

    : 后面的星号(*)表示 admin 项目中的所有用户都可以访问 books 容器。

  8. 现在检查 books 容器的详细信息:

    swift stat -v books

    这将产生如下输出:

     URL: http://172.29.236.100:8080/v1/AUTH_402e8fe/books Auth Token: gAAAAABaODQ8R93x7kW46CW_u9ZS3 Account: AUTH_402e8fe274c143ea91fe905a1b8c7614 Container: books Objects: 3 Bytes: 32764 Read ACL: admin:* Write ACL: Sync To: Sync Key: Accept-Ranges: bytes X-Trans-Id: tx20b0d0d8394b4b0a81cba-005a38343c X-Storage-Policy: default Last-Modified: Mon, 18 Dec 2017 21:24:27 GMT X-Timestamp: 1512278405.11522 Content-Type: text/plain; charset=utf-8X-Openstack-Request-Id: tx20b0d0d8394b4b0a81cba-005a38343c

    注意容器详细信息中的 URL。任何希望访问此容器的人都需要将 URL 字段作为参数传递。

  9. 作为 admin 用户,测试访问 books 容器:

    swift --os-storage-url http://172.29.236.100:8080/v1/AUTH_402e8fe/books list

    这将提供来自我们共享容器的对象,指定 URL 如下:

    chapter1chapter1/swift.txtintro.txt

    在我们的示例中,admin 用户属于 admin 项目,因此可以通过 --os-storage-url 标志访问 books 容器。

它是如何工作的…

可以通过设置 ACL 来与其他用户共享容器。目前,OpenStack 客户端不支持 ACL 功能,因此我们在示例中使用了 Swift CLI。

容器可以设置两种类型的 ACL,,并且它们需要单独设置。

使用以下命令设置读 ACL:

swift post -r \"project:user\" container

按如下方式设置写 ACL:

swift post -w \"project:user\" container

在这里,项目和用户都可以用通配符(*)来替代。

要使容器完全公开,可以使用以下命令:

swift post --read-acl \".r:*,.rlistings\" containerswift post --write-acl \"*:*\" container

设置 .r:*.rlistings 元素后,books 容器将公开可访问。.r* 元素允许访问容器中的对象,.rlistings 允许列出容器的内容。

注意

设置写 ACL 为 \"*:*\" 后,容器可以被任何人更新,因此请小心使用。

-r--read-acl 命令,以及 -w--write-acl 是相同标志的短形式和长形式。也就是说,-r--read-acl 可以互换,-w--write-acl 也可以互换。

一旦启用了其他用户对容器的访问,可以使用以下命令查找容器的 URL:

swift stat -v container | grep URL

启用访问后,要访问其他用户的容器,请使用此命令:

swift --os-storage-url URL list

提示

如果你始终访问相同的存储 URL,可以将其设置为 OS_STORAGE_URL 环境变量。