# MinIO в Kubernetes: объектное хранилище 1 ТБ с веб-интерфейсом **Кластер:** Rocky Linux 9 · Kubernetes 1.33 · Flannel CNI **Текущая топология:** k8s-manager-01 (10.203.0.92) · k8s-master-01 (10.203.0.97) · k8s-worker-01 (10.203.0.96) **Дата исследования:** 2026-05-28 **Проверено на кластере:** 2026-05-28 (kubectl + Longhorn API) --- ## Содержание 1. [Обзор и назначение](#1-обзор-и-назначение) 2. [Режимы развёртывания](#2-режимы-развёртывания) 3. [Планирование хранилища 1 ТБ](#3-планирование-хранилища-1-тб) 4. [Helm-развёртывание (standalone)](#4-helm-развёртывание-standalone) 5. [MinIO Console: веб-интерфейс](#5-minio-console-веб-интерфейс) 6. [Интеграция с Traefik](#6-интеграция-с-traefik) 7. [Безопасность: пользователи и политики](#7-безопасность-пользователи-и-политики) 8. [Интеграция с Loki (S3 backend)](#8-интеграция-с-loki-s3-backend) 9. [Ansible-роль и плейбук](#9-ansible-роль-и-плейбук) 10. [Масштабирование до distributed-режима](#10-масштабирование-до-distributed-режима) 11. [Итоги и рекомендации](#11-итоги-и-рекомендации) --- ## 1. Обзор и назначение MinIO — S3-совместимое объектное хранилище. Работает в Kubernetes как StatefulSet или Deployment, предоставляет: - **S3 API** (порт 9000) — совместим с любым клиентом AWS SDK, boto3, mc, s3cmd - **MinIO Console** (порт 9001) — встроенный веб-интерфейс: браузер объектов, управление пользователями, мониторинг ### Сценарии использования в текущем кластере | Сценарий | Описание | |---|---| | Loki S3 backend | Хранилище chunks/index при переходе на distributed Loki | | Бэкапы баз данных | S3-target для pg_dump, mysqldump, Velero | | Артефакты CI/CD | GitLab Runner cache, артефакты сборки | | Файловое хранилище | Статика, медиафайлы приложений | | Резервные копии etcd | Автоматические снэпшоты control plane | --- ## 2. Режимы развёртывания ### Текущее состояние кластера (проверено) ``` Longhorn-диски на k8s-worker-01: longhorn-disk1 /mnt/longhorn-disk1 ~4.09 TiB (свободно ~4.06 TiB) allowScheduling=true longhorn-disk2 /mnt/longhorn-disk2 ~4.09 TiB (свободно ~4.06 TiB) allowScheduling=true k8s-master-01: диск из Longhorn удалён — нода без дисков, в планировании не участвует ✓ StorageClass longhorn (default): numberOfReplicas: 1 ✓ allowVolumeExpansion: true createDefaultDiskLabeledNodes: true Traefik hostPort (занято): 10001 (k8s-dashboard), 10002 (longhorn-ui) Traefik hostPort (свободно): 10003+ → MinIO: 10005 (API), 10006 (Console) ``` ### Standalone (текущий кластер — 1 worker) ``` ┌─────────────────────────────────────────────────────────────┐ │ k8s-worker-01 (10.203.0.96) │ │ │ │ [MinIO Pod — StatefulSet 1 replica] │ │ ├── порт 9000 (S3 API) │ │ └── порт 9001 (Console UI) │ │ ↓ │ │ [PVC 1 TiB → StorageClass longhorn-minio] │ │ [Longhorn → longhorn-disk1 (/mnt/longhorn-disk1, 4 TiB)] │ └─────────────────────────────────────────────────────────────┘ ↓ ClusterIP ┌─────────────────────┐ │ Traefik │ │ 10005 → API :9000 │ │ 10006 → UI :9001 │ └─────────────────────┘ ``` **Ограничения standalone:** нет erasure coding. Потеря диска = потеря данных. Приемлемо при наличии Longhorn-снэпшотов по расписанию. ### SNMD — Single Node Multi-Drive (будущее) Worker уже имеет два диска (~4 TiB каждый). MinIO поддерживает SNMD начиная с 4 дисков. При добавлении ещё двух дисков к worker-ноде можно перейти на SNMD без новых нод: ``` MinIO SNMD, 4 диска по ~1 TiB (из доступных 4 TiB на каждом диске): - usable storage ≈ 2 TiB (EC:2 — паритет 50%) - допустимая потеря: 2 из 4 дисков ``` ### Distributed (4+ нод) При добавлении worker-нод: 1 под MinIO на ноду, PVC через Longhorn на каждой. Требует минимум 4 пода (4 ноды) для полноценного erasure coding. **Для текущего кластера** (1 worker, 2 диска) — только standalone. --- ## 3. Планирование хранилища 1 ТБ ### Реальная конфигурация дисков (проверено) На `k8s-worker-01` уже настроены два Longhorn-диска: | Диск | Путь | Всего | Свободно | Статус | |---|---|---|---|---| | `longhorn-disk1` | `/mnt/longhorn-disk1` | ~4.09 TiB | ~4.06 TiB | Ready, Schedulable | | `longhorn-disk2` | `/mnt/longhorn-disk2` | ~4.09 TiB | ~4.06 TiB | Ready, Schedulable | Оба диска полностью свободны. PVC 1 TiB займёт ~25% одного диска, оставляя ~3 TiB в резерве на том же диске. ### Выделенный StorageClass для MinIO Дефолтный `longhorn` (numberOfReplicas: 1) технически подойдёт, но для MinIO рекомендуется отдельный StorageClass по двум причинам: - **reclaimPolicy: Retain** — при случайном удалении namespace или PVC данные на диске не уничтожаются (дефолтный Longhorn использует `Delete`) - **diskSelector** — позволяет зафиксировать MinIO на `longhorn-disk1`, оставив `longhorn-disk2` для других workload (Loki, бэкапы и т.д.) ```yaml # применить через роль minio/tasks/storageclass.yml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: longhorn-minio provisioner: driver.longhorn.io reclaimPolicy: Retain # данные остаются при удалении PVC allowVolumeExpansion: true parameters: numberOfReplicas: "1" dataLocality: "best-effort" diskSelector: "minio" # тег только на longhorn-disk1 fsType: "ext4" dataEngine: "v1" ``` ### Disk-тег для изоляции MinIO на disk1 (опционально) Если нужно зафиксировать MinIO именно на `longhorn-disk1` (рекомендуется при нескольких workload): ```bash kubectl -n longhorn-system patch node.longhorn.io k8s-worker-01 --type=json -p='[ {"op":"add","path":"/spec/disks/longhorn-disk1/tags","value":["minio"]} ]' ``` Без тега Longhorn выберет любой из двух дисков (disk1 или disk2) — это тоже корректно, просто менее предсказуемо. ### Репликация на уровне Longhorn Сейчас: `numberOfReplicas: 1` — без репликации. При добавлении второго worker с Longhorn-дисками поднять до `2` — Longhorn начнёт реплицировать PVC MinIO между нодами без остановки пода. > **Важно:** репликация Longhorn защищает от потери ноды, но **не заменяет** MinIO distributed mode. Longhorn реплицирует блочное устройство целиком, erasure coding MinIO работает на уровне объектов. ### Расчёт полезной ёмкости Физический диск (`longhorn-disk1`) — ~4.09 TiB. MinIO получает PVC 1 TiB — остаток диска доступен для других PVC. | Параметр | Значение | |---|---| | Физический диск | ~4.09 TiB (`longhorn-disk1`) | | PVC для MinIO | 1 TiB | | Overhead Longhorn + ext4 | ~2% | | Overhead MinIO (метаданные) | ~1% | | **Доступно для объектов** | **~990 Gi** | | Рекомендуемый порог заполнения | 80% → ~790 Gi | | Остаток на диске для других PVC | ~3.09 TiB | MinIO по умолчанию отказывается принимать данные при заполнении > 95% (настраивается через `MINIO_STORAGE_CLASS_STANDARD`). --- ## 4. Helm-развёртывание (standalone) ### Helm chart Используется официальный chart `minio/minio` (не bitnami — он добавляет лишние зависимости). ```bash helm repo add minio https://charts.min.io/ helm repo update ``` ### `minio-values.yml` ```yaml # roles/minio/files/minio-values.yml ## Режим: standalone mode: standalone ## Образ image: repository: quay.io/minio/minio tag: RELEASE.2025-04-22T22-12-26Z # фиксированная версия pullPolicy: IfNotPresent ## Корневые учётные данные (переопределяются через Secret) existingSecret: minio-root-credentials ## Хранилище persistence: enabled: true storageClass: longhorn-minio # выделенный SC: numberOfReplicas=1, только worker-диски accessMode: ReadWriteOnce size: 1Ti ## Ресурсы пода resources: requests: memory: 512Mi cpu: 250m limits: memory: 2Gi cpu: 1000m ## Привязка к worker-ноде (не запускать на control plane) nodeSelector: node-role.kubernetes.io/control-plane: "" # исключить affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/control-plane operator: DoesNotExist ## Сервисы service: type: ClusterIP port: 9000 consoleService: type: ClusterIP port: 9001 ## Buckets создаются автоматически при старте buckets: - name: loki-chunks policy: none purge: false - name: backups policy: none purge: false - name: artifacts policy: none purge: false ## Пользователи (пароли — через Secret, задаются ниже) users: - accessKey: loki existingSecret: minio-user-loki existingSecretKey: secretKey policy: readwrite - accessKey: backup existingSecret: minio-user-backup existingSecretKey: secretKey policy: readwrite ## Политики для бакетов policies: - name: loki-policy statements: - resources: - "arn:aws:s3:::loki-chunks" - "arn:aws:s3:::loki-chunks/*" actions: - "s3:GetObject" - "s3:PutObject" - "s3:DeleteObject" - "s3:ListBucket" ## Метрики (если Prometheus есть) metrics: serviceMonitor: enabled: false # включить когда появится Prometheus ## MinIO Console — веб-интерфейс consoleIngress: enabled: false # используем Traefik напрямую через ClusterIP ## Окружение MinIO environment: MINIO_BROWSER_REDIRECT_URL: "http://10.203.0.96:10006" # URL Console через Traefik MINIO_STORAGE_CLASS_STANDARD: "EC:0" # standalone: без erasure coding MINIO_UPDATE: "off" # отключить автообновление ``` ### Secret с корневыми учётными данными ```bash kubectl create secret generic minio-root-credentials \ --from-literal=rootUser=minioadmin \ --from-literal=rootPassword='СИЛЬНЫЙ_ПАРОЛЬ_МИНИМУМ_8_СИМВОЛОВ' \ -n minio ``` ### Установка ```bash kubectl create namespace minio helm upgrade --install minio minio/minio \ --namespace minio \ --version 5.4.0 \ --values roles/minio/files/minio-values.yml \ --wait ``` ### Проверка ```bash # Статус пода kubectl get pod -n minio # Логи kubectl logs -n minio -l app=minio # Проброс порта для быстрой проверки kubectl port-forward -n minio svc/minio 9000:9000 & kubectl port-forward -n minio svc/minio-console 9001:9001 & # Проверка S3 API через mc (MinIO Client) mc alias set local http://localhost:9000 minioadmin ПАРОЛЬ mc ls local mc admin info local ``` --- ## 5. MinIO Console: веб-интерфейс MinIO Console — встроенный React-интерфейс, запускается в том же поде на порту 9001. Отдельная установка не нужна начиная с MinIO RELEASE.2021-07-08. ### Возможности Console | Раздел | Функции | |---|---| | Object Browser | Навигация по бакетам, загрузка/скачивание файлов, просмотр метаданных | | Buckets | Создание бакетов, версионирование, lifecycle policies, replication | | Identity → Users | Создание пользователей, назначение политик | | Identity → Groups | Группировка пользователей | | Identity → Policies | Редактор IAM-политик (JSON) | | Monitoring | Дашборд загрузки, IOPS, throughput в реальном времени | | Logs | Потоковый просмотр логов MinIO в браузере | | Audit | Журнал операций (включается через `MINIO_AUDIT_WEBHOOK_*`) | ### Настройка адреса Console MinIO Console проверяет `MINIO_BROWSER_REDIRECT_URL` при формировании redirect после логина. Без правильного значения Console вернёт 401 или redirect на неверный URL. ```yaml # В minio-values.yml — уже задано выше environment: MINIO_BROWSER_REDIRECT_URL: "http://10.203.0.96:10006" ``` --- ## 6. Интеграция с Traefik Два порта в `traefik_port_map`: - `10005` — MinIO S3 API (для клиентов, boto3, mc) - `10006` — MinIO Console (веб-интерфейс) ### Добавить в `inventory/prod/group_vars/traefik.yml` ```yaml traefik_port_map: # ... существующие записи ... - name: minio-api description: "MinIO S3 API" port: 10005 backend: namespace: minio service: minio port: 9000 scheme: http basicauth: enabled: false # MinIO использует собственную аутентификацию (AWS Signature v4) - name: minio-console description: "MinIO Console (Web UI)" port: 10006 backend: namespace: minio service: minio-console port: 9001 scheme: http basicauth: enabled: false # MinIO Console имеет собственный логин ``` > **Важно:** BasicAuth от Traefik + MinIO Console не совместимы — браузер не может пройти двойную аутентификацию. MinIO Console защищён своим логином, этого достаточно. После добавления запустить `setup_traefik.yml`. ### Адреса после развёртывания | Сервис | URL | Назначение | |---|---|---| | MinIO S3 API | `http://10.203.0.96:10005` | Внешний доступ клиентов | | MinIO Console | `http://10.203.0.96:10006` | Веб-интерфейс администратора | | MinIO API (внутри кластера) | `http://minio.minio.svc.cluster.local:9000` | Для подов кластера | | MinIO Console (внутри кластера) | `http://minio-console.minio.svc.cluster.local:9001` | — | ### Настройка mc (MinIO Client) для внешнего доступа ```bash # На manager-ноде или локально mc alias set prod http://10.203.0.96:10005 minioadmin ПАРОЛЬ # Проверка mc ls prod mc admin info prod mc du prod/loki-chunks ``` --- ## 7. Безопасность: пользователи и политики ### Принцип минимальных привилегий Не используйте root-учётные данные в приложениях. Для каждого сервиса — отдельный пользователь с ограниченной политикой. ### Создание пользователей через mc ```bash # Пользователь для Loki (только свой бакет) mc admin user add prod loki ПАРОЛЬ_LOKI mc admin policy create prod loki-policy /dev/stdin <<'EOF' { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:*"], "Resource": [ "arn:aws:s3:::loki-chunks", "arn:aws:s3:::loki-chunks/*" ] } ] } EOF mc admin policy attach prod loki-policy --user loki # Пользователь для бэкапов (только запись в backups) mc admin user add prod backup ПАРОЛЬ_BACKUP mc admin policy create prod backup-policy /dev/stdin <<'EOF' { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:PutObject", "s3:GetObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::backups", "arn:aws:s3:::backups/*" ] } ] } EOF mc admin policy attach prod backup-policy --user backup ``` ### Lifecycle policy: автоудаление старых объектов ```bash # Удалять объекты в backups старше 30 дней mc ilm rule add --expire-days 30 prod/backups # Удалять незавершённые multipart uploads старше 7 дней mc ilm rule add --expire-days 7 --noncurrent-expire-days 7 prod/backups ``` ### Версионирование бакетов (защита от случайного удаления) ```bash # Включить версионирование mc version enable prod/backups # Посмотреть все версии объекта mc ls --versions prod/backups/db-dump.sql.gz ``` --- ## 8. Интеграция с Loki (S3 backend) При переходе Loki на distributed-режим (см. [PLG исследование](../logging/plg.md)) MinIO становится S3 backend для хранения chunks и index. ### Loki values для S3 backend ```yaml # roles/logging/templates/loki-values.yml.j2 (distributed режим) loki: storage: type: s3 s3: endpoint: http://minio.minio.svc.cluster.local:9000 region: us-east-1 # MinIO игнорирует region, но поле обязательно bucketnames: loki-chunks access_key_id: loki secret_access_key: "{{ loki_minio_password }}" insecure: true # http (не https) s3forcepathstyle: true # обязательно для MinIO schemaConfig: configs: - from: "2024-01-01" store: tsdb object_store: s3 # ← было filesystem schema: v13 index: prefix: loki_index_ period: 24h ``` ### Secret для Loki в namespace monitoring ```bash kubectl create secret generic loki-minio-secret \ --from-literal=AWS_ACCESS_KEY_ID=loki \ --from-literal=AWS_SECRET_ACCESS_KEY='ПАРОЛЬ_LOKI' \ -n monitoring ``` --- ## 9. Ansible-роль и плейбук ### Структура роли `roles/minio/` ``` roles/minio/ ├── defaults/main.yml ├── tasks/ │ ├── main.yml │ ├── namespace.yml — создать namespace minio │ ├── secrets.yml — создать Secrets из vault/переменных │ ├── helm.yml — helm upgrade --install minio │ └── mc.yml — настройка mc alias, пользователей, политик, lifecycle ├── files/ │ └── minio-values.yml └── templates/ └── minio-values.yml.j2 ``` ### `defaults/main.yml` ```yaml minio_namespace: minio minio_chart_version: "5.4.0" # minio/minio chart minio_image_tag: "RELEASE.2025-04-22T22-12-26Z" minio_storage_class: longhorn-minio # выделенный SC, не дефолтный longhorn (numberOfReplicas=3) minio_storage_size: 1Ti minio_console_url: "http://10.203.0.96:10006" minio_api_external_url: "http://10.203.0.96:10005" # Имена Secrets (значения создаются вручную через kubectl) minio_root_secret: minio-root-credentials minio_buckets: - loki-chunks - backups - artifacts minio_resources_requests_memory: "512Mi" minio_resources_limits_memory: "2Gi" ``` ### `tasks/helm.yml` ```yaml - name: MinIO | Add Helm repo kubernetes.core.helm_repository: name: minio repo_url: https://charts.min.io/ - name: MinIO | Deploy via Helm kubernetes.core.helm: name: minio chart_ref: minio/minio chart_version: "{{ minio_chart_version }}" release_namespace: "{{ minio_namespace }}" create_namespace: true values: "{{ lookup('template', 'minio-values.yml.j2') | from_yaml }}" wait: true wait_condition: type: Ready status: "True" timeout: "10m0s" ``` ### `playbooks/setup_minio.yml` ```yaml --- - name: Deploy MinIO object storage hosts: manager_nodes become: false roles: - minio ``` ### `.gitlab-ci.yml` — новый job ```yaml setup/minio: stage: setup script: - ansible-playbook -i inventory/prod playbooks/setup_minio.yml rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: manual resource_group: production ``` ### Переменные GitLab CI/CD (добавить) | Переменная | Описание | |---|---| | `MINIO_ROOT_PASSWORD` | Пароль root-пользователя MinIO | | `MINIO_LOKI_PASSWORD` | Пароль пользователя loki | | `MINIO_BACKUP_PASSWORD` | Пароль пользователя backup | --- ## 10. Масштабирование ### Этапы роста: Longhorn и MinIO вместе Реальное текущее состояние (проверено): worker имеет 2 диска по ~4 TiB, оба пустые. Это даёт несколько путей масштабирования без добавления нод: | Этап | Кластер | Longhorn | MinIO | |---|---|---|---| | **Сейчас** | 1 worker, 2 диска по 4 TiB | `longhorn` SC: `numberOfReplicas: 1`, master без дисков ✓ | standalone, PVC 1 TiB на disk1 | | +2 диска к worker | 1 worker, 4 диска | 4 PVC по 1 TiB, `numberOfReplicas: 1` | **SNMD**: 4 drives, EC:2, ~2 TiB usable | | +1 worker с дисками | 2 workers | Поднять `numberOfReplicas: 2` в `longhorn-minio` | standalone + Longhorn-репликация между нодами | | +3 workers (4 total) | 4 workers | `numberOfReplicas: 2` | **Distributed**: 4 пода, EC:2 | ### Шаг 1: добавление второго worker (без пересоздания MinIO) После добавления `k8s-worker-02` в кластер: ```bash # Убедиться что Longhorn видит новую ноду и диск kubectl get nodes -o wide kubectl get nodes.longhorn.io -n longhorn-system # Обновить numberOfReplicas у StorageClass (или через Longhorn UI) kubectl edit storageclass longhorn # numberOfReplicas: "1" → "2" # Обновить replicas у существующего PVC MinIO kubectl -n longhorn-system edit volume # spec.numberOfReplicas: 1 → 2 # Longhorn начнёт ребалансировку в фоне, MinIO продолжает работать ``` ### Шаг 2: SNMD — 4 диска на одной ноде (реалистичный следующий шаг) Worker уже имеет 2 диска (~4 TiB каждый). При добавлении ещё 2 дисков можно перейти на SNMD **без новых нод**: ```yaml # minio-values.yml — SNMD режим (4 диска на k8s-worker-01) mode: distributed # в MinIO SNMD тоже использует mode: distributed replicas: 1 # 1 нода drivesPerNode: 4 # 4 PVC на под persistence: storageClass: longhorn-minio size: 1Ti # 4 × 1 TiB = 4 TiB raw → ~2 TiB usable (EC:2) ``` При SNMD Longhorn создаёт 4 отдельных PVC (по одному на каждый логический диск MinIO). `numberOfReplicas: 1` в StorageClass — MinIO EC уже обеспечивает отказоустойчивость. ### Шаг 3: distributed (4+ workers) ```yaml # minio-values.yml при 4 worker-нодах mode: distributed replicas: 4 # 4 пода на 4 нодах drivesPerNode: 1 # 1 Longhorn PVC на под persistence: storageClass: longhorn-minio size: 1Ti # 4 × 1 TiB raw → ~2 TiB usable (EC:2) affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: minio topologyKey: kubernetes.io/hostname ``` В distributed-режиме Longhorn предоставляет отдельный PVC каждому поду MinIO. Репликацию Longhorn для distributed оставить на `numberOfReplicas: 1` — MinIO EC уже обеспечивает отказоустойчивость. ### Миграция standalone → distributed MinIO **не поддерживает** in-place миграцию. Процедура: ``` 1. Запустить distributed MinIO рядом (namespace minio-dist) 2. mc mirror minio-standalone minio-distributed --preserve --watch 3. Дождаться синхронизации всех объектов (mc du для сверки объёмов) 4. Переключить Traefik (изменить service в IngressRoute) на новый сервис 5. Обновить endpoint в configs Loki, бэкапов и других клиентов 6. Подождать 24-48 часов, убедиться что клиенты работают корректно 7. Удалить standalone namespace и PVC ``` ### Расширение объёма без миграции (только standalone) Longhorn поддерживает расширение PVC онлайн — без остановки MinIO: ```bash kubectl patch pvc minio -n minio \ -p '{"spec":{"resources":{"requests":{"storage":"2Ti"}}}}' # Longhorn расширит том; MinIO увидит новое пространство автоматически mc admin info prod # проверить новый объём в разделе capacity ``` --- ## 11. Итоги и рекомендации ### Почему Longhorn — правильный выбор для этого кластера Longhorn уже является стандартом хранилища в кластере. Использование его для MinIO даёт: - **Единая точка управления** — диски, снэпшоты, репликация управляются через Longhorn UI, без отдельной операционной нагрузки - **Онлайн-расширение** — PVC MinIO расширяется без остановки пода (`kubectl patch pvc`) - **Путь к отказоустойчивости** — при добавлении второго worker достаточно поднять `numberOfReplicas: 2`, MinIO продолжает работать без изменений - **Снэпшоты как бэкап** — Longhorn умеет делать снэпшоты PVC по расписанию; для MinIO standalone это основной механизм защиты данных до перехода на distributed ### Порядок развёртывания ``` 1. Применить StorageClass longhorn-minio (см. раздел 3) (опц.) Longhorn UI → k8s-worker-01 → добавить тег "minio" на longhorn-disk1 для изоляции 2. kubectl create namespace minio 3. Создать Secret minio-root-credentials вручную 4. Запустить setup_minio.yml (Helm install) 5. Добавить minio-api и minio-console в traefik_port_map (порты 10005, 10006 — свободны) 6. Запустить setup_traefik.yml 7. Проверить Console: http://10.203.0.96:10006 8. Создать пользователей через mc (loki, backup) 9. Обновить loki-values.yml если Loki уже работает ``` ### Итоговые адреса | Сервис | URL | |---|---| | MinIO Console (UI) | `http://10.203.0.96:10006` | | MinIO S3 API | `http://10.203.0.96:10005` | | MinIO API (внутри кластера) | `http://minio.minio.svc.cluster.local:9000` | ### Следующие шаги - [ ] Применить StorageClass `longhorn-minio` (раздел 3) - [ ] (опц.) Longhorn UI: добавить тег `minio` на `longhorn-disk1` для изоляции диска - [ ] Создать Secret `minio-root-credentials` вручную - [ ] Написать роль `roles/minio/` по структуре из раздела 9 - [ ] Добавить job `setup/minio` в `.gitlab-ci.yml` - [ ] Добавить `minio-api` и `minio-console` в `traefik_port_map` (порты 10005, 10006) - [ ] Добавить переменные `MINIO_ROOT_PASSWORD`, `MINIO_LOKI_PASSWORD` в GitLab CI/CD Variables - [ ] Добавить firewalld-правило в `roles/minio/tasks/firewall.yml` (порты 9000, 9001 в `trusted` zone для flannel.1/cni0)