MinIO 复制最佳实践

MinIO 复制最佳实践

必须保护有价值的数据免遭损坏和丢失,但不断增加的数据量和日益分散的数据使这项任务变得艰巨。MinIO 包括多种数据保护机制,这篇博文重点介绍复制最佳实践,这是对软件定义对象存储的关键保护,有助于创建和维护多云数据湖,因此您可以在最佳运行的地方运行工作负载,使用您的组织的最新数据。

我们将建立一个地理分布的基础设施,我们在远距离的多站点中拥有一个多节点多驱动器 MinIO 集群。这将使我们能够真正理解大规模复制工作,以帮助我们了解地理负载平衡和高可用性所需的基础设施。

MinIO 包括多种复制数据的方法,因此您可以选择最佳方法来满足您的需求。我们已经在博文中介绍了用于在存储桶级别复制对象的基于存储桶的主动-主动复制,以及用于复制存储桶中特定对象的批量复制,这为您提供了更精细的控制

我们对灵活性的专注意味着 MinIO 支持现场和存储桶级别的复制,使您能够根据应用程序的需要微调复制配置,并尽可能多地控制流程。使用 S3 样式策略和 PBAC,跨多个 MinIO 部署的 IAM 仍然保护数据。复制同步对象和桶的创建、删除和修改。此外,它还同步元数据、加密设置和安全令牌服务 (STS)。请注意,您可以使用站点复制或存储桶复制,但不能同时使用两者。如果您已经在运行存储桶复制,则必须禁用它才能使站点复制正常工作。

自从我们引入多站点主动-主动复制以来,我们的重点一直放在性能上,而不会对集群执行的现有操作造成任何额外的影响。这使您可以跨多个数据中心、云复制数据,甚至可以满足灾难恢复需求,其中一个站点离线不会降低可用性。复制配置完全在服务器端处理,具有“设置好后不用管”的精神,其中使用 MinIO 的应用程序不需要以任何方式修改,一切都在服务器端处理。

数据保护远比复制重要。MinIO 还包括:

  • 加密:MinIO 支持静态加密传输中加密。这确保了从发出调用的那一刻起直到对象被放入桶中,数据在事务的所有方面都被加密。

  • Bitrot Protection:物理磁盘上的数据损坏有多种原因。这可能是由于电压尖峰、固件错误、错误的读写等原因造成的。MinIO 确保这些被捕获并即时修复以确保数据完整性。

  • 擦除编码:MinIO 没有使用 RAID 来确保数据冗余,这会增加额外的性能开销,而是使用这种数据冗余和可用性功能来动态重建对象,而无需任何额外的硬件或软件。

  • 安全访问 ACL 和 PBAC:支持带有内置 IDP 的 IAM S3 样式策略,请参阅MinIO 最佳实践 - 安全和访问控制以获取更多信息。

  • 分层:对于不经常访问的数据,您可以将数据虹吸到另一个运行 MinIO 的冷存储中,这样您就可以在最好的硬件上优化最新数据,而无需使用的数据占用空间。

  • 对象锁定和保留:MinIO 支持对象锁定(保留),它强制执行一次写入并为基于持续时间和无限期合法持有的许多操作做好准备。这允许关键数据保留合规性并满足 SEC17a-4(f)、FINRA 4511(C) 和 CFTC 1.31(c)-(d) 要求。

在本教程中,我们将进一步介绍复制,以更深入地介绍多站点复制,并向您展示实施基于复制的存储架构的最佳实践。MinIO 的复制架构不会干扰集群的现有操作,确保不会出现性能下降。

基础设施概览

下面我们有一个图表来显示我们的基础设施设置的简要概述。

我们有三个不同的 MinIO 站点,每个站点在地理上彼此相距很远。在每个站点中,我们让 NGINX 将请求代理到后端的三个 MinIO 服务器。如果其中一个 MinIO 服务器离线,NGINX 确保请求被路由到其他 MinIO 节点。Unbound 是一种 DNS 服务,它将解析内部运行的 MinIO 服务器的 DNS 请求。我们可以使用外部 DNS,例如 Route53,但这需要专用域。所以我们将使用一个虚拟主机名,而不是在所有虚拟机上minio.local编辑文件;/etc/hosts我们只需要更新/etc/resolv.confUnbound 服务器的 IP 地址。


MinIO Site Replication.jpeg


所以它引出了一个问题,为什么 MinIO 推荐多站点设置作为最佳实践,而不是单站点、单节点和单驱动器配置?有几个原因。当您考虑数据完整性时,您不仅会考虑数据的安全位置,还会希望它具有冗余性和可扩展性,以便您的现有操作不受影响。在此设置中,我们正在考虑堆栈各个方面的冗余:

