文章内容

2024/7/16 23:31:33,作 者: 黄兵

Ubuntu 22.04 安装 OpenStack Swift 存储策略

创建存储策略

每个用户定义的存储策略都使用策略索引号和名称进行声明。如果策略被弃用或是默认策略,还可以使用其他字段。存储策略的一般格式为:

[storage-policy:N]
name =
default =
(optional) deprecated=

//Here's an example
[storage-policy:1]
name =  level1
(optional) deprecated=yes

存储策略索引 [storage-policy] 是必需的。 N 是存储策略索引,其值为 0 或正整数。不能使用已经在使用的数字,并且一旦使用后不能更改。

策略名称 ( name = ) 是必需的,并且只能包含字母(不区分大小写)、数字和破折号。不能使用已经在使用的名称,但名称可以更改。然而,在更改之前,请考虑这种更改对使用当前名称的系统的影响。

必须指定一个存储策略为默认策略。在定义一个或多个存储策略时,请务必也声明一个策略 0。这使得管理策略更容易并防止错误。如前所述,如果没有用户定义的策略,那么默认情况下将使用内部引用的存储策略 0。可以随时指定不同的策略为默认策略;然而,在进行更改之前,请考虑其对系统的影响。

当存储策略不再需要时,可以将其标记为已弃用( deprecated=yes ),而不是删除。策略不能同时是默认和已弃用的。当策略被标记为已弃用时:

  • 不会出现在 /info 中
  • 允许在预先存在的容器上成功进行 PUT/GET/DELETE/POST/HEAD 请求
  • 不能应用于新容器(将返回 400 Bad Request

虽然在此安装中不需要存储策略,但我们包含了一些例子以展示它们如何添加和使用。

要声明存储策略,请编辑 /etc/swift/ 目录中的 swift.conf 文件。建议在 [swift-hash] 部分下方放置存储策略。

在 OpenStack Swift 中Policy 0 是强制必需的! 如果 swift.conf 里没有 [storage-policy:0],Swift 会拒绝启动

[storage-policy:0]
name = gold
default = yes

之后在定义其它的存储策略:

[storage-policy:1]
name = level2
default = yes

[storage-policy:2]
name = level3
deprecated = yes

配置 rsync

编辑 /etc/default/rsync 文件,修改如下内容:

RSYNC_ENABLE=true

创建 /etc/rsyncd.conf 文件,内容如下:

uid = swift
gid = swift
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid

[account]
max connections = 25
path = /srv/node/
read only = false
lock file = /var/lock/account.lock

[container]
max connections = 25
path = /srv/node/
read only = false
lock file = /var/lock/container.lock

[object]
max connections = 25
path = /srv/node/
read only = false
lock file = /var/lock/object.lock

开启 rsync 服务器:

service rsync start

开启之后,我们可以使用如下方式测试 rsync: 

rsync localhost::
rsync localhost::account
rsync localhost::container
rsync localhost::object

创建环构造器文件

由于上一篇文章:Ubuntu 24.04 安装 OpenStack Swift 我们使用的是虚拟环境安装,所以这里如果需要启动环构造文件,我们需要启动虚拟环境,否则会出现:
Command 'swift-ring-builder' not found, but can be installed with: apt install swift
Command 'swift-ring-builder' not found, but can be installed with: apt install swift
Command 'swift-ring-builder' not found, but can be installed with: apt install swift

启动虚拟环境:

cd /opt/swift
source venv/bin/activate

之后执行如下命令:

cd /etc/swift
swift-ring-builder account.builder create 10 1 1
swift-ring-builder container.builder create 10 1 1
swift-ring-builder object.builder create 10 1 1

向构造文件中添加磁盘

首先,添加第一块磁盘(d1)到构造文件中:

swift-ring-builder account.builder add r1z1-127.0.0.1:6202/d1 100
swift-ring-builder container.builder add r1z1-127.0.0.1:6201/d1 100
swift-ring-builder object.builder add r1z1-127.0.0.1:6200/d1 100

接下来,添加下一块磁盘(d2)到构造文件当中:

swift-ring-builder account.builder add r1z1-127.0.0.1:6202/d2 100
swift-ring-builder container.builder add r1z1-127.0.0.1:6201/d2 100
swift-ring-builder object.builder add r1z1-127.0.0.1:6200/d2 100

构造环

使用如下命令来构造 2 个环:

cd /etc/swift
swift-ring-builder account.builder rebalance
swift-ring-builder container.builder rebalance
swift-ring-builder object.builder rebalance

配置 Swift 日志

/etc/rsyslog.d 目录中创建一个名为 0-swift.conf 的文件,内容如下:

local0.* /var/log/swift/all.log

创建日志目录:

mkdir /var/log/swift

为目录设置权限,以便日志可以写入目录:

sudo chmod 750 /var/log/swift
sudo chown -R syslog:adm /var/log/swift

重启 Rsyslog,开始记录 Swift 日志

使用如下命令重启 Rsyslog:

service rsyslog restart

通过上面的配置,所有 OpenStack Swift 的日志文件都会写入到 all.log 文件里,长时间会导致文件非常大,我们可以通过以下方式实现日志的轮转:

创建一个 logrotate 配置文件 /etc/logrotate.d/swift

/var/log/swift/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 640 syslog adm
    sharedscripts
    postrotate
        service rsyslog reload > /dev/null
    endscript
}

