k8s/roles/minio/README.md
2026-07-15 11:14:21 +03:00

12 KiB
Raw Permalink Blame History

MinIO — стандарт объектного хранилища S3 в кластере

MinIO — S3-совместимое объектное хранилище. Предоставляет S3 API (порт 9000) и веб-интерфейс Console (порт 9001). Запускается как standalone StatefulSet на worker-ноде, использует отдельный StorageClass longhorn-minio с политикой Retain.


Содержание

  1. Архитектура
  2. Предварительные условия
  3. Развёртывание
  4. StorageClass longhorn-minio
  5. Traefik: порты 10005 и 10006
  6. Пользователи и политики
  7. Бакеты и lifecycle
  8. Интеграция с Loki
  9. Масштабирование
  10. Диагностика

1. Архитектура

k8s-worker-01 (10.203.0.96)
│
├── MinIO Pod (StatefulSet, 1 replica, namespace: minio)
│     ├── порт 9000  — S3 API (aws s3, boto3, mc, s3cmd)
│     └── порт 9001  — Console UI (браузер)
│
├── PVC 1 TiB → StorageClass longhorn-minio
│     └── Longhorn volume → longhorn-disk1 (/mnt/longhorn-disk1, ~4 TiB)
│
└── Traefik DaemonSet
      ├── :10005 → minio:9000         (S3 API, внешний доступ)
      └── :10006 → minio-console:9001 (Console UI, внешний доступ)

Адреса

Адрес Назначение
http://10.203.0.96:10005 S3 API (внешний, через Traefik)
http://10.203.0.96:10006 Console UI (внешний, через Traefik)
http://minio.minio.svc.cluster.local:9000 S3 API (внутри кластера)
http://minio-console.minio.svc.cluster.local:9001 Console (внутри кластера)

2. Предварительные условия

  • Longhorn установлен и работает (setup_longhorn.yml выполнен)
  • Traefik установлен (setup_traefik.yml выполнен; записи minio-api и minio-console добавлены в traefik_port_map)
  • Secret minio-root-credentials создан вручную в namespace minio:
kubectl create namespace minio

kubectl create secret generic minio-root-credentials \
  --from-literal=rootUser=minioadmin \
  --from-literal=rootPassword='СИЛЬНЫЙ_ПАРОЛЬ_МИНИМУМ_8_СИМВОЛОВ' \
  -n minio

Пароль — минимум 8 символов. MinIO не примет короткий пароль и не запустится.


3. Развёртывание

# Запуск через CI/CD (рекомендуется)
# GitLab → CI/CD → Pipelines → setup:minio → Run manually

# Запуск локально
ansible-playbook -i inventory/prod playbooks/setup_minio.yml

# После установки Traefik нужно перезапустить setup_traefik.yml,
# если записи minio-api и minio-console ещё не применены
ansible-playbook -i inventory/prod playbooks/setup_traefik.yml

Проверка после развёртывания

# Статус пода
kubectl get pod -n minio

# Логи
kubectl logs -n minio -l app=minio --tail=50

# Проброс порта для локальной проверки
kubectl port-forward -n minio svc/minio 9000:9000 &

# Проверка S3 API через mc (MinIO Client)
mc alias set local http://localhost:9000 minioadmin ПАРОЛЬ
mc ls local
mc admin info local

4. StorageClass longhorn-minio

Отдельный StorageClass с двумя ключевыми отличиями от дефолтного longhorn:

Параметр longhorn (default) longhorn-minio
reclaimPolicy Delete Retain
numberOfReplicas 1 1
dataLocality disabled best-effort

Retain — при удалении PVC или namespace minio данные на диске не уничтожаются. Для восстановления: пересоздать PVC с тем же volumeName, указав имя существующего Longhorn volume.

(Опционально) Изоляция MinIO на disk1 через тег

Если нужно зафиксировать MinIO именно на longhorn-disk1, добавить тег через Longhorn API:

kubectl -n longhorn-system patch node.longhorn.io k8s-worker-01 --type=json -p='[
  {"op":"add","path":"/spec/disks/longhorn-disk1/tags","value":["minio"]}
]'

Затем раскомментировать diskSelector: "minio" в roles/minio/templates/storageclass.yml.j2 и перезапустить setup_minio.yml.

Без тега Longhorn выбирает любой из доступных дисков — это тоже корректно.


5. Traefik: порты 10005 и 10006

Записи в inventory/prod/group_vars/traefik.yml:

- name: minio-api
  port: 10005
  backend:
    namespace: minio
    service: minio
    port: 9000
    scheme: http
  basicauth:
    enabled: false   # MinIO использует AWS Signature v4

