MinIO服務器搭建步驟
1.搭建服務
- 新建目錄
mkdir -p /usr/local/minio/{bin,etc,data}
- 創建minio用戶
groupadd -g 2021 minio
useradd -r -u 2021 -g 2021 -c "Minio User" -s /sbin/nologin minio
# 查看用戶
id minio
# uid=2021(minio) gid=2021(minio) 組=2021(minio)
- 下載minio二進制包
curl -O https://dl.minio.io/server/minio/release/linux-amd64/minio
- 更改權限,並移動目錄
chmod 750 minio
cp minio /usr/local/minio/bin
- 創建MinIO配置文件
cat >/usr/local/minio/etc/minio.conf<<EOF
MINIO_VOLUMES="/usr/local/minio/data"
MINIO_OPTS="-C /usr/local/minio/etc --address :9000"
MINIO_ACCESS_KEY="xujunkai"
MINIO_SECRET_KEY="12345678"
EOF
- 配置自啟動文件
vim /etc/systemd/system/minio.service
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/minio/bin/minio
[Service]
User=minio
Group=minio
EnvironmentFile=/usr/local/minio/etc/minio.conf
ExecStart=/usr/local/minio/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=65536
TimeoutStopSec=infinity
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
- 更改屬組,屬主
chown -R minio:minio /usr/local/minio
- 啟動minio,並設置開機自啟動
systemctl daemon-reload
systemctl enable minio
systemctl start minio
systemctl status minio
- 防火牆設置開放9000端口
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --reload
- 進入Minio web管理頁面
-
輸入帳號密碼。帳號為設置的
MINIO_ACCESS_KEY
,密碼為設置的MINIO_SECRET_KEY
-
創建一個
桶
來保存文件
- 上傳文件
2.shell命令操作
- 下載客戶端
wget https://dl.minio.io/client/mc/release/linux-amd64/mc
- 設置指令的別名:
./mc
別名或添加環境變量
alias mc="~/mc"
# 刪除alias
unalias mc
# 配置mc環境變量
mv mc /usr/local/minio/
vi /etc/profile
export PATH=$PATH:/usr/local/minio/
source /etc/profile
- 將MinIO Server添加到客戶端
mc config host add minio http://172.16.215.141:9000 xujunkai 12345678 --api S3v4
- 桶的基本命令
# 創建 buk2 的桶
mc mb minio/buk2
# 上傳當前目錄所有文件到buk2桶上
mc cp -r * minio/buk2
# 查找buk2存儲桶中html結尾文件
mc find minio/buk2 --name "*.html"
# 設置buk2只讀權限 download
# 共可以設置四種權限:none, download只讀, upload只寫, public
mc policy set download minio/buk2
# 查看buk2存儲桶權限
mc policy list minio/buk2
# 共享buk2下baidu.html文件下載路徑
mc share download minio/buk2/baidu.html
# 查看存儲桶
mc ls minio
# 查看buk2存儲桶文件
mc ls minio/buk2
# 設置桶策略為public模式,這樣MinIO可以提供永久文件服務
mc policy set public minio/buk2
3.python 操作MinIO
- 版本要求
python 3.6+
- 下載
pip install minio
- 連接
from minio import Minio
client = Minio('0.0.0.0:9000',access_key='xujunkai',secret_key='12345678',secure=False)
- 查詢桶是否存在
from minio import Minio
from minio.error import S3Error
try:
client = Minio('0.0.0.0:9000',access_key='xujunkai',secret_key='12345678',secure=False)
found = client.bucket_exists("buk2")
except S3Error as e:
print("error:", e)
print(found)# 返回布爾值 True or False
- 上傳文件,若文件已存在,會直接覆蓋
client.fput_object("buk2", "1.jpg", "/opt/img/1.jpg")
# 文件不存在會報錯FileNotFoundError
- 獲取文件數據寫入指定文件
data = client.get_object("buk2", "1.jpg")
with open("/opt/1demo.jpg","wb") as fp:
for d in data.stream(1024):
fp.write(d)
- 直接將文件下載到本地
client.fget_object("buk2", "1.jpg", "/opt/static/new.jpg")
- 刪除文件
client.remove_object("buk2", file_name)
- 刪除多個文件
client.remove_objects("buk2", ["baidu.html", "taobao.html"])
a.獲取文件url最長時間期限只能設置為7天?
a.通過桶權限設置方法,修改時間期限限制。
set_bucket_policy(policy)
示例:更改桶權限 設置公共可下載
policy = '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetBucketLocation","s3:ListBucket"],"Resource":["arn:aws:s3:::%s"]},{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetObject"],"Resource":["arn:aws:s3:::%s/*"]}]}' % (bucket_name, bucket_name)
minioClient.set_bucket_policy(bucket_name=bucket_name, policy=policy)
4.封裝python API
import os
from minio import Minio
from minio.error import S3Error
from datetime import timedelta
from minio.deleteobjects import DeleteObject
class Bucket(object):
client = None
policy = '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetBucketLocation","s3:ListBucket"],"Resource":["arn:aws:s3:::%s"]},{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetObject"],"Resource":["arn:aws:s3:::%s/*"]}]}'
def __new__(cls, *args, **kwargs):
if not cls.client:
cls.client = object.__new__(cls)
return cls.client
def __init__(self, service, access_key, secret_key, secure=False):
self.service = service
self.client = Minio(service, access_key=access_key, secret_key=secret_key, secure=secure)
def exists_bucket(self, bucket_name):
"""
判斷桶是否存在
:param bucket_name: 桶名稱
:return:
"""
return self.client.bucket_exists(bucket_name=bucket_name)
def create_bucket(self, bucket_name:str, is_policy:bool=True):
"""
創建桶 + 賦予策略
:param bucket_name: 桶名
:param is_policy: 策略
:return:
"""
if self.exists_bucket(bucket_name=bucket_name):
return False
else:
self.client.make_bucket(bucket_name = bucket_name)
if is_policy:
policy = self.policy % (bucket_name, bucket_name)
self.client.set_bucket_policy(bucket_name=bucket_name, policy=policy)
return True
def get_bucket_list(self):
"""
列出存儲桶
:return:
"""
buckets = self.client.list_buckets()
bucket_list = []
for bucket in buckets:
bucket_list.append(
{"bucket_name": bucket.name, "create_time": bucket.creation_date}
)
return bucket_list
def remove_bucket(self, bucket_name):
"""
刪除桶
:param bucket_name:
:return:
"""
try:
self.client.remove_bucket(bucket_name=bucket_name)
except S3Error as e:
print("[error]:", e)
return False
return True
def bucket_list_files(self, bucket_name, prefix):
"""
列出存儲桶中所有對象
:param bucket_name: 同名
:param prefix: 前綴
:return:
"""
try:
files_list = self.client.list_objects(bucket_name=bucket_name, prefix=prefix, recursive=True)
for obj in files_list:
print(obj.bucket_name, obj.object_name.encode('utf-8'), obj.last_modified,
obj.etag, obj.size, obj.content_type)
except S3Error as e:
print("[error]:", e)
def bucket_policy(self, bucket_name):
"""
列出桶存儲策略
:param bucket_name:
:return:
"""
try:
policy = self.client.get_bucket_policy(bucket_name)
except S3Error as e:
print("[error]:", e)
return None
return policy
def download_file(self, bucket_name, file, file_path, stream=1024*32):
"""
從bucket 下載文件 + 寫入指定文件
:return:
"""
try:
data = self.client.get_object(bucket_name, file)
with open(file_path, "wb") as fp:
for d in data.stream(stream):
fp.write(d)
except S3Error as e:
print("[error]:", e)
def fget_file(self, bucket_name, file, file_path):
"""
下載保存文件保存本地
:param bucket_name:
:param file:
:param file_path:
:return:
"""
self.client.fget_object(bucket_name, file, file_path)
def copy_file(self, bucket_name, file, file_path):
"""
拷貝文件(最大支持5GB)
:param bucket_name:
:param file:
:param file_path:
:return:
"""
self.client.copy_object(bucket_name, file, file_path)
def upload_file(self,bucket_name, file, file_path, content_type):
"""
上傳文件 + 寫入
:param bucket_name: 桶名
:param file: 文件名
:param file_path: 本地文件路徑
:param content_type: 文件類型
:return:
"""
try:
with open(file_path, "rb") as file_data:
file_stat = os.stat(file_path)
self.client.put_object(bucket_name, file, file_data, file_stat.st_size, content_type=content_type)
except S3Error as e:
print("[error]:", e)
def fput_file(self, bucket_name, file, file_path):
"""
上傳文件
:param bucket_name: 桶名
:param file: 文件名
:param file_path: 本地文件路徑
:return:
"""
try:
self.client.fput_object(bucket_name, file, file_path)
except S3Error as e:
print("[error]:", e)
def stat_object(self, bucket_name, file):
"""
獲取文件元數據
:param bucket_name:
:param file:
:return:
"""
try:
data = self.client.stat_object(bucket_name, file)
print(data.bucket_name)
print(data.object_name)
print(data.last_modified)
print(data.etag)
print(data.size)
print(data.metadata)
print(data.content_type)
except S3Error as e:
print("[error]:", e)
def remove_file(self, bucket_name, file):
"""
移除單個文件
:return:
"""
self.client.remove_object(bucket_name, file)
def remove_files(self, bucket_name, file_list):
"""
刪除多個文件
:return:
"""
delete_object_list = [DeleteObject(file) for file in file_list]
for del_err in self.client.remove_objects(bucket_name, delete_object_list):
print("del_err", del_err)
def presigned_get_file(self, bucket_name, file, days=7):
"""
生成一個http GET操作 簽證URL
:return:
"""
return self.client.presigned_get_object(bucket_name, file, expires=timedelta(days=days))
if __name__ == '__main__':
minio_obj = Bucket(service="10.0.0.70:9000", access_key="xujunkai", secret_key="12345678")
- docker方式快速構建minio
docker run -p 9000:9000 --name minio \
-d --restart=always \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=xjk214365" \
-v /home/data:/data \
-v /home/config:/root/.minio \
minio/minio server /data