
MinIO 클라이언트의 사용방법에 대해서 자세히 알아보자
MinIO 클라이언트(mc)를 사용하면 간단히 버킷을 생성할 수 있습니다. 다음은 버킷을 생성하는 기본적인 단계입니다.
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 명령어를 사용하여 별칭(alias)을 만듭니다.
mc alias set myminio http://<MINIO_SERVER>:9000 <ACCESS_KEY> <SECRET_KEY>
<MINIO_SERVER>: MinIO 서버의 호스트 주소 (예: 127.0.0.1 또는 서버 IP)<ACCESS_KEY>: MinIO 서버의 관리자 계정 Access Key<SECRET_KEY>: MinIO 서버의 관리자 계정 Secret Key설정이 정상적으로 완료되면 mc alias ls 명령어로 별칭을 확인할 수 있습니다:
mc alias ls
별칭이 설정된 후 다음 명령어로 버킷을 생성할 수 있습니다.
mc mb myminio/mybucket
myminio는 위에서 설정한 alias 이름이며, mybucket은 생성할 버킷 이름입니다.정상적으로 생성되면 다음과 같은 메시지가 표시됩니다:
Bucket created successfully `myminio/mybucket`.
생성된 버킷이 정상적으로 표시되는지 확인하려면:
mc ls myminio
이 명령으로 해당 서버의 모든 버킷을 확인할 수 있으며, mybucket/이 표시되면 성공적으로 생성된 것입니다.
버킷에 데이터 업로드:
mc cp /path/to/localfile.txt myminio/mybucket
버킷에서 데이터 다운로드:
mc cp myminio/mybucket/localfile.txt /path/to/local/
만약 로컬 디렉토리 구조를 유지한 채로 MinIO 버킷에 업로드 할려면 아래와 같은 방법을 사용할 수 있다. 즉, 여러 폴더로 나누어진 데이터를 한 번에 한 버킷에 넣을 수 있습니다.
/local/data/
├── folder1/
│ ├── file1.jpg
│ └── file2.jpg
├── folder2/
│ ├── file3.jpg
│ └── file4.txt
└── folder3/
├── subfolder/
│ └── file5.png이러한 구조를 myminio/mybucket에 업로드하고 싶다고 가정할 때 다음과 같은 명령을 사용할 수 있습니다.
mc cp 명령어 사용 (재귀 옵션)mc cp에 -r 옵션(재귀 복사)을 붙여 전체 폴더를 복사할 수 있습니다.
mc cp -r /local/data myminio/mybucket/
이렇게 하면 /local/data 폴더 아래의 모든 디렉토리와 파일이 MinIO 버킷 mybucket 하위에 업로드됩니다.
mybucket/
├── data/
├── folder1/
├── folder2/
└── folder3/mc mirror 명령어 사용mc mirror는 로컬 디렉토리와 MinIO 버킷을 동기화할 때 유용합니다.
mc mirror /local/data myminio/mybucket
mc mirror는 /local/data 디렉토리 구조와 파일을 MinIO mybucket으로 동일하게 반영합니다. 이미 있는 파일을 제외하고 새 파일만 업로드하거나, 삭제나 업데이트를 반영할 수도 있습니다.
버킷 경로 지정:
myminio/mybucket/ 뒤에 슬래시(/)를 붙이면 해당 버킷 루트 디렉토리 아래에 업로드됩니다. 슬래시를 붙이지 않아도 기본적으로 동일하게 동작합니다.
재귀 옵션 필수:
디렉토리를 전체적으로 업로드하려면 -r 옵션을 사용해야 합니다(mc mirror는 기본적으로 재귀적으로 동작).
폴더 구조 유지:
mc cp나 mc mirror는 기본적으로 폴더 구조를 그대로 유지합니다.
python을 이용해도 버킷에 파일을 업로드 할 수 있다.
Python과 boto3 라이브러리를 사용하면 로컬 폴더 전체를 MinIO 버킷에 쉽게 업로드할 수 있습니다. 다음 예제 코드는 로컬 디렉토리 구조를 유지하면서, 해당 폴더 내 모든 파일을 재귀적으로 업로드하는 방법을 보여줍니다.
pip install boto3endpoint_url: MinIO 서버 URL (예: http://127.0.0.1:9000)aws_access_key_id: MinIO Access Keyaws_secret_access_key: MinIO Secret Keybucket_name: 업로드할 버킷 이름local_folder: 업로드할 로컬 폴더 경로 (예: ./data)import os
import boto3
# MinIO 접속 정보 설정
endpoint_url = "http://127.0.0.1:9000"
access_key = "your-access-key"
secret_key = "your-secret-key"
bucket_name = "mybucket"
local_folder = "./data" # 업로드할 로컬 폴더 경로
# boto3를 사용하여 MinIO 클라이언트 생성
s3_client = boto3.client(
"s3",
endpoint_url=endpoint_url,
aws_access_key_id=access_key,
aws_secret_access_key=secret_key
)
# 폴더 전체 업로드 함수
def upload_directory(local_directory, bucket, s3_client):
# os.walk를 사용하여 디렉토리 내 모든 파일과 하위 디렉토리를 순회
for root, dirs, files in os.walk(local_directory):
for file in files:
# 로컬 파일의 전체 경로
local_path = os.path.join(root, file)
# S3(또는 MinIO) 내부 경로: 버킷 내에서 디렉토리 구조 유지
# os.path.relpath를 사용하여 local_directory를 기준으로 상대 경로 생성
relative_path = os.path.relpath(local_path, local_directory)
s3_path = relative_path.replace("\\", "/") # 윈도우 OS 대비 슬래시 처리
# 파일 업로드
s3_client.upload_file(local_path, bucket, s3_path)
print(f"Uploaded {local_path} to {bucket}/{s3_path}")
# 함수 실행
upload_directory(local_folder, bucket_name, s3_client)
os.walk 사용:
os.walk(local_directory)로 지정한 local_folder 내의 모든 파일, 하위 디렉토리를 탐색합니다.
상대 경로 유지:
업로드할 때 os.path.relpath를 사용하여 local_folder를 기준으로 상대 경로를 계산합니다. 이렇게 하면 로컬 구조와 동일한 폴더 구조를 MinIO 버킷 안에 재현할 수 있습니다.
업로드:
s3_client.upload_file(local_path, bucket, s3_path)를 호출하면 해당 파일이 MinIO에 업로드됩니다.
출력:
각 파일 업로드 시 어떤 경로로 업로드되었는지 출력하여 진행 상황을 알 수 있습니다.
그러나 이러한 방식으로는 총 파일갯수가 1000개 까지 밖에 못올린다. 왜냐하면 AWS S3 및 호환 API(list_objects_v2)는 한 번 호출 시 최대 1000개의 객체만 반환하기 때문이다. 1000개를 초과하는 객체 수를 세려면 Pagenation(페이지네이션)을 사용하여 모든 객체를 불러와야 합니다. MinIO 또한 S3 호환 API를 사용하므로 동일한 방법이 적용됩니다.
list_objects_v2 응답에서 IsTruncated 값이 True이면 아직 더 많은 오브젝트가 남아있음을 의미합니다. 이 경우 NextContinuationToken 값을 사용하여 다음 페이지를 불러올 수 있습니다.
아래는 calculate_bucket_stats 함수에서 모든 오브젝트를 순회하는 예시입니다.
def calculate_bucket_stats(bucket_name):
total_size = 0
total_files = 0
s3_client = boto3.client(
's3',
endpoint_url='http://127.0.0.1:9000', # MinIO endpoint
aws_access_key_id='your-access-key',
aws_secret_access_key='your-secret-key'
)
# 첫 번째 요청
response = s3_client.list_objects_v2(Bucket=bucket_name)
while True:
# 응답에 Contents 키가 있으면 객체 목록 처리
if 'Contents' in response:
for obj in response['Contents']:
total_files += 1
total_size += obj['Size']
# 다음 페이지가 있는지 확인
if response.get('IsTruncated'): # 더 많은 오브젝트가 존재
# 다음 페이지 요청: ContinuationToken 사용
response = s3_client.list_objects_v2(
Bucket=bucket_name,
ContinuationToken=response.get('NextContinuationToken')
)
else:
# 더 이상 오브젝트 없음
break
print(f"Bucket '{bucket_name}' Statistics:")
print(f"- Total Files: {total_files}")
print(f"- Total Size: {total_size / (1024**2):.2f} MB")
list_objects_v2(Bucket=bucket_name)로 최대 1000개의 오브젝트를 받아옵니다.IsTruncated=True라면 아직 더 많은 오브젝트가 남아있습니다.NextContinuationToken을 ContinuationToken 파라미터로 사용하여 다음 1000개 오브젝트를 요청합니다.IsTruncated=False일 때까지 이 과정을 반복합니다.이렇게 페이지네이션을 통해 1000개를 초과하는 객체에 대해서도 전체 통계를 낼 수 있습니다.