MinIO

高性能オブジェクトストレージサーバー。Amazon S3互換API、クラウドネイティブ設計、Kubernetes対応。プライベートクラウド向けソリューション。

ファイルサーバーオブジェクトストレージS3互換セルフホスト高性能AI対応

サーバー

MinIO

概要

MinIOは、Amazon S3完全互換のAPIを提供する高性能オープンソースオブジェクトストレージです。GNU AGPLv3ライセンスの下で公開され、クラウドネイティブワークロード、特にAI・機械学習向けに最適化されています。秒間2.2TiB以上の本番スループットを実現し、600万以上のデプロイメント実績を持つ世界最速のオブジェクトストレージとして評価されています。シングルノードからペタバイト級の分散環境まで、パブリッククラウド、プライベートクラウド、ベアメタル、エッジインフラ、Kubernetesなど、あらゆる環境での展開が可能です。

詳細

MinIO 2025年版は、RELEASE.2025-06-13T11-33-47Zを最新安定版として、AI・機械学習ワークロードに特化した「AIStor」機能を大幅に強化しました。企業向け機能として、IAM(Identity and Access Management)、ILM(Information Lifecycle Management)、レプリケーション、バージョニング、可観測性、暗号化、キー管理、ファイアウォール、イベント・Lambda統合、管理コンソールなど包括的な機能を標準提供。最新のデプロイメントトポロジーは、SNSD(単一ノード・単一ドライブ)、SNMD(単一ノード・複数ドライブ)、MNMD(複数ノード・複数ドライブ)の3パターンに対応し、用途に応じた柔軟な構成が可能です。2025年5月版からコンソールUIがオブジェクトブラウザー機能に特化され、管理操作はmcコマンドラインツールに統合されました。

主な特徴

  • S3完全互換: AWS S3 APIとの100%互換性とエンタープライズレベルの信頼性
  • 世界最高性能: 秒間2.2TiB以上のスループットと業界標準ベンチマーク
  • AI・機械学習特化: クラウドネイティブAIワークロード向け最適化
  • マルチ環境対応: Kubernetes、Docker、ベアメタル、クラウド全対応
  • 高可用性: 最大50%のノード・ドライブ障害に対する耐障害性
  • 包括的セキュリティ: オブジェクトレベル暗号化とS3拡張セキュリティ機能

メリット・デメリット

メリット

  • S3互換により既存のツールやライブラリをそのまま活用可能
  • オープンソースでベンダーロックインを回避、自由度の高い運用
  • AI・機械学習ワークロードに最適化された世界最高レベルの性能
  • シングルノードから分散クラスターまで用途に応じたスケーラブルな展開
  • 包括的なエンタープライズ機能による運用コストの削減
  • Kubernetesネイティブ設計によるコンテナ環境での優れた運用性

デメリット

  • 分散構成でのクラスター管理にはErlang Cookieなど専門知識が必要
  • 高性能を活かすためには適切なハードウェア設計とネットワーク構成が重要
  • レプリケーション設定や分散合意アルゴリズムの理解が複雑
  • 本格的な分散構成では最低4ノード以上の要件によるインフラコスト
  • エンタープライズ機能をフル活用するための習得コストが高い
  • 従来のファイルサーバーからの移行時にアプリケーション改修が必要

参考ページ

書き方の例

Dockerによる基本セットアップ

# データディレクトリ作成
mkdir -p ~/minio/data

# MinIOコンテナ起動(スタンドアロン構成)
docker run -d \
  --name minio-server \
  -p 9000:9000 \
  -p 9001:9001 \
  -v ~/minio/data:/data \
  -e "MINIO_ROOT_USER=minioadmin" \
  -e "MINIO_ROOT_PASSWORD=minioadmin123" \
  quay.io/minio/minio server /data --console-address ":9001"

# コンテナ状態確認
docker ps | grep minio
docker logs minio-server

# ブラウザでアクセス
# Object API: http://localhost:9000
# Console UI: http://localhost:9001

# Docker Compose設定例
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
  minio:
    image: quay.io/minio/minio:latest
    container_name: minio
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin123
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio_data:/data
    command: server /data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

