OpenStack存储管理-Swift

Swift相关概念

Swift是一个分布式对象存储系统,属于OpenStack的一个核心组件之一。作为对象存储它可以为大规模的数据存储提供高可用性、可扩展性和数据安全性。它允许用户将大量的数据存储在云上,并且可以随时访问、检索和管理这些数据。在openstack中,Swift也可以作为Glance的后端存储,负责存储镜像文件。

块存储、对象存储、文件存储

这三者的本质差别是使用数据的“用户”不同:块存储的用户是可以读写块设备的软件系统,例如传统的文件系统、数据库;文件存储的用户是自然人;对象存储的用户则是其它计算机软件。

Swift特点

  1. 高可用性:Swift采用了多副本、冗余和分布式架构,以确保数据的高可用性和可靠性。当一个存储节点发生故障时,系统可以自动地将数据复制到其他节点上,以保证数据的完整性和可用性。

  2. 可扩展性:Swift可以轻松地扩展到数千台服务器,支持PB级别的数据存储,同时也支持水平和垂直扩展,以应对日益增长的数据需求。

  3. 强安全性:Swift提供了多种安全机制,包括认证、授权、访问控制、加密等,以保护用户的数据免受恶意攻击和非法访问。

  4. 高性能:Swift采用了分布式存储和负载均衡技术,以确保数据的快速访问和高效传输。同时,Swift还支持多种数据访问协议,如RESTful API、Swift API、S3 API等,以满足不同用户的需求。

  5. 易用性:Swift提供了简单、易用的API和Web界面。

Swift架构

1700271777569.png

Swift对象的层次模型

1700110449415.png
  1. Swift 采用层次数据模型,共设三层逻辑结构:Account/Container/Object(即账户/容器/对象),每层节点数均没有限制,可以任意扩展。

  2. 账户和个人账户不是一个概念,可理解为租户,用来做顶层的隔离机制,可以被多个个人账户所共同使用。

  3. 容器代表封装一组对象,类似文件夹或目录(容器不能像文件夹一样嵌套);叶子节点代表对象(对象由元数据和内容两部分组成)。

1700272354216.png

数据一致性

  1. Replicator(复制器) – 复制的目的是在网络中断或硬盘故障等临时错误情况下保持系统状态一致。复制过程将本地数据与每个远程副本进行比较,以确保它们都包含最新版本。

  2. Updater(更新器) – 有时,容器或账户数据无法立即更新。这通常发生在故障情况或高负载期间。如果更新失败,更新会在本地文件系统上排队,更新器将处理失败的更新。

  3. Auditor(审计器) – 审计器会抓取本地服务器,检查对象、容器和账户的完整性。如果发现损坏,文件将被隔离,复制器将从另一个副本替换坏文件。

Swift实验

作业与实验环境

超星网址
虚拟机openstack-allinone,账户root,密码000000

1701610472777.png

Swift命令行使用

查看swift相关服务

  1. 查看系统中正在运行的swift相关的服务。

    [root@controller ~]# systemctl -l |grep "swift"
    1700273105539.png

    执行脚本完成身份认证。

    [root@controller ~]# source /etc/keystone/admin-openrc.sh

创建容器

  1. swift命令行工具的名称是swift,可通过swift post命令创建容器。

    [root@controller ~]# swift post test_container
  2. 使用swift list命令查看当前用户下所创建的容器。

    [root@controller ~]# swift list
    test_container

对象操作

  1. 创建一个文件并把它上传到容器test_container中。

    [root@controller ~]# echo "hello world" > test.txt
    [root@controller ~]# swift upload test_container test.txt
    test.txt
  2. 同样使用swift list + 容器名可以列出指定容器内所包含的对象。

    [root@controller ~]# swift list test_container
    test.txt
  3. 使用swift download命令将对象从存储中下载到本地。

    [root@controller ~]# swift download test_container test.txt
    test.txt [auth 0.694s, headers 1.014s, total 1.015s, 0.000 MB/s]
  4. 查看当前存储情况。

    [root@controller ~]# swift stat
                            Account: AUTH_f9ff39ba9daa4e5a8fee1fc50e2d2b34
                        Containers: 1
                            Objects: 1
                            Bytes: 0
    Containers in policy "policy-0": 1
    Objects in policy "policy-0": 1
        Bytes in policy "policy-0": 0
        X-Account-Project-Domain-Id: 9321f21a94ef4f85993e92a228892418
                        X-Timestamp: 1700303560.27498
                        X-Trans-Id: txa1c625c0e1f845b883322-006558a140
                    Content-Type: text/plain; charset=utf-8
                    Accept-Ranges: bytes

作业1:使用命令查看当前的存储情况后截图。

Swift Api使用

  1. 使用swift auth获取swift服务的地址和token(令牌)。

    [root@controller ~]# swift auth
    export OS_STORAGE_URL=http://controller:8080/v1/AUTH_f9ff39ba9daa4e5a8fee1fc50e2d2b34
    export OS_AUTH_TOKEN=gAAAAABlWKPJhp_TU9OxT6j7jzESq5oyxTE25nk_0Idy0BfaNv75-rMwXtUEfRNqBES5IJ0dV3k-BjejVSta5rpEctCWpeyxTYSmqwRYTB6En1yr678mNgQzwJUJKY2CFKnS28K1UX_lOrI1T0zzgeTtYucrV3sYPX9cR9vfeIsnZkcnEAaxFbYwLKgltlZ8kOeqIikD-_Ka
    # swift auth 会返回对象存储地址和 token,复制执行命令,导出到环境变量便于 curl 使用
    [root@controller ~]# export OS_STORAGE_URL=http://controller:8080/v1/AUTH_f9ff39ba9daa4e5a8fee1fc50e2d2b34
    [root@controller ~]# export OS_AUTH_TOKEN=gAAAAABlWKPJhp_TU9OxT6j7jzESq5oyxTE25nk_0Idy0BfaNv75-rMwXtUEfRNqBES5IJ0dV3k-BjejVSta5rpEctCWpeyxTYSmqwRYTB6En1yr678mNgQzwJUJKY2CFKnS28K1UX_lOrI1T0zzgeTtYucrV3sYPX9cR9vfeIsnZkcnEAaxFbYwLKgltlZ8kOeqIikD-_Ka
  2. 执行上述命令将url和获取到的token导出为环境变量。

  3. 使用curl工具通过GET请求方式查看当前的容器列表。

    [root@controller ~]# curl -X GET -H "X-Auth-Token: $OS_AUTH_TOKEN" $OS_STORAGE_URL
    test_container
    # 创建容器(REST PUT 等价 swift post),用于后续 ACL 实验
    [root@controller ~]# curl -i -X PUT -H "X-Auth-Token: $OS_AUTH_TOKEN" $OS_STORAGE_URL/acl_container
  4. 通过PUT请求,上传文件到对象存储并命名为test.txt,然后查看容器内的对象列表。

    [root@controller ~]# curl -X PUT -H "X-Auth-Token: $OS_AUTH_TOKEN" --data-binary "@/root/test.txt" $OS_STORAGE_URL/acl_container/test.txt
    [root@controller ~]#
    [root@controller ~]#
    [root@controller ~]# curl -X GET -H "X-Auth-Token: $OS_AUTH_TOKEN" $OS_STORAGE_URL/acl_container
    test.txt
    # 创建容器
    

作业2:通过api请求查看到容器内的对象列表后截图上传。

  • 下面是使用python实现的swift对象上传参考代码。

    from swiftclient import client
    
    # 配置参数 (对应 admin-openrc.sh)
    auth_url = 'http://controller:35357/v3'
    user = 'admin'
    key = '000000'
    project = 'admin'
    domain = 'xiandian'
    
    # 建立连接 (v3 版本必须通过 os_options 指定 Domain)
    conn = client.Connection(
        authurl=auth_url,
        user=user,
        key=key,
        auth_version='3',
        os_options={
            'user_domain_name': domain,
            'project_domain_name': domain,
            'project_name': project
        }
    )
    
    # 上传文件
    container = 'acl_container'
    local_file = '/root/test.txt'
    object_name = 'test.txt'
    
    try:
        # 如果容器不存在,先创建容器(可选,防止报错)
        conn.put_container(container)
        
        with open(local_file, 'rb') as f:
            conn.put_object(container, object_name, contents=f)
        print('Uploaded:', object_name)
    except Exception as e:
        print('Error:', e)

Horizon界面使用对象存储

Horizon登录地址192.168.100.10/dashboard,使用域xiandian、用户名admin、密码000000登录。

在项目->对象存储菜单内可以上传、删除文件,也可以对容器进行管理。

1700395313493.png

配置Swift作为Glance后端存储

Glance的后端存储默认为本地e文件系统,这个实验是将Glance的后端存储配置为Swift对象存储,上传到OpenStack平台的镜像文件会被保存在对象存储中。

  1. 修改Glance的配置文件/etc/glance/glance-api.conf

    [glance_store]
    # 添加swift存储
    stores = file,http,swift
    # 默认使用swift存储
    default_store = swift
    # 设置多项目存储以及项目授权
    swift_store_multi_tenant = true
    swift_store_admin_tenants = admin
    # 设置允许创建容器
    swift_store_create_container_on_put = true
  2. 重启Glance相关服务。

    [root@controller ~]# systemctl restart openstack-glance*
  3. 登录Horizon控制台上传镜像并验证对象存储内的镜像文件。

    1700464991941.png 1700465024334.png

作业3:上传镜像文件后能在容器菜单内看到上传的镜像后截图。

Swift ACL(访问控制)

