Да, сам MinIO Server Pool считается отказоустойчивым если вы всё сделали по рекомендациям. Но никто не отменял возможности того что у вас полностью выйдет из строя всё оборудование, находящееся в одном дата-центре, ну или же просто плановое отключение серверов.

В таком случае вам будет необходимо наличие полной копии данных в другом дата-центре, желательно в другом городе. Благодаря репликации корзин вы можете копировать все данные на другой пул серверов. Т.е. повышаете уровень отказоустойчивости.

minio bucket replication

Source vs Target

Давайте сразу определимся с этими понятиями: Source (Источник) - это та корзина (bucket) на которой вы настраиваете репликацию, Target (Цель) - это корзина (bucket) на другом пуле серверов, которая выбрана как место назначения.

minio bucket replication source target

Версионность

Крайне рекомендуется использовать одинаковые версии кластеров или пулов MinIO. Т.е. если на Source у вас стоит MinIO v1, то и на Target тоже должен стоять MinIO v1. Да конечно работать будет и с разными версиями, но могут вылезти проблемы, которые придётся решать самому. Для примера у меня были
корзины ( bucket ) с большим количеством ошибок репликации и как только я обновил все пулы серверов до последней версии всё реплицировалось на ура.

Также каждая корзина ( bucket ) должна быть создана с включенной опцией версионности.

Пользователь для репликации

Конечно же самым правильным решением перед настройкой репликации будет создание отдельного пользователя, учетные данные которого будут использоваться MinIO для доступа к файлам и их дальнейшей репликации.

Политика для пользователя, под которым будет производится репликация:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetReplicationConfiguration",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:GetBucketLocation",
                "s3:GetBucketVersioning",
                "s3:GetBucketObjectLockConfiguration",
                "s3:GetEncryptionConfiguration"
            ],
            "Resource": [
                "arn:aws:s3:::*"
            ],
            "Sid": "EnableReplicationOnBucket"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetReplicationConfiguration",
                "s3:ReplicateTags",
                "s3:AbortMultipartUpload",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetObjectVersionTagging",
                "s3:PutObject",
                "s3:PutObjectRetention",
                "s3:PutBucketObjectLockConfiguration",
                "s3:PutObjectLegalHold",
                "s3:DeleteObject",
                "s3:ReplicateObject",
                "s3:ReplicateDelete"
            ],
            "Resource": [
                "arn:aws:s3:::*"
            ],
            "Sid": "EnableReplicatingDataIntoBucket"
        }
    ]
}

Чтобы выдать права пользователю для создания правил репликации применяется следующая политика:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "admin:SetBucketTarget",
                "admin:GetBucketTarget"
            ],
            "Effect": "Allow",
            "Sid": "EnableRemoteBucketConfiguration"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetReplicationConfiguration",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:GetBucketLocation",
                "s3:GetBucketVersioning",
                "s3:GetObjectRetention",
                "s3:GetObjectLegalHold",
                "s3:PutReplicationConfiguration"
            ],
            "Resource": [
                "arn:aws:s3:::*"
            ],
            "Sid": "EnableReplicationRuleConfiguration"
        }
    ]
}
mcli admin user add minio1 repluser
mcli admin policy create minio1 repluser /tmp/repluser.json
mcli admin policy attach minio1 repluser --user=repluser 

Достаточно будет создать на одном сервере ( Source ), но если репликация будет двухсторонней то на обоих пулах серверов.

Server-Side Bucket Replication

Как мы уже поняли для репликации необходимо указать Target. Под Target подразумевается корзина ( bucket ) на другом пуле серверов. При этом имя корзины ( bucket ) может отличаться от имени Source.

При каждой записи объекта в Source корзину MinIO проверяет правила репликации и применяет их. При необходимости можно настроить репликацию уже существующих объектов и также репликацию операций удаления.

minio file delete replication

  • Для начала создадим корзины для Source и Target. Напоминаю имеется в виду то что это два разных пула серверов.
mcli mb minio1/testbucketsource
mcli mb minio2/testbuckettarget
  • На Source пуле выполняем ( !!!! Перед созданием прочтите всю статью до конца ):
mcli replicate add minio1/testbucketsource --remote-bucket 'http://ROOTUSER:CHANGEME123@172.31.144.8:9000/testbucket
target'
  • Проверяем что обе корзины пусты:
mcli ls minio1/testbucketsource
mcli ls minio2/testbuckettarget
  • Загрузим файл на Source :
mcli cp /tmp/repluser.json minio1/testbucketsource
  • Проверяем что файл присутствует на обоих пулах серверов:
mcli ls minio1/testbucketsource
mcli ls minio2/testbuckettarget
[2023-10-11 23:09:29 +06] 1.3KiB STANDARD repluser.json
[2023-10-11 23:09:29 +06] 1.3KiB STANDARD repluser.json

Active-Active (Two-Way) Bucket Replication

На первой схеме видно, что я нарисовал стрелки в обе стороны. Это не ошибка так как одна корзина может быть, как Source так и Target. Соответственно всё что записывается в Server Pool1 попадает и в Server Pool2 и наоборот.

Для того чтобы создать двухстороннюю репликацию делаем всё тоже самое только также выполняем команду mcli replicate и на Target ( !!!! Перед созданием прочтите всю статью до конца ).

mcli replicate add minio1/testbucketsource --remote-bucket 'http://ROOTUSER:CHANGEME123@172.31.144.8:9000/testbuckettarget'
mcli replicate add minio1/testbuckettarget --remote-bucket 'http://ROOTUSER:CHANGEME123@172.31.144.11:9000/testbucketsource'