volumes:
  minio_data:
EOF

docker-compose up -d

Linux環境でのネイティブインストール

# MinIO最新版ダウンロード(Linux AMD64)
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/

# サービスユーザー作成
sudo useradd -r -s /sbin/nologin minio-user

# データディレクトリ作成
sudo mkdir -p /mnt/minio/data
sudo chown minio-user:minio-user /mnt/minio/data

# 設定ディレクトリ作成
sudo mkdir -p /etc/minio
sudo chown minio-user:minio-user /etc/minio

# 環境設定ファイル作成
sudo tee /etc/default/minio << 'EOF'
# Volume to be used for MinIO server.
MINIO_VOLUMES="/mnt/minio/data"
# Use if you want to run MinIO on a custom port.
MINIO_OPTS="--console-address :9001"
# Root credentials
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin123
EOF

# systemdサービス設定
sudo tee /etc/systemd/system/minio.service << 'EOF'
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio

[Service]
WorkingDirectory=/usr/local/

User=minio-user
Group=minio-user
ProtectProc=invisible

EnvironmentFile=/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES

# Let systemd restart this service always
Restart=always

# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536

# Specifies the maximum number of threads this process can create
TasksMax=infinity

# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no

[Install]
WantedBy=multi-user.target
EOF

# サービス有効化・起動
sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
sudo systemctl status minio

MinIO Client (mc) のセットアップと基本操作

# MinIO Client (mc) インストール
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/

# MinIOサーバーの設定
mc alias set myminio http://localhost:9000 minioadmin minioadmin123

# エイリアス設定確認
mc alias list

# バケット操作
mc mb myminio/test-bucket                    # バケット作成
mc ls myminio                                # バケット一覧
mc rb myminio/test-bucket                    # 空のバケット削除
mc rb myminio/test-bucket --force            # 強制削除(中身も含む)

# オブジェクト操作
echo "Hello MinIO" > test.txt
mc cp test.txt myminio/test-bucket/          # ファイルアップロード
mc ls myminio/test-bucket                    # オブジェクト一覧
mc cp myminio/test-bucket/test.txt ./downloaded.txt  # ダウンロード
mc rm myminio/test-bucket/test.txt           # オブジェクト削除

# 同期操作
mc mirror ./local-folder myminio/test-bucket/remote-folder/  # アップロード同期
mc mirror myminio/test-bucket/remote-folder/ ./sync-folder/  # ダウンロード同期

# バケットポリシー設定
mc anonymous set download myminio/test-bucket  # パブリック読み取り許可
mc anonymous set none myminio/test-bucket      # パブリックアクセス無効

# バージョニング有効化
mc version enable myminio/test-bucket
mc version info myminio/test-bucket

# バケット通知設定
mc event add myminio/test-bucket arn:minio:sqs::1:webhook --event put,delete
mc event list myminio/test-bucket

Python SDKを使用したプログラミング例

from minio import Minio
from minio.error import S3Error
import io
import json
from datetime import datetime, timedelta

# MinIOクライアント初期化
client = Minio(
    "localhost:9000",
    access_key="minioadmin",
    secret_key="minioadmin123",
    secure=False  # HTTPSの場合はTrue
)

def basic_operations():
    """基本的なバケット・オブジェクト操作"""
    bucket_name = "python-test-bucket"
    object_name = "test-object.txt"
    
    try:
        # バケット存在確認・作成
        if not client.bucket_exists(bucket_name):
            client.make_bucket(bucket_name)
            print(f"バケット '{bucket_name}' を作成しました")
        
        # オブジェクトアップロード(文字列から)
        data = "Hello from MinIO Python SDK!"
        client.put_object(
            bucket_name,
            object_name,
            io.BytesIO(data.encode('utf-8')),
            len(data.encode('utf-8')),
            content_type="text/plain"
        )
        print(f"オブジェクト '{object_name}' をアップロードしました")
        
        # オブジェクトダウンロード
        response = client.get_object(bucket_name, object_name)
        content = response.read().decode('utf-8')
        print(f"ダウンロード内容: {content}")
        response.close()
        response.release_conn()
        
        # オブジェクト一覧
        objects = client.list_objects(bucket_name)
        print("オブジェクト一覧:")
        for obj in objects:
            print(f"  - {obj.object_name} (サイズ: {obj.size}, 更新日: {obj.last_modified})")
        
    except S3Error as e:
        print(f"エラー: {e}")

