文章内容

2025/11/3 6:11:46,作 者: 黄兵

OpenStack Swift InternalClient 具体作用分析

🧩 一、InternalClient 是什么

InternalClientOpenStack Swift 内部提供的一个 Python 客户端类
它允许 Swift 的中间件或后台任务直接访问 Swift 的存储系统,而不需要通过外部 HTTP 接口

换句话说:

InternalClient = Swift 内部调用 Swift 自己的 REST API 的“本地接口”。

🧠 二、使用场景

在 Swift 生态中,你可能会遇到这些情况:

场景 传统方式(HTTP) 更推荐方式(InternalClient)
在中间件中读取 container 元数据 发送 HTTP 请求到 proxy 端口 使用 InternalClient.get_container_metadata()
在后台脚本中列出对象 curl 到 REST API 使用 InternalClient.iter_objects()
检查对象是否存在 HTTP HEAD 请求 使用 InternalClient.head_object()

使用 InternalClient 的好处是:

  • 不需要经过 proxy 的外部认证;

  • 性能更高(直接与 Swift 进程通信);

  • 不会触发外部防火墙、认证系统;

  • 可以复用 Swift 的配置文件。

⚙️ 三、如何配置 InternalClient

1️⃣ 新建配置文件

/etc/swift/internal-client.conf(通常已经自带模板)

[DEFAULT]
# Internal client 日志配置
log_name = internal
log_facility = LOG_LOCAL0
log_level = INFO

# Swift 集群的配置路径
swift_dir = /etc/swift

[pipeline:main]
pipeline = proxy-server

[app:proxy-server]
use = egg:swift#proxy
set log_name = internal

这个文件告诉 InternalClient 如何连接到 Swift 内部的各个服务。

2️⃣ 在代码中导入并初始化

from swift.common.internal_client import InternalClient

ic = InternalClient(
    '/etc/swift/internal-client.conf',  # 配置文件路径
    'my-internal-app',                  # 应用名称,可任意
    3,                                  # 重试次数
    use_replication_network=False       # 是否使用 replication 网络
)

3️⃣ 调用示例

# 获取 container 元数据
meta = ic.get_container_metadata('AUTH_user', 'my-container')
print(meta)
# 输出示例:
# {'x-container-read': '.r:*,.rlistings', 'x-container-write': '', 'x-container-object-count': '12', ...}

# 判断是否为公有读
if '.r:*' in meta.get('x-container-read', ''):
    print("Public Read Container")

# 获取 object 元数据
obj_meta = ic.get_object_metadata('AUTH_user', 'my-container', 'test.jpg')
print(obj_meta)

🔒 四、权限说明

InternalClient 是“内部客户端”,它是以 系统用户身份 访问 Swift 的,
不需要 Token 或外部认证

但它必须运行在:

  • proxy 节点 或 有访问 Swift proxy 服务的节点上;

  • 且有 /etc/swift 配置文件的读取权限。

🧰 五、在中间件中常见用法

在你的中间件中,可以这样集成:

from swift.common.internal_client import InternalClient
from swift.common.swob import HTTPForbidden

class ContainerAclCheckMiddleware(object):
    def __init__(self, app, conf):
        self.app = app
        self.ic = InternalClient('/etc/swift/internal-client.conf', 'acl-check', 3)

    def __call__(self, env, start_response):
        path = env.get('PATH_INFO', '')
        try:
            _, ver, account, container, obj = path.split('/', 4)
        except ValueError:
            return self.app(env, start_response)

        if not container:
            return self.app(env, start_response)

        meta = self.ic.get_container_metadata(account, container)
        read_acl = meta.get('x-container-read', '')
        if '.r:*' in read_acl or '.rlistings' in read_acl:
            # 公有读,直接放行
            return self.app(env, start_response)
        else:
            # 私有,需要验证 token
            token = env.get('HTTP_AUTHORIZATION')
            if not token:
                return HTTPForbidden()(env, start_response)

        return self.app(env, start_response)


其他相关推荐:

1、Ubuntu 22.04 安装 OpenStack Swift

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

3、Ubuntu 22.04 安装 OpenStack Swift 存储策略

4、OpenStack Swift 配置 Memcached

5、OpenStack Swift 与 AWS S3 对比

6、OpenStack Swift 优质文章收集

分享到:

发表评论

评论列表