Cat

Собственное S3-хранилище на базе MinIO

В этой статье разберём, что такое S3 и Объектные хранилища, где его взять, а также как поднять своё собственное на VPS используя MinIO.

Все статьи

Icon Link

Реклама

Icon Link
Применение Docker proDream 09 Январь 2025 Просмотров: 259

В статье "Гайд по первоначальной настройке VPS" я упомянул об утилите для создания бэкапов — ReBack. В процессе разработки стояла задача найти компромисс для хранения бекапов, который соответствовал бы следующим параметрам: надежно, просто, быстро и надолго - таким решением мне показалось использование S3 хранилища.

После публикации статьи начали поступать вопросы о том "как создать и настроить своё S3-хранилище?"

Поэтому в этой статье мы рассмотрим:

  • какие бывают виды хранилищ?
  • что из себя представляет S3 хранилище?
  • какие есть способы получить S3 хранилище?
  • как развернуть собственное S3 хранилище с помощью MinIO?

 

Что такое S3 и объектное хранилище?

S3 (Simple Storage Service) — это облачный сервис для хранения файлов, предоставляемый компанией Amazon. Он предназначен для хранения неструктурированных данных (или объектов) в интернете. Основное преимущество S3 заключается в его удобстве и масштабируемости: пользователи могут хранить практически неограниченное количество данных и управлять ими через простой интерфейс.

Со временем протокол и стандарт, изначально разработанные Amazon, стали использоваться другими компаниями для создания альтернативных решений. Такие сервисы называют S3-совместимыми. Они поддерживают те же API и функционал, что и оригинальный Amazon S3, что делает их удобным выбором для разработчиков.

Стоит отметить, что название S3 стало именем нарецательным, то есть оно применимо как и к оригинальному продукту от Amazon, так и к S3-совместимым решениям, будь то Minio или S3 от хостинг провайдера.

Объектное хранилище — это система, где данные хранятся не в традиционной файловой структуре, а в виде объектов. Каждый объект состоит из:

  1. Данных (содержимое файла).
  2. Метаданных (дополнительной информации о данных, например, даты создания или типа файла).
  3. Уникального идентификатора (обычно называемого ключом или названием объекта).

Этот подход к хранению данных обладает несколькими важными преимуществами:

  • Простота масштабирования для хранения огромных объёмов данных.
  • Возможность эффективного доступа через API, вместо традиционного файлового интерфейса.

Объектные хранилища идеально подходят для работы с большими объёмами неструктурированных данных, таких как:

  • Изображения и видео.
  • Резервные копии.
  • Журналы.
  • Научные данные.

 

Как получить S3-хранилище

Существует два основных способа обзавестись S3-хранилищем: использование облачных решений или развёртывание собственного (Self-Hosted) хранилища.

 

Облачные решения

Облачные S3-хранилища предоставляются хостинг-провайдерами, которые берут на себя все технические аспекты, такие как управление ресурсами, настройка доступов и поддержка инфраструктуры. Пользователю нужно лишь выбрать подходящий тариф, оплатить его и получить данные для подключения.

Преимущества облачных решений:

  • Простота настройки и использования.
  • Удобный веб-интерфейс для управления хранилищем.
  • Автоматическое масштабирование и техническая поддержка.

Примеры облачных решений:

  • Amazon AWS S3 — оригинальное S3-хранилище от Amazon.
  • TimeWeb — удобное S3-совместимое решение с серверами на территории России.
  • Cloud.ru — предоставляет 15 ГБ бесплатного хранилища на момент написания статьи.
  • Другие хостинги — существует множество провайдеров с различными ценами и условиями, но все они совместимы с протоколом Amazon S3.

 

Self-Hosted решения

Self-Hosted хранилища разворачиваются на собственных серверах. Этот вариант требует больше усилий и знаний, но предоставляет полный контроль над данными и их безопасностью.

Преимущества Self-Hosted решений:

  • Полная автономность и контроль над данными.
  • Возможность настройки под собственные нужды.
  • Отсутствие зависимости от сторонних провайдеров.

Примеры Self-Hosted решений:

  • MinIO — масштабируемое объектное хранилище, полностью совместимое с API S3.
  • Zenko — платформа для управления несколькими облачными хранилищами и гибридными облаками.
  • Ceph — распределённая система хранения с высокой отказоустойчивостью.
  • Другие — например, Nextcloud (для обмена файлами) или OpenStack (для создания частных облаков).

 

