26Z24a

QK·2026년 8월 23일

네. 지금 말씀하신 구조라면 MLflow와 별도로 "Project Management Portal"을 두고, AIStor는 실제 data plane + IAM/quota enforcement를 담당하게 하는 구조가 가장 깔끔합니다.

특히 한 가지는 먼저 짚고 가는 게 좋습니다.

가능하면 "프로젝트 = AIStor bucket 1개"로 매핑하는 것을 강하게 추천합니다.

AIStor의 quota는 bucket 단위이고, prefix에는 hard quota가 없습니다. 반면 IAM policy는 bucket/prefix 단위로 제한할 수 있습니다. 따라서 project → bucket으로 만들면 사용량/Quota/권한/키 관리가 모두 AIStor native 기능과 자연스럽게 맞습니다. (MinIO AIStor Documentation)


1. 전체 구조

제가 추천하는 구조는 다음입니다.

                    ┌─────────────────────┐
                    │   Project Portal    │
                    │                     │
                    │ Project 생성/삭제   │
                    │ Access Key 발급     │
                    │ Quota 설정          │
                    │ Usage 조회           │
                    │ 상태/권한 관리       │
                    └─────────┬───────────┘
                              │
                    AIStor Admin API
                              │
                              ▼
                  ┌───────────────────────┐
                  │      MinIO AIStor     │
                  │                       │
                  │  IAM / Bucket / Quota │
                  │  S3 / Usage           │
                  └──────────┬────────────┘
                             │
              ┌──────────────┴──────────────┐
              │                             │
         MLflow Server                 Project User
              │                             │
              │ S3 API                     │ S3 API
              ▼                             ▼
       mlflow-project-A              project-A bucket
       artifact store                     │
                                          ▼
                                   AIStor Object Data

여기서 역할을 명확하게 나누는 게 중요합니다.


2. MLflow의 역할

MLflow는 AIStor를 object storage로 사용하는 애플리케이션입니다.

MLflow가 담당하는 것은:

  • Experiment
  • Run
  • Parameter
  • Metric
  • Tag
  • Model
  • Artifact
  • Model Registry
  • Artifact upload/download

등입니다.

MLflow 공식 문서에서도 artifact store는 모델 weight, image, Parquet 등의 실제 파일을 저장하는 역할이고, metadata는 PostgreSQL/MySQL 같은 backend store에 저장하는 구조로 설명합니다. S3-compatible storage도 지원하며 MinIO를 S3-compatible endpoint로 사용할 수 있습니다. (MLflow AI Platform)

즉:

MLflow
 ├── Metadata
 │     └── PostgreSQL
 │
 └── Artifact
       └── AIStor

입니다.


3. MLflow는 AIStor Admin API를 사용하면 안 됨

이게 상당히 중요합니다.

MLflow는:

AIStor S3 API

만 사용하도록 만드는 것이 좋습니다.

즉:

MLflow
   │
   ├── PUT Object
   ├── GET Object
   ├── LIST Object
   ├── DELETE Object
   └── Multipart Upload
          │
          ▼
       AIStor S3

입니다.

AIStor의 S3 API는 AWS Signature V4를 사용하며 일반적인 S3 object/bucket API와 multipart upload를 제공합니다. (MinIO AIStor Documentation)

MLflow 역시 S3-compatible artifact store에 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, MLFLOW_S3_ENDPOINT_URL 등을 설정해서 사용합니다. (MLflow AI Platform)


4. MLflow에서 필요한 AIStor API

프로젝트 하나를:

project-a

bucket으로 만든다고 하면 MLflow가 실제로 필요한 것은 대략 다음입니다.

기본

GetBucketLocation
ListBucket
GetObject
PutObject
DeleteObject

그리고 artifact 크기가 큰 경우:

CreateMultipartUpload
UploadPart
CompleteMultipartUpload
AbortMultipartUpload
ListParts

가 필요할 수 있습니다.

MLflow artifact upload에서 multipart upload를 사용할 수 있고, AIStor의 S3 API도 multipart 관련 API를 제공합니다. (MLflow AI Platform)


5. MLflow Access Key의 권한

예를 들어:

Project: fraud-model
Bucket: mlflow-fraud-model
Access Key: AKIA...

라면 이 key는 해당 bucket만 접근할 수 있도록 합니다.

개념적으로:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketLocation",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::mlflow-fraud-model"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload",
        "s3:ListMultipartUploadParts"
      ],
      "Resource": [
        "arn:aws:s3:::mlflow-fraud-model/*"
      ]
    }
  ]
}

정도로 제한합니다.

AIStor policy는 AWS IAM과 유사한 policy 구조를 사용하며 bucket과 object resource를 구체적으로 제한할 수 있습니다. (MinIO AIStor Documentation)


6. Project Management Portal의 역할

반대로 관리화면은 MLflow API를 직접 제어하는 게 아니라 AIStor provisioning/control plane 역할을 합니다.

예를 들어:

프로젝트 생성

사용자
 ↓
Project Portal
 ↓
Create Project
 ↓
AIStor Bucket 생성
 ↓
IAM Policy 생성
 ↓
Access Key 생성
 ↓
Quota 설정
 ↓
Project 정보 저장

결과:

Project
  │
  ├── Bucket
  │     └── mlflow-project-a
  │
  ├── Access Key
  │
  ├── Secret Key
  │
  ├── Policy
  │
  └── Quota
        ├── 1 TB
        └── 1M objects

7. 관리화면에서 필요한 AIStor API

관리화면은 크게 5개 API 영역을 사용합니다.

A. Bucket

프로젝트 생성/삭제:

CreateBucket
DeleteBucket
HeadBucket
GetBucketLocation

AIStor S3 API에서 bucket 생성은 PUT /{bucket}, object listing은 GET /{bucket}?list-type=2 형태입니다. (MinIO AIStor Documentation)


8. B. IAM / Access Key

여기가 관리화면의 핵심입니다.

AIStor Admin API에는 service account/access key 관리 API가 있습니다.

CreateServiceAccount
ListServiceAccounts
GetServiceAccount
UpdateServiceAccount
DeleteServiceAccount

공식 Admin API reference에서도 service account 관련 endpoint를 제공합니다. (MinIO AIStor Documentation)

AIStor의 access key는 application authentication credential이고 parent user의 권한을 상속하면서 별도로 더 제한된 custom policy를 붙일 수 있습니다. (MinIO AIStor Documentation)

따라서:

Project Portal
      │
      ├── Parent User / Service Account
      │
      └── Access Key
             │
             └── Project Policy

로 구성합니다.


9. C. Policy

프로젝트별 policy를 생성합니다.

예:

policy-project-a

권한:

Bucket:
  mlflow-project-a

Allowed:
  ListBucket
  GetObject
  PutObject
  DeleteObject
  Multipart

Denied:
  다른 bucket
  다른 project

AIStor Admin API에는 policy 생성/조회/삭제 및 user/group에 policy를 연결하는 API가 있습니다. (MinIO AIStor Documentation)

관리화면에서는 사실상:

CreatePolicy
AttachPolicy

가 중요합니다.


10. D. Quota

이 부분은 AIStor native quota를 사용하는 것을 강력히 추천합니다.

프로젝트가:

Project A
Quota = 5 TB

라면:

Project Portal
       │
       ▼
admin:SetBucketQuota
       │
       ▼
AIStor
       │
       └── bucket = 5TB

으로 설정합니다.

AIStor는 bucket hard quota를 제공하고 quota에 도달하면 추가 PUT을 거부합니다. 다만 quota usage 계산은 내부 scanner를 기반으로 하기 때문에 실시간/원자적 hard limit은 아니며 일시적으로 quota를 초과할 수 있습니다. (MinIO AIStor Documentation)

AIStor의 quota 관련 권한은:

admin:SetBucketQuota
admin:GetBucketQuota

입니다. (MinIO AIStor Documentation)


11. 그래서 "quota 초과 시 관리화면이 policy를 바꾼다"는 것은 굳이 필요 없음

현재 구현하신:

quota 한도 초과 → policy 변경 → PutObject 차단

이라는 아이디어는 AIStor bucket quota를 쓰는 경우에는 AIStor에 맡기는 게 더 좋습니다.

즉:

기존 방식

Usage >= quota
       ↓
관리화면 감지
       ↓
Policy 변경
       ↓
PutObject Deny

보다는:

Project Portal
       │
       │ SetBucketQuota
       ▼
AIStor Bucket Quota
       │
       │
Usage >= quota
       ↓
AIStor S3 handler
       ↓
