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

348 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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. Через 2448 ч удалить 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 |