Kubernetes 有狀態集羣服務部署與管理

極牛技術分享活動html

極牛技術實踐分享系列活動是極牛聯合頂級VC、技術專家,爲企業、技術人提供的一種系統的線上技術分享活動。mysql

每期不一樣的技術主題,和行業專家深度探討,專一解決技術實踐難點,推進技術創新。隔週三20點經過極牛線上技術分享羣準時開課。歡迎各個機構、企業的行業專家、技術人報名參加。nginx

本期主題
Kubernetes 有狀態集羣服務部署與管理sql

嘉賓介紹docker

張壽紅,從事軟件研發工做十餘年,目前從事基於Docker和Kubernetes的企業級容器雲平臺研發工做,主要包括容器服務、存儲服務、CI/CD和鏡像服務等。在加入時速雲以前,前後在CA Technologies和Symantec擔任Tech Lead和Principal Software Engineer。參與研發的軟件產品有:企業數據保護軟件、雲平臺上的服務管理系統、企業客戶服務平臺等。數據庫

摘要:
在容器化時代,除了無狀態的容器服務,好比Web服務器,用戶也愈來愈多地使用容器部署有狀態的應用,好比MySQL、Redis、Cassandra等。這些Pets(運行有狀態服務的容器,須要特殊處理)就帶來了新的需求,包括更長的生命週期,配置依賴,有狀態的故障轉移等。bootstrap

張壽紅講師深刻介紹Kubernetes如何知足有狀態集羣服務對容器編排系統提出的新需求,包括如何使用Kubernetes的動態存儲請求與分配機制來實現服務狀態的持久化存儲,以及與高效部署和運行有狀態集羣服務相關的Kubernetes新特性,如Init Container、PetSet (StatefulSet)等。最後經過一個MySQL集羣實例詳解在Kubernetes中如何輕鬆部署一個高可用的有狀態集羣服務並實現自動化管理。緩存

大綱:
· Kubernetes簡介和運行有狀態集羣服務的挑戰
· Kubernetes存儲系統
· Kubernetes有狀態集羣服務相關特性
· 實戰:在Kubernetes上部署和管理MySQL集羣服務器

你們晚上好,我是來自時速雲的張壽紅,很高興有機會和你們作此次有關容器雲的技術分享。網絡

在容器化時代,除了無狀態的容器服務,好比Web服務器,用戶也愈來愈多地使用容器部署有狀態的應用,這就對容器編排系統提出了新的需求。

我今天要和你們分享的主題就是如何在目前主流的容器雲平臺Kubernetes 上部署和管理有狀態集羣服務。此次分享的關鍵詞有兩個:一個是Kubernetes, 另外一個是有狀態集羣服務。

咱們會在第一部分了解一下什麼是 Kubernetes,以及運行有狀態集羣服務面臨的一些挑戰。接下來的兩部分咱們會重點介紹 Kubernetes 是如何應對這些挑戰,以及經過哪些特性來解決有狀態集羣服務所特有的一些問題。最後一部分是實戰,經過一個MySQL集羣的例子來展現如何在Kubernetes上輕鬆地部署和管理一個有狀態集羣服務。

什麼是Kubernetes?

clipboard.png

簡單一句話來講,Kubernetes是一個運行和管理容器的平臺。它在Docker、rkt等容器運行時之上,實現了容器的集羣化和高可用。

Kubernetes簡稱K8S,來自Google,支持多種雲計算環境,而且100% 開源,是雲原生計算基金會的一部分,用Go語言開發的。

Kubernetes的一些基本概念:

其中最核心的一個概念是Pod,它是Kubernetes對容器進行的封裝,是Kubernetes管理的最小單位。Pod經過Deployment來部署,Deployment會建立一個Replica Set 來保證Pod的個數始終是一個指定的值 。Pod通常不直接對外提供服務,而是經過Service對外提供一個穩定的訪問接口,一個Service後面能夠掛多個Pod實例 。

Service是如何找到它匹配的Pod呢?靠的是Label。Label是聯繫各個K8S資源的紐帶。Replica Set 和它管理的Pod之間也是經過 Label 來關聯的。若是Pod裏的容器運行的是有狀態服務,如數據庫與緩存等,還須要掛載存儲卷,用於存儲服務狀態。

講完原理,咱們來看一個實例:

clipboard.png

這是一個在K8S集羣裏運行的容器化應用案例,這個應用有本身的Web 客戶端,同時還從Twitter採集數據,處理完後存儲到本身的DB。

能夠看到容器裏跑的服務有兩類,無狀態和有狀態。像Web服務器,流處理器等無狀態服務出現問題後,直接殺掉,新建一個,管理起來很是簡單。

可是對有狀態服務,像數據庫,它要求有更長的生命週期。在一個集羣的狀況下,集羣成員之間如何能保持穩定的成員關係?這都對容器編排系統提出了新的挑戰。

K8S是如何應對這些挑戰的呢?

K8S運行的服務,從簡單到複雜能夠分紅三類:無狀態服務、普通有狀態服務和有狀態集羣服務。下面分別來看K8S是如何運行這三類服務的。

clipboard.png

無狀態服務,K8S使用RC(或更新的ReplicaSet)來保證一個服務的實例數量。經過Service來對外提供一個穩定的訪問接口。
普通有狀態服務,它多了狀態保存的需求。Kubernetes提供了以Volume和Persistent Volume爲基礎的存儲系統,能夠實現服務的狀態保存。

狀態集羣服務,它又多了集羣管理的需求。K8S爲此開發了一套以Pet Set爲核心的全新特性,方便了有狀態集羣服務在K8S上的部署和管理。

clipboard.png

下面咱們來看Kubernetes如何知足「狀態保存」的需求。

K8S的存儲系統大體分爲三個層次:普通Volume,Persistent Volume 和動態存儲供應。

普通Volume
普通Volume,最簡單的一種是「單節點存儲卷」。它和Docker的存儲卷相似,使用的是Pod所在K8S節點的本地目錄。

clipboard.png

具體有兩種,一種是 emptyDir,是一個匿名的空目錄,由Kubernetes在建立Pod時建立,刪除Pod時刪除。

另一種是 hostPath,與emptyDir的區別是,它在Pod以外獨立存在,由用戶指定路徑名。

這類和節點綁定的存儲卷在Pod遷移到其它節點後數據就會丟失,因此只能用於存儲臨時數據或用於在同一個Pod裏的容器之間共享數據。

普通Volume,第二種類型是「跨節點存儲卷」。這種存儲卷不和某個具體的K8S節點綁定,而是獨立於K8S節點存在的 。

clipboard.png

跨節點存儲卷因爲能夠在任何一個Kubernetes 節點上都可以被訪問到,比較靈活,因此應用比較普遍。Kubernetes上的Volume是經過插件方式來實現的,因此可擴展性很強。

clipboard.png

目前來講幾乎全部主流的存儲在Kubernetes上都有相應的插件來支持。若是已有的存儲不能知足要求,還能夠開發本身的volume插件。
persistent volume,它和普通volume的區別是什麼呢?

普通Volume和使用它的Pod之間是一種靜態綁定關係,咱們沒法單首創建一個普通volume,由於它不是一個獨立的K8S資源對象。

而Persistent Volume 簡稱PV是一個K8S資源對象,因此咱們能夠單首創建。它不和Pod直接發生關係,而是經過Persistent Volume Claim,簡稱PVC來實現動態綁定。

動態綁定過程是怎樣的?

clipboard.png

這是PV的生命週期,首先是Provision,即建立PV,這裏建立PV有兩種方式,靜態和動態。

靜態方式是管理員手動建立一堆PV,組成一個PV池,供PVC來綁定。動態方式是經過一個叫 storage class的對象由存儲系統根據PVC的要求自動建立。

一個PV建立完後狀態會變成Available,等待被PVC綁定。一旦被PVC邦定,PV的狀態會變成Bound,就能夠被相應的Pod使用。Pod使用完後會釋放PV,PV的狀態變成Released。