Что мы будем использовать?

В этой статье мы будем использовать MinIO, так как это популярное, простое в настройке и экономичное решение.

MinIO — высокопроизводительная платформа для объектного хранения, полностью совместимая с Amazon S3 API. Она может быть развёрнута как на локальных серверах, так и в облачных инфраструктурах. MinIO поддерживает основные возможности объектного хранилища, такие как:

  • Управление версиями объектов.
  • Создание бакетов.
  • ACL (списки управления доступом).

MinIO ориентирован на масштабируемость и простоту использования, что делает его отличным выбором для Self-Hosted решений.

Что ещё понадобится?

  1. VPS 
    Если у вас ещё нет настроенного VPS, вы можете ознакомиться с инструкцией в статье "Гайд по первоначальной настройке VPS".
  2. Docker 
    MinIO будет установлен в контейнере, поэтому необходим Docker. Установку Docker я также описывал в вышеупомянутом гайде.
  3. Caddy (веб-сервер) 
    Для обработки запросов и управления HTTPS-соединением мы будем использовать Caddy — простой и удобный веб-сервер. Подробнее об этом сервере можно почитать в статье "Веб-сервер Caddy - Альтернатива NGINX и Apache".
  4. Доменное имя 
    Для доступа к MinIO по HTTPS нужно доменное имя, настроенное с помощью A-записи. Если вы не знаете, как это сделать, ознакомьтесь с постом "Docker 5.1 Почтовый сервер на Docker Mailserver - настройка домена".

 

Docker Compose

 

Директория проекта

Для удобства работы создадим отдельную директорию для проекта, чтобы все необходимые файлы находились в одном месте.

Если вы подключены к VPS от имени пользователя root, его домашняя директория будет /root/. Если используется другой пользователь, то домашняя директория будет /home/user_name/. Все команды ниже выполняются из домашней директории текущего пользователя.

Сначала создадим директорию для проекта и сразу перейдём в неё:

mkdir minio && cd minio
  • minio — это имя директории, в которой будет располагаться наш проект.

 

Проверьте, что вы находитесь в нужной директории, выполнив команду pwd. Результат должен быть следующим:

  • Для пользователя root: /root/minio/
  • Для другого пользователя: /home/user_name/minio/

 

Создание файла docker-compose.yml

Теперь создадим файл docker-compose.yml, где будут описаны сервисы для MinIO и Caddy.

Чтобы создать и открыть файл, воспользуемся редактором nano. Если файл ещё не существует, nano автоматически создаст его при сохранении изменений.

Выполним команду:

nano docker-compose.yml
  • nano — это текстовый редактор, простой и удобный для работы в терминале.

 

Файл docker-compose.yml

После выполнения команды откроется окно редактора, в котором нам необходимо описать конфигурацию сервисов.

Первая строка будет ключом services::

services:

Важно! Формат YAML требует строгого соблюдения отступов! Каждый уровень вложенности должен быть отделён ДВУМЯ ПРОБЕЛАМИ!

 

Сервис Caddy

Начинаем с описания сервиса для Caddy.

После строки services: делаем два пробела и прописываем ключ caddy:. На следующей строке, после отступа, прописываем параметры для этого сервиса.

Нам нужно указать 5 ключей:

  • image: — образ для использования. Указываем caddy:latest для последней версии образа.
  • container_name: — задаём имя контейнера caddy. Если имя не указано, контейнер получит имя по умолчанию, например, minio-caddy-1, что менее удобно.
  • restart: — политика перезапуска контейнера. Используем значение unless-stopped, чтобы контейнер перезапускался автоматически, пока его не остановят вручную.
  • ports: — перенаправление портов. Прописываем внешний и внутренний порты:
    • - "80:80" — для HTTP.
    • - "443:443" — для HTTPS.
  • volumes: — монтирование локальных директорий и файлов в контейнер:
    • - ./Caddyfile:/etc/caddy/Caddyfile — локальный файл Caddyfile будет заменять файл внутри контейнера.
    • - caddy_data:/data и - caddy_config:/config — Docker volume для хранения данных и конфигурации, чтобы данные сохранялись при перезапуске контейнера.

 

Готовое описание сервиса Caddy:

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config

 

Сервис MinIO

После описания сервиса caddy оставляем пустую строку и на уровне двух отступов добавляем ключ minio:.