这样就可以实现日志的轮转,避免 all.log 日志文件无限增长。

关于 logrotate 的详细说明,可以查看这篇文章:OpenStack Swift 使用 logrotate 自动分割日志

配置代理服务

找到 /etc/swift/swift.conf 文件,修改 swift_hash_path_prefix 和 swift_hash_path_suffix 值:

swift_hash_path_suffix = changeme
swift_hash_path_prefix = changeme

这里推荐设置一个前缀和后缀至少是 32 字符的随机字符串,目的是为了防止拒绝服务攻击(DOS)。

如果有人知道了哈希前缀和后缀,它可以确定您的对象实际存储的分区。攻击者可以在分区中生成容器和对象,以及重复的向一个分区上传大文件来填满您的硬盘。

我们可以使用如下命令生成一个随机的 32 位字符串,命令如下:

head -c 32 /dev/random | base64

确保两个哈希值足够安全,这可以让分区路径难以猜测。

配置 CORS(跨域资源共享)

为了支持 Web 前端(如 JavaScript、Dropzone 等)直接上传文件到对象存储,我们需要启用 CORS 中间件。在第一篇文章中我们已经安装了 oslo.middleware 库,现在需要在配置文件中启用它。

编辑 /etc/swift/proxy-server.conf 文件:

sudo nano /etc/swift/proxy-server.conf

1. 修改 Pipeline 顺序(至关重要) 找到 [pipeline:main] 部分。必须将 cors 加入到管道中,并且位置非常关键:必须放在 tempurlratelimitauthtoken 之前

建议的顺序如下:

[pipeline:main]
# 注意 cors 的位置
pipeline = catch_errors gatekeeper healthcheck proxy-logging cors cache container_sync bulk tempurl ratelimit authtoken keystoneauth proxy-logging proxy-server

2. 添加 CORS 过滤器配置 在文件的末尾(或者 [filter:tempauth] 附近),添加以下配置块。这将允许浏览器进行跨域访问。

