容器云對接持久化存儲并使用
隨著容器為互聯(lián)網(wǎng)應用提供的敏捷開發(fā)、快速交付,對傳統(tǒng)金融IT帶來了技術(shù)革新的挑戰(zhàn)。針對數(shù)據(jù)爆炸式增長、應用復雜性提高、業(yè)務品種快速更新、應用系統(tǒng)軟件快速迭代等一系列挑戰(zhàn),容器技術(shù)在金融行業(yè)數(shù)字化轉(zhuǎn)型浪潮中越來越受到青睞。
本文主要從容器云對存儲的使用方面做建議介紹。Kubernetes支持很多類型的卷,Pod可以同時使用任意數(shù)目的卷類型。臨時卷類型的生命周期與Pod相同,但持久卷可以比Pod的存活期長。當Pod不再存在時,Kubernetes也會銷毀臨時卷;不過Kubernetes不會銷毀持久卷。對于給定Pod中任何類型的卷,在容器重啟期間數(shù)據(jù)都不會丟失,卷掛載在鏡像中的指定路徑下。容器對接存儲,都會使用一個存儲CSI插件進行連接和管理。
容器云中存儲的分類
Kubernetes能使用的存儲可以分為如下幾類:
1)臨時存儲
常見的臨時存儲主要是emptyDir卷,當Pod分派到某個Node上時,emptyDir 卷會被創(chuàng)建,并且Pod在該節(jié)點上運行期間,卷一直存在。當Pod因為某些原因被從節(jié)點上刪除時,emptyDir 卷中的數(shù)據(jù)也會被永久刪除。一般情況下emptyDir存儲都是用來充當臨時存儲空間。emptyDir 常見的一些用途如:(1)緩存空間,例如基于磁盤的歸并排序。(2)為耗時較長的計算任務提供檢查點,以便任務能方便地從崩潰前狀態(tài)恢復執(zhí)行。(3)在 Web 服務器容器服務數(shù)據(jù)時,保存內(nèi)容管理器容器獲取的文件。
2)半持久存儲
半持久化存儲主要是HostPath。當使用HostPath卷時,它的范圍應盡量限于所需的文件或目錄,并以只讀方式掛載。HostPath 常見的一些用途如:(1)運行一個需要訪問Docker 內(nèi)部機制的容器;可使用 hostPath 掛載 /var/lib/docker 路徑。(2)在容器中運行cAdvisor時,以 hostPath 方式掛載 /sys。(3)允許Pod指定給定的hostPath在運行 Pod 之前是否應該存在,是否應該創(chuàng)建以及應該以什么方式存在。
3)持久化存儲
對于持久化存儲,Kubernetest引入了StorageClass,Volume,PVC,PV的概念。Kubernetes支持的持久化存儲包括主流的塊存儲、對象存儲和網(wǎng)絡文件存儲等等。Kubernetes引入了兩個新的API資源:PersistentVolume和PersistentVolumeClaim。持久卷(PersistentVolume,PV)是集群中的一塊存儲,可以由管理員事先制備,或者使用存儲類(Storage Class)來動態(tài)制備。持久卷是集群資源,就像節(jié)點也是集群資源一樣。
4)特殊存儲
特殊存儲類主要包括secret,configMap等。(1)secret 卷用來給Pod傳遞敏感信息,例如密碼。secret 卷由tmpfs(基于RAM的文件系統(tǒng))提供存儲,因此它們永遠不會被寫入非易失性(持久化的)存儲器。(2)ConfigMap提供了向Pod注入配置數(shù)據(jù)的方法,用來將非機密性的數(shù)據(jù)保存到鍵值對中,比如存儲卷中的配置文件,以key-value的形式調(diào)用。
容器云中存儲的使用
Kubernetes中,PV卷是集群中的資源。PVC申領(lǐng)是對這些資源的請求,也被用來執(zhí)行對資源的申領(lǐng)檢查。PV卷和PVC 的使用過程一般如下:
1)制備:PV 卷的制備有兩種方式:靜態(tài)制備或動態(tài)制備。(1)靜態(tài)制備。集群管理員創(chuàng)建若干PV卷。這些卷對象帶有真實存儲的細節(jié)信息,并且對集群用戶可用。(2)動態(tài)制備。動態(tài)制備操作是基于StorageClass來實現(xiàn)的:PVC申領(lǐng)必須請求某個存儲類,同時集群管理員必須已經(jīng)創(chuàng)建并配置了該類,這樣動態(tài)制備卷的動作才會發(fā)生。如果PVC申領(lǐng)指定存儲類為 “”(空),則相當于為自身禁止使用動態(tài)制備的卷。
2)綁定:用戶創(chuàng)建一個帶有特定存儲容量和特定訪問模式需求的PersistentVolumeClaim對象;在動態(tài)制備場景下,這個PVC對象可能已經(jīng)創(chuàng)建完畢。一旦PV與PVC的綁定關(guān)系建立,則PersistentVolumeClaim綁定就是排他性的,PVC申領(lǐng)與PV卷之間的綁定是一種一對一的映射。
如果找不到匹配的PV卷,PVC申領(lǐng)會無限期地處于未綁定狀態(tài)。當與之匹配的PV卷可用時,PVC申領(lǐng)會被綁定。例如,即使某集群上制備了很多10 Gi大小的PV卷,也無法與請求20 Gi大小的存儲的PVC匹配。當新的20 Gi PV卷被加入到集群時,該PVC才有可能被綁定。
3)使用:Pod將PVC申領(lǐng)當做存儲卷來使用。集群會檢查PVC申領(lǐng),找到所綁定的卷,并為Pod掛載該卷。對于支持多種訪問模式的卷,用戶要在Pod中以卷的形式使用申領(lǐng)時指定期望的訪問模式。
4)保護使用中的存儲對象:保護使用中的存儲對象(Storage Object in Use Protection)這一功能特性的目的是確保仍被Pod使用的PersistentVolumeClaim(PVC)對象及其所綁定的PersistentVolume(PV)對象在系統(tǒng)中不會被刪除,因為這樣做可能會引起數(shù)據(jù)丟失。
5)回收(Reclaiming):當用戶不再使用其存儲卷時,他們可以從API中將PVC對象刪除,從而允許該資源被回收再利用。PersistentVolume對象的回收策略告訴集群,當其被從申領(lǐng)中釋放時如何處理該數(shù)據(jù)卷。目前,數(shù)據(jù)卷可以被 Retained(保留)、Recycled(回收)或 Deleted(刪除)。
- 保留(Retain):回收策略 Retain 使得用戶可以手動回收資源。當PersistentVolumeClaim對象被刪除時,PersistentVolume卷仍然存在,對應的數(shù)據(jù)卷被視為"已釋放(released)"。
- 刪除(Delete):對于支持Delete回收策略的卷插件,刪除動作會將PersistentVolume對象從 Kubernetes中移除,同時也會從外部基礎設施(如 AWS EBS、CEPH)中移除所關(guān)聯(lián)的存儲資產(chǎn)。
- 回收(Recycle):回收策略Recycle在Kubernetes 新版本中已被廢棄。取而代之的建議方案是使用動態(tài)制備。
容器云存儲的落地實踐
目前,我們銀行已經(jīng)在開發(fā)測試和生產(chǎn)環(huán)境部署了多套容器云集群平臺,并已經(jīng)承載運行了重要應用系統(tǒng)的服務。現(xiàn)階段主要還是將無狀態(tài)的應用容器化,數(shù)據(jù)庫、中間件等一些有狀態(tài)的組件仍在虛擬機中運行,將在未來逐步遷移。行內(nèi)容器云平臺涉及到的持久化存儲主要分為如下幾大塊:
1)容器鏡像類數(shù)據(jù)存儲。在內(nèi)網(wǎng)環(huán)境中,建立一套自己的私有鏡像倉庫,做好相關(guān)配置后容器云平臺就可以從私有鏡像庫中拉取鏡像。當有pod所在服務器宕機或故障,pod需要在新節(jié)點啟動時,這時就會需要向私有鏡像庫拉取鏡像,當生產(chǎn)環(huán)境pod數(shù)量達到一定規(guī)模時,需要考慮多鏡像并行拉取導致的IO風暴。所以容器鏡像類數(shù)據(jù)存儲建議采用分布式塊存儲,能夠承擔一定的并發(fā)能力和有一定擴展能力的持久性存儲,當然有存量集中式塊存儲也是可以利舊以節(jié)約投資,同時也要考慮做好該部分存儲的備份或私有鏡像倉庫的冗余存儲。
2)Pod/container類數(shù)據(jù)存儲。容器云集群的Etcd 的數(shù)據(jù)會時刻以日志的形式記錄在內(nèi)存和硬盤中,etcd 對磁盤的延遲會非常敏感,建議將Etcd部署在物理機/虛擬機(視集群規(guī)模)中,底層存儲配置SSD磁盤,保證低延遲、高性能的寫入。大部分應用Pod/container對于存儲性能要求不高,主要耗費計算資源,所以Pod/container在node上運行的鏡像建議采用服務器本地盤存儲即可。
3)應用之間共享類數(shù)據(jù)存儲。不管是有狀態(tài)還是無狀態(tài)應用之間需要共享數(shù)據(jù)時,NFS是一個主流的文件共享服務器。NFS數(shù)據(jù)卷可以提供對NFS掛載支持,可以自動將NFS共享路徑掛載到Pod中。在各應用pod中需文件共享時建議采用NAS雙活存儲提供的NFS文件系統(tǒng)以滿足業(yè)務系統(tǒng)文件共享需求。
4)日志類數(shù)據(jù)存儲。日志類數(shù)據(jù)收集,一般有如下常見幾種方案。(1)app的鏡像中自己集成日志收集組件,好處在于app應用的yaml文件不需要特殊配置,一個鏡像解決問題,但是同時也造成耦合性強,未來組件或應用無法單獨升級。(2)在同一個pod中運行app容器和日志收集組件容器,相較如上方案降低了耦合度,但是pod的yaml文件需單獨編寫、配置,較繁瑣。(3)直接將pod的日志掛在到宿主機node,每臺node起一個pod或者采用二進制進程進行日志收集,好處是收集日志與應用pod完全解耦,管理方便,只需要做好日志輸出規(guī)范,統(tǒng)一日志目錄和輸出方式即可,此方式日志存儲性能高。日志類數(shù)據(jù)存儲建議可采用pod日志輸出掛載在本地服務器的存儲,通過Filebeat+Logstash+ElasticSearch+Kibana(ELK)或者Fluentd + Filebeat + Elasticsearch + Kibana(EFK)構(gòu)建統(tǒng)一的日志采集、分類、分析、查詢、展示平臺。
在整個容器云平臺的持久化存儲選型過程中,比如在日志類數(shù)據(jù)存儲我們也有考慮將其存放于分布式塊存儲(如ceph、longhorn等)上做日志統(tǒng)一存儲平臺,但是為沿用已有的ELK日志收集展示平臺、初期容器規(guī)模較小等原因,暫將分布式塊存儲列為二期規(guī)劃建設。一期主要完成無狀態(tài)應用的容器化工作,二期將重點放在有狀態(tài)應用(如redis、zk、輕載mysql等)的容器化,建議部署為StatefulSet,當節(jié)點重啟漂移到其他機器上時,可通過掛載的PVC(PersistentVolumeClaim)拿到原來的完整數(shù)據(jù),但是分布式存儲帶來的讀寫延遲需要根據(jù)不同的容器化應用敏感程度配置不同性能的分布式存儲,以滿足對業(yè)務發(fā)展的IO需求。
總而言之,容器云持久化存儲最佳實踐沒有一個統(tǒng)一使用某種存儲的完美方案,而是需要根據(jù)業(yè)務類型、系統(tǒng)重要等級、集群規(guī)模、擴展性等多方面進行綜合考量,再結(jié)合本行的一個長遠規(guī)劃進行存儲架構(gòu)設計,以匹配科技戰(zhàn)略,助力業(yè)務發(fā)展。


























