OpenStack核心组件解析与应用实践
发布时间: 2025-08-13 01:36:37 阅读量: 6 订阅数: 7 


OpenStack云应用开发实战指南
# OpenStack核心组件解析与应用实践
## 1. OpenStack组件通信机制
OpenStack采用模块化架构,不同组件作为独立服务,通过标准化REST API进行通信。这种设计原则在项目开发中至关重要,因为不同团队负责不同组件的开发。所有组件的功能和更新都始于API设计讨论,这些API应具备简单、标准、可复用和可重新实现的特点,并且可以利用消息队列处理内部操作和事件。
不同OpenStack服务之间的请求通过原始请求的令牌进行身份验证,服务间请求的授权会直接向终端服务进行检查。例如,用户创建计算实例快照时,计算服务会向镜像服务发送请求以存储快照,此时原始身份验证令牌会在两个服务的REST API请求中传递。若镜像服务使用对象存储服务作为存储后端,这两个服务之间也会使用原始身份验证令牌生成经过身份验证的请求。
OpenStack的主要核心组件如下:
| 组件名称 | 功能描述 |
| ---- | ---- |
| Identity (Keystone) | 提供身份验证和授权服务 |
| Dashboard (Horizon) | 提供可视化的管理界面 |
| Compute (Nova) | 负责实例的创建和管理 |
| Image (Glance) | 管理镜像服务 |
| Object Storage (Swift) | 提供对象存储服务 |
| Network (Neutron) | 管理网络服务 |
| Block Storage (Cinder) | 提供块存储服务 |
下面是OpenStack组件通信的mermaid流程图:
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(用户):::process -->|创建实例快照请求| B(Compute - Nova):::process
B -->|传递原始令牌请求存储快照| C(Image - Glance):::process
C -->|若使用对象存储| D(Object Storage - Swift):::process
```
## 2. 应用中使用Keystone
在创建使用OpenStack的应用时,必须使用Keystone来确保不同服务或应用部分的适当授权和结构。以一个允许访客用户上传文档(如图片)的应用为例,该应用需要图片转换或调整大小的服务,使用OpenStack对象存储服务存储图片,还需要自动配置和管理计算实例。为了安全起见,会设置两个不同的角色或项目以及两个不同的用户,避免公共可访问的应用管理实例。
示例应用的源代码可通过GitHub获取:[https://github.com/johnbelamaric/openstack‐appdev‐book](https://github.com/johnbelamaric/openstack‐appdev‐book)
## 3. 计算服务(Compute - Nova)
### 3.1 计算服务概述
OpenStack中的计算项目名为Nova,它包含了跨多个物理主机大规模配置和管理实例(物理计算节点上的虚拟机)所需的所有API和工具。该项目对全球主要使用的虚拟机管理程序配置进行了抽象,允许通过标准API轻松配置虚拟机,而不受特定虚拟机管理程序技术的限制。
### 3.2 实例的组成部分
在OpenStack中,实例具有虚拟机管理程序提供的虚拟化服务器的传统组件,这些特性由计算服务中的flavors定义:
- **CPU资源**:一个或多个分配的专用或虚拟CPU(vCPUs)。
- **内存资源**:分配的内存(RAM)。
- **存储资源**:根磁盘可以是连接到主机服务器的任何设备(虚拟或非虚拟、本地、远程或分布式)。
实例通常会配置一个或多个网络,可使用网络服务(Neutron)进行配置,网络设备由Nova服务通过网络API在主机中配置,并由虚拟机管理程序在实例中进行设置。实例还可以附加持久块存储(即实例中的虚拟硬盘),可通过卷服务进行配置和管理,并由虚拟机管理程序附加到实例。通过Nova中的VNC服务可以查看实例的控制台(屏幕),类似于物理服务器的KVM(键盘、视频和鼠标),它提供了一种统一透明的方式来访问所有实例的图形界面和控制台,无论使用的虚拟化技术和实例的操作系统如何,还可以为运行Microsoft Windows的实例代理RDP(远程桌面协议)。
### 3.3 理解Flavors
在OpenStack中,flavor代表实例的一种模型,即虚拟机分配的一组资源及其特性。在公共云服务中,主机服务器由多个项目或租户(客户)共享,flavor类似于商业套餐,计费资源根据特定flavor的实例在一个月内的运行总时间计算。
一个计算flavor包含以下一些资源细节:
- 唯一标识符名称
- 核心数量(vCPUs)以及与多个实例共享时的权重
- 内存(RAM)和交换空间大小
- 根磁盘和临时磁盘空间
flavor可能包含额外的规格,用于在计算基础设施中调度实例时做出决策,并分配运行实例所需的资源(例如处理器架构、过度配置、所需的PCI设备等)。flavors可以是公共的,也可以与特定的OpenStack项目关联。例如,在公共云中推出新的处理器模型时,可以创建专用的flavors,让客户使用新的物理服务器模型创建新实例。
### 3.4 调度过滤器
当在OpenStack计算基础设施中配置实例时,Nova的调度器的一项任务是选择实例将被创建或迁移到的计算节点(物理主机)。调度器的操作包括过滤和加权两个步骤。
#### 3.4.1 过滤
计算调度器会获取一组可用节点,然后应用一组过滤器来排除不符合所需配置不同标准的节点。以下是一些调度过滤器的示例:
- 跳过已满的主机(无可用CPU、内存或磁盘)
- 仅匹配具有确切可用资源量的主机
- 使用与另一个实例相同的主机
- 使用具有特定PCI设备的物理主机
物理主机可以添加到聚合组中,通常用于通过调度过滤器匹配一个或多个特定的flavors或项目。常见用例如下:
- 为客户创建一个包含一些专用主机和硬件的聚合组,使用专用flavor(针对某个域、项目或多个项目私有)中的额外规格,当用户使用此特定flavor创建实例时,调度器将仅过滤该特定聚合组中的主机。
- 将具有特定硬件(如SSD硬盘、特定CPU架构等)或分配规则(如专用资源、过度配置资源)的主机设置在一个聚合组中,并创建匹配的flavors。这些主机可以由计算基础设施的所有项目(客户)共享,flavor将作为一种公共商业套餐。
#### 3.4.2 加权
主机过滤完成后,调度器会对主机或实例的每个资源应用权重,以确定最佳的主机来分配和安装实例。例如,可以为几乎已满的物理服务器添加更高的权重,使其分配一个与剩余保留和可分配资源量完全匹配的实例;或者相反,为使用较少的服务器设置更高的权重,选择当前负载最小的服务器。
### 3.5 支持的虚拟机管理程序类型
#### 3.5.1 Libvirt
Linux中的libvirt是一个抽象库,用于访问和管理Linux服务器中的虚拟机和容器及其网络和存储配置。它支持多种技术,如KVM/QEMU、Xen、VirtualBox、VMware ESX、Hyper - V、OpenVZ、LXC等。它是OpenStack默认使用的驱动程序,也是基于内核的虚拟机/快速模拟器(KVM/QEMU)虚拟化最常用的驱动程序。优点是可以独立于虚拟化技术管理虚拟机,但由于主要为KVM/QEMU设计,可能会隐藏其他虚拟化技术提供的一些功能。不过,其他虚拟化技术可以通过自己的Nova驱动程序直接支持。
#### 3.5.2 VMware
在OpenStack中使用VMware可以同时享受两种技术的优势:VMware的虚拟化功能和OpenStack的管理/标准API。VMware提供了出色的虚拟化技术,具有以下特点:
- 高可用性(HA):当虚拟机管理程序检测到问题时,能够在正常工作的硬件上自动重启实例。在VMware市场中,“HA”更多地被称为“容错”。
- 容错:主机出现故障时,实例可以在正常工作的主机上进行实时迁移而无需重启。
- 分布式资源调度器(DRS):根据实时资源使用情况智能调度运行中的实例。
在存储方面,可以直接在Cinder和Glance中使用VMware数据存储技术,通过标准块存储API管理所有块。
## 4. 存储服务
### 4.1 对象存储概念与应用挑战
对于使用本地文件系统存储应用创建和使用的所有静态媒体(如图片、视频、音乐等)和文档的应用开发者来说,理解对象存储(在OpenStack中称为Swift)的概念可能相当复杂。然而,这通常是对使用这些媒体的应用进行水平扩展的重要步骤。
传统的内容管理系统(CMS)和博客引擎默认将所有通过Web应用上传的媒体本地存储。将应用过渡到对象存储基础设施并非易事,因为代码通常需要部分重写以支持新的存储系统。这是因为应用访问文件(对象)的方式需要改变,例如,访问硬盘中的本地文件与使用REST API访问对象是不同的。
### 4.2 对象存储的优势
虽然过渡存在挑战,但切换到对象存储有诸多优势:
| 优势 | 说明 |
| ---- | ---- |
| 空间管理 | 无需担心总空间大小,这是基础设施提供商的工作,像Swift这样的对象存储服务可以轻松进行水平扩展。 |
| 对象大小 | 可以将对象拆分为多个小块,对象大小几乎不受限制。 |
| 存储数量 | 可以在单个容器或对象桶中存储无限数量的对象。 |
| 数据复制 | 对象的复制在基础设施层面完成,甚至可以跨多个基础设施区域进行。 |
### 4.3 潜在的设计和实现问题
在将使用本地文件系统的应用切换到对象存储服务时,可能会遇到以下潜在的设计和实现问题:
- **访问方式**:只能通过HTTP(s)访问对象,但如果应用的客户端已经使用HTTP协议,这可以在不将对象下载到应用服务器的情况下提供访问。
- **存储逻辑**:对象存储不是文件系统,不应像使用文件系统一样使用它。例如,在开发应用时尝试匹配现有的文件系统层次结构是不好的做法。在OpenStack Swift中重命名(移动)对象时,由于对象在存储基础设施中的分发基于对象名称的哈希值,对象会在两个服务器之间复制并从源服务器删除。而且重命名虚拟目录(实际上是具有特定目录mime类型的对象)意味着重命名目录中的每个对象。
### 4.4 OpenStack Swift服务介绍
Swift服务(OpenStack的对象存储)为所有OpenStack项目提供HTTP REST API,允许使用标准HTTP设计和功能处理存储对象的所有常见操作。该项目设计上具有水平可扩展性、分布式和高可用性,主要由以下组件组成:
- **Swift代理服务器**:将访问不同对象的HTTP请求分发到所有后端节点。由于对象在基础设施中的位置通过对其名称进行哈希处理并使用环算法确定,因此该组件可以轻松扩展。
- **Swift账户服务器**:负责存储不同现有账户中容器的列表。
- **Swift容器服务器**:类似于账户服务器,但负责列出容器中的对象。
- **Swift对象服务器**:可安装在物理主机上的存储后端,提供内部对象存储API来管理本地服务器上存储的对象。
所有这些组件都必须进行复制,并且可以无限水平复制。以下是Swift服务组件的mermaid流程图:
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(应用):::process -->|请求| B(Swift代理服务器):::process
B -->|分发请求| C(Swift账户服务器):::process
B -->|分发请求| D(Swift容器服务器):::process
B -->|分发请求| E(Swift对象服务器):::process
```
### 4.5 最终一致性
OpenStack Swift具有最终一致性。例如,如果容器服务器负载过重,当执行PUT操作存储对象时,只要对象存储在不同的对象服务器中,并且处理HTTP请求的Swift代理服务器向客户端成功响应,该对象就可以通过GET操作获取。然而,容器服务器将对象添加到列表中可能会排队和延迟,对容器的GET请求可能不会列出这个新对象。另一个例子是,删除对象(DELETE)时,会创建一个具有更新修改时间戳的空对象,以确保如果存储对象的对象服务器副本出现故障,该文件不会再次同步。根据存储对象的不同对象服务器之间的同步延迟,DELETE操作后该对象可能会在一段时间内仍然可用。
### 4.6 在Swift中存储第一个对象
在Swift账户中存储对象的第一步是为其创建一个容器。容器使用特定的设置将具有相同用途的多个对象组合在一起,例如授予公共读取或列出权限。可以使用curl作为HTTP客户端通过API轻松创建容器:
```bash
$ curl –I -X PUT $swift/my-container -H "X-Auth-Token: $token"
HTTP/1.1 202 Accepted
Content-Length: 76
Content-Type: text/html; charset=UTF-8
X-Trans-Id: 5B44C388:EB0D_05C4F7D0:01BB_55AEDF79_18A38C8:4451
Date: Mon, 27 Jul 2015 22:25:40 GMT
Connection: close
```
如前所述,身份验证使用通过身份服务创建的令牌,并在HTTP头中指定为X - Auth - Token。
容器创建完成后,就可以在其中存储对象。可以对新存储的资源路径执行另一个PUT请求:
```bash
$ curl -I -X PUT -T $object $swift/my-container/my-object
HTTP/1.1 201 Created
Last-Modified: Mon, 27 Jul 2015 22:25:43 GMT
Content-Length: 0
Etag: 168e1afe97b471eb8948a1b612283d04
Content-Type: text/html; charset=UTF-8
X-Trans-Id: 5B44C388:35C8_05C4F7D0:01BB_55B6AFE5_2125569:444C
Date: Mon, 27 Jul 2015 22:25:42 GMT
Connection: close
```
至此,第一个对象已存储在OpenStack对象存储服务中,现在可以使用HTTP API进行私有访问:
```bash
$ curl -X GET -i $swift/my-container/my-object.json \
-H "X-Auth-Token: $ktoken"
HTTP/1.1 200 OK
Content-Length: 42
Accept-Ranges: bytes
Last-Modified: Mon, 27 Jul 2015 22:25:43 GMT
Etag: 168e1afe97b471eb8948a1b612283d04
X-Timestamp: 1438035942-04822
Content-Type: application/json
X-Trans-Id: 5B44C388:CCFA_05C4F7C0:01BB_55B6B352_1039A1B:637A
Date: Mon, 27 Jul 2015 22:40:18 GMT
Connection: close
[…]
```
也可以使用Python Swift客户端(https://github.com/openstack/python - swiftclient)通过命令行执行所有这些请求,它提供了一种简单的方式来浏览账户、容器和对象:
```bash
# 上传对象
$ swift upload <container> <file_or_directory>
# 下载对象
$ swift download <container> <object>
```
### 4.7 临时Swift URL
对OpenStack Swift API执行的任何请求都可以使用加密签名进行预认证。这种机制允许与第三方软件或浏览器共享对单个资源使用单个HTTP方法(例如POST swift/my - container/my - object)的访问授权。如果应用是多租户的,并且多个用户共享一个Swift账户,这种机制非常方便。
例如,一个应用将一些PDF账单存储在对象容器中,并向应用的客户返回一个临时链接以下载其中一个账单。应用可以向浏览器返回一个签名URL,仅允许在有限时间内GET该对象。签名将使用账户中设置的密钥进行验证。
以下是设置密钥和查看账户信息的操作:
```bash
# 设置密钥作为账户元数据 "X-Account-Meta-Temp-Url-Key"
$ swift post -m "Temp-URL-Key:92cfceb39d57d914ed8b14d0e37643de0797ae56"
# 显示账户信息(处理 'GET /v1/AUTH_account' 请求时作为HTTP头返回)
$ swift stat
Account: AUTH_account
Containers: 1
Objects: 42
Bytes: 4200
Meta Temp-Url-Key: 92cfceb39d57d914ed8b14d0e37643de0797ae56
Connection: close
X-Timestamp: 1365615113.11739
X-Trans-Id: 5B44C388:D669_5CDEF184:01BB_55C72581_2160:50A3
Content-Type: text/plain; charset=utf-8
Accept-Ranges: bytes
```
以下是一个包含两个额外查询字符串的临时URL示例:代表链接过期日期的时间戳(temp_url_expires)和加密签名本身(temp_url_sign):
```
/v1/AUTH_acount/c/o?temp_url_sig=9da40a8a7e288027809129d03ea2e5b09be70
d57&temp_url_expires=1439116248
```
在测试时,可以使用OpenStack Swift项目的swift - temp - url(https://github.com/openstack/swift/blob/master/bin/swift - temp - url)工具轻松创建临时链接。以下是一个Python示例,可在应用中使用:
```python
#! /usr/bin/env python
import hmac
from hashlib import sha1
from time import time
# 链接的过期时间戳,这里设置为1小时后
expires = int(time() + 60 * 60)
# 签名URL授权的方法
method = 'GET'
# 对象相对于服务器原点的相对路径
path = '/v1/AUTH_account/c/o'
# Swift账户的 'X-Account-Meta-Temp-URL-Key' 元数据
key = '92cfceb39d57d914ed8b14d0e37643de0797ae56'
# 签名计算
hmac_body = '%s\n%s\n%s' % (method, expires, path)
signature = hmac.new(key, hmac_body, sha1).hexdigest()
# 格式化临时URL
u = 'https://{host}/{path}?temp_url_sig={sig}&temp_url_expires={expires}'
url = u.format(
host='your_host',
path=path,
sig=signature,
expires=expires
)
```
通过以上对OpenStack核心组件的解析和应用实践介绍,我们可以看到OpenStack在云计算领域提供了强大而灵活的解决方案,无论是计算服务还是存储服务,都能满足不同场景的需求。
0
0
相关推荐