def advanced_operations():
    """高度な操作(メタデータ、署名付きURL等)"""
    bucket_name = "advanced-test-bucket"
    
    try:
        # バケット作成
        if not client.bucket_exists(bucket_name):
            client.make_bucket(bucket_name)
        
        # メタデータ付きオブジェクトアップロード
        data = json.dumps({"message": "Hello", "timestamp": datetime.now().isoformat()})
        metadata = {
            "x-amz-meta-author": "Python-SDK",
            "x-amz-meta-version": "1.0",
            "x-amz-meta-category": "test"
        }
        
        client.put_object(
            bucket_name,
            "metadata-object.json",
            io.BytesIO(data.encode('utf-8')),
            len(data.encode('utf-8')),
            content_type="application/json",
            metadata=metadata
        )
        
        # オブジェクト情報取得(メタデータ含む)
        stat = client.stat_object(bucket_name, "metadata-object.json")
        print(f"オブジェクト情報:")
        print(f"  サイズ: {stat.size}")
        print(f"  更新日: {stat.last_modified}")
        print(f"  ETag: {stat.etag}")
        print(f"  メタデータ: {stat.metadata}")
        
        # 署名付きURL生成(ダウンロード用)
        download_url = client.presigned_get_object(
            bucket_name, 
            "metadata-object.json",
            expires=timedelta(hours=1)
        )
        print(f"ダウンロード用署名付きURL: {download_url}")
        
        # 署名付きURL生成(アップロード用)
        upload_url = client.presigned_put_object(
            bucket_name,
            "upload-via-url.txt",
            expires=timedelta(hours=1)
        )
        print(f"アップロード用署名付きURL: {upload_url}")
        
        # ファイルアップロード
        with open("test.txt", "w") as f:
            f.write("Test file for MinIO")
        
        client.fput_object(
            bucket_name,
            "uploaded-file.txt",
            "test.txt",
            content_type="text/plain"
        )
        print("ファイルアップロード完了")
        
        # ファイルダウンロード
        client.fget_object(
            bucket_name,
            "uploaded-file.txt",
            "downloaded-file.txt"
        )
        print("ファイルダウンロード完了")
        
    except S3Error as e:
        print(f"エラー: {e}")

def lifecycle_management():
    """ライフサイクル管理とバージョニング"""
    bucket_name = "lifecycle-test-bucket"
    
    try:
        if not client.bucket_exists(bucket_name):
            client.make_bucket(bucket_name)
        
        # バージョニング有効化(mc コマンド必要)
        print("バージョニングはmcコマンドで設定してください:")
        print(f"mc version enable myminio/{bucket_name}")
        
        # 複数バージョンのオブジェクト作成
        for version in range(1, 4):
            data = f"Version {version} of the document"
            client.put_object(
                bucket_name,
                "versioned-document.txt",
                io.BytesIO(data.encode('utf-8')),
                len(data.encode('utf-8')),
                content_type="text/plain"
            )
            print(f"バージョン {version} をアップロードしました")
        
        # オブジェクトのバージョン一覧(mc コマンド例)
        print("\nオブジェクトバージョン確認:")
        print(f"mc ls --versions myminio/{bucket_name}/versioned-document.txt")
        
    except S3Error as e:
        print(f"エラー: {e}")

# 実行例
if __name__ == "__main__":
    print("=== MinIO Python SDK 基本操作 ===")
    basic_operations()
    
    print("\n=== MinIO Python SDK 高度な操作 ===")
    advanced_operations()
    
    print("\n=== MinIO Python SDK ライフサイクル管理 ===")
    lifecycle_management()

分散クラスター構成(4ノード構成例)

