348 lines
12 KiB
Markdown
348 lines
12 KiB
Markdown
# MinIO — стандарт объектного хранилища S3 в кластере
|
||
|
||
MinIO — S3-совместимое объектное хранилище. Предоставляет S3 API (порт 9000) и веб-интерфейс Console (порт 9001). Запускается как standalone StatefulSet на worker-ноде, использует отдельный StorageClass `longhorn-minio` с политикой Retain.
|
||
|
||
---
|
||
|
||
## Содержание
|
||
|
||
1. [Архитектура](#1-архитектура)
|
||
2. [Предварительные условия](#2-предварительные-условия)
|
||
3. [Развёртывание](#3-развёртывание)
|
||
4. [StorageClass longhorn-minio](#4-storageclass-longhorn-minio)
|
||
5. [Traefik: порты 10005 и 10006](#5-traefik-порты-10005-и-10006)
|
||
6. [Пользователи и политики](#6-пользователи-и-политики)
|
||
7. [Бакеты и lifecycle](#7-бакеты-и-lifecycle)
|
||
8. [Интеграция с Loki](#8-интеграция-с-loki)
|
||
9. [Масштабирование](#9-масштабирование)
|
||
10. [Диагностика](#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`:
|
||
|
||
```bash
|
||
kubectl create namespace minio
|
||
|
||
kubectl create secret generic minio-root-credentials \
|
||
--from-literal=rootUser=minioadmin \
|
||
--from-literal=rootPassword='СИЛЬНЫЙ_ПАРОЛЬ_МИНИМУМ_8_СИМВОЛОВ' \
|
||
-n minio
|
||
```
|
||
|
||
> Пароль — минимум 8 символов. MinIO не примет короткий пароль и не запустится.
|
||
|
||
---
|
||
|
||
## 3. Развёртывание
|
||
|
||
```bash
|
||
# Запуск через 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
|
||
```
|
||
|
||
### Проверка после развёртывания
|
||
|
||
```bash
|
||
# Статус пода
|
||
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:
|
||
|
||
```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"]}
|
||
]'
|
||
```
|
||
|
||
Затем раскомментировать `diskSelector: "minio"` в `roles/minio/templates/storageclass.yml.j2` и перезапустить `setup_minio.yml`.
|
||
|
||
Без тега Longhorn выбирает любой из доступных дисков — это тоже корректно.
|
||
|
||
---
|
||
|
||
## 5. Traefik: порты 10005 и 10006
|
||
|
||
Записи в `inventory/prod/group_vars/traefik.yml`:
|
||
|
||
```yaml
|
||
- 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
|
||
|
||
```bash
|
||
# Настройка 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: автоудаление старых объектов
|
||
|
||
```bash
|
||
# Удалять объекты в 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:
|
||
|
||
```yaml
|
||
# В 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:
|
||
|
||
```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. Масштабирование
|
||
|
||
### Расширение PVC без остановки MinIO
|
||
|
||
Longhorn поддерживает online-расширение PVC:
|
||
|
||
```bash
|
||
kubectl patch pvc minio -n minio \
|
||
-p '{"spec":{"resources":{"requests":{"storage":"2Ti"}}}}'
|
||
|
||
# MinIO увидит новое пространство автоматически
|
||
mc admin info prod
|
||
```
|
||
|
||
### Переход на SNMD (4 диска на 1 ноде)
|
||
|
||
При добавлении ещё 2 дисков к worker-ноде (итого 4 диска):
|
||
|
||
```yaml
|
||
# 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. Диагностика
|
||
|
||
```bash
|
||
# Статус пода и 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 |
|