12 KiB
MinIO — стандарт объектного хранилища S3 в кластере
MinIO — S3-совместимое объектное хранилище. Предоставляет S3 API (порт 9000) и веб-интерфейс Console (порт 9001). Запускается как standalone StatefulSet на worker-ноде, использует отдельный StorageClass longhorn-minio с политикой Retain.
Содержание
- Архитектура
- Предварительные условия
- Развёртывание
- StorageClass longhorn-minio
- Traefik: порты 10005 и 10006
- Пользователи и политики
- Бакеты и lifecycle
- Интеграция с Loki
- Масштабирование
- Диагностика
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создан вручную в namespaceminio:
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. Через 24–48 ч удалить 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 |