# 4ノード分散MinIOクラスター設定
# 各ノードで以下の設定を実行

# Node 1 (192.168.1.10)
export MINIO_ROOT_USER=minioadmin
export MINIO_ROOT_PASSWORD=minioadmin123
minio server \
  http://192.168.1.10/mnt/disk{1...4} \
  http://192.168.1.11/mnt/disk{1...4} \
  http://192.168.1.12/mnt/disk{1...4} \
  http://192.168.1.13/mnt/disk{1...4} \
  --console-address ":9001"

# Node 2-4でも同様のコマンドを実行

# クラスター状態確認
mc admin info myminio
mc admin cluster info myminio

# ノード追加(既存クラスターの拡張)
# 新しいノードセットを追加する場合
export MINIO_ROOT_USER=minioadmin
export MINIO_ROOT_PASSWORD=minioadmin123
minio server \
  http://192.168.1.{10...13}/mnt/disk{1...4} \
  http://192.168.1.{14...17}/mnt/disk{1...4} \
  --console-address ":9001"

# ヘルスチェック
mc admin heal myminio
mc admin health myminio

Kubernetes環境での高可用性構成

# minio-operator.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: minio-system
---
# MinIO Operatorのインストール
# kubectl apply -k "github.com/minio/operator"

# MinIO Tenant設定例
apiVersion: minio.min.io/v2
kind: Tenant
metadata:
  name: minio-cluster
  namespace: minio-system
spec:
  image: quay.io/minio/minio:latest
  credsSecret:
    name: minio-creds-secret
  pools:
  - servers: 4
    name: pool-0
    volumesPerServer: 4
    volumeClaimTemplate:
      metadata:
        name: data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Ti
        storageClassName: fast-ssd
  requestAutoCert: false
  console:
    image: quay.io/minio/console:latest
    replicas: 2
    consoleSecret:
      name: minio-console-secret
---
apiVersion: v1
kind: Secret
metadata:
  name: minio-creds-secret
  namespace: minio-system
type: Opaque
data:
  accesskey: bWluaW9hZG1pbg==  # minioadmin (base64)
  secretkey: bWluaW9hZG1pbjEyMw==  # minioadmin123 (base64)
---
apiVersion: v1
kind: Secret
metadata:
  name: minio-console-secret
  namespace: minio-system
type: Opaque
data:
  CONSOLE_PBKDF_PASSPHRASE: c2VjcmV0  # secret (base64)
  CONSOLE_PBKDF_SALT: c2FsdA==  # salt (base64)
  CONSOLE_ACCESS_KEY: bWluaW9hZG1pbg==  # minioadmin (base64)
  CONSOLE_SECRET_KEY: bWluaW9hZG1pbjEyMw==  # minioadmin123 (base64)

監視・運用管理とパフォーマンス最適化

# システム情報・統計確認
mc admin info myminio
mc admin prometheus info myminio
mc admin prometheus generate myminio

# ストレージ使用量確認
mc admin storage-info myminio
mc du myminio --recursive

# ユーザー・ポリシー管理
mc admin user add myminio newuser newpassword
mc admin user list myminio

# カスタムポリシー作成
cat > readwrite-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::test-bucket/*",
        "arn:aws:s3:::test-bucket"
      ]
    }
  ]
}
EOF

mc admin policy create myminio readwrite-policy readwrite-policy.json
mc admin policy attach myminio readwrite-policy --user newuser

# サービスアカウント管理
mc admin user svcacct add myminio newuser
mc admin user svcacct list myminio newuser

# 設定のバックアップ・復元
mc admin config export myminio > minio-config-backup.json
mc admin config import myminio < minio-config-backup.json

# パフォーマンステスト
mc admin speedtest myminio --duration 60s --size 1GiB

# Prometheusメトリクス設定
mc admin prometheus info myminio
mc admin prometheus generate myminio

# ログレベル設定
mc admin config set myminio logger_webhook:1 endpoint="http://elasticsearch:9200/logs/_doc"
mc admin service restart myminio

# 暗号化設定(KMS)
mc admin kms key create myminio my-key
mc admin kms key list myminio