變成Released的PV會根據定義的回收策略作相應的回收工做。有三種回收策略,Retain、Delete 和Recycle。

Retain就是保留現場,K8S什麼也不作。Delete 策略,K8S會自動刪除該PV及裏面的數據。Recycle方式,K8S會將PV裏的數據刪除,而後把PV的狀態變成Available,又能夠被新的PVC綁定使用。

動態方式是經過StorageClass來完成的,這是一種新的存儲供應方式。

clipboard.png

使用StorageClass有什麼好處呢?除了由存儲系統動態建立,節省了管理員的時間,還有一個好處是能夠封裝不一樣類型的存儲供PVC選用。

好比這裏就有兩個StorageClass,它們都是用谷歌的存儲系統,可是一個使用的是普通磁盤,名字爲slow。另外一個使用的是SSD,名字爲fast。

clipboard.png

在PVC裏經過annotation指定了storageclass的名字爲fast,這樣這個PVC就會綁定一個SSD,而不會綁定一個普通的磁盤。

好,到這裏Kubernetes的整個存儲系統就都介紹完了。

下面進入Kubernetes與有狀態集羣服務相關的兩個新特性:Init Container 和Pet Set。

什麼是Init Container?

從名字來看就是作初始化工做的容器。能夠有一個或多個,這些 Init Container 按照定義的順序依次執行,只有全部的InitContainer 執行完後,主容器才啓動。因爲一個Pod裏的存儲卷是共享的,因此 Init Container 裏產生的數據能夠被主容器使用到。

Init Container的一個使用樣例

這個例子建立一個Pod,這個Pod裏跑的是一個nginx容器,Pod裏有一個叫workdir的存儲卷,訪問nginx容器服務的時候,就會顯示這個存儲卷裏的index.html 文件。而這個index.html 文件就是經過一個 busybox的初始化容器得到的。
介紹完Init Container,千呼萬喚始出來,該今天的主角Pet Set出場了。
什麼是Pet Set?

clipboard.png

顧名思義是Pet的集合,那什麼是Pet呢?它是一種須要特殊照顧的Pod。它有狀態、有身份、固然也比普通的Pod要複雜一些。具體來講,一個Pet有三個特徵:

一是有穩定的存儲,這是經過咱們前面介紹的PV/PVC 來實現的。

二是穩定的網絡身份,這是經過一種叫 Headless Service 的特殊Service來實現的。 和普通Service相比,Headless Service沒有Cluster IP,用於爲一個集羣內部的每一個成員提供一個惟一的DNS名字,用於集羣內部成員之間通訊 。
三是序號命名規則, 好比 Pet Set 的名字叫 mysql,那麼第一個啓起來的Pet就叫mysql-0,第二個叫mysql-1,如此下去。當一個Pet down 掉後,新建立的Pet 會被賦予跟原來Pet同樣的名字,經過這個名字就能匹配到原來的存儲,實現狀態保存。

好,與有狀態服集羣服務相關的K8S特性就介紹到這裏。理論講完了,下面進入實戰,以Galera MySQL集羣爲例子,介紹如何在 Kubernetes如何上部署和管理一個有狀態集羣服務。

首先大體瞭解一下Galera MySQL:

![圖片上傳中...]

它不是那種主從式的集羣,而是多Master集羣,經過 Galera Replication 把多個MySQL實例關聯起來組成一個集羣。由Galera Replication 負責節點間的數據同步。

用戶訪問時能夠鏈接到任何一個節點進行讀寫操做。每次寫入的數據會被Galera Replication同步到整個集羣,纔算寫入成功。節點之間沒有數據延遲,在某個節點失效後,直接退出集羣便可,無需失效轉移。

如何在Kubernetes上部署和運行它?這是總體結構圖:

clipboard.png

左邊的Headless Service用於爲每一個MySQL Pet實例提供一個DNS名字,右邊的PV池爲MySQL提供存儲。

這裏有兩個初始化容器,第一個用於安裝須要的文件,第二個作MySQL的初始化工做 。

一個Pet Set裏有多個Pet,每一個Pet對應MySQL集羣裏的一個節點。經過Pet Set能夠管理整個MySQL集羣。

