使用 minio 作为对象存储进行重建时出错

使用 minio 作为对象存储时重建显示

I, [2022-09-01T00:37:48.192311 #1]  INFO -- : cd /var/www/discourse & sudo -E -u discourse bundle exec rake s3:upload_assets
rake aborted!
Aws::S3::Errors::BadRequest: 解析 PUT 请求 '/' 时出错

我已为 minio 配置了多个域

minio.example.com (作为 minio 访问控制台)
s3.example.com (作为 minio 的 API)

还添加了存储桶名称
bucket.s3.example.com (作为 minio 的 API)

所有域都已正确授权,并且尝试使用 Cyberduck 使用 s3.example.combucket.s3.example.com 连接到账户可用于上传和下载文件。

我的 app.yml s3 设置

  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: anything
  discourse_s3_endpoint: https://s3.example.com
  DISCOURSE_S3_ACCESS_KEY_ID: *****
  DISCOURSE_S3_SECRET_ACCESS_KEY: ********
  #Discourse_s3_cdn_url: 
  DISCOURSE_S3_BUCKET: bucket
  DISCOURSE_S3_BACKUP_BUCKET: bucket/backups
  DISCOURSE_BACKUP_LOCATION: S3

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets

我搜索了相关问题但没有解决,如果使用 vultr 对象存储则工作正常。那么,是 minio 和 discourse 不能很好地协同工作,但我见过有人成功使用 minio。请大家帮忙,我相信这个问题很快就会得到解决。

1 个赞

您是否遵循了使用对象存储进行上传(S3 和克隆)

2 个赞

是的,我看了很多遍,也看了 使用您运行的 MinIO 存储服务器为您的 Discourse 实例进行基本操作指南

问题仍未解决,让我困扰的是,使用 Cyberduck 的 amazon s3 传输协议连接到 minio 帐户是可用的,而且我认为我的 minio 设置似乎运行良好。

1 个赞

您是否已确认您的 MinIO 配置是否能与 MinIO 客户端或其他机制(例如 ?)正常配合使用?并且您是否正确使用了针对 MinIO 的 URL 和配置?

我的建议是,首先确保所有内容都符合 MinIO 和 s3cmd 命令行客户端的要求——我从未听说过这个“Cyberduck”客户端(有充分理由:它是 Windows 和 Mac 的,我是 Linux 用户),而且我无法确认它是否符合 MinIO 和其他要求,因为它在其标识上写着“AWS S3”,很可能它是为亚马逊的完整 S3 API 而设计的,而不是 S3 兼容/合规的项目。在您尝试工作的机器上或附近设置命令行上的 MinIO 客户端 (mcli),然后尝试手动将文件推送到您的存储桶。

此外,请注意,据我所知,MinIO 的 DISCOURSE_S3_BACKUP_BUCKET 被设计为独立的存储桶,而不是现有存储桶内的子路径。这也有可能破坏当前设置,这就是为什么我编写的示例以及您提供的“操作指南”链接将其设置为单独的存储桶。

我这里没有关于实际发出的具体请求的信息——URL 路径等,系统在发出 BadRequest 查询时使用了这些信息。看起来是因为它只有 INFO 级别的日志记录。在 rake 进程中是否可以获得调试级别的日志记录,@pfaffman(或其他更熟悉 Discourse 方面的人)?

另外,请确保您也为 Discourse 配置传递了 DISCOURSE_S3_INSTALL_CORS_RULE: false——如果应用程序重建器/烘焙器尝试推送 CORS 规则,将会导致错误消息。

2 个赞

我使用 mcli 创建了一个新存储桶,并手动将一个文件发送到该存储桶

我在存储桶中看到了发送的文件,这是否意味着我已按照正确的步骤安装了 minio,我使用 docker compose 和我的 docker-compose.yml 文件安装了 minio


version: '3'

services:
  minio:
    image: minio/minio:latest
    container_name: minio
    restart: always
    ports:
      - "9000:9000"
      - "9001:9001"
    
    volumes:
      - ./:/data

    environment:
      MINIO_ROOT_USER: ***** 
      MINIO_ROOT_PASSWORD: *****
      MINIO_SERVER_URL: https://s3.example.com
      MINIO_BROWSER_REDIRECT_URL: https://minio.example.com/

    command: server --console-address ":9001" /data

volumes:
  minio:

然后转到 Web 控制台,创建两个新存储桶,并将对象存储的访问策略设置为公共

我使用 Nginx proxy manager 将 minio.example.com 转发到端口 9001,将 s3.example.combucket-name.example.com 转发到端口 9000

DISCOURSE_S3_BACKUP_BUCKET:我尝试使用一个单独的存储桶,并将域名转发配置为端口 9000 到该存储桶,但它不起作用

转发什么端口? 80/443 以便 http/https 可以工作? 这就是它所需要的全部,您永远不需要单独配置端口 9000。单独的存储桶将具有与 s3.example.com 相同的端点 - 它不是独立的东西,所以您的配置是错误的。另外请记住,在 MinIO 的术语中,如果您使用路径身份验证,则会得到 s3.example.com/BUCKETNAME,或者使用您应该使用的 DNS 身份验证 BUCKET.s3.example.com 作为您需要在 nginx 端接受并转发到内部端口 9000 的 URL 端点。您不必在此端进行配置,这需要在 MinIO 端进行配置。

MinIO 客户端支持 pathdns 风格的设置。据我所知,Discourse 使用基于 URL 的机制来识别存储桶,而不是路径风格的设置(如果您愿意,可以纠正我,Discourse 开发人员)。因此,您正在配置的“默认”行为是不正确的。

现在,我的 MinIO 不是 Docker 化的,但为了符合 Discourse 的要求,您需要使用 DNS 风格的路径,即您需要在环境变量 MINIO_DOMAIN=BASEDOMAINHERE 中进行设置,以便 Discourse 希望使用的 DNS 风格路径能够工作。在您的示例中,它将是 MINIO_DOMAIN=s3.example.com,然后您需要配置 NGINX 以将 Host 头传递到端口 9000 或运行基本非控制台服务器组件的任何位置的后端。然后,您需要确保 NGINX 接受 *.s3.example.com 并将其正确转发到 MinIO 容器。这是 MinIO 联合设置的一部分,但对于具有多个存储桶名称的单节点实例,如果您希望它与 Discourse 一起工作,则需要正确配置。

然而,不幸的是,您必须从这里开始深入研究 MinIO 的配置。我在文档中指定的要求之一是您拥有一个完全正常运行且配置正确的 MinIO 实例,这超出了 Discourse 站点的范围。我相信您的 MinIO 没有正确配置 DNS 风格的存储桶解析,就像 AWS S3 那样(例如 bucket.s3.example.com),因此无法正常工作。

请注意,我为 Lubuntu 项目 (lubuntu.me)(Ubuntu 的一个变体,使用 LXQt)运行 Discourse 实例,使用的是具有DNS 风格存储桶 URL 解析的 MinIO,以使其与 Discourse 正常工作,否则对 BUCKET.basedomain.example.com 的请求将会失败。

有趣的是,我甚至提到您需要正确配置 MinIO 以支持 DNS 风格的路径,如果您在设置 MinIO 时没有包含 MINIO_DOMAIN,它将不会执行 DNS 风格的路径。对于 Discourse 来说,这是必需的,正如我在我的注意事项部分第 3 项中所述:

2 个赞

嗨,兄弟,设置 MINIO_DOMAIN 可以消除上述错误,但会出现新的错误

Aws::S3::Errors::MalformedXML: 您提供的 XML 格式不正确或未通过我们发布的架构验证。

我觉得我快成功了,因为 discourse 可以正确访问我的 minio,我尝试删除所有 minio 存储桶,重建 discourse,它会提示指定的存储桶不存在

通过这篇文章 Discover AWS Official Knowledge Center Articles | AWS re:Post 我认为这个错误是由存储桶权限引起的?通过教程 将文件和图片上传设置为 S3 我看到似乎需要添加存储桶策略


               "s3:PutObject",
               "s3:PutObjectAcl",
               "s3:PutObjectVersionAcl",
               ....

但是 minio 不支持 Acl,提示不支持的操作“s3:PutObjectAcl”。

也许,我可能需要使用旧版本的 minio,这可能会让事情变得更容易 :sweat_smile:

1 个赞

问题已解决,方法是不通过 app.yml 添加对象存储变量。否则将发生 MalformedXML 错误,只需将 s3 参数添加到设置中。安装 minio 时需要添加 MINIO_DOMAIN 变量(我使用的是单节点部署)。

感谢 @teward 的帮助

现在我可以使用 minio 上传文件和进行备份。

1 个赞

不,MinIO 不支持 PutObjectAcl。它支持存储桶级别的权限,但不支持该 API 形式的对象级别 ACL。

MinIO 不支持完整的 AWS API。请参阅 AIStor Object Store Documentation 以了解完全支持的 API 集。

需要添加 MINIO_DOMAIN 才能实现 DNS 样式存储桶,这就是无效 PUT 发生的原因。一旦我们进一步了解,我们就会看到 XML 中的失败与允许在模式中使用的内容进行对比。请确保您永远不要设置任何包含 MinIO 实际支持的受支持集之外的变量的策略。

请记住:S3 兼容不意味着它与所有支持的 AWS S3 API 变量/端点/值 100% 匹配。

1 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.