[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
# 允许的来源域名,生产环境建议指定具体域名,测试环境可用 *
allowed_origin = *
# 允许的方法
allow_methods = GET, POST, PUT, DELETE, HEAD, OPTIONS
# 允许的 Header,前端直传时通常需要这些
allow_headers = Content-Type, X-Auth-Token, X-Storage-Token, X-Container-Meta-Access-Control-Allow-Origin, X-CSRFToken, Origin, Accept, X-Requested-With
# 暴露给前端的 Header
expose_headers = Content-Type, X-Trans-Id, ETag, X-Storage-Url, Access-Control-Allow-Origin

现在我们增加自己编写的认证中间件,由于我们是通过虚拟环境的安装方式,所以中间件的位置在:/opt/swift/venv/lib/python3.12/site-packages/swift/common/middleware/,我们直接将我们编写的中间件复制到这个目录下面,复制完成之后可以开启代理服务。

开启代理服务

我们现在开启代理服务进程:

cd /opt/swift
# 切换到虚拟环境 
source venv/bin/activate
swift-init proxy start
# 你将会看到
Starting proxy-server...(/etc/swift/proxy-server.conf)

设置 TempAuth 认证和 Switft 授权

开启 memcahed

使用如下命令开启 memcahed:

service memcached start

如果没有安装 Memcached,可以参考这篇文章:OpenStack Swift 配置 Memcached

在 proxy-server.conf 中添加用户

我们找到 /etc/swift/proxy-server.conf 会有如下描述 TempAuth 的部分:

[filter:tempauth]
use = egg:swift#tempauth
# You can override the default log routing for this filter here:
...
# Here are example entries, required for running the tests:
user_admin_admin = admin .admin .reseller_admin
user_admin_auditor = admin_ro .reseller_reader
user_test_tester = testing .admin
user_test_tester2 = testing2 .admin
user_test_tester3 = testing3
user_test2_tester2 = testing2 .admin
user_test5_tester5 = testing5 service

我们可以在默认的 TempAuth 账户下面添加一条正确的信息来创建自己的用户和账户:

user_test_tester3 = testing3
user_myaccount_me = secretpassword .admin .reseller_admin

账户必须还要设置另外两个字段,在文件中找到并设置 allow_account_management 和 account_autocreate 值设置位 true

# If set to 'true' any authorized user may create and delete accounts; if
# 'false' no one, even authorized, can.
allow_account_management = true
#
# If set to 'true' authorized accounts that do not yet exist within the Swift
# cluster will be automatically created.
account_autocreate = true

需要注意的是:如果删除 allow_account_management 和 account_autocreate 的注释,这两个参数一定要定格,不能又空格,否则会报错。我就是没有定格写导致冲洗 proxy 出现错误。

启动服务和重启代理

必须先启动账户服务进程然后才能访问账户。

swift-init account start
Starting account-server...(/etc/swift/account-server.conf)

swift-init container start
Starting container-server...(/etc/swift/container-server.conf)

swift-init object start
Starting object-server...(/etc/swift/object-server.conf)

由于我们更改了代理服务的配置文件,所以我们还需要重启代理服务进程:

swift-init proxy restart

Signal proxy-server  pid: 5240  signal: 15
proxy-server (5240) appears to have stopped
Starting proxy-server...(/etc/swift/proxy-server.conf)

在 Ubuntu 24.04 系统中更推荐使用服务来启动,增加 /etc/systemd/system/openstack-swift-object.service 文件:

[Unit]
Description=OpenStack Swift Object Server
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-object-server /etc/swift/object-server.conf
Restart=on-failure
User=swift
Group=swift
Environment=SWIFT_CONFIG_DIR=/etc/swift

[Install]
WantedBy=multi-user.target

增加 /etc/systemd/system/openstack-swift-proxy.service 文件:

[Unit]
Description=OpenStack Swift Proxy Server
After=network.target

[Service]
# 【关键修改】这里必须是 swift-proxy-server,而不是 swift-object-server
ExecStart=/opt/swift/venv/bin/swift-proxy-server /etc/swift/proxy-server.conf
Restart=on-failure
User=swift
Group=swift
Environment=SWIFT_CONFIG_DIR=/etc/swift

[Install]
WantedBy=multi-user.target

增加 /etc/systemd/system/openstack-swift-account.service 文件:

[Unit]
Description=OpenStack Swift Account Server
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-account-server /etc/swift/account-server.conf
# 仅在服务异常退出时自动重启
Restart=on-failure
User=swift
Group=swift
Environment=SWIFT_CONFIG_DIR=/etc/swift

[Install]
WantedBy=multi-user.target

增加 /etc/systemd/system/openstack-swift-container.service 文件:

[Unit]
Description=OpenStack Swift Container Server
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-container-server /etc/swift/container-server.conf
# 仅在服务异常退出时自动重启
Restart=on-failure
User=swift
Group=swift
Environment=SWIFT_CONFIG_DIR=/etc/swift

[Install]
WantedBy=multi-user.target

确保在修改或创建这些服务文件之后,重新加载 systemd 配置并启动服务:

sudo systemctl daemon-reload

sudo systemctl enable openstack-swift-proxy.service
sudo systemctl enable openstack-swift-account.service
sudo systemctl enable openstack-swift-container.service
sudo systemctl enable openstack-swift-object.service
sudo systemctl start openstack-swift-proxy.service
sudo systemctl start openstack-swift-account.service
sudo systemctl start openstack-swift-container.service
sudo systemctl start openstack-swift-object.service

确认所有服务已经成功启动:

sudo systemctl status openstack-swift-proxy.service
sudo systemctl status openstack-swift-account.service
sudo systemctl status openstack-swift-container.service
sudo systemctl status openstack-swift-object.service

通过这些步骤,所有 OpenStack Swift 服务应该能够通过 systemd 正常启动和管理。


账户认证

现在,我们使用 cURL 来验证添加到 TempAuth 中的 Swift 账户:

 curl -v -H 'X-Auth-User: myaccount:me' -H 'X-Auth-Key: secretpassword' http://localhost:8080/auth/v1.0/

我们会得到如下类似内容:

*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /auth/v1.0/ HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> X-Auth-User: myaccount:me
> X-Auth-Key: secretpassword
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< X-Auth-Token: AUTH_tk6b34020f78fb4e499c856cc71f004c03
< X-Storage-Token: AUTH_tk6b34020f78fb4e499c856cc71f004c03
< X-Auth-Token-Expires: 86399
< X-Storage-Url: http://localhost:8080/v1/AUTH_myaccount
< Content-Length: 0
< X-Trans-Id: txa2ecf0b9ffcc4016b485b-00669782bc
< X-Openstack-Request-Id: txa2ecf0b9ffcc4016b485b-00669782bc
< Date: Wed, 17 Jul 2024 08:37:16 GMT
<
* Connection #0 to host localhost left intact

HTTP 响应包含 X-Auth-Token:

< X-Auth-Token: AUTH_tk6b34020f78fb4e499c856cc71f004c03

验证账户访问

现在我们已经可以发送请求。这里,我门将试图列出账户中的容器。系统应该返回 204 No Content 响应,因为我们没有创建任何容器:

curl -v -H 'X-Auth-Token:  AUTH_tk6b34020f78fb4e499c856cc71f004c03'  http://localhost:8080/v1/AUTH_myaccount

其结果如下:

*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /v1/AUTH_myaccount HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> X-Auth-Token:  AUTH_tk6b34020f78fb4e499c856cc71f004c03
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 204 No Content
< Content-Type: text/plain; charset=utf-8
< Content-Length: 0
< X-Account-Container-Count: 0
< X-Account-Object-Count: 0
< X-Account-Bytes-Used: 0
< X-Timestamp: 1721285003.77649
< X-Put-Timestamp: 1721285003.77649
< Vary: Accept
< X-Trans-Id: tx461bc524bfa84e9a93b20-006698b98b
< X-Openstack-Request-Id: tx461bc524bfa84e9a93b20-006698b98b
< Date: Thu, 18 Jul 2024 06:43:23 GMT
<
* Connection #0 to host localhost left intact

创建容器

账户和容器仅仅是 SQLite 数据库。对每个账户来说,均有一个账户数据库存储着该账户中所有容器列表。对每个容器来说,均有一个容器数据库存储着该容器中所有对象的列表,这些数据库都存储在集群中,并且拥有与对象一样的复制方式。

p>为了在账户中创建一个容器,我们这里使用 HTTP 的 PUT 请求来把容器名称追加在存储 URL 后面。

使用前面的令牌,执行下面的命令创建一个名为 mycontainer 的容器:

curl -v -H 'X-Auth-Token:  AUTH_tk6b34020f78fb4e499c856cc71f004c03' -X PUT  http://localhost:8080/v1/AUTH_myaccount/mycontainer

执行结果如下:

*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> PUT /v1/AUTH_myaccount/mycontainer HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> X-Auth-Token:  AUTH_tk6b34020f78fb4e499c856cc71f004c03
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 Created
< Content-Type: text/html; charset=UTF-8
< Content-Length: 0
< X-Trans-Id: tx0df3ad69a8c944879dd37-006698bc04
< X-Openstack-Request-Id: tx0df3ad69a8c944879dd37-006698bc04
< Date: Thu, 18 Jul 2024 06:53:56 GMT
<
* Connection #0 to host localhost left intact

说明我们已经创建了一个容器,这条请求背后发生着这样的过程:

  • 代理服务进程向账户服务进程发送一个更新账户数据库请求,将新建的容器更新到账户数据库当中。
  • 代理服务进程给容器发送一个创建容器数据库的请求。

上传对象

现在我们使用 Swift 命令行界面来上传一个文件,命令如下:

swift -A http://localhost:8080/auth/v1.0/ -U myaccount:me -K secretpassword upload mycontainer /root/35.jpg

请求被集群接收。一个完整的流程是这样的:

首先,集群计算出数据将要被存放在哪里。对象环使用对象存储位置(账户名称、容器名称和对象名称)来定位副本分区的节点。一旦分区被找到,数据就会被分发到每个存储节点的分区。同时,还需要一个判断!三个对象至少又两个写成功才会通知客户端上传成功。接下来,容器数据库更新以反映新的加入对象。

配置后台一致性服务 (Background Services)

OpenStack Swift 不仅仅只有 4 个主服务进程,它还依赖大量的后台进程来负责数据的复制(Replication)、更新(Updating)和审计(Auditing)。如果没有这些进程,集群将无法维持数据一致性,删除操作也可能无法完成。

我们需要为每一个后台进程创建 Systemd 服务文件。

1. 对象存储后台进程 (Object Services)

创建 swift-object-replicator.service(负责数据副本同步):

[Unit]
Description=OpenStack Swift Object Replicator
After=network.target

[Service]
# 指向虚拟环境
ExecStart=/opt/swift/venv/bin/swift-object-replicator /etc/swift/object-server.conf
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

创建 swift-object-updater.service(负责更新容器列表):

[Unit]
Description=OpenStack Swift Object Updater
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-object-updater /etc/swift/object-server.conf
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

创建 swift-object-auditor.service(负责检查文件损坏):

[Unit]
Description=OpenStack Swift Object Auditor
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-object-auditor /etc/swift/object-server.conf
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

2. 容器存储后台进程 (Container Services)

创建 swift-container-replicator.service

[Unit]
Description=OpenStack Swift Container Replicator
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-container-replicator /etc/swift/container-server.conf
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

创建 swift-container-updater.service

[Unit]
Description=OpenStack Swift Container Updater
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-container-updater /etc/swift/container-server.conf
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

创建 swift-container-auditor.service

[Unit]
Description=OpenStack Swift Container Updater
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-container-updater /etc/swift/container-server.conf
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

3. 账户存储后台进程 (Account Services)

创建 swift-account-replicator.service

[Unit]
Description=OpenStack Swift Account Replicator
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-account-replicator /etc/swift/account-server.conf
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

创建 swift-account-auditor.service

[Unit]
Description=OpenStack Swift Account Auditor
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-account-auditor /etc/swift/account-server.conf
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

创建 swift-account-reaper.service(负责清理已删除账户的残留数据):

# /etc/systemd/system/openstack-swift-account-reaper.service
[Unit]
Description=OpenStack Swift Account Reaper
After=network.target

[Service]
ExecStart=/opt/swift/venv/bin/swift-account-reaper /etc/swift/account-server.conf
# 仅在服务异常退出时自动重启
Restart=on-failure
User=swift
Group=swift

[Install]
WantedBy=multi-user.target

4. 启动并启用所有后台服务

创建完上述文件后,执行以下命令使配置生效并启动服务:

# 重载 Systemd 配置
sudo systemctl daemon-reload

# 启动并设置开机自启(对象服务后台)
sudo systemctl enable --now openstack-swift-object-replicator
sudo systemctl enable --now openstack-swift-object-updater
sudo systemctl enable --now openstack-swift-object-auditor

# 启动并设置开机自启(容器服务后台)
sudo systemctl enable --now openstack-swift-container-replicator
sudo systemctl enable --now openstack-swift-container-updater
sudo systemctl enable --now openstack-swift-container-auditor

# 启动并设置开机自启(账户服务后台)
sudo systemctl enable --now openstack-swift-account-replicator
sudo systemctl enable --now openstack-swift-account-auditor
sudo systemctl enable --now openstack-swift-account-reaper

通过 sudo systemctl status openstack-swift-object-replicator 等命令检查服务是否处于 active (running) 状态。

此时,所有的 Swift 进程都应该在运行了,并且 OpenStack Swift 也应该被完整的安装了。


参考资料:

1、《对象存储:OpenStack Swift 应用、管理与开发》


其它相关推荐:

1、OpenStack Swift 配置 Memcached

2、如何卸载 OpenStack Swift

3、OpenStack Swift 自定义认证中间件

4、Ubuntu 22.04 安装 OpenStack Swift

5、only IPv6 vps 访问GitHub等网站的方法

分享到:

发表评论

评论列表