- name: minio-console
  port: 10006
  backend:
    namespace: minio
    service: minio-console
    port: 9001
    scheme: http
  basicauth:
    enabled: false   # Console защищён собственным логином

BasicAuth от Traefik несовместим с MinIO Console — браузер не может пройти двойную аутентификацию. Console имеет свой логин.

После изменения traefik_port_map перезапустить setup_traefik.yml.


6. Пользователи и политики

Не используйте root-учётные данные в приложениях. Для каждого сервиса — отдельный пользователь с ограниченной политикой.

Создание пользователей через mc

# Настройка alias (через Traefik)
mc alias set prod http://10.203.0.96:10005 minioadmin ПАРОЛЬ

# Пользователь для Loki (только бакет loki-chunks)
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

7. Бакеты и lifecycle

Бакеты создаются автоматически при старте MinIO через values.buckets. Дефолтный список: loki-chunks, backups, artifacts. Изменить список — через переменную minio_buckets в defaults/main.yml или group_vars.

Lifecycle: автоудаление старых объектов

# Удалять объекты в backups старше 30 дней
mc ilm rule add --expire-days 30 prod/backups

# Включить версионирование бакета
mc version enable prod/backups

# Посмотреть все версии объекта
mc ls --versions prod/backups/db-dump.sql.gz

8. Интеграция с Loki

При переходе Loki на distributed-режим MinIO становится S3 backend. Внутрикластерный endpoint:

# В loki-values.yml (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"
      insecure: true            # http, не https
      s3forcepathstyle: true    # обязательно для MinIO

Secret для Loki в namespace monitoring:

kubectl create secret generic loki-minio-secret \
  --from-literal=AWS_ACCESS_KEY_ID=loki \
  --from-literal=AWS_SECRET_ACCESS_KEY=АРОЛЬ_LOKI' \
  -n monitoring

9. Масштабирование

Расширение PVC без остановки MinIO

Longhorn поддерживает online-расширение PVC:

kubectl patch pvc minio -n minio \
  -p '{"spec":{"resources":{"requests":{"storage":"2Ti"}}}}'

# MinIO увидит новое пространство автоматически
mc admin info prod

Переход на SNMD (4 диска на 1 ноде)

При добавлении ещё 2 дисков к worker-ноде (итого 4 диска):

# minio-values.yml — SNMD (mode: distributed для 1 ноды с 4 дисками)
mode: distributed
replicas: 1
drivesPerNode: 4
persistence:
  storageClass: longhorn-minio
  size: 1Ti   # 4 × 1 TiB raw → ~2 TiB usable (EC:2)

Миграция standalone → distributed

MinIO не поддерживает in-place миграцию. Процедура:

1. Запустить distributed MinIO рядом (namespace minio-dist)
2. mc mirror prod prod-dist --preserve --watch
3. Дождаться синхронизации (mc du для сверки объёмов)
4. Переключить Traefik (изменить service в traefik_port_map)
5. Обновить endpoint в Loki, бэкапах и других клиентах
6. Через 2448 ч удалить standalone namespace и PVC

10. Диагностика

# Статус пода и PVC
kubectl get pod,pvc -n minio

# Логи MinIO
kubectl logs -n minio -l app=minio --tail=100

# Проверка S3 API напрямую
kubectl port-forward -n minio svc/minio 9000:9000 &
mc alias set local http://localhost:9000 minioadmin ПАРОЛЬ
mc admin info local

# Проверка через Traefik
curl -I http://10.203.0.96:10005/minio/health/live

# StorageClass
kubectl get storageclass longhorn-minio -o yaml

# Longhorn volume для MinIO
kubectl get pvc -n minio
kubectl -n longhorn-system get volume

# Console недоступна (redirect на неверный URL)
# → проверить MINIO_BROWSER_REDIRECT_URL в values
kubectl get pod -n minio -o yaml | grep MINIO_BROWSER_REDIRECT_URL

Типичные ошибки

Симптом Причина Решение
Pod в состоянии Pending PVC не создан (StorageClass не найден) Проверить kubectl get sc, перезапустить setup_minio.yml
Access Denied при входе Неверные данные в Secret Пересоздать minio-root-credentials
Console → 401 после логина Неверный MINIO_BROWSER_REDIRECT_URL Исправить URL в values, перезапустить setup_minio.yml
Traefik → 404 на порту 10005/10006 IngressRoute не применён Перезапустить setup_traefik.yml
PVC завис в Released после удаления reclaimPolicy: Retain (ожидаемо) Удалить PV вручную или привязать к новому PVC