若我們直接存取雲端資源,將面臨到帳單的問題;若隔離雲端資源,那隔離的成本將會大大的增加,也不利於整合測試,因此有很多的開源專案模擬出了這些網路服務,只要在本地開發環境安裝模擬器,就可以盡情的享受開發的樂趣,大大的降低雲端費用,好好地善用它們吧,搜尋關鍵字 AWS S3 Simulation/Emulation、Local S3,就可以找到不少資源。
在開始動手之前我調查幾套有關 AWS S3 ,我覺得都還不錯,有興趣的可以自行去瞧瞧
擁有許多的服務
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
登入之後,就能看到 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