部署MySQL集羣具體的YAML文件
右邊是一個Headless Service,名字是galera,左邊是Pet Set,它用到了右邊的Headless service。Replicas的數目爲3,會建立3個Pet。
Pet Set 的annotation裏定義了兩個初始化容器:

Install容器安裝的文件能夠被bootstrap容器使用到;同時bootstrap容器生成的MySQL配置文件會放到config存儲卷裏,供後面的MySQL 容器使用。

主容器 Galera MySQL 的定義
除了常規的3306端口外,它還暴露了其它一些端口,用於集羣內部的數據同步和狀態轉移等操做。這裏MySQL啓動參數裏用到的文件,是在初始化容器裏生成的,經過共享存儲卷傳遞過來。

數據存儲卷的定義
這裏定義了三個存儲卷,其中config、workdir就是簡單的本地目錄,而 datadir是一個PVC,它能夠去綁定PV來存儲MySQL數據庫的數據 。

因此部署一個集羣總共就須要兩個YAML文件就能夠了,一個Headless Service,一個 Pet Set。其中Pet Set裏定義了初始化容器和存儲卷。

用上面的方式部署完MySQL集羣后,後面的運維工做是比較簡單的。

假如某個集羣節點因爲某種緣由Crash掉了,Kubernetes 會自動建立一個新的Pet來替代,實現自動恢復。若是要擴容或縮容,也是一條命令、指定一下這個Pet Set 的Replicas的數目就好了。

若是要升級,只須要修改Pet Set 定義裏 podTemplate 的image值,而後把老的Pet刪除,新建立的Pet,就是最新版本的了。

對於在Kubernetes上部署有狀態集羣服務,咱們補充兩點:

第一點是在最新發布的Kubernetes 1.5 裏 PetSet 從新命名爲StatefulSet。因此根據你使用的K8S版本不一樣,可能看到的名字也不同。

第二點是簡單介紹一下時速雲提供的有狀態集羣服務:數據庫與緩存。
務的建立工做,用戶再也不須要了解咱們前面介紹的全部技術術語,只須要指定一下副本數目,存儲的大小就能夠了。
最後如下面這張圖作爲今天分享內容的總結:

clipboard.png

有狀態集羣服務的兩個需求:一個是存儲需求,另外一個是集羣需求。
對存儲需求,Kubernetes的解決方案是:Volume、Persistent Volume 。對PV,除了手動建立PV池外,還能夠經過Storage Class來讓存儲系統自動建立。

對集羣需求,Kubernetes的解決方案是Pet Set。Pet Set 又經過Init Container來作集羣初始化,經過Headless Service來爲集羣成員提供穩定 的網絡身份。

最後咱們以MySQL集羣爲例,說明了如何在Kubernetes上部署和運行一個有狀態集羣服務。

目前有狀態集羣服務在Kubernetes上的部署還不是正式版,但徹底可用。若是您的項目中有容器化的需求,能夠嘗試。

Q&A
Q1:容器內的數據該保存在鏡像裏仍是宿主機中?
A1:一般數據是保存在獨立的存儲設備中,容器經過Volume掛載使用。簡單的存儲也能夠用宿主機的目錄。

Q2:k8s Resource 監控怎麼作?
A2:有專門的容器監控工具,如Prometheus

Q3:Kubernetes和Mesos有啥區別,如何選擇?
A3:Kubernetes爲容器集羣而生,Mesos除了容器集羣,傳統集羣也能用。若是是純容器雲環境,推薦使用K8S。

Q4:在什麼樣的業務量下適合用Kubernetes?
A4: K8S 來自Google,經歷了Google內部海量生產環境的檢驗,普通公司的業務量不是問題。

Q5:實際生產環境中對比k8s 和swarm 各有什麼優劣,如何正確選型?
A5:swarm 是docker原生的容器管理系統,但相對K8S而言還比較新,不是很成熟。生產環境目前仍是推薦用K8S。

報名請關注極牛(ji-niu)公號回覆技術分享

相關文章
相關標籤/搜索