PUT reject

가 훨씬 좋습니다.

AIStor는 hard quota가 설정된 bucket에 대해 quota에 도달하면 이후 PUT을 거부하도록 구현되어 있습니다. 다만 quota가 scanner 기반이라 정확히 quota byte에서 원자적으로 차단되는 것은 아닙니다. (MinIO AIStor Documentation)


12. 이 부분이 관리화면의 핵심 UX가 될 것 같음

관리화면:

Project: Project-A

Storage
────────────────────────────
Quota             5 TB
Current Usage     3.8 TB
Usage             76%

Objects           1,283,442

Status             NORMAL
────────────────────────────

그리고:

Quota
[ 5 TB ]

[Apply]

를 누르면:

admin:SetBucketQuota

가 호출됩니다.


13. E. Usage

이건 약간 다릅니다.

관리화면에서:

Objects
Total Size

를 보여주려면 AIStor usage 정보를 가져와야 합니다.

AIStor Admin API에는:

/datausageinfo

계열의 Data Usage API가 있고 admin:DataUsageInfo 권한으로 data usage 정보를 조회할 수 있습니다. (MinIO AIStor Documentation)

또 AIStor Admin API v4의 cluster query는 cluster-level bucket count/object count/capacity 등의 정보를 제공합니다. (MinIO AIStor Documentation)


14. 다만 여기서 "프로젝트가 prefix인 경우" 문제가 생김

예를 들어:

bucket: mlflow

mlflow/
 ├── project-a/
 ├── project-b/
 └── project-c/

라면:

Project A
Usage = ?
Quota = ?

를 AIStor native bucket quota로 처리할 수 없습니다.

AIStor quota는 bucket 단위입니다. (MinIO AIStor Documentation)

반면 IAM은:

arn:aws:s3:::mlflow/project-a/*

처럼 prefix를 제한할 수 있습니다. AIStor policy는 prefix 기반 resource/condition을 지원합니다. (MinIO AIStor Documentation)

따라서:

권한

prefix 수준 가능

quota

bucket 수준

입니다.

이 차이가 매우 중요합니다.


15. 그래서 프로젝트별 quota가 핵심이면 bucket-per-project가 훨씬 좋음

제가 사용자 시스템이라면:

Project A
    ↓
bucket-a

Project B
    ↓
bucket-b

Project C
    ↓
bucket-c

로 갑니다.

그리고 MLflow artifact root:

s3://bucket-a/
s3://bucket-b/
s3://bucket-c/

로 합니다.

이렇게 하면:

Project
  ├── Bucket
  ├── Access Key
  ├── Policy
  ├── Quota
  └── Usage

가 정확하게 1:1로 매핑됩니다.


16. 전체 API를 역할별로 정리하면

MLflow

AIStor S3 API만 사용

기능AIStor API
Bucket 접근GetBucketLocation
Artifact 목록ListObjectsV2
Artifact 업로드PutObject
Artifact 다운로드GetObject
Artifact 삭제DeleteObject
대용량 uploadCreateMultipartUpload
UploadPart
CompleteMultipartUpload
AbortMultipartUpload
Multipart 조회ListParts

MLflow에는 AIStor Admin credential을 주지 않습니다.


17. Project Management Portal

기능AIStor API/권한
Project bucket 생성S3 CreateBucket
Bucket 확인HeadBucket
Bucket 삭제S3 DeleteBucket
Project policy 생성Admin CreatePolicy
Policy 조회Admin GetPolicy
Policy 연결Admin AttachUserOrGroupPolicy
Access Key 생성Admin CreateServiceAccount
Access Key 조회ListServiceAccounts / InfoServiceAccount
Access Key 변경UpdateServiceAccount
Access Key 폐기DeleteServiceAccount
Quota 설정admin:SetBucketQuota
Quota 조회admin:GetBucketQuota
Usage 조회admin:DataUsageInfo
Cluster usageAdmin Query API
Project 상태Bucket/IAM/Usage 조합

AIStor Admin API가 이러한 bucket quota, service account, policy, data usage 기능을 제공한다는 점이 공식 API reference에 명시되어 있습니다. (MinIO AIStor Documentation)


18. 제가 권장하는 보안 구조

관리화면 자체가 AIStor의 consoleAdmin credential을 갖게 하면 안 됩니다.

현재 AIStor에는 IAM 전용 iamAdmin과 infrastructure 전용 infraAdmin 정책이 분리되어 있습니다. infraAdmin에는 bucket quota와 data usage 같은 infrastructure 관련 권한이 포함됩니다. (MinIO AIStor Documentation)

따라서 관리 backend에는 필요한 권한만 가진 custom admin policy를 만드는 게 좋습니다.

예:

Project Management Service Account

ALLOW:
  admin:CreateServiceAccount
  admin:ListServiceAccounts
  admin:InfoServiceAccount
  admin:UpdateServiceAccount
  admin:DeleteServiceAccount

  admin:CreatePolicy
  admin:GetPolicy
  admin:DeletePolicy
  admin:AttachUserOrGroupPolicy

  admin:SetBucketQuota
  admin:GetBucketQuota
  admin:DataUsageInfo

  s3:CreateBucket
  s3:DeleteBucket
  s3:GetBucketLocation
  ...

그리고:

DENY:
  admin:ServiceRestart
  admin:ServerUpdate
  admin:Heal
  admin:Decommission
  admin:Rebalance
  admin:KMS*

등을 명확히 분리합니다.


19. 특히 Access Key와 Secret Key를 관리 DB에 저장할 때 주의

Project Portal에서:

Project A
 ├── Access Key
 └── Secret Key

를 발급해준다면 Secret Key를 일반 DB에 평문으로 저장하지 않는 것을 권장합니다.

AIStor도 access key 생성 시 secret/password 값을 나중에 다시 조회할 수 없도록 하고, credential rotation 시 새 key를 생성한 뒤 기존 key를 삭제하는 방식을 안내합니다. (MinIO AIStor Documentation)

따라서:

Project Portal
       │
       ├── Access Key → DB 저장 가능
       │
       └── Secret Key → Vault

가 가장 좋습니다.

사용자 환경에 이미 Vault OSS를 구축하려고 하고 있으니:

Project Portal
       │
       ├── metadata → PostgreSQL
       │
       └── secret → Vault

로 가져가는 것을 추천합니다.


20. 최종적으로는 이런 3-layer 구조가 가장 좋음

                  ┌─────────────────────┐
                  │   Project Portal    │
                  │                     │
                  │ Project lifecycle   │
                  │ IAM provisioning    │
                  │ Quota management    │
                  │ Usage dashboard     │
                  └─────────┬───────────┘
                            │
                    AIStor Admin API
                            │
             ┌──────────────┼──────────────┐
             │              │              │
             ▼              ▼              ▼
          Bucket           IAM           Quota
             │              │              │
             └──────────────┼──────────────┘
                            │
                         AIStor
                            ▲
                            │ S3 API
                            │
                     ┌──────┴──────┐
                     │             │
                  MLflow        Project
                  Server        Workload
                     │             │
                     └──────┬──────┘
                            │
                         Artifact

그리고 metadata:

Project Portal
      │
      ▼
   PostgreSQL
      │
      └── project_id
          bucket
          quota
          access_key_id
          status
          owner

Secret:

Vault
 └── project/{project-id}/s3
       ├── accessKey
       └── secretKey

제가 특히 권장하는 최종 정책

Project = Bucket = Access Key = Quota를 1:1로 맞추세요.

project-a
   │
   ├── bucket: mlflow-project-a
   ├── access-key: project-a-xxxx
   ├── policy: policy-project-a
   ├── quota: 5TB
   └── usage: 3.8TB / 1.2M objects

이렇게 만들면 관리화면의 거의 모든 기능이 AIStor native 기능에 정확히 대응됩니다.

반대로:

bucket
 ├── project-a/
 ├── project-b/
 └── project-c/

구조는 권한 분리는 가능하지만 project별 quota enforcement가 AIStor native quota와 맞지 않기 때문에 관리화면에서 별도의 usage scanner + policy 변경 로직을 만들어야 합니다. 그리고 AIStor quota 자체도 scanner 기반 best-effort이므로, 관리화면에서 "quota 초과 즉시 policy deny"를 구현하는 것 역시 정확한 hard-limit으로 보기는 어렵습니다. (MinIO AIStor Documentation)

따라서 MLflow + AIStor + Project Portal 조합에서는 bucket-per-project가 훨씬 운영하기 좋은 모델이라고 봅니다.

profile
engineer

0개의 댓글