在K8S運行的服務,從簡單到復雜可以分成三類:無狀態服務、普通有狀態服務和有狀態集群服務。下面分別來看K8S是如何運行這三類服務的。
K8S使用RC(或更新的Replica Set)來保證一個服務的實例數量,如果說某個Pod實例由于某種原因Crash了,RC會立刻用這個Pod的模版新啟一個Pod來替代它,由于是無狀態的服務,新啟的Pod與原來健康狀態下的Pod一模一樣。在Pod被重建后它的ip地址可能發生變化,為了對外提供一個穩定的訪問接口,K8S引入了Service的概念重點內容。一個Service后面可以掛多個Pod,實現服務的高可用。
和無狀態服務相比,它多了狀態保存的需求。Kubernetes提供了以Volume和Persistent Volume為基礎的存儲系統,可以實現服務的狀態保存。
與普通有狀態服務相比,它多了集群管理的需求。K8S為此開發了一套以Pet Set為核心的全新特性,方便了有狀態集群服務在K8S上的部署和管理。具體來說是通過Init Container來做集群的初始化工作,用 Headless Service 來維持集群成員的穩定關系,用動態存儲供給來方便集群擴容,最后用Pet Set來綜合管理整個集群。 要運行有狀態集群服務要解決的問題有兩個,一個是狀態保存,另一個是集群管理。 我們先來看如何解決第一個問題:狀態保存。Kubernetes 有一套以Volume插件為基礎的存儲系統,通過這套存儲系統可以實現應用和服務的狀態保存。
K8S的存儲系統從基礎到高級又大致分為三個層次:普通Volume,Persistent Volume 和動態存儲供應(dynamic PRovisioning)。
單節點Volume是最簡單的普通Volume,它和Docker的存儲卷類似,使用的是Pod所在K8S節點的本地目錄。具體有兩種,一種是 emptyDir,是一個匿名的空目錄,由Kubernetes在創建Pod時創建,刪除Pod時刪除。另外一種是 hostPath,與emptyDir的區別是,它在Pod之外獨立存在,由用戶指定路徑名。這類和節點綁定的存儲卷在Pod遷移到其它節點后數據就會丟失,所以只能用于存儲臨時數據或用于在同一個Pod里的容器之間共享數據。
這種存儲卷不和某個具體的K8S節點綁定,而是獨立于K8S節點存在的,整個存儲集群和K8S集群是兩個集群,相互獨立。
跨節點的存儲卷在Kubernetes上用的比較多,如果已有的存儲不能滿足要求,還可以開發自己的Volume插件,只需要實現Volume.Go 里定義的接口。如果你是一個存儲廠商,想要自己的存儲支持Kubernetes 上運行的容器,就可以去開發一個自己的Volume插件。普通volume目前支持的各種存儲插件及情況如下:
普通Volume和使用它的Pod之間是一種靜態綁定關系,在定義Pod的文件里,同時定義了它使用的Volume。Volume 是Pod的附屬品,我們無法單獨創建一個Volume,因為它不是一個獨立的K8S資源對象。
而Persistent Volume 簡稱PV是一個K8S資源對象,所以我們可以單獨創建一個PV。它不和Pod直接發生關系,而是通過Persistent Volume Claim,簡稱PVC來實現動態綁定。Pod定義里指定的是PVC,然后PVC會根據Pod的要求去自動綁定合適的PV給Pod使用。
用戶根據所需存儲空間大小和訪問模式創建(或在動態部署中已創建)一個 PersistentVolumeClaim。Kubernetes的Master節點循環監控新產生的PVC,找到與之匹配的PV(如果有的話),并把他們綁定在一起。動態配置時,循環會一直將PV與這個PVC綁定,直到PV完全匹配PVC。避免PVC請求和得到的PV不一致。綁定一旦形成,PersistentVolumeClaim綁定就是獨有的,不管是使用何種模式綁定的。
如果找不到匹配的volume,用戶請求會一直保持未綁定狀態。在匹配的volume可用之后,用戶請求將會被綁定。比如,一個配置了許多50Gi PV的集群不會匹配到一個要求100Gi的PVC。 只有在100Gi PV被加到集群之后,這個PVC才可以被綁定。
在CLI下,訪問方式被簡寫為:
RWO – ReadWriteOnceROX – ReadOnlyManyRWX – ReadWriteManyImportant! A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time.
剛才提到說PV與普通Volume的區別是動態綁定,我們來看一下這個過程是怎樣的。
這是PV的生命周期,首先是Provision,即創建PV,這里創建PV有兩種方式,靜態和動態。
靜態,是管理員手動創建一堆PV,組成一個PV池,供PVC來綁定。
動態,是指在現有PV不滿足PVC的請求時,可以使用存儲分類(StorageClass),描述具體過程為:PV先創建分類,PVC請求已創建的某個類(StorageClass)的資源,這樣就達到動態配置的效果。即通過一個叫 Storage Class的對象由存儲系統根據PVC的要求自動創建。
一個PV創建完后狀態會變成Available,等待被PVC綁定。一旦被PVC邦定,PV的狀態會變成Bound,就可以被定義了相應PVC的Pod使用。Pod使用完后會釋放PV,PV的狀態變成Released。變成Released的PV會根據定義的回收策略做相應的回收工作。有三種回收策略,Retain、Delete 和 Recycle。Retain就是保留現場,K8S什么也不做,等待用戶手動去處理PV里的數據,處理完后,再手動刪除PV。Delete 策略,K8S會自動刪除該PV及里面的數據。Recycle方式,K8S會將PV里的數據刪除,然后把PV的狀態變成Available,又可以被新的PVC綁定使用。
在實際使用場景里,PV的創建和使用通常不是同一個人。這里有一個典型的應用場景:管理員創建一個PV池,開發人員創建Pod和PVC,PVC里定義了Pod所需存儲的大小和訪問模式,然后PVC會到PV池里自動匹配最合適的PV給Pod使用。
現有回收策略有:
Retain – 手動重新使用Recycle – 基本的刪除操作 (“rm -rf /thevolume/*”)Delete – 關聯的后端存儲卷一起刪除,后端存儲例如AWS EBS, GCE PD或OpenStack Cinder目前只有NFS和HostPath支持回收,AWS EBS, GCE PD和Cinder volumes只支持刪除。
卷有四種狀態,一個卷必屬于其中之一:
Available –閑置狀態,沒有被綁定到PVCBound – 綁定到PVCReleased – PVC被刪掉,資源沒有被在利用Failed – 自動回收失敗前面在介紹PV的生命周期時,提到PV的供給有兩種方式,靜態和動態。動態卷供給是一個 Kubernetes 獨有的功能,這一功能允許按需創建存儲卷。在沒有這種能力之前,集群管理員需要打電話給他們的云或者存儲提供者來創建新的存儲卷,成功以后再創建 PersistentVolume對象,才能夠在 Kubernetes 中使用。動態卷供給能力讓管理員不必進行預先創建存儲卷,而是隨用戶需求進行創建。這一特性在 1.2 版本中處于 α 階段,在版本 1.4 中提升為 β。這一版本提高了動態卷的彈性和可用性。 其中動態方式是通過StorageClass來完成的,這是一種新的存儲供應方式。
使用StorageClass有什么好處呢?除了由存儲系統動態創建,節省了管理員的時間,還有一個好處是可以封裝不同類型的存儲供PVC選用。在StorageClass出現以前,PVC綁定一個PV只能根據兩個條件,一個是存儲的大小,另一個是訪問模式。在StorageClass出現后,等于增加了一個綁定維度。
比如這里就有兩個StorageClass,它們都是用谷歌的存儲系統,但是一個使用的是普通磁盤,我們把這個StorageClass命名為slow。另一個使用的是SSD,我們把它命名為fast。
在PVC里除了常規的大小、訪問模式的要求外,還通過annotation指定了Storage Class的名字為fast,這樣這個PVC就會綁定一個SSD,而不會綁定一個普通的磁盤。
例:用戶在 PersistentVolumeClaim 中可以包含一個 StorageClass 申請動態提供存儲。這一任務需要使用 volume.beta.kubernetes.io/storage-class 注解來完成。這一注解的值必須符合管理員配置的 StorageClass 名稱。
要選擇 “fast” 存儲類,用戶需要創建如下的 PVC:
上述報文會提供一個等效于 SSD 的持久盤,當這個 PVC 被刪除,這個卷也隨之銷毀。
缺省行為
所有的 PVC 都可以在不使用 StorageClass 注解的情況下,直接使用某個動態存儲。把一個StorageClass 對象標記為 “default” 就可以了。StorageClass 用注解storageclass.beta.kubernetes.io/is-default-class 就可以成為缺省存儲。
有了缺省的 StorageClass,用戶創建 PVC 就不用 storage-class 的注解了,1.4 中新加入的DefaultStorageClass 準入控制器會自動把這個標注指向缺省存儲類。
到這里Kubernetes的整個存儲系統就都介紹完了。總結一下,兩種存儲卷:普通Volume 和Persistent Volume。普通Volume在定義Pod的時候直接定義,Persistent Volume通過Persistent Volume Claim來動態綁定。PV可以手動創建,也可以通過StorageClass來動態創建。
http://blog.tenxcloud.com/?p=1816&utm_source=tuicool&utm_medium=referral
http://blog.csdn.net/QQ_26923057/article/details/52713463
http://dockone.io/article/2016?utm_source=tuicool&utm_medium=referral
https://www.kubernetes.org.cn/1146.html
具體用法請參考官方文檔:https://kubernetes.io/docs/user-guide/persistent-volumes/ 或http://blog.csdn.net/qq_26923057/article/details/52713463
頂0踩新聞熱點
疑難解答