首先让我们谈谈冗余

  • 每个节点有多个磁盘,以防磁盘出现故障。使用纠删码 MinIO 可确保在磁盘发生故障时将数据复制到其他磁盘。

  • 我们将其设置为多个节点具有多个磁盘,以防整个节点脱机,站点中还有其他节点可以提供数据。

  • 在最坏的情况下,当整个站点由于电源故障或网络问题而离线时,数据可以在另一个可以提供服务的位置使用。

但我们还需要考虑可扩展性和维护性。在管理基础架构时,事情几乎不是一成不变的。

  • 此设置允许您向池中添加更多服务器,以便随着数据大小和要求的增加水平扩展您的基础设施。您甚至可以在维护时从池中删除节点,这样您就可以在故障发生之前抢占它们。

  • 整个网站也是如此。您将能够在不破坏现有站点的情况下添加一个全新的站点并在地理级别进行扩展。例如,假设您想使用 Anycast DNS,您可以将您的请求定向到地理位置更近的站点,以便您的最终用户尽快获取数据。如果您必须对特定站点进行维护,您可以将其从处理流量中移除,直到它准备好使用 MinIO 多站点配置再次接收流量。

基础设施设置


在本教程中,我们将以分布式方式设置软件定义的基础设施(MinIO、VPC、Unbound、NGINX),并共享用于启动它的代码。结果将是三个相同的 MinIO 部署,每个都在自己的区域中,所有三个之间都有主动-主动复制。这种设计的优点是,如果特定站点中的一个 MinIO 节点出现故障,其他节点可以处理流量,因为 NGINX 会将流量重新路由到健康的节点。此外,如果整个站点离线,其他两个站点可以在不对应用程序进行任何更改的情况下处理读取和写入,因为写入其他站点的任何数据都将在在线后离线的站点上进行复制。

它已准备好生产并可根据您的要求进行定制,基础设施即代码已按如下方式设置。

MinIO 站点 1:https://github.com/minio/blog-assets/tree/main/replication-best-practices/terraform/infra/minio-1

MinIO 站点 2:https://github.com/minio/blog-assets/tree/main/replication-best-practices/terraform/infra/minio-2

MinIO 站点 3:https://github.com/minio/blog-assets/tree/main/replication-best-practices/terraform/infra/minio-3

通用模块:https://github.com/minio/blog-assets/tree/main/replication-best-practices/terraform/infra/modules

以下是将要部署的组件:

  • VPC:这是我们所有资源将在虚拟专用网络中启动的地方。将其想象成数据中心内您自己的笼子/机架。

  • Unbound:这是一项 DNS 服务,您可以在其中为节点在本地添加区域记录以解析 MinIO 主机名。我们为什么需要这个?原因有两个:首先我们需要确保 MinIO 服务器主机名在配置中按顺序排列。其次,管理所有这些记录可能会变得笨拙/etc/hosts,因为每次添加或删除节点时,都需要在所有节点上更新主机文件,这可能会变得很麻烦。这允许我们在 Unbound 中更新它,我们将指向/etc/resolv.confUnbound 的 IP 来解析主机名。

  • NGINX:在之前的一篇博文中,我们展示了如何将 NGINX 用作反向代理,并将多个 MinIO 服务器作为后端。在配置站点到站点复制时,我们将提供 NGINX 端点而不是单个 MinIO 服务器,这样,如果其中一个 MinIO 节点脱机,请求将被路由到其他 MinIO 节点。

  • MinIO:最后但同样重要的是,我们将在多节点、多驱动器设置中设置 MinIO 集群。我们将在多个区域复制此配置,以便我们可以真正测试跨地域的站点到站点复制。

总的来说,我们将在 3 个不同的地区推出 3 种相同的基础设施配置。

专有网络


我们将通过调用目录中的模块来启动 VPC。

这就是我们调用模块的方式

module "hello_minio_vpc" {
    source = "../modules/vpc"

    minio_cidr_block   = var.hello_minio_cidr_block
    minio_cidr_newbits = var.hello_minio_cidr_newbits

    minio_public_igw_cidr_blocks   	= var.hello_minio_public_igw_cidr_blocks
    minio_private_ngw_cidr_blocks  	= var.hello_minio_private_ngw_cidr_blocks
    minio_private_isolated_cidr_blocks = var.hello_minio_private_isolated_cidr_blocks

}

这是我们定义 VPC 模块的地方

https://github.com/minio/blog-assets/blob/main/replication-best-practices/terraform/infra/modules/vpc/main.tf

未绑定


使用我们在上一步中创建的 VPC 资源,我们将在该 VPC 的公共子网中启动 Unbound。这也可以在私有子网中,只要您不需要对 DNS 服务器的任何其他外部访问。