В этом сервисе пропишем семь ключей, некоторые из которых уже знакомы:

  • image: — используем образ minio/minio:latest.
  • container_name: — задаем имя контейнера minio.
  • restart: — используем политику unless-stopped, чтобы контейнер перезапускался при сбоях, но не при остановке вручную.
  • volumes: — подключаем Docker volumes для хранения данных, чтобы они не терялись при перезапуске контейнера:
    • - minio-storage:/data
    • - minio-config:/root/.minio

 

Новые ключи:

  • environment: — передаем массив переменных окружения внутрь контейнера в формате "ключ=значение":
    • - MINIO_ROOT_USER=miniouser — задаем имя пользователя для администратора.
    • - MINIO_ROOT_PASSWORD=admin123 — задаем пароль администратора.
    • - MINIO_BROWSER_REDIRECT_URL=https://your_domain.com/console/ — указываем путь, по которому будет доступна консоль MinIO. Адрес должен включать https:// и маршрут.
    • - MINIO_DOMAIN=your_domain.com — задаем домен, на котором будет работать MinIO (без https://).
  • command: — указывает команду, которая будет выполнена при запуске контейнера. В нашем случае это команда для старта сервиса: server /data --console-address ":9001".
  • healthcheck: — настройка для проверки состояния контейнера. Используем типичный пример из документации для MinIO.

 

Готовое описание сервиса:

minio:  
  image: minio/minio:latest  
  container_name: minio  
  restart: unless-stopped  
  volumes:  
    - minio-storage:/data  
    - minio-config:/root/.minio  
  environment:  
    - MINIO_ROOT_USER=miniouser  
    - MINIO_ROOT_PASSWORD=admin123  
    - MINIO_BROWSER_REDIRECT_URL=https://your_domain.com/console/  
    - MINIO_DOMAIN=your_domain.com  
  command: server /data --console-address ":9001"  
  healthcheck:  
    test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]  
    interval: 30s  
    timeout: 20s  
    retries: 3

 

Docker-Volume

Мы прописали использование Docker-volume, но не инициализировали их.

После сервиса minio оставляем пустую строку и прописываем ключ volumes: без отступов от границы. Далее, на внутреннем уровне добавляем используемые Docker-volume:

volumes:
  caddy_data:
  caddy_config:
  minio-storage:
  minio-config:

 

Полный пример конфигурации

services:
  caddy:
    image: caddy:latest
    container_name: caddy 
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config

  minio:  
    image: minio/minio:latest  
    container_name: minio  
    restart: unless-stopped  
    volumes:  
      - minio-storage:/data  
      - minio-config:/root/.minio  
    environment:  
      - MINIO_ROOT_USER=miniouser  
      - MINIO_ROOT_PASSWORD=admin123  
      - MINIO_BROWSER_REDIRECT_URL=https://your_domain.com/console/  
      - MINIO_DOMAIN=your_domain.com  
    command: server /data --console-address ":9001"  
    healthcheck:  
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]  
      interval: 30s  
      timeout: 20s  
      retries: 3

volumes:
  caddy_data:
  caddy_config:
  minio-storage:
  minio-config:

 

Сохраняем файл с помощью CTRL+S и выходим из редактора, нажав CTRL+X.


 

Caddyfile

После настройки конфигурации Docker Compose, необходимо создать файл конфигурации для Caddy.

Откроем файл с помощью редактора, чтобы он создался при сохранении:

nano Caddyfile

 

Формат Caddyfile напоминает упрощённый JSON, поэтому сначала покажу готовую конфигурацию, а затем разберём её:

your_domain.com {  
    tls info@pressanybutton.ru  

    log {  
        output stdout  
        format json
        level WARN  
    }  

    reverse_proxy /console/api/* minio:9000 {  
        header_up Host {host}  
        header_up X-Real-IP {remote}  
    }  

    handle_path /console/* {  
        reverse_proxy minio:9001 {  
            header_up Host {host}  
            header_up X-Real-IP {remote}  
        }  
    }  

    handle_path /* {  
        reverse_proxy minio:9000 {  
            header_up Host {host}  
            header_up X-Real-IP {remote}  
        }  
    }  
}

 

  1. Сначала прописывается доменное имя, за которым открываются фигурные скобки.
  2. Внутри блока указываем ключ tls с адресом электронной почты. Это сообщает Caddy, что нужно получить SSL-сертификат для этого домена для работы через HTTPS.
  3. В блоке log указываем, что выводить следует только предупреждения уровня WARN и выше в формате JSON. Это исключает информационные сообщения и оставляет только важные логи.
  4. Далее начинается интересная часть. Обычно панель управления и API-сервис располагают на разных доменах, но для удобства мы будем использовать один.
    • В блоке reverse_proxy перенаправляем запросы с пути /console/api/* на API-порт minio:9000. Здесь minio — это имя сервиса в docker-compose.yml, а 9000 — внутренний порт контейнера.
  5. С помощью handle_path отслеживаем путь /console/* и перенаправляем запросы на порт консоли minio:9001.
  6. В конце, чтобы правильно обрабатывать запросы к API, с помощью handle_path отслеживаем все остальные маршруты /* и перенаправляем их на API-порт minio:9000.
  7. Во всех блоках мы передаем вместе с запросом информацию о хосте и IP-адресе клиента. Это необходимо для корректной работы MinIO.

 

После внесения изменений сохраняем файл с помощью CTRL+S и выходим из редактора, нажав CTRL+X.


 

Альтернатива: Использование NGINX

Не все хотят использовать Caddy в качестве веб-сервера по разным причинам, поэтому решено вкратце рассказать об альтернативном варианте - использование веб-сервера NGINX.

 

Изменения в docker-compose.yaml

Для того, чтобы сменить Caddy на NGINX, необходимо модифицировать docker-compose.yml:

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/ssl
      - nginx_data:/data
  • image - теперь ссылается на образ nginx.
  • volumes - тут несколько изменений:
    • Вместо Caddyfile, мы передаём файл конфигурации nginx.conf
    • Подключаем локальную директорию с SSL-сертификатами. Как их получить описано в статье "Certbot - бесплатный SSL-сертификат для сайта"
    • Подключаем Docker volume - nginx_data. Не забудьте добавить его в блок volumes в конце файла!

 

Файл конфигурации nginx.conf

Структура и принцип работы достаточно сильно отличается от Caddyfile.

Создадим файл nginx.conf открыв его в редакторе nano:

nano nginx.conf

 

И пропишем следующее содержимое:

worker_processes auto;  

events {  
    worker_connections 1024;  
}  

http {  

    log_format json '{ "time_local": "$time_local", "remote_addr": "$remote_addr", "request": "$request", "status": "$status", "body_bytes_sent": "$body_bytes_sent", "request_time": "$request_time", "upstream_response_time": "$upstream_response_time", "remote_user": "$remote_user", "http_referer": "$http_referer", "http_user_agent": "$http_user_agent" }';  

    access_log /var/log/nginx/access.log json;  
    error_log /var/log/nginx/error.log warn;  

    upstream minio_s3 {  
        server minio:9000;  
    }  

    upstream minio_console {  
        server minio:9001;  
    }  

    server {  
        listen 80;  
        listen [::]:80;  
        server_name storage.napkincontent.ru;  

        return 301 https://$host$request_uri;  
    }  

    server {  
        listen 443 ssl;  
        server_name storage.napkincontent.ru;  

        ssl_certificate /etc/ssl/cert.pem;  
        ssl_certificate_key /etc/ssl/key.pem;  

        location / {  
            proxy_pass http://minio_s3;  
            proxy_set_header Host $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;  
        }  

        location /console/ {  
            rewrite ^/console/(.*) /$1 break;  
            proxy_pass http://minio_console;  
            proxy_set_header Host $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_http_version 1.1;  
            proxy_set_header Upgrade $http_upgrade;  
            proxy_set_header Connection "upgrade";  
        }  
    }  
}

 

Разбор конфигурации:

  1. worker_processes auto; — указывает NGINX автоматически определять количество рабочих процессов в зависимости от числа доступных ядер процессора.
  2. events { worker_connections 1024; } — настраивает количество одновременных подключений, которые NGINX может обрабатывать в одном рабочем процессе.
  3. http { ... } — блок, который включает настройки для обработки HTTP-запросов.
  4. log_format json — указывает формат логирования запросов в формате JSON. Это позволяет собирать информацию о запросах в структурированном виде.
  5. upstream minio_s3 и upstream minio_console — блоки, которые настраивают пул серверов для проксирования запросов.
  6. server { listen 80; ... } — перенаправление всех HTTP-запросов на HTTPS. Это гарантирует, что трафик всегда будет зашифрован.
  7. server { listen 443 ssl; ... } — конфигурация для работы через HTTPS. Здесь мы указываем сертификаты SSL (ssl_certificate и ssl_certificate_key), а также настраиваем проксирование запросов:
    • location / { proxy_pass http://minio_s3; ... } — проксируем запросы на основной сервис MinIO (порт 9000).
    • location /console/ { ... } — проксируем запросы на консоль MinIO (порт 9001), с дополнительной настройкой для корректной работы WebSocket-соединений, необходимых для работы интерфейса MinIO.
  8. proxy_set_header — эти строки обеспечивают правильную передачу заголовков при проксировании запросов, что важно для корректной работы с хостом и IP-адресами клиентов.

 

После внесения изменений сохраняем файл с помощью CTRL+S и выходим из редактора, нажав CTRL+X.

Перед запуском не забудьте создать директорию ssl и поместить в неё ваши SSL-ключи и удостоверьтесь, что названия файлов совпадают с указанными в nginx.conf.


 

Запуск

Теперь, когда все настройки завершены, осталось только запустить сервисы!

Для этого выполните команду:

sudo docker compose up -d
  • up — указывает на запуск сервисов, определённых в Docker Compose.
  • -d — запускает контейнеры в фоновом режиме.

 

Запуск начнётся с загрузки образов. Когда процесс завершится, вы увидите сообщение Started рядом с именем контейнера.

Теперь откройте в браузере домен, указанный в конфигурации. Если все сделано правильно, вас встретит страница авторизации:

 

 


 

Минимальная настройка

После авторизации вы попадаете в консоль управления вашим хранилищем.

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

 

Указание региона

В оригинальном Amazon S3 параметр "Регион" определяет физическое местоположение сервера. Однако, в S3-совместимых хранилищах этот параметр может быть реализован по-разному: где-то его просто нет, а где-то используется "заглушка".

Это связано с тем, что протокол совместимости S3 требует обязательного указания региона. В некоторых случаях отсутствие региона может вызвать конфликты, особенно при использовании библиотек, предназначенных для Amazon S3. Несмотря на то, что MinIO не требует указания региона, для обеспечения лучшей совместимости с другими сервисами, его всё же рекомендуется указать.

Для этого откройте раздел "Configuration". В первом пункте конфигурации — "Region" — укажите нужный регион. Например, у хостинга TimeWeb это может быть "ru-1", а у Cloud.ru — "ru-central-1".

Для примера давайте укажем "ru-central-1" и нажмём "Save":

 

 

После сохранения появится уведомление, что для применения изменений необходимо перезагрузить сервер. Нажмите "Restart", чтобы завершить настройку.

 

 

Создание ключа доступа

Чтобы подключаться к вашему S3-хранилищу с помощью сторонних программ (например, ReBack) или библиотек (например, boto3 для Python), необходимо создать пару ключей: access и secret.

Для этого перейдите в раздел "Access Keys" и нажмите кнопку "Create access key".

 

 

На следующей странице вам будут показаны ключи: access и secret. Обязательно сохраните их в безопасном месте, так как после создания их можно будет увидеть только один раз — в дальнейшем они станут недоступными и их придётся создавать заново.

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

Нажмите "Create".

 

 

После этого вам снова покажут ваши ключи и предупредят, что в следующий раз они будут недоступны для просмотра.

 

Создание бакета

Чтобы хранить файлы в объектном хранилище, необходимо создать "Бакет". Это своего рода контейнер, к которому будет происходить подключение. В MinIO можно создать несколько бакетов, каждый для разных задач или файлов.

Для создания бакета откройте раздел "Buckets" и нажмите "Create Bucket".

На открывшейся странице в поле "Bucket Name" введите имя бакета. Имя бакета должно соответствовать строгим правилам, которые можно просмотреть, нажав кнопку "View Bucket Naming Rules". Также на этой странице доступны дополнительные настройки, такие как контроль версий или ограничения на размер загружаемых файлов.

Я назову свой бакет "local-backups", после чего нажму "Create Bucket".

 

 

После создания бакета вы можете перейти в раздел "Object Browser" и загрузить файлы напрямую в бакет:

 

 

Также можно использовать программы или библиотеки, например, результат работы ReBack:

 

 

 

 


 

Заключение

S3-хранилища стали отраслевым стандартом для хранения файлов. Они используются не только для бэкапов и файлов пользователей, но и для других целей. Например, вы можете настроить Django для хранения статей и изображений, а вариантов применения таких хранилищ масса.

Теперь, благодаря этому руководству, вы знаете, что такое S3-хранилище, как его получить или как развернуть собственное решение на базе MinIO.

Автор

    Нет комментариев

    Реклама