1. 程式人生 > >Docker(二):理解容器編排工具Kubernetes內部工作原理

Docker(二):理解容器編排工具Kubernetes內部工作原理

一、Kubernetes是什麼

  要說到Docker就不得不說說Kubernetes。當Docker容器在微服務的環境下數量一多,那麼統一的,自動化的管理自然少不了。而Kubernetes就是一個這樣的工具,它不僅僅提供了健康檢查和自修復,還有自動擴容縮容,以及服務發現和負載均衡等等功能。總的來說它使我們對於大量的Docker容器管理更加的方便。

二、Kubernetes整體架構圖及對應功能分析

 

  1、kubectl:這是相當於使用者客戶端一樣,也是我們較常使用的命令列工具,通過這個工具可以發起對應的請求到master節點中,當然自己開發的客戶端同樣可以通過HTTP協議發起對應的RESTAPI請求訪問APIServer。

  2、Master:Master節點是整個Kubernetes的核心節點,主要職責是負責排程,即應用放在哪裡執行,同樣為了高可用可執行多個Master。而Master中主要有APIServer,ControllerManager,Scheduler,Etcd,Kube-dns。對應的職責分別如下:

  2.1、APIServer:提供了資源操作的唯一入口,注意其他節點是無法被外面請求操作的(不是說內部執行的容器無法被訪問,而是說無法通過發請求的方式直接操作Node),只有Master節點才能接受外面的請求進行操作Node節點,其中主要提供了認證、授權、訪問控制整個叢集。而dashboard是提供了一個展示介面。

  2.2、Scheduler:負責資源的排程,根據一定的排程策略,將對應Node上面的Pod執行起來。

  2.3、ControllerManager:負責維護叢集的狀態,比如故障檢測,擴縮容,滾動更新。在Pod執行起來,就由ControllerManager負責管理其狀態

  2.4、ETCD:用於一致性儲存,儲存pod,service等等的Kubernetes狀態。這裡可以理解為MySQL在我們日常專案中的儲存作用,只要是用於存取Kubernetes中所有的持久化資料。

  2.5、Kube-dns:DNS元件負責整個叢集的DNS服務。使得內部Pod相互之間可通過名字訪問。有了這個功能就不需要寫繁瑣的IP地址,通過服務的名字即可訪問對方。

  3、Node:理解為分支節點,主要作用在於提供Kubernetes執行時的環境,以及維護Pod。內部主要有Kubblet,kube-proxy,docker等

  3.1、Kubblet:通過Master傳送的請求到Node分支上的Kubblet,然後就由Kubblet負責維護當前節點上容器的生命週期,也負責維護當前節點的資料卷及網路。

  3.2、Kube-proxy:提供內部的服務發現和負載均衡。可以在圖上看見虛線框起來的三個框,可以認為這三個Pod算是一個服務,即service,而外部可通過Kube-proxy暴露的埠來進行統一的訪問。並且預設是使用輪詢的負載均衡策略來訪問。

三、Pod詳解

  Pod作為Kubernetes的核心資源,這裡單獨拿出來解釋。在Kubernetes叢集中,Pod是所有業務型別的基礎,它是一個或多個容器的組合,也就是Pod內部可以有多個Docker容器存在,不是一個Pod代表一個容器,注意區分概念。在其中的這些容器共享儲存、網路和名稱空間,以及如何執行的規範。在Pod中,所有容器都被同一安排和排程,並執行在共享的上下文中。對於具體應用而言,Pod是它們的邏輯主機,Pod包含業務相關的多個應用容器。這些容器可以通過localhost發現彼此。每一個Pod有自己的一個IP地址。

  1、Pod工作方式

    在Kubernetes中一般不會直接建立一個獨立的Pod,這是因為Pod是臨時存在的一個實體。當直接建立一個獨立的Pod時,如果缺少資源或者所被排程到的Node失敗,則Pod會直接被刪除。這裡需要注意的是,重起Pod和重起Pod中的容器不是一個概念,Pod自身不會執行,它只是容器所執行的一個環境。Pod本身沒有自愈能力,如果Pod所在的Node失敗,或者如果排程操作本身失敗,則Pod將會被刪除;同樣的,如果缺少資源,Pod也會失敗。Kubernetes使用高層次的抽象,即控制器來管理臨時的Pod。通過控制器能夠建立和管理多個Pod,並在叢集範圍內處理副本、部署和提供自愈能力。

  2、重啟策略

    Pod既然內部執行著容器,那麼免不了會因為異常等原因導致其終止退出,Pod支援三種重啟策略,需要在配置檔案中通過restartPolicy欄位設定重啟策略:

    Always:只要退出就會重啟

    OnFailure:只有在失敗退出(即exit code不等於0時),才會重啟

    Never:只要退出就不再重啟

  3、映象拉取策略

    前一篇部落格有講容器與映象的概念,在Kubernetes中執行容器時,需要為容器獲取映象。Pod中容器的映象有三個來源,即Docker公共映象倉庫、私有映象倉庫和本地映象。當在內網使用的Kubernetes場景下,就需要搭建和使用私有映象倉庫。Pod支援三種映象拉取策略,在配置檔案中通過imagePullPolicy欄位設定映象拉取策略:

    Always:不管本地是否存在映象都會進行一次拉取

    Never:不管本地是否存在映象都不會進行拉取

    IfNotPresent:僅在本地映象不存在時,才會進行映象拉取

  這裡有需要注意的點:映象拉取策略的預設值IfNotPresent,但:lastest標籤的映象預設為Always。所以生產環境中避免使用:lastest標籤。還有就是拉取映象時docker會進行校驗,如果映象中的MD5碼沒有變,則不會拉取映象資料。

  4、資源限制

    Kubernetes通過cgroups來限制容器的CPU和記憶體等計算資源,在建立Pod時,可以為Pod中的每個容器設定資源請求(request)和資源限制(limit),資源請求是容器需要的最小資源要求,資源限制為容器所能使用的資源上限。CPU的單位是核(core),記憶體(Memory)的單位是位元組(byte)。

  5、終止Pod

    在叢集中,Pod代表執行的程序,但不再需要這些程序時,如何優雅的終止這些程序是非常重要的。當用戶請求刪除一個Pod時,Kubernetes將會發送一個終止訊號給每個容器,一旦過了優雅期,就會發送kill訊號,從而通過APIServer刪除Pod。通常預設的優雅退出時間為30s。緩慢關閉的Pod依然可以對外繼續服務,直到負載均衡器將其移除,當超過優雅的退出時間,在Pod中任何正在執行的程序都會被kill。

四、Pod的生命週期

  1、Pending

    Pod已經被Kubernetes系統接受,但是還有一個或者多個容器映象未被建立。這包括Pod正在被排程和從網路上下載映象的時間。

  2、Running

    Pod已經被繫結到了一個Node,所有容器已經被建立,至少有一個容器在執行

  3、Succeeded

    在Pod中所有容器已經被成功停止,並且不再重啟

  4、Failed

    在Pod中所有容器已經被終止,並且至少有一個容器是非正常終止的,即容器以非零狀態退出或者被系統強行終止的。

  5、Unknown

    Pod在某些原因下不能被獲取。通常是網路問題。

五、service圖

  前面有說到Docker目前在微服務架構執行的很廣泛,而Kubernetes作為編排Docker容器的強大工具自然是我們的首選。而Kubernetes又是怎麼和微服務結合起來的呢?

 

  上面有說到Pod擁有自己的IP地址,實際上在Pod外面還包裹著一層Service,這個Service是邏輯存在的,在最上面的架構圖中就類似kube-proxy串在一起的三個Pod,而service的IP是由kube-proxy給我們提供。這就是與微服務之間能夠連起來了。其中同一個service的Pod應該是相同的,kube-proxy會自動給我們做負載均衡,預設使用輪詢。同樣與Docker不相同的是Pod之間是可以通過名字直接訪問的,Node同樣也是,這就為我們的服務呼叫提供了很便利的方式。

六、總結

  Kubernetes是一個容器編排及其自動化管理的工具。隨著業務增長Docker容器越來越多,如果需要每一個自己手動管理,那麼將會翻倍的增加我們的工作量。所以Kubernetes是我們在學習Docker中需要進階的知識。

 

&n