module "hello_minio_instance_unbound" {
    source = "../modules/instance"

    minio_vpc_security_group_ids = [module.hello_minio_security_group_unbound.minio_security_group_id]
    minio_subnet_id      	= module.hello_minio_vpc.minio_subnet_public_igw_map[local.common_public_subnet]

    minio_ami_filter_name_values = var.hello_minio_ami_filter_name_values
    minio_ami_owners         	= var.hello_minio_ami_owners
    minio_instance_type      	= var.hello_minio_instance_type
    minio_instance_key_name  	= var.hello_minio_instance_key_name

    minio_instance_user_data 	= templatefile("../templates/_user_data_unbound.sh.tftpl", {})

}

大多数 Unbound 配置是通过_user_data_unbound.sh.tftpl管理的。

但是为了配置 Unbound,我们需要我们将启动的 MinIO 服务器的私有 IP,但此时 MinIO 服务器还没有启动。

一旦 MinIO 服务器启动并且您拥有它们的私有 IP,请将以下配置添加到指令/etc/unbound/unbound.conf.d/myunbound.conf下方文件的第 2 行server:您需要将其添加到每个站点上运行的每个未绑定服务器,并使用每个 MinIO 节点的各自私有 IP。

local-zone: minio.local transparent
local-data: "server-1.minio.local A <MinIO Node 1 Private IP>"
local-data: "server-2.minio.local A <MinIO Node 2 Private IP>"
local-data: "server-3.minio.local A <MinIO Node 3 Private IP>"

使用 A 记录更新上面的配置后,请务必重新启动 Unbound 以使更改生效

systemctl restart unbound

NGINX集群


NGINX 博客文章中,我们使用了以下配置,我们在此处稍作调整以匹配 MinIO 服务器主机名

upstream minio_server {
    server server-1.minio.local:9000;
    server server-2.minio.local:9000;
    server server-3.minio.local:9000;
}

server {
    listen   	80 default_server;

    ignore_invalid_headers off;
    client_max_body_size 0;
    proxy_buffering off;
    proxy_request_buffering off;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_connect_timeout 300;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding off;

        proxy_pass http://minio_server;
    }
}

我们将使用此配置启动 NGINX 服务器

module "hello_minio_instance_nginx" {
    source = "../modules/instance"

    minio_vpc_security_group_ids = [module.hello_minio_security_group_nginx.minio_security_group_id]
    minio_subnet_id      	= module.hello_minio_vpc.minio_subnet_public_igw_map[local.common_public_subnet]

    minio_ami_filter_name_values = var.hello_minio_ami_filter_name_values
    minio_ami_owners         	= var.hello_minio_ami_owners
    minio_instance_type      	= var.hello_minio_instance_type
    minio_instance_key_name  	= var.hello_minio_instance_key_name

    minio_instance_user_data 	= templatefile("../templates/_user_data_nginx.sh.tftpl", {
    	unbound_ip = module.hello_minio_instance_unbound.minio_instance_private_ip
    })

    minio_instance_user_data_replace_on_change = false

    depends_on = [
    	module.hello_minio_instance_unbound
    ]

}

我们启动的 NGINX VM 将使用来自_user_data_nginx.sh.tftpl的用户数据,这有助于我们在启动 VM 后立即安装和配置 NGINX。

MinIO集群


最后但同样重要的是,我们将使用下面的配置启动 3 个 MinIO 节点,这不仅会启动 VM,还会附加一个用于数据的辅助卷。

module "hello_minio_instance_minio" {
    source = "../modules/instance"

    for_each = var.hello_minio_private_ngw_cidr_blocks

    minio_vpc_security_group_ids = [module.hello_minio_security_group_minio.minio_security_group_id]
    minio_subnet_id      	= module.hello_minio_vpc.minio_subnet_private_ngw_map[each.key]

    minio_ami_filter_name_values = var.hello_minio_ami_filter_name_values
    minio_ami_owners         	= var.hello_minio_ami_owners
    minio_instance_type      	= var.hello_minio_instance_type
    minio_instance_key_name  	= var.hello_minio_instance_key_name

    minio_instance_user_data 	= templatefile("../templates/_user_data_minio.sh.tftpl", {
        minio_version = "20221207005637.0.0"
        unbound_ip = module.hello_minio_instance_unbound.minio_instance_private_ip
    })

}

resource "aws_ebs_volume" "ebs_volume_minio" {

    for_each = var.hello_minio_private_ngw_cidr_blocks

    availability_zone = each.key

    size = 10
}

resource "aws_volume_attachment" "volume_attachment_minio" {

    for_each = var.hello_minio_private_ngw_cidr_blocks

    device_name = "/dev/xvdb"
    volume_id = aws_ebs_volume.ebs_volume_minio[each.key].id
    instance_id = module.hello_minio_instance_minio[each.key].minio_instance_id

}

使用连接的 HDD 启动 VM 后,我们将格式化并将其挂载到_user_data_minio.sh.tftpl中。它还具有/etc/default/minio与我们的多节点设置相匹配的 MinIO 配置。

理想情况下,您在此设置中唯一需要手动配置的是将 MinIO 服务器的私有 IP 作为 DNS A 记录添加到 Unbound,其余的应该根据我们预设的 DNS 名称自动配置。

在所有节点上启动 MinIO 服务。您可以使用 Ansible 之类的工具或手动执行

systemctl start minio

站点复制配置


接下来我们将实际启动我们在前面的步骤中配置的基础设施。这涉及使用 Terraform 启动虚拟机,然后使用 MinIOmc客户端配置站点复制。

进入每个minio-1minio-2minio-3目录并运行 terraform 命令以启动基础设施。

cd minio-1
terraform apply

cd minio-2
terraform apply

cd minio-3
terraform apply

一旦所有三个站点都启动,输出将显示 Unbound 和 NGINX 的公共 IP 以及类似于下面的 3 个 MinIO 节点的私有 IP。

hello_minio_aws_instance_nginx = "<public_ip>"
hello_minio_aws_instance_unbound = "<public_ip>"
minio_hostname_ips_map = {
    "server-1.minio.local" = "<private_ip>"
    "server-2.minio.local" = "<private_ip>"
    "server-3.minio.local" = "<private_ip>"
}

不要忘记使用我们在上一步配置未绑定时显示的配置来配置未绑定 A 记录。

登录站点 1 中的其中一个 NGINX 节点,mc alias为所有三个站点进行设置。确保任何站点中都没有数据。

/opt/minio-binaries/mc alias set minio1 http://<nginx_public_ip> minioadmin minioadmin
/opt/minio-binaries/mc alias set minio2 http://<nginx_public_ip> minioadmin minioadmin
/opt/minio-binaries/mc alias set minio3 http://<nginx_public_ip> minioadmin minioadmin

让我们对其进行设置,以便它在所有 3 个站点上进行复制

$ /opt/minio-binaries/mc admin replicate add minio1 minio2 minio3

Requested sites were configured for replication successfully.

验证 3 个站点是否配置正确

/opt/minio-binaries/mc admin replicate info minio1

SiteReplication enabled for:

Deployment ID                    	| Site Name   	| Endpoint
f96a6675-ddc3-4c6e-907d-edccd9eae7a4 | minio1      	| http://<nginx_public_ip>
0dfce53f-e85b-48d0-91de-4d7564d5456f | minio2      	| http://<nginx_public_ip>
8527896f-0d4b-48fe-bddc-a3203dccd75f | minio3      	| http://<nginx_public_ip>

检查以确保复制正常工作

/opt/minio-binaries/mc admin replicate status minio1

Bucket replication status:
No Buckets present

Policy replication status:
●  5/5 Policies in sync

User replication status:
No Users present

Group replication status:
No Groups present

在 minio1 中创建一个桶

/opt/minio-binaries/mc mb minio1/testbucket

将任何对象添加到桶中

/opt/minio-binaries/mc cp my_object  minio1/testbucket

列出其他站点中的对象,在本例中为 minio2 和 minio3

/opt/minio-binaries/mc ls minio2/testbucket
[2022-12-19 18:52:09 UTC] 3.0KiB STANDARD my_object

/opt/minio-binaries/mc ls minio3/testbucket
[2022-12-19 18:52:09 UTC] 3.0KiB STANDARD my_object

如您所见,将数据复制到其他站点几乎是即时的,即使它们在不同的地理位置也是如此。

站点复制和自动化使能多云


云操作模型允许您运行相同的设置和配置,无论它是物理数据中心还是云上的虚拟资源。这是有效处理海量数据以及必须实时进行的人工智能和分析的唯一方法。您还必须针对多云架构进行设计,该架构可以收集数据并与计算资源/同类最佳服务共享数据,无论它们位于何处,以确保工程和 DevOps 团队管理基础设施的开销尽可能低.

站点复制通过设置多个站点并在服务器端处理复制来强调多云架构的功能。这使您可以简化跨多个站点的数据管理、元数据和配置,而无需任何额外开销来在一个节点甚至整个站点出现故障时修改应用程序。我们向您展示了一个如何部署到多个站点/区域以配置复制的工作示例,同时我们还部署了高可用性,将每个多站点 MinIO 集群放置在一个单独的区域中以实现强大的业务连续性和灾难恢复策略


上一篇 下一篇