通常情况下,容器和对象的默认权限仅限所属项目(租户)和用户。要把访问权限授予其它用户或公开访问,可以使用容器级别的 ACL(Access Control List)。

  • 核心概念:

    • Container ACL(容器 ACL):只影响某个容器及其对象(常用)。
    • Account ACL(帐户 ACL):影响整个账户下的所有容器(较少用)。
  • 容器ACL存储在以下两个常用的元数据头中:

    • X-Container-Read:谁可以读取(GET、HEAD)容器内对象。
    • X-Container-Write:谁可以写入(PUT、POST、DELETE)容器内对象。
  • 简单语法(V1):逗号分隔的条目,例如:

.r:*,.rlistings
  • .r:* 表示公开读取(任何人无需令牌即可下载对象)。
  • .rlistings 允许列出容器(前提是对象本身也可读)。

示例 1 — 公开容器(任何人可列出与下载):

# 使容器公开可读
[root@controller ~]# swift post test_container --read-acl ".r:*,.rlistings"
# 验证1(查看容器元数据)
[root@controller ~]# swift stat test_container
1765332944695.png
# 验证2(使用新的ssh会话,在未经身份验证的情况下访问容器)
# 现在原始会话中查看容器的访问链接、复制链接即变量OS_STORAGE_URL的值
[root@controller ~]# swift auth
[root@controller ~]# export OS_STORAGE_URL=http://controller:8080/v1/AUTH_f9ff39ba9daa4e5a8fee1fc50e2d2b34
[root@controller ~]# export OS_AUTH_TOKEN=gAAAAABpOUX1bjBMpxHlolqLa1b1M1c6YGieK6v_9amCasW9Dlwrp74z-8j1bg9VNcsi4ARkL9XPTXjUS0ll__V3oFDU-B2hvgtvM9b8pmfkU2_KgEuBvkU47CAHWfyHP2ulGbIq41mvCotRdpAl1Qi12ig0p-jXAN0zXHtAb1etC3J5kJe77_0

# 打开一个新的ssh会话直接执行以下命令查看容器内的对象列表
[root@controller ~]# curl http://controller:8080/v1/AUTH_f9ff39ba9daa4e5a8fee1fc50e2d2b34/test_container
test.txt

# 接着下载容器内的对象到本地并且重命名为download.txt
[root@controller ~]# curl -o download.txt http://controller:8080/v1/AUTH_f9ff39ba9daa4e5a8fee1fc50e2d2b34/test_container/test.txt
[root@controller ~]# cat download.txt
hello world

示例 2 — 授予某项目的成员读/写权限(替换为真实项目 ID):

下面的实验回到第一个ssh会话中执行

# 只允许指定项目的成员读写(需要替换 PROJECT_ID)
[root@controller ~]# swift post acl_container --read-acl "PROJECT_ID:*" --write-acl "PROJECT_ID:*"

提示:可以通过 openstack project list 或从管理员控制台获得demo项目的ID并替换掉命令中的 PROJECT_ID

# 验证1(查看容器元数据)
[root@controller ~]# swift stat acl_container
# 验证1(查看容器元数据)
[root@controller ~]# swift stat acl_container
# 设置环境变量,切换到非 admin 的用户(如 demo):
[root@controller ~]# export OS_PROJECT_NAME=demo   # 切换项目
[root@controller ~]# export OS_USERNAME=demo       # 切换用户
# 获取当前demo用户的TOKEN
[root@controller ~]# openstack token issue -c id -f value
gAAAAABpOU2PSYsXWG0QXTWB3pzAH0dLK4uGfWAhm7bem9wKHFtc-jZy_k0EpgtOhtwpjHfmhJ1GPMuFlj8zKoerLn89hhWIccLrU7eJzdURBTKZwSLKFulZ_E8n5fTpyOf68I_g48dCUShys6Dd4L-uOtI6HD2sMjSGabFYv1nY6PlZyBYaQAI
# 将上述返回的TOKEN复制并替换下面命令中的<TOKEN>,该命令使用demo用户的TOKEN请求了acl_container容器的对象列表
[root@controller ~]# curl  -H "X-Auth-Token: <TOKEN>" http://controller:8080/v1/AUTH_f9ff39ba9daa4e5a8fee1fc50e2d2b34/acl_container/
test.txt

# 以下命令用demo用户的TOKEN下载了acl_container容器内的对象test.txt并重命名为demo.txt
[root@controller ~]# curl -o demo.txt -H "X-Auth-Token: <TOKEN>" http://controller:8080/v1/AUTH_f9ff39ba9daa4e5a8fee1fc50e2d2b34/acl_container/test.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    14  100    14    0     0    800      0 --:--:-- --:--:-- --:--:--   823
[root@controller ~]# cat demo.txt
hello world

作业4:把 acl_container 设为公开并用非管理员账号(如 demo)用 curl 验证能否列出以及下载对象,截屏上传。