minio 高性能 Kubernetes 原生對象存儲
-
minio 高性能 Kubernetes 原生
對象存儲
- 特點
- 安裝
- 單機
- 分布式
- 客戶端mc安裝和使用
- minio在K8S的優化實踐
MinIO 是一個基於Apache License v2.0開源協議的對象存儲服務。它兼容亞馬遜S3雲存儲服務接口,非常適合於存儲大容量非結構化的數據,例如圖片、視頻、日志文件、備份數據和容器/虛擬機鏡像等,而一個對象文件可以是任意大小,從幾kb到最大5T不等。 MinIO是一個非常輕量的服務,可以很簡單的和其他應用的結合,類似 NodeJS, Redis 或者 MySQL。
特點
- 高性能 minio是世界上最快的對象存儲(官網說的: https://min.io/)
- 彈性擴容 很方便對集群進行彈性擴容
- 天生的雲原生服務
- 開源免費,最適合企業化定制
- S3事實標准
- 簡單強大
- 存儲機制(Minio使用糾刪碼erasure code和校驗和checksum來保護數據免受硬件故障和無聲數據損壞。 即便丟失一半數量(N/2)的硬盤,仍然可以恢復數據)
安裝
minio分服務端和客戶端,服務端是通過minio進行部署,客戶端只是1個二進制命令(mc),通過mc可以操作對象存儲(增刪查等),當然minio也提供各種語言的SDK,具體可以參考官網
服務端的安裝分為獨立單機模式和分布式安裝, 以下單機模式的安裝方法. 分布式的安裝和單機模式的安裝類似,只是根據傳參不同
單機
- Docker容器安裝 docker pull minio/minio docker run -p 9000:9000 minio/minio server /data
- macOS brew install minio/stable/minio minio server /data
- Linux wget https://dl.min.io/server/minio/release/linux-amd64/minio chmod +x minio ./minio server /data
- Windows wget https://dl.min.io/server/minio/release/windows-amd64/minio.exe minio.exe server D:\Photos
分布式
分布式好處 分布式Minio可以讓你將多塊硬盤(甚至在不同的機器上)組成一個對象存儲服務。由於硬盤分布在不同的節點上,分布式Minio避免了單點故障
數據保護 分布式Minio采用 糾刪碼來防范多個節點宕機和位衰減bit rot。 分布式Minio至少需要4個硬盤,使用分布式Minio自動引入了糾刪碼功能。
高可用 單機Minio服務存在單點故障,相反,如果是一個有N塊硬盤的分布式Minio,只要有N/2硬盤在線,你的數據就是安全的。不過你需要至少有N/2+1個硬盤來創建新的對象。 例如,一個16節點的Minio集群,每個節點16塊硬盤,就算8台服務器宕機,這個集群仍然是可讀的,不過你需要9台服務器才能寫數據。 注意,只要遵守分布式Minio的限制,你可以組合不同的節點和每個節點幾塊硬盤。比如,你可以使用2個節點,每個節點4塊硬盤,也可以使用4個節點,每個節點兩塊硬盤,諸如此類。
一致性 Minio在分布式和單機模式下,所有讀寫操作都嚴格遵守read-after-write一致性模型。
糾刪碼 Minio使用糾刪碼erasure code和校驗和checksum來保護數據免受硬件故障和無聲數據損壞。 即便您丟失一半數量(N/2)的硬盤,您仍然可以恢復數據。
什么是糾刪碼erasure code? 糾刪碼是一種恢復丟失和損壞數據的數學算法, Minio采用Reed-Solomon code將對象拆分成N/2數據和N/2 奇偶校驗塊。 這就意味着如果是12塊盤,一個對象會被分成6個數據塊、6個奇偶校驗塊,你可以丟失任意6塊盤(不管其是存放的數據塊還是奇偶校驗塊),你仍可以從剩下的盤中的數據進行恢復,是不是很NB,感興趣的同學請google。
為什么糾刪碼有用? 糾刪碼的工作原理和RAID或者復制不同,像RAID6可以在損失兩塊盤的情況下不丟數據,而Minio糾刪碼可以在丟失一半的盤的情況下,仍可以保證數據安全。 而且Minio糾刪碼是作用在對象級別,可以一次恢復一個對象,而RAID是作用在卷級別,數據恢復時間很長。 Minio對每個對象單獨編碼,存儲服務一經部署,通常情況下是不需要更換硬盤或者修復。Minio糾刪碼的設計目標是為了性能和盡可能的使用硬件加速。
什么是位衰減bit rot保護? 位衰減又被稱為數據腐化Data Rot、無聲數據損壞Silent Data Corruption,是目前硬盤數據的一種嚴重數據丟失問題。硬盤上的數據可能會神不知鬼不覺就損壞了,也沒有什么錯誤日志。正所謂明槍易躲,暗箭難防,這種背地里犯的錯比硬盤直接咔咔宕了還危險。 不過不用怕,Minio糾刪碼采用了高速 HighwayHash 基於哈希的校驗和來防范位衰減。
分布式部署:GNU/Linux 和 macOS 示例1: 啟動分布式Minio實例,8個節點,每節點1塊盤,需要在8個節點上都運行下面的命令。
export MINIO_ACCESS_KEY=<ACCESS_KEY>
export MINIO_SECRET_KEY=<SECRET_KEY>
minio server http://192.168.1.11/export1 http://192.168.1.12/export2 \
http://192.168.1.13/export3 http://192.168.1.14/export4 \
http://192.168.1.15/export5 http://192.168.1.16/export6 \
http://192.168.1.17/export7 http://192.168.1.18/export8
#helm安裝自行google
helm install minio --set mode=distributed,numberOfNodes=4,imagePullPolicy=IfNotPresent,accessKey=v9rwqYzXXim6KJKeyPm344,secretKey=0aIRBu9KU7gAN0luoX8uBE1eKWNPDgMnkVqbPC,service.type=NodePort,service.nodePort=25557 googleapis/minio -n velero
#安裝完成之后查詢pods狀態,如果pods的READY狀態是正常的,則安裝成功,如下圖圖示
kubectl get pods -n velero -o wide
#如果pods的READY狀態一直不是狀態的話,查看下logs
kubectl logs minio-0 -n velero
#如果都是提示disk都是等待狀態,可以重啟pods在查看
kubectl delete pods -n velero minio-{0,1,2,3}
#默認是cluser訪問,為了方便,我這里是nodeport方式
如上圖,當我使用4個節點創建分布式minio時,會使用默認的pvc創建存儲.默認每個節點創建1個10G的存儲(可以自定義修改)
客戶端mc安裝和使用
安裝
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
./mc --help
mc命令指南
ls 列出文件和文件夾。
mb 創建一個存儲桶或一個文件夾。
cat 顯示文件和對象內容。
pipe 將一個STDIN重定向到一個對象或者文件或者STDOUT。
share 生成用於共享的URL。
cp 拷貝文件和對象。
mirror 給存儲桶和文件夾做鏡像。
find 基於參數查找文件。
diff 對兩個文件夾或者存儲桶比較差異。
rm 刪除文件和對象。
events 管理對象通知。
watch 監聽文件和對象的事件。
policy 管理訪問策略。
session 為cp命令管理保存的會話。
config 管理mc配置文件。
update 檢查軟件更新。
version 輸出版本信息。
mc命令實踐
#查看minio服務端配置
mc config host ls
#添加minio服務端配置
mc config host add minio http://minio.vaicheche.com:25555 v9rwqYzXXim6KJKeyPm344 0aIRBu9KU7gAN0luoX8uBE1eKWNPDgMnkVqbPC --api s3v4
#查看minio bucket
mc ls minio
#創建bucket
mc mb minio/backup
#上傳本地目錄(文件不加r)
mc cp -r ingress minio/backup/
#下載遠程目錄(文件不加r)
mc cp -r minio/backup .
#將一個本地文件夾鏡像到minio(類似rsync)
mc mirror localdir/ minio/backup/
#持續監聽本地文件夾鏡像到minio(類似rsync)
mc mirror -w localdir/ minio/backup/
#持續從minio存儲桶中查找所有jpeg圖像,並復制到minio "play/bucket"存儲桶
mc find minio/bucket --name "*.jpg" --watch --exec "mc cp {} play/bucket"
#刪除目錄
mc rm minio/backup/ingress --recursive --force
#刪除文件
mc rm minio/backup/service_minio.yaml
#從mybucket里刪除所有未完整上傳的對象
mc rm --incomplete --recursive --force play/mybucket
#刪除7天前的對象
mc rm --force --older-than=7 play/mybucket/oldsongs
#將MySQL數據庫dump文件輸出到minio
mysqldump -u root -p ******* db | mc pipe minio/backups/backup.sql
#mongodb備份
mongodump -h mongo-server1 -p 27017 -d blog-data --archive | mc pipe minio1/mongobkp/backups/mongo-blog-data-`date +%Y-%m-%d`.archive
minio在K8S的優化實踐
如上minio在k8s的實踐,在我實踐環境里面.我通過helm安裝分布式之后,我默認是采用nfs作為storeagesclasses,一共起了4個節點,自動創建了4個pvc,在我刪除1個pvc的數據之后,minio依然可以正常讀寫,數據依然的可以存在.參考下圖
但這其中有1個最大的問題, 如果你使用的是nfs這種自建共享存儲的話,就算minio起了4個節點,能保證數據安全.但是你的nfs磁盤確只有1個,萬一的你的nfs宕機,磁盤損壞了,你的數據全都沒有了.所以為了保證數據的安全性.建議通過hostPath
的方式,在每個節點保存對應的數據.這樣就算節點的宕機了,磁盤損壞了,你的數據並不會丟.而且通過本地節點的方式,讀寫數據的速度也會更快.當然你需要額外管理節點本地存儲.
minio在K8S的hostPath
部署實踐
環境描述: 5個節點k8s環境,使用其中4個節點作為mino,同時都使用節點主機網絡
#1.給其中4個節點打標簽,因為我要選擇標簽為minio-server=true的節點部署minio
kubectl get node --show-labels=true
kubectl label nodes node-hostname1 minio-server=true
kubectl label nodes node-hostname2 minio-server=true
kubectl label nodes node-hostname3 minio-server=true
kubectl label nodes node-hostname3 minio-server=true
#2.給對應主機添加hosts,如果你的hostname能夠自動解析,不用修改.4台主機都添加
echo "host1 [IP1] >> /etc/hosts"
echo "host2 [IP2] >> /etc/hosts"
echo "host3 [IP3] >> /etc/hosts"
echo "host4 [IP4] >> /etc/hosts"
#3.創建namespace
#你也可以使用自定義的其他namespace,不過你需要修改下面yaml文件
kubectl create ns velero
#4.下載headless、daemonset、service
wget https://download.osichina.net/tools/k8s/yaml/minio/minio-distributed-headless-service.yaml
wget https://download.osichina.net/tools/k8s/yaml/minio/minio-distributed-daemonset.yaml
wget https://download.osichina.net/tools/k8s/yaml/minio/minio-distributed-service.yaml
#5.修改並創建對應的service、daemonset
其中主要修改的是`minio-distributed-daemonset.yaml`
hostPath: 定義你需要使用節點本地路徑
MINIO_ACCESS_KEY、MINIO_SECRET_KEY: 定義你的秘鑰,為了安全及時修改
args: 啟動參數后url改成主機名方式: http://host{1...4}/data/minio
`minio-distributed-service.yaml`為對外服務,默認為ClusterIP,可以結合ingress或者nodePort來訪問,可以自行修改
kubectl create -f minio-distributed-statefulset.yaml
kubectl create -f minio-distributed-daemonset.yaml
kubectl create -f minio-distributed-service.yaml