Сборка Min.io dev кластера в контейнерах

от автора

Привет! В этой статье рассмотрим разворачивание dev кластера min.io в контейнерах (docker-compose) с tls, site-replication, nginx и заденем немного tiering. Также настроим мониторинг нашего кластера в prometheus+grafana.

Статья представляет собой пошаговое руководство для разворачивания кластерного minio в контейнерах от bitnami. Также рядом развернем однонодный minio. Объединим эти 2 minio с помощью site-replication. Создадим тестового пользователя, тестовый policy, тестовый бакет и попробуем с ним работать.

Подготовка

Начнем с клонирования репозитория https://github.com/yubazh/minio-compose

git clone git@github.com:yubazh/minio-compose.git

Для использования TLS нам необходимо сгенерировать сертификаты. Сертификаты можно сгенерировать с помощью скрипта generate_ssl_cert.ssh, который лежит в директории certsgen. Скрипт использует openssl. Перед запуском сертификата, необходимо поместить свой ip-адрес в файл certsgen/server-ext.cnf вместо адреса 192.168.0.199. Также стоит обратить внимание, что сертификат будет выписан на *.local. Доменные имена minio{1..4}.local будут использовать для взаимодействия нод minio между собой.

cat certsgen/server-ext.cnf        subjectAltName=DNS:*.local,IP:0.0.0.0,IP:127.0.0.1,IP:192.168.0.199

Посмотрим на сам скрипт:

# удаляем существующие сертификаты rm *.pem  # генерируем certificate authority с ключом  # 1. Generate CA's private key and self-signed certificate openssl req -x509 -newkey rsa:4096 -days 365 -nodes -keyout ca-key.pem -out ca-cert.pem -subj "/C=XX/ST=XXX/L=XXXX/O=XXXXX/OU=XXXXXX/CN=*.local/emailAddress=mail@gmail.com"  echo "CA's self-signed certificate" openssl x509 -in ca-cert.pem -noout -text  # генерируем сертификат с ключом # 2. Generate web server's private key and certificate signing request (CSR) openssl req -newkey rsa:4096 -keyout server-key.pem -out server-req.pem -subj "/C=XX/ST=XXX/L=XXXX/O=XXXXX/OU=XXXXXX/CN=*.local/emailAddress=mail@gmail.com" -nodes  # 3. Use CA's private key to sign web server's CSR and get back the signed certificate openssl x509 -req -in server-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 60 -extfile server-ext.cnf  echo "Server's signed certificate" openssl x509 -in server-cert.pem -noout -text  echo "Command to verify Server and CA certificates" openssl verify -CAfile ca-cert.pem server-cert.pem  # удаляем директорию certs, в которую мы положим вновь созданные сертификаты для minio echo "Deleting certs dir" rm -rf ../certs  # создаем заново директорию ../certs и помещаем туда необходимые сертификаты echo "Creating certs dirs" mkdir -p ../certs/CAs cp ca-cert.pem ../certs/ca.crt cp ca-cert.pem ../certs/CAs/ca.crt cp server-cert.pem ../certs/public.crt cp server-key.pem ../certs/private.key  chmod +r ../certs/private.key  # удаляем существующие директории для хранения данных самого minio  echo "Deleting minio dirs" rm -rf ../minio*  # создаем новые директории для хранения данных minio  echo "Creating minio dirs" mkdir ../minio1 mkdir ../minio2 mkdir ../minio3 mkdir ../minio4 mkdir ../miniosolo sudo chown -R 1001:1001 ../minio*

Если коротко, то мы удаляем все ранее созданные сертификаты в диреткории certsgen, удаляем директорию ../certs (в которую сложим новые сертификаты и прокинем в контейнеры), удаляем старые директории для хранения персистентных данных minio и создадим новые с необходимыми правами. Запустим скрипт:

cd certsgen ./generate_ssl_cert.ssh

Если все ок, то мы увидим вывод наших сертификатов, а также сообщения об удалении старых директорий и создании новых.

Основной кластер min.io

Теперь разберем основной compose и развернем кластер.

Для разворачивания будем использовать контейнеры minio от bitnami (https://github.com/bitnami/containers/tree/main/bitnami/minio). В docker-compose мы зададим админский пароль, хостнеймы контейнеров, настроим «кластерность», https, постоянное хранилище, healthcheck, а также nginx, который будет выступать в виде прокси перед нашим кластером.

Отдельно стоит отметить, что в документации указано, что минимальное количество нод в кластере minio — 4. Также, указано что в продакшн среде необходимо использовать минимум 4 диска на каждой ноде. Это вся связано с внутренним устройством minio, и тем как он разбивает всё на объекты и хранит данные объекты в дальнейшем. На сайте minio есть удобный калькулятор для продакшн решений: https://min.io/product/erasure-code-calculator.

Также отмечу, что в документации указано, использовать на дисках для хранения «data» файловую систему xfs.

Разберем более детально файл docker-compose.yaml, а именно первый контейнер minio (остальные 3 совершенно идентичны) и контейнер с nginx:

cat docker-compose.yaml             version: '3.7'  services:   # first cluster   minio1:     # рестарт в случае падения - всегда     restart: always     # указываем использование образа bitnami minio с тегом 2024.7.26     image: bitnami/minio:2024.7.26     # отдельно указываем название контейнера     container_name: minio1     # указываем hostname по которому к нему можно будет обращаться внутри docker network     hostname: minio1.local     # блок с переменными, которые будут загружаться в minio     environment:       # указываем админский логин и пароль       - MINIO_ROOT_USER=minioadmin       - MINIO_ROOT_PASSWORD=MBVfbuu2NDS3Aw       # указываем использование distributed mode (кластера)       - MINIO_DISTRIBUTED_MODE_ENABLED=yes       # указываем из каких нод будет состоять кластер.       # в нашем случае это будут контейнеры, обращаемся к ним по хостнеймам       - MINIO_DISTRIBUTED_NODES=minio1.local,minio2.local,minio3.local,minio4.local       # данную переменную подсмотрел где-то на стаковерфлоу, фиксит некоторые падения       - MINIO_SKIP_CLIENT=yes       # указываем явное использование https       - MINIO_SCHEME=https       # указывает порт, по которому можем попасть на web-ui       - MINIO_CONSOLE_PORT_NUMBER=9001       # следующие 2 переменные следует добавлять при использовании nginx перед кластером       # первая переменная указывает адрес всего кластер       - MINIO_SERVER_URL=https://minio.local       # вторая указываем конкретное расположение web-ui       - MINIO_BROWSER_REDIRECT_URL=https://minio.local/minio/ui       # обе эти переменные решают вопрос взаимодействия и переадресации между нодами minio и nginx     volumes:       # указываем директорию для хранения данных. монтируем в /bitnami/minio/data       # обратите внимание что в разных контейнерах (разных сборщиков) разное место монтирования        - ./minio1:/bitnami/minio/data       # монтируем директорию с сертификатами, для взаимодействия по https       - ./certs:/certs     healthcheck:       # производим очень простой healthcheck       test: [ "CMD", "curl", "-k", "https://localhost:9000/minio/health/live" ]       interval: 30s       timeout: 20s       retries: 3 ... ... ...   minio:     # контейнер с nginx. указываем используемый образ     image: nginx:1.19.2-alpine     # указываем имя контейнера     container_name: minio     # указываем hostname, по которому сможем взаимодействовать с контейнером внутри docker сети     hostname: minio.local     volumes:       # монтируем конфиг nginx       - ./nginx.conf:/etc/nginx/nginx.conf:ro       # монтируем сертификаты, для взаимодействия с нодами по https       - ./certs:/certs     ports:       # выбрасываем порт 443, причем только в nginx. так как соединения будет принимать только nginx       - "443:443"

Остальные 3 контейнера minio имеют идентичные настройки. Только порядковые номера в названии, хостнейме и директории для монтирования отличаются.

Рассмотрим файл конфигурации nginx.conf. Он в общем виде представлен в документации minio (https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html). Нам его необходимо лишь немного подправить. Обратите внимание на раздел upstream:

user  nginx; worker_processes  auto;  error_log  /var/log/nginx/error.log warn; pid        /var/run/nginx.pid;  events {     worker_connections  4096; }  http {    include       /etc/nginx/mime.types;    default_type  application/octet-stream;     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                    '$status $body_bytes_sent "$http_referer" '                    '"$http_user_agent" "$http_x_forwarded_for"';     access_log  /var/log/nginx/access.log  main;    sendfile        on;    keepalive_timeout  65;     # include /etc/nginx/conf.d/*.conf;    upstream minio_s3 {       least_conn;       server minio1.local:9000;       server minio2.local:9000;       server minio3.local:9000;       server minio4.local:9000;    }     upstream minio_console {       least_conn;       server minio1.local:9001;       server minio2.local:9001;       server minio3.local:9001;       server minio4.local:9001;    }     server {       listen       443 ssl;       listen  [::]:443 ssl;       server_name  minio.local;        # Allow special characters in headers       ignore_invalid_headers off;       # Allow any size file to be uploaded.       # Set to a value such as 1000m; to restrict file size to a specific value       client_max_body_size 0;       # Disable buffering       proxy_buffering off;       proxy_request_buffering off;       ssl_certificate      /certs/public.crt;       ssl_certificate_key  /certs/private.key;       ssl_protocols TLSv1.2 TLSv1.3;       ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;       ssl_prefer_server_ciphers off;       ssl_verify_client off;        location / {          proxy_set_header Host $http_host;          proxy_set_header X-Real-IP $remote_addr;          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;          proxy_set_header X-Forwarded-Proto $scheme;           proxy_connect_timeout 300;          # Default is HTTP/1, keepalive is only enabled in HTTP/1.1          proxy_http_version 1.1;          proxy_set_header Connection "";          chunked_transfer_encoding off;           proxy_pass https://minio_s3; # This uses the upstream directive definition to load balance       }        location /minio/ui/ {          rewrite ^/minio/ui/(.*) /$1 break;          proxy_set_header Host $http_host;          proxy_set_header X-Real-IP $remote_addr;          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;          proxy_set_header X-Forwarded-Proto $scheme;          proxy_set_header X-NginX-Proxy true;           # This is necessary to pass the correct IP to be hashed          real_ip_header X-Real-IP;           proxy_connect_timeout 300;           # To support websockets in MinIO versions released after January 2023          proxy_http_version 1.1;          proxy_set_header Upgrade $http_upgrade;          proxy_set_header Connection "upgrade";          # Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)          # Uncomment the following line to set the Origin request to an empty string          # proxy_set_header Origin '';           chunked_transfer_encoding off;           proxy_pass https://minio_console; # This uses the upstream directive definition to load balance       }    } } 

Посмотрим на директорию certs. Мы увидим, что в нее поместили сертификат public.crt, который по факту является файлом certsgen/server-cert.pem (т.е. грубо говоря сертификат сервера). Также ключ от упомянутого выше сертификата — private.key, который является файлом certsgen/server-key.pem. И положили исходный самоподписанный ca-cert.pem, переименовав в ca.crt. Также создали директорию certs/CAs и в нее скопировали ca.crt. Директорию CAs необходимо для minio, так как по дефолту он в ней ищет необходимый ему ca.crt. (https://min.io/docs/minio/linux/operations/network-encryption.html) Все сертификаты пробрасываются в контейнеры с minio.

Запустим кластерную версию:

docker compose -f docker-compose.yaml up -d

Подождем минуту пока все запустится и пройдет healthcheck’и. Сделаем

docker ps -a

И мы должны увидеть, что все наши контейнеры поднялись:

docker ps

docker ps

Заходим в webui

Теперь добавим наш ca.crt в браузер и попробуем зайти в webui.

Я использую firefox, поэтому опишу как добавить сертификат в firefox: Переходим в settings => в строке поиска вводим «cert» => нажимаем на кнопку «View Certificates» =>

View Certificates

View Certificates

В появившемся окне выбираем крайнюю правую вкладку «Authorities» => далее снизу «Import» => теперь выбираем наш ca.crt из certs/ca.crt => проставляем необходимые галки => жмем «OK» => еще раз «OK».

Также, добавим у себя локально запись в /etc/hosts:

cat /etc/hosts ... 127.0.0.1 minio.local

Теперь открываем браузер и переходим на https://127.0.0.1/minio/ui/login и вводим логин и пароль, которые мы указали в docker-compose.yaml в переменных MINIO_ROOT_USER и MINIO_ROOT_PASSWORD. Обратите внимание на замочек возле нашего адреса, он должен быть без восклицательного знака, что будет свидетельствовать о защищенности подключения.

TLS

TLS

После успешного логина, мы попадем в web интерфейс minio. Можем убедиться что все хорошо, выбрав в левой части экрана пункты: monitoring => metrics. Мы увидим сводную информацию по кластеру:

Встроенный мониторинг

Встроенный мониторинг

Создание policy

Теперь создадим policy. Перейдем в «policies» => create policy. Введем testpolicy в строку с названием, и добавим свой блок Statemenet.

  "Statement": [     {       "Action": [         "s3:PutBucketPolicy",         "s3:GetBucketPolicy",         "s3:DeleteBucketPolicy",         "s3:ListAllMyBuckets",         "s3:ListBucket"       ],       "Effect": "Allow",       "Resource": [         "arn:aws:s3:::testbucket"       ],       "Sid": ""     },     {       "Action": [         "s3:AbortMultipartUpload",         "s3:DeleteObject",         "s3:GetObject",         "s3:ListMultipartUploadParts",         "s3:PutObject"       ],       "Effect": "Allow",       "Resource": [         "arn:aws:s3:::testbucket/*"       ],       "Sid": ""     }   ]

Этот полиси дает полный контроль над бакетом с названием testbucket. Жмем «Save»

testpolicy

testpolicy

Создание user’a

Теперь создадим пользователя. Перейдем в Identify => Users => Create User. Введем в поле Name: testuser. В поле password: testpassword. Также чуть ниже, среди существующих политик, выберем созданную нами ранее testpolicy. Жмем Save.

User

User

Создание bucket’a

Ну и создадим тестовый бакет. Переходим в Buckets => Create Bucket. В Name вносим testbucket и обязательно вклю1чаем версионирование. Нам оно понадобится при включении site replication в дальнейшем. Жмем create bucket.

testbucket

testbucket

s3cmd

Попробуем повзаимодействовать с бакетом из операционной системы. Устанавливаем утилиту s3cmd

sudo apt install -y s3cmd 

Настраиваем ее, создам файл ~/.s3cfg. Приведу пример моего конфига:

# Setup endpoint # указываем наш сервер host_base = 127.0.0.1 host_bucket = 127.0.0.1 # оставляем по дефолту bucket_location = us-east-1 # указываем что используем https use_https = True  # указываем логин и пароль нашего тестового пользователя # Setup access keys access_key = testuser secret_key = testpassword   # Enable S3 v4 signature APIs # при выполнении большого количества тестов,  # у меня возникла необходимость подключить указанную ниже директиву # однако при выполнении дефолтных действий она не нужна # поэтому я ее закоментил, но оставил на всякий случай # signature_v2 = False

Теперь нам необходимо установить сертификат в нашу операционную систему (у меня ubuntu)

sudo cp certs/ca.crt /usr/local/share/ca-certificates/ca-minio.crt sudo update-ca-certificates

Произведем тест. Попробуем получить список бакетов в нашем s3:

s3cmd ls

s3cmd ls

Видим, что отражается наш testbucket. В случае, если вместо успеха, вы получаете сообщение, говорящее о проблемах с сертификатом, то можете подложить его к утилите s3cmd вручную при помощи аргумента ca-certs:

s3cmd --ca-certs ./certs/ca.crt ls s3://

Получим тот же вывод:

Положим наш файл nginx.conf в бакет и проверим его в web-ui:

Переходим в webui, object browser и открываем testbucket. Файл на месте:

testbucket

testbucket

Отдельный minio

Для организации site-replication или tiering нам понадобиться второй minio. Однако необходимо в кластерном решении у нас нет, поэтому развернем отдельностоящий minio из одного контейнера.

Рассмотрим docker-compose.yaml. Остановлюс только на отличиях от кластерного варианта:

cat docker-compose-solo.yaml  version: '3.7'  services:   # minio solo   miniosolo:     restart: always     image: bitnami/minio:2024.7.26     container_name: miniosolo     hostname: miniosolo.local     # в данном случае мы обязательно выбрасываем порты, по которым будем     # взаимодействовать с нашим minio     # 9001 - webuil 9000 - api     ports:       - '9000:9000'       - '9001:9001'     environment:       # также указываем login & password       - MINIO_ROOT_USER=minioadmin       - MINIO_ROOT_PASSWORD=2eG1~B/j{70d       - MINIO_SKIP_CLIENT=yes       # указываем использование https       - MINIO_SCHEME=https       # указываем порт для web-ui       - MINIO_CONSOLE_PORT_NUMBER=9001     extra_hosts:       # вносим в /etc/hosts данного контейнера связку minio.local c 192.168.0.199       - "minio.local:192.168.0.199"     volumes:       - ./miniosolo:/bitnami/minio/data       - ./certs:/certs     healthcheck:       test: [ "CMD", "curl", "-k", "https://localhost:9000/minio/health/live" ]       interval: 30s       timeout: 20s       retries: 3 

Разворачиваем minio и проверяем контейнер:

docker compose -f docker-compose-solo.yaml up -d docker ps

Убеждаемся, что контейнер поднялся. После этого заходим в webui: https://127.0.0.1:9001/login (обратите внимание, данный минио доступен по конкретным портам. для webui — 9001).

и логинимся, используя переменные из docker-compose-solo.yaml. Удостоверяемся секьюрности коннекта (тот же замочек рядом с адресом). А также удостоверяемся, что это совершенно другой minio. У него только одна нода в metrics. А также нет пользователей, политик и бакетов.

Site Replication

Настроим репликацию между этими кластерами

Переходим в webui основого кластера на вкладку site replication в самом низу панели администрирования. Жмем Add Sites и заполняем все поля. В данный момент воспользуемся админской учеткой, однако для этих целей лучше создать отдельную учетную запись:

Site Replication

Site Replication

Здесь нам понадобятся ранее внесенные записи в /etc/hosts. К первому (main) кластеру мы обратимся по minio.local. А ко второму кластеру по внешнему ip-адресу (192.168.0.199 — мы его прописали в самом начале, при создании сертификата). Жмем Save и получаем:

Можем перейти на вкладку Replication Status и убедиться, в том, что все сущности перенесены. Также можем перейти в webui stand-alone minio (https://127.0.0.1:9001/) и посмотреть содержимое его бакеты:

Видим что бакет создан, а вот количество objects = 0. Проверим через утилиту s3cmd. Изменим s3cfg, указав использовать stand-alone minio (добавим только порт, остальное оставим таким же):

cat ~/.s3cfg                 # Setup endpoint host_base = 127.0.0.1 host_bucket = 127.0.0.1 bucket_location = us-east-1 use_https = True   # Setup access keys access_key = testuser secret_key = testpassword   # Enable S3 v4 signature APIs #signature_v2 = False

Попытаемся загрузить файл nginx.conf:

Видим, что все прошло успешно. Насколько я понял, это «фича» отображения. Теперь в web-ui видим, что объект — 1.

Tiering

Особо сильно останавливаться не будем на этом пункте. Опишу только основные собственные выводы. Minio не умеет делить диски на ssd и hdd. Он их просто собирает все в одну кучу. Причем, насколько указано в документации — по принципу самого слабого звена. Т.е. если диски разных размеров, то по факту использоваться будет только емкость в диске, соответствующая самому маленькому по объему диску.

Ну и так как minio не умеет делить диски на ssd и hdd, то он и не может создавать bucket’ы только на каких-то конкретных дисках. Т.е. бакет размазывается в общем, а не на конкретных дисках. Из этого следует, что для использования tiering, вам необходимый рядом стоящие кластеры, или арендованные бакеты, которые развернут на соответствующих дисках. Т.е. например свой кластер на ssd в виде горячего хранилище. И арендованный s3 бакет где-то еще в виде холодного хранилища.

Для настройки tiering’a есть соответствующий раздел слева на панели: tiering. После подключения бакета в этом разделе, мы можем его использовать в уже конкретном нашем бакете: buckets => testbucket => lifecycle => add lifecycle rule. Т.е. по факту tiering в minio = lifecycle management.

В правилах мы устанавливаем какие конкретно файлы в какой tiering-bucket выгрузятся после какого именно периода времени. Т.е. например, мы можем хранить в нашем бакете файлы только 1 месяц. После этого, они все выгружаются на удаленный бакет. Причем они остаются доступны из нашего основого бакета. Также отмечу, что движения файлов обратно — нет. Если файлы выгрузились в tiering bucket — то настройки чтобы их поместить обратно в горячее хранилище нет (по крайней мере я не нашел).

Стоит отдельно отметить. При настройке site replication + tiering нам необходимо настраивать каждому кластеру свой tiering отдельно. В документации отдельно указано, что tiering не реплецируемая сущность.

По данному разделу приветствуются комменты. Не сказать, что в документации эта часть расписана предельно понятно. Здесь ответы на вопросы можно получить только после поднятия кластера и самостоятельных тестов.

Minio client

Для настройки мониторинга нам понадобится утилита minio client. Установим ее по инструкции из оф документации: https://min.io/docs/minio/linux/reference/minio-mc.html

После установки, добавим наш main кластер в minio client:

# в случае если у вас уже установлена утилита midnight commander,  # то обратитесь к mc например через ~/minio-binaries/mc ~/minio-binaries/mc alias set mainminio https://127.0.0.1 minioadmin MBVfbuu2NDS3Aw 

Увидим сообщение об успехе:

Проверим и получим краткую информацию о кластере:

minio client

minio client

Monitoring

Как мы видели ранее, в web интерфейса минио уже есть раздел monitoring, в котором можно посмотреть некоторую информацию о кластере. Однако мы развернем prometheus, настроим scrapeconfig и отрисуем собранные метрики в grafana.

Для начала сгенерируем токен для сбора метрик:

~/minio-binaries/mc admin prometheus generate mainminio

Получим следующее:

Нам необходимо скопировать bearer_token и заменить его в файле prometheus/prometheus.yml в двух местах (строки 7 и 16):

global:   scrape_interval: 15s   scrape_timeout: 10s   evaluation_interval: 15s scrape_configs: - job_name: minio-job-server   bearer_token: #####ВОТ_ЗДЕСЬ######   metrics_path: /minio/v2/metrics/cluster   scheme: https   tls_config:     ca_file: /certs/ca.crt     #insecure_skip_verify: true   static_configs:   - targets: [minio.local] - job_name: minio-job-bucket   bearer_token: #####И_ВОТ_ЗДЕСЬ######   metrics_path: /minio/v2/metrics/bucket   scheme: https   tls_config:     ca_file: /certs/ca.crt     #insecure_skip_verify: true   static_configs:   - targets: [minio.local]

В данном скрейпконфиге мы указываем прометеусу, что нужно собирать метрики с minio.local, перейдя по https://minio.local/minio/v2/metrics/cluster и https://minio.local/minio/v2/metrics/bucket. Также указываем какой ca.crt использовать при сборе метрик (/certs/ca.crt — директорию certs мы прокинем в prometheus).

Посмотрим docker-compose-monitoring.yaml:

version: "3.5"  services:   prometheus:     image: prom/prometheus:v2.51.2     container_name: prometheus     # указываем прометеусу что нужно подхватить в качестве конфиг-файла наш,      # который лежит в /etc/prometheus/prometheus.yml     # это конфиг, который мы правили немного выше     command:       - '--config.file=/etc/prometheus/prometheus.yml'     # "выбрасываем" порт 9090     ports:       - 9090:9090     volumes:       # монтируем директорию prometheus с нашим конфигом       - ./prometheus:/etc/prometheus       # для хранения данных используем volume       # мне не нужно хранить данные в директории с кластером minio       # поэтому будем класть их в volume       - prom_data:/prometheus       # прокидываем директорию certs с нашими сертификатами       - ./certs:/certs     healthcheck:       test: wget --no-verbose --tries=1 --spider localhost:9090 || exit 1       interval: 5s       timeout: 10s       retries: 3       start_period: 5s        grafana:     image: grafana/grafana:10.4.2     container_name: grafana     ports:       # порт, по которому мы будем ходить в grafana       - 3000:3000     environment:       # указываем логин и пароль от админа       # AUTH       - GF_SECURITY_ADMIN_USER=admin       - GF_SECURITY_ADMIN_PASSWORD=admin       # указываем возможность просматривать дашборды без аутентификации       - GF_AUTH_ANONYMOUS_ENABLED=true     volumes:       # монтируем директорию provisioning, в которой настройки по        # добавлению datasources и dashboards       - ./grafana/provisioning:/etc/grafana/provisioning       # монтируем директорию c json наших дашбордов       - ./grafana/dashboards:/var/lib/grafana/dashboards     depends_on:       # перед разворачиванием графаны, дожидаемся готовности prometheus       - prometheus     healthcheck:       test: curl --fail localhost:3000       interval: 5s       timeout: 10s       retries: 3       start_period: 10s  # раздел описания томов (volume) volumes:   prom_data:

Поднимаем мониторинг:

docker compose -f docker-compose-monitoring.yaml up -d

Через docker ps убеждаемся что оба контейнера healthy. Даем еще некоторое время подняться графане и заходим на http://127.0.0.1:3000. Выбираем слева вверху меню (три горизонтальные черты) и переходим в dashboards.

Minio Dashboard

Minio Dashboard

Minio dashboard выдает информацию по кластеру в общем.

Minio Bucket Dashboard выводит информацию конкретно по бакетам:

Обратите внимание, что прометеусу нужно некоторое время, чтобы собрать хоть какие-то метрики. Также, если видите что пустыми только часть полей — то видимо именно эти метрики еще пусты. Например так может случится если бакетов еще нет совсем, тогда и дашборд с бакетами будет выводить «no data». Или например если обращений к api еще не было, то и S3 Api Request тоже будет пуст.

Разделение на виртуальные машины

Если вы хотите развернуть свой кластер минио на разных машинах, а не на одной, то compose можно немного трансформировать. Рассмотрим отдельно компоуз первого контейнера. Обратите внимание, что в данном случае мы пробрасываем порты 9000 и 9001 для связи с контейнером из вне. А также жестко закрепляем в /etc/hosts (раздел extra_hosts) адреса всех наших виртуальных машин с контейнерами

version: '3.7'  services:   minio1:     restart: always     image: bitnami/minio:2024.7.26     container_name: minio1.local     hostname: minio1.local     ports:       - '9000:9000'       - '9001:9001'     environment:       - MINIO_ROOT_USER=minioadmin       - MINIO_ROOT_PASSWORD=MBVfbuu2NDS3Aw       - MINIO_DISTRIBUTED_MODE_ENABLED=yes       - MINIO_DISTRIBUTED_NODES=minio1.local,minio2.local,minio3.local,minio4.local       - MINIO_SKIP_CLIENT=yes       - MINIO_SCHEME=https       - MINIO_CONSOLE_PORT_NUMBER=9001       - MINIO_SERVER_URL=https://minio.local       - MINIO_BROWSER_REDIRECT_URL=https://minio.local/minio/ui     extra_hosts:       - "minio1.local:192.168.0.55"       - "minio2.local:192.168.0.56"       - "minio3.local:192.168.0.57"       - "minio4.local:192.168.0.58"       - "minio.local:192.168.0.59"     volumes:       - /mnt/minio1:/bitnami/minio/data       - ./certs:/certs     healthcheck:       test: [ "CMD", "curl", "-k", "https://localhost:9000/minio/health/live" ]       interval: 30s       timeout: 20s       retries: 3  # раздел с разворачиванием node exporter   node_exporter:     image: prom/node-exporter:v1.8.2     container_name: node_exporter     command:       - '--path.rootfs=/host'     network_mode: host     pid: host     restart: unless-stopped     volumes:       - '/:/host:ro,rslave'

Листинг nginx:

version: '3.7' services:   nginx:     image: nginx:1.19.2-alpine     hostname: nginx     volumes:       - ./nginx.conf:/etc/nginx/nginx.conf:ro       - ./certs:/certs     extra_hosts:       - "minio1.local:192.168.0.55"       - "minio2.local:192.168.0.56"       - "minio3.local:192.168.0.57"       - "minio4.local:192.168.0.58"       - "minio.local:192.168.0.59"     ports:       - "443:443"   node_exporter:     image: prom/node-exporter:v1.8.2     container_name: node_exporter     command:       - '--path.rootfs=/host'     network_mode: host     pid: host     restart: unless-stopped     volumes:       - '/:/host:ro,rslave'

А также посмотрим на nginx.conf. В файле конфигурации nginx, нас интересует прежде всего раздел upstream, там мы перечисляем наши ноды:

user  nginx; worker_processes  auto;  error_log  /var/log/nginx/error.log warn; pid        /var/run/nginx.pid;  events {     worker_connections  4096; }  http {    include       /etc/nginx/mime.types;    default_type  application/octet-stream;     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                    '$status $body_bytes_sent "$http_referer" '                    '"$http_user_agent" "$http_x_forwarded_for"';     access_log  /var/log/nginx/access.log  main;    sendfile        on;    keepalive_timeout  65;     # include /etc/nginx/conf.d/*.conf;    upstream minio_s3 {       least_conn;       server minio1.local:9000;       server minio2.local:9000;       server minio3.local:9000;       server minio4.local:9000;    }     upstream minio_console {       least_conn;       server minio1.local:9001;       server minio2.local:9001;       server minio3.local:9001;       server minio4.local:9001;    }     server {       listen       443 ssl;       listen  [::]:443 ssl;       server_name  minio.local;        # Allow special characters in headers       ignore_invalid_headers off;       # Allow any size file to be uploaded.       # Set to a value such as 1000m; to restrict file size to a specific value       client_max_body_size 0;       # Disable buffering       proxy_buffering off;       proxy_request_buffering off;       ssl_certificate      /certs/public.crt;       ssl_certificate_key  /certs/private.key;       ssl_protocols TLSv1.2 TLSv1.3;       ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;       ssl_prefer_server_ciphers off;       ssl_verify_client off;        location / {          proxy_set_header Host $http_host;          proxy_set_header X-Real-IP $remote_addr;          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;          proxy_set_header X-Forwarded-Proto $scheme;           proxy_connect_timeout 300;          # Default is HTTP/1, keepalive is only enabled in HTTP/1.1          proxy_http_version 1.1;          proxy_set_header Connection "";          chunked_transfer_encoding off;           proxy_pass https://minio_s3; # This uses the upstream directive definition to load balance       }        location /minio/ui/ {          rewrite ^/minio/ui/(.*) /$1 break;          proxy_set_header Host $http_host;          proxy_set_header X-Real-IP $remote_addr;          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;          proxy_set_header X-Forwarded-Proto $scheme;          proxy_set_header X-NginX-Proxy true;           # This is necessary to pass the correct IP to be hashed          real_ip_header X-Real-IP;           proxy_connect_timeout 300;           # To support websockets in MinIO versions released after January 2023          proxy_http_version 1.1;          proxy_set_header Upgrade $http_upgrade;          proxy_set_header Connection "upgrade";          # Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)          # Uncomment the following line to set the Origin request to an empty string          # proxy_set_header Origin '';           chunked_transfer_encoding off;           proxy_pass https://minio_console; # This uses the upstream directive definition to load balance       }    } } 

Заключение

На просторах интернета готовых компоузов не нашел, поэтому решил выложить свои. Надеюсь, кому-то поможет в работе.


ссылка на оригинал статьи https://habr.com/ru/articles/834020/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *