如何使用 AWS S3 (MinIO) 模擬器進行本地端應用程式開發

  • 2029
  • 0
  • AWS
  • 2023-01-17

若我們直接存取雲端資源,將面臨到帳單的問題;若隔離雲端資源,那隔離的成本將會大大的增加,也不利於整合測試,因此有很多的開源專案模擬出了這些網路服務,只要在本地開發環境安裝模擬器,就可以盡情的享受開發的樂趣,大大的降低雲端費用,好好地善用它們吧,搜尋關鍵字 AWS S3 Simulation/Emulation、Local S3,就可以找到不少資源。

在開始動手之前我調查幾套有關 AWS S3   ,我覺得都還不錯,有興趣的可以自行去瞧瞧

LocalStack

擁有許多的服務

fake s3

文件:使用 Fake S3 模擬及測試 Amazon S3 服務 | Devforgalaxy (zeckli.github.io)

專案:lphoward/fake-s3: Dockerfile for lphoward/fake-s3 on Docker Hub. (github.com)

 

MinIO

官網:MinIO | High Performance, Kubernetes Native Object Storage

專案:minio/minio: Multi-Cloud Object Storage (github.com)

不論是 AWS S3 的配置還是 SDK,他的文件寫得很詳細,而且還直接整合了 S3 的管理介面,最終我選用它來當我 AWS S3 模擬器、Local S3

開發環境

  • Windows 11
  • Rider
  • .NET 6
  • docker
  • AWS .NET SDK、AWS CLI
  • Windows Terminal

快速安裝

docker run `
--name s3-minio `
-p 9000:9000 -p 9001:9001 `
quay.io/minio/minio server /data --console-address ":9001"

預設 Console 帳密
minioadmin:minioadmin

訪問 http://localhost:9001

 

登入之後,就能看到 Bucket 的管理介面了,管理介面對於除錯、驗證都是相當的方便,這也是我選用的原因之一

沒有 docker 也能使用單一執行檔掛起服務,參考:MinIO | The MinIO Quickstart Guide

安裝 AWS CLI

安裝位置 https://aws.amazon.com/cli/

我選擇用 scoop 

 scoop install aws-cli

配置 AWS 開發環境

接下來我需要用到 AWS SDK,需要配置開發環境

aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: ENTER

aws configure set default.s3.signature_version s3v4

 

 

完成之後,在 %USERPROFILE%\.aws 路徑底下會有 credentials 和 config 兩個檔案

AWS Access Key ID、AWS Secret Access Key 是官方提供的假授權金鑰,不是真的,若要整合 AWS 服務,請依照 AWS 文件取得授權。

接下來我要把 MinIO 的帳密換成跟上面的 Key 一樣,在 MinIO 的授權,卡了好久,花了一點時間才知道要把它們調成一樣,後續用 AWS SDK 開發才會順利。

刪除剛剛的 container 並用以下的配置執行

docker run `
-d `
--name s3-minio `
-p 9000:9000 `
-p 9001:9001 `
-e "MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE" `
-e "MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" `
-v ${PWD}/minio/data:/data `
-v ${PWD}/minio/config:/root/.minio `
minio/minio:latest server /data --console-address ":9001"

 

開發之前我先使用 aws-cli 新增 bucket、列舉 bucket

aws --endpoint-url http://localhost:9000 s3 mb s3://mybucket
aws --endpoint-url http://localhost:9000 s3 ls

確定可以順利存取後,再進行開發。

.NET 開發

安裝 AWS SDK

我選擇用測試專案來實作,新增一個測試專案,安裝以下套件

dotnet add package AWSSDK.S3 --version 3.7.9.21

 

新增一個 bucket 儲存桶

很開心的根據 AWS 官網文件庫,貼上以下代碼

[TestMethod]
public async Task 新增一個儲存桶()
{
	var s3Config = new AmazonS3Config()
	{
		RegionEndpoint = RegionEndpoint.USEast1,
		ServiceURL = "http://localhost:9000",
	};
	var s3Client = new AmazonS3Client(s3Config);
	var response = await s3Client.PutBucketAsync(new PutBucketRequest
	{
		BucketName = "test-bucket",
	});
}

 

卻換來了無情的錯誤

Test method Lab.Aws.S3.MinIOS3.UnitTest1.新增一個儲存桶 threw exception: 
System.Net.Http.HttpRequestException: The requested name is valid, but no data of the requested type was found. (test-bucket.localhost:9000) ---> System.Net.Sockets.SocketException: The requested name is valid, but no data of the requested type was found.
   …..

 

費了好大的力氣,翻了好多文件,最後,請同事幫忙才找到問題,加了 ForcePathStyle = true,就成功了

[TestMethod]
public async Task 新增一個儲存桶()
{
	var s3Config = new AmazonS3Config()
	{
		RegionEndpoint = RegionEndpoint.USEast1,
		ServiceURL = "http://localhost:9000",
		ForcePathStyle = true
	};
	var s3Client = new AmazonS3Client(s3Config);
	var response = await s3Client.PutBucketAsync(new PutBucketRequest
	{
		BucketName = "test-bucket",
	});
}

 

更多的 SDK 教學可以參考以下

建立儲存貯體 - Amazon Simple Storage Service

 

專案位置

sample.dotblog/AWS/Lab.AwsS3 at master · yaochangyu/sample.dotblog (github.com)

最後,我在專案增加 docker-compose

services:
  s3-minio:
    container_name: "s3-minio"
    hostname: "minio"
    image: minio/minio:latest
    volumes:
      - ./minio/data:/data
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      # 這裡的 key 要跟 .aws/credentials 裡的 key 名稱一樣,aws cli 才能正常的運作
      MINIO_ROOT_USER: "AKIAIOSFODNN7EXAMPLE"
      MINIO_ROOT_PASSWORD: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    command: server --console-address :9001 /data

 

Rider 直接整合 docker 使用起來變得更方便了

結論

  • 要注意的是它畢竟是模擬的,最終,還是要以雲端服務的配置為準。
  • 在實作的過程,卡最久的就是無法建立 bucket,在強大的同事幫忙之下才順利的解決
  • MinIO 會驗證 ID/Key,fake s3 則不會

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo