k8s如何管理Pod

本文整理自【時速雲線上微信羣分享】第十二期node

在本次分享開始前,讓咱們先回想下Pod。Pod直譯是豆莢,能夠把容器想像成豆莢裏的豆子,把一個或多個關係緊密的豆子包在一塊兒就是豆莢(一個Pod)。在k8s中咱們不會直接操做容器,而是把容器包裝成Pod再進行管理(關於Pod,你們能夠參考第二期的分享「談談Pod在微服務中的運用」)。Pod是運行服務的基礎,那咱們如何來管理Pod呢,下面咱們就來聊一聊。分爲這三個部分:docker

1. 使用Replication Controller 來部署、升級Podapi

2. Replica Set – 下一代Replication Controller安全

3. Deployment – 更加方便的管理Pod和Replica Set微信

先舉個例子

假設咱們有一個Pod在提供線上服務,如今有以下幾個場景,你們想一想如何應對:網絡

  1. 節日活動,網站訪問量突增運維

  2. 遭到攻擊,網站訪問量突增微服務

  3. 運行Pod的節點發生故障工具

第1種狀況, 活動前預先多啓動幾個Pod,活動結束後再結束掉多餘的,雖然要啓動和結束的Pod有點多,但也能有條不紊按計劃進行性能

第2種狀況, 正在睡覺忽然手機響了說網站反應特慢卡得要死,趕忙爬起來邊擴容邊查找攻擊模式、封IP等等……

第3種狀況, 正在休假忽然手機又響了說網站上不去,趕忙打開電腦查看緣由,啓動
新的Pod

Pod須要手動管理,好累……

可否在Pod發生問題時自動恢復呢,咱們先來看下Replication Controller(如下簡稱RC)

先說RC 是什麼。RC保證在同一時間可以運行指定數量的Pod副本,保證Pod老是可用。若是實際Pod數量比指定的多就結束掉多餘的,若是實際數量比指定的少就啓動缺乏的。當Pod失敗、被刪除或被終結時RC會自動建立新的Pod來保證副本數量。

因此即便只有一個Pod也應該使用RC來進行管理。

接下來咱們看下如何建立RC,看這個定義文件rc.yaml

alt 文本

這個文件定義了RC的屬性,咱們先關注以下字段:

spec.replicas:副本數量3

spec.selector:RC經過spec.selector來篩選要控制的Pod

spec.template:這裏寫Pod的定義(但不須要apiVersion和kind)

spec.template.metadata.labels:Pod的label,能夠看到這個label與spec.selector相同

這個文件的意思是定義了一個RC對象,它的名字是hello-rc(metadata.name:hello-rc),保證有3個Pod運行(spec.replicas:3),Pod的鏡像是index.tenxcloud.com/tailnode/hello:v1.0(spec.template.spec.containers.image: index.tenxcloud.com/tailnode/hello:v1.0)

關鍵在於spec.selector與spec.template.metadata.labels,這兩個字段必須相同,不然下一步建立RC會失敗。(也能夠不寫spec.selector,這樣默認與spec.template.metadata.labels相同)

如今經過kubectl來建立RC:

alt 文本

查看結果能夠看到當前RC的狀態:指定了須要3個Pod、當前實際有3個Pod、3個Pod都在運行中(圖片較大隻截取部分):

alt 文本

若是使用的鏡像較大查看狀態多是Waiting,這是由於正在下載鏡像,等待一段時間就好。

alt 文本

上面說過RC會自動管理Pod保證指定數量副本運行,咱們來實驗一下,看下圖:

alt 文本

1.查看當前Pod,(注意NAME和AGE列)

2.刪除hello-rc-5crgq

3.再次查看Pod,發現新的Pod啓動了(注意NAME和AGE列)

到這裏咱們對RC有了基本的認識,並進行了簡單的使用。

如今回到最開始的問題,如何經過RC修改Pod副本數量。其實很是簡單,只須要修改yaml文件spec.replicas字段成想要的值,而後執行kubectl replace命令(或者使用kubect edit replicationcontroller hello-rc直接修改).

執行結果看下圖:

alt 文本

當咱們有新功能發佈或修復BUG時使用滾動升級是不錯的選擇,可使用工具kubectl rolling-update完成這個任務。對照下圖咱們來看下是如何進行的

使用命令kubectl rolling-update hello-rc –image=index.tenxcloud.com/tailnode/hello:v2.0

alt 文本

在另外一個窗口查看RC

alt 文本

對照兩張截圖,咱們可以看出升級步驟以下:

1.建立一個使用新版本Pod的RC,hello-rc-4f7ed44b6db1e20aa1bc681c81d63caf

2.依次增長新RC的副本數量、減小舊RC的副本數量

3.當升級成功後,刪除舊RC

4.重命名新RC爲hello-rc

當Pod中只有一個容器時經過–image參數指定新的Tag,若是有多個容器或其餘字段的修改時,須要使用kubectl rolling-update NAME -f FILE指定文件

若是在升級過程當中出現問題(好比長時間無響應),能夠CTRL+C結束再使用kubectl rolling-update hello-rc –rollback進行回滾,但若是升級完成後出現問題(好比新版本程序出core),此命令無能爲力,須要使用一樣方法「升級」爲舊版本

在時速雲平臺咱們可以很是方便的使用彈性伸縮功能來調整Pod副本數量,仍是舉例說明:

啓動一個可以輸出Pod主機名和版本號的服務,看下圖當前只有一個Pod副本運行

alt 文本

點擊彈性伸縮,修改數量爲3,同時使用下面的命令測試,從輸出結果能夠看出提供服務的Pod數量變成了3個:

alt 文本

下面再來測試下灰度升級功能,修改目標版本爲v2.0(以前是v1.0,爲了便於查看效果新建有2個Pod的服務),而後查看Pod變化

第一個新Pod hello-v2.0-ywcc2已經啓動

alt 文本

第二個新Pod hello-v2.0-whtvh正在啓動

alt 文本

最後一箇舊Pod hello-41ee8正在中止

alt 文本

升級完成,只有兩個新Pod提供服務

alt 文本

同時使用命令查看服務的響應以下:

alt 文本

k8s是一個高速發展的項目,在新的版本中官方推薦使用Replica Set和Deployment來代替RC。

那麼它們優點在哪裏,咱們來看一看:

  1. RC只支持基於等式的selector(env=dev或environment!=qa)但Replica Set還支持新的基於集合的selector(version in (v1.0, v2.0)或env notin (dev, qa)),這對複雜的運維管理帶來很大方便

  2. 使用Deployment升級Pod只須要定義Pod的最終狀態,k8s會爲你執行必要的操做,雖然可以使用命令kubectl rolling-update完成升級,但它是在客戶端與服務端屢次交互控制RC完成的,因此REST API中並無rolling-update的接口,這爲定製本身的管理系統帶來了一些麻煩。

  3. Deployment擁有更加靈活強大的升級、回滾功能

Replica Set目前與RC的區別只是支持的selector不一樣,後續確定會加入更多功能。Deployment使用了Replica Set,是更高一層的概念。除非須要自定義升級功能或根本不須要升級Pod,因此推薦使用Deployment而不直接使用Replica Set。

下面咱們繼續來看Deployment的定義文件,與RC的定義文件基本相同(注意apiVersion仍是beta版),因此再也不詳細解釋各字段意思

alt 文本

與建立RC相同,使用命令kubectl create -f deployment.yaml –record建立Deployment,注意–record參數,使用此參數將記錄後續對建立的對象的操做,方便管理與問題追溯

使用kubectl edit deployment hello-deployment修改spec.replicas/spec.template.spec.container.image字段來完成擴容縮容與滾動升級(比kubectl rolling-update速度快不少)

修改image字段爲新版本鏡像後查看Pod,在STATUS列看到正在執行升級的Pod:

alt 文本

使用kubectl rollout history命令查看Deployment的歷史信息

alt 文本

上面提到過kubectl rolling-update升級成功後不能直接回滾,不是很方便,那使用Deployment能夠嗎,答案是確定的。

首先在上面的命令加上–revision參數,查看改動詳細信息以下:

alt 文本

而後使用kubctl rollout undo deployment hello-deployment回滾至前一版本(使用–to-revision參數指定版本)便可。

命令kubectl describe deployment hello-deployment查看詳細信息,在Message一列看到回滾以下,詳細的信息記錄對於問題發生後的緣由查找有很大幫助:

alt 文本

經過對比RC、Replica Set與Deployment,能夠看出新的Replica Set與Deployment比RC要強大易用不少,但由於如今仍是beta版本因此不建議在生產環境使用,不過相信不久的未來咱們就能使用上。

Q&A

  1. 問:灰度發佈, 能夠指定新舊版共存麼, 怎麼整?
    答:能夠像上面說的那樣,使用命令行工具建立新舊兩個RC,而後分別指定須要的Pod數量。但目前時速雲平臺還不支持這種。

  2. 問:時速雲是怎麼保持k8s master的高可用的?
    答:高可用目前是官方推薦的多master standby方式,以及咱們本身的agent監管方式。

  3. 問:Pod 之間通訊是否是也是用的flannel?
    答:pod和pod之間,能夠採用官方推薦的各類網絡解決方案,目前咱們主要關注 flannel(vxlan)和 Calico

  4. 問:flannel以及calico,大家選其一仍是兩個方案都在用?有測試報告嗎?
    答:兩個方案都在用,測試報告之前分享過幾種方案的網絡性能比較,這裏有一個Calico的,能夠參考:https://www.projectcalico.org/ ... ance/

  5. 問:Replica Set 這個有demo的例子麼?
    答:由於通常Replica Set不會直接使用,而是經過Deployment來控制它,因此本次沒有寫出Replica Set的demo

  6. 問:Deployment如今是沒有rest api修改Pod數量麼?
    答:有的,PUT /apis/extensions/v1beta1/namespaces/{namespace}/deployments/{name}

  7. 問:因爲k8s嚴重依賴etcd中的數據,一旦etcd的數據紊亂,可能形成業務故障。這個問題在大量業務接入的時候可能有概率出現,時速雲有解決方案嗎?
    答:這個問題,目前尚未碰到,不過咱們會將服務信息同時存放到另外的存儲中,也會對etcd進行備份,這樣在出現故障時也能夠很容易恢復或者遷移整個集羣。

  8. 問:時速雲用的是原生k8s嗎,都作了哪些優化?
    答:優化是有一些的,包括部署方式、網絡、存儲、以及一些用戶體驗上的優化爲主,以便充分發揮 k8s 的一些優點。

  9. 問:Docker 1.12版本開始集成了Swarm到Docker Engine中,Swarm功能也變得愈來愈強大,那麼時速雲怎麼看這個問題?之後考不考慮用高版本Docker,用k8s管理集成Swarm的Docker,會不會性能浪費?
    答:咱們目前主要關注swarm,swarmkit這些docker原生的工具,會去了解他們的主要特性,能夠看到swarmkit正在向 k8s 方向邁進。

  10. 問:再問個問題,有狀態服務的pod,掛載個數據卷(好比rbd)。用rc或者deployment管理的pod重啓或者升級之後,數據卷從新掛載到新的pod上會有什麼問題麼?
    答:沒有遇到過問題,理論上也不該該會有問題的。

  11. 問:能不能介紹一下怎麼作用戶隔離的,公有云的話,安全對你們很重要
    答:能夠參考 Calico 的網絡隔離和 k8s 的服務、api訪問控制,以及一些用戶角色上的設計,k8s在安全上仍是考慮了很多東西的。

  12. 問:容器飄移和虛擬機飄移同樣嗎?
    答:仍是不太同樣的,虛擬機能夠支持熱遷移,目前容器還不行。

如何參與線上分享?

添加微信號:時速雲小助手(tenxcloud6),咱們便可拉您進羣

相關文章
相關標籤/搜索