Ресинхронизация

Если вдруг по, какой-то причине подключение между пулами серверов прервалось и ваши данные не синхронизируются можно воспользоваться командой mc replicate resync bucket.

При использовании данной команды происходит проверка всех объектов в Source, после чего каждый объект помещается в очередь на репликацию не зависимо от того был ли он реплицирован ранее. Но если в Target есть объекты, которые полностью соответствуют объектам в Source включая метаданные, то естественно эти объекты не будут синхронизироваться заново.

mcli replicate export minio1/testbucketsource | grep arn
"Destination":{"Bucket":"arn:minio:replication::ff92a1d3-324b-4e35-a7e6-d7319e51f1d8:testbuckettarget"}
mcli replicate resync start minio1/testbucketsource --remote-bucket "arn:minio:replication::ff92a1d3-324b-4e35-a7e6-d7319e51f1d8:testbuckettarget"
mcli replicate resync status minio1/testbucketsource
Resync status summary:
 arn:minio:replication::ff92a1d3-324b-4e35-a7e6-d7319e51f1d8:testbuckettarget
   Status: Pending
   Replication Status | Size (Bytes)    | Count
   Replicated         | 0 B             | 0
   Failed             | 0 B             | 0

Репликация операций удаления

Как я уже говорил выше есть возможность реплицировать операция удаления. Т.е. если удалить какой-то объект на Source он также удалится и на Target.

По умолчанию эта опция при создании репликации корзин включена. Если мы настраиваем репликацию в графике, то необходимо включать эту опцию руками через nmcli. Но всё зависит ещё и от версии самого сервера MinIO.

mcli replicate add minio1/testbucketsource --remote-bucket 'http://ROOTUSER:CHANGEME123@172.31.144.8:9000/testbuckettarget' --replicate "delete,delete-marker"

Репликация существующих объектов

Также, как и с ситуацией выше Репликация существующих объектов по умолчанию включена.

Для включения используется команда mc replicate add --replicate с опцией existing-objects.

Если же у вас уже настроена репликация, то всегда можно воспользоваться командой mc replicate update --replicate.

mcli replicate add minio1/testbucketsource --remote-bucket 'http://ROOTUSER:CHANGEME123@172.31.144.8:9000/testbuckettarget' --replicate "existing-objects"

Изменение настроек репликации

Если вы уже настроили правило репликации, но вам вдруг понадобилось что-то изменить можно использовать команду mcli replicate export alias.

Но не забываем, что перед изменением любой конфигурации лучше сделать сперва бэкап.

mcli replicate export minio1/testbucketsource > /tmp/repl.json
mcli replicate export minio1/testbucketsource
mcli replicate update minio1/testbucketsource --id ckjdbncv4aqg10tqmbcg --replicate "delete"
mcli replicate export minio1/testbucketsource
mcli replicate update minio1/testbucketsource --id ckjdbncv4aqg10tqmbcg --replicate "delete,delete-marker,existing-objects"

Синхронная и асинхронная репликация

При использовании асинхронной репликации объект помещается в корзину сразу и только потом добавляется в очередь. Т.е. если Target недоступен, то в любом случае объект будет записан.

При использовании синхронной репликации важно чтобы Target всегда был доступен, иначе вы потратите больше времени на загрузку объекта. При синхронной репликации MinIO пытается реплицировать объект до завершения исходной операции PUT. MinIO возвращает успешную операцию PUT независимо от того, были ли успешной попытка репликации. Хотя у меня была ситуация, когда файл не удавалось загрузить из-за того, что на Target не хватало места на HDD.

Рекомендуется использовать асинхронную репликацию. Да есть конечно возможность потерять какие-то количество данных при выходе из строя Source но по крайней мере чаще встречаются обрывы на каналах связи между дата-центрами.

Как проходит репликация

Мы уже ни раз в этой статье затрагивали тему постановки в очередь на репликацию. Если какой-то объект не удаётся реплицировать трижды, то этот объект исключается из очереди. Также через какое-то время при сканировании объектов эти исключенные объекты будут снова помещены в очередь.

mcli replicate status minio1/testbucketsource
  Replication status since 29 minutes
  172.31.144.8:9000
  Replicated:                   1 objects (1.3 KiB)
  Queued:                        0 objects, 0 B (avg: 0 objects, 0 B ; max: 0 objects, 0 B)
  Workers:                      0 (avg: 0; max: 0)
  Transfer Rate:                0 B/s (avg: 0 B/s; max: 0 B/s
  Latency:                      1ms (avg: 1ms; max: 1ms)
  Link:                          online (total downtime: 0 seconds)
  Errors:                       0 in last 1 minute; 0 in last 1hr; 0 since uptime

Статусы репликации:

Статус Описание
PENDING Это состояние говорит о том, что объект еще не реплицирован. Объекты с этим статусом помещаются в очередь репликации. Также если объект настроен на множественную репликацию, то статус не изменится пока не пройдёт репликация на все Target
COMPLETED Объект успешно реплицирован
FAILED Объект не удалось реплицировать. Объекты с этим статусом снова помещаются в очередь при возможности
REPLICA Объект сам по себе является копией из удаленного источника

Собственно, сам процесс можно разбить на 2 варианта:

  • PENDING -> COMPLETED

  • PENDING -> FAILED -> COMPLETED

Также для проверки наличия неудачных попыток можно использовать команду mcli replicate backlog minio1/testbucketsource --full