Kubernetes 源自於 Google 內部的服務編排系統 - Borg,誕生於2014年。它汲取了Google 十五年生產環境的經驗積累,並融合了社區優秀的idea和實踐經驗。html
Kubernetes這個單詞起源於古希臘是舵手的意思,因此它的logo是一個漁網狀的七邊形,裏面還有一個羅盤。Google選擇這樣一個名字也是有必定的深意:既然docker把本身比做一隻鯨魚託着集裝箱在大海中遨遊,Google就要用Kubernetes去掌握去掌握大航海時代的話語權,去捕獲和指引着這條鯨魚按照主人設定的路線去巡遊。算法
得益於 Docker 的特性,服務的建立和銷燬變得很是快速、簡單。Kubernetes 正是以此爲基礎,實現了集羣規模的管理、編排方案,使應用的發佈、重啓、擴縮容可以自動化。docker
Kubernetes 能夠管理大規模的集羣,使集羣中的每個節點彼此鏈接,可以像控制一臺單一的計算機同樣控制整個集羣。後端
在k8s集羣中有兩種角色,一種是 Master ,一種是 Node(也叫worker):網絡
以下圖:架構
瞭解了集羣中的兩大角色後,咱們再看看Kubenetes的架構示意圖:app
Kubenetes Master節點剖析圖:負載均衡
在上文也說了Master節點至關於Kubenetes集羣中的大腦,在Master節點具有四個主要模塊:分佈式
kubectl
)與Kubenetes集羣進行交互Kubenetes Node節點剖析圖:ide
Kubernetes 的 Node 作的事情也並非簡單的 docker run
一個容器。出於像易用性、靈活性、穩定性等的考慮,Kubernetes 提出了一個叫作 Pod 的東西,做爲 Kubernetes 的最小調度單位。因此咱們的應用在每一個 Node 上運行的實際上是一個 Pod。Pod 也只能運行在 Node 上。以下圖:
Pod中會包含一個或多個容器。容器自己就是一個小盒子了,Pod 至關於在容器上又包了一層小盒子。這個盒子裏面的容器有什麼特色呢?
127.0.0.1:8080
就能夠訪問到B容器的服務,反之亦然。每一個Pod裏都會有一個特殊的Pause容器有時候也稱爲Infra容器,它與用戶容器」捆綁「運行在同一個 Pod 中,最大的做用是維護 Pod 網絡協議棧,將用戶容器link
到一塊兒。這也是爲何同一個Pod裏的容器之間僅需經過localhost
就能互相通訊的緣由。除此之外,Pause容器還會負責Pod的健康檢查,而後彙報給k8s。
Pause容器主要爲每一個用戶容器提供如下功能:
關於Pause容器更多的內容能夠參考:
Pod的上一層是ReplicaSet(副本集),簡稱RS。ReplicaSet負責維護應用的實例副本,因此ReplicaSet裏的每個Replica就是一個Pod而不是容器,由於Pod是最小調度單位。例如某個應用的ReplicaSet數量是2,當某一個節點上的Pod掛掉了,那麼ReplicaSet就會檢測到副本數量不知足2,此時k8s就會從新根據調度算法在其餘節點建立並運行一個新的Pod,通俗來講就是再拉起一個Pod。
當咱們擁有一個 Kubernetes 集羣后,就能夠在上面跑咱們的應用了,前提是咱們的應用必須支持在 Docker 中運行,也就是咱們要事先準備好Docker鏡像。
有了鏡像以後,通常咱們會經過Kubernetes的 Deployment 的配置文件去描述應用,好比應用叫什麼名字、使用的鏡像名字、要運行幾個實例、須要多少的內存資源、cpu 資源等等。
有了配置文件就能夠經過Kubernetes提供的命令行客戶端 - kubectl
去管理這個應用了。kubectl
會跟 Kubernetes 的 master 經過RestAPI通訊,最終完成應用的管理。
好比咱們建立並配置好的 Deployment 配置文件叫 app.yaml
,咱們就能夠經過"kubectl create -f app.yaml
" 命令來建立這個應用,以後就由 Kubernetes 來保證咱們的應用處於運行狀態,當某個實例運行失敗了或者運行着應用的 Node 忽然宕機了,Kubernetes 會自動發現並在新的 Node 上調度一個新的實例,保證咱們的應用始終達到咱們預期的結果。
滾動升級是Kubernetes中最典型的服務升級方案,主要思路是一邊增長新版本應用的實例數,一邊減小舊版本應用的實例數,直到新版本的實例數達到預期,舊版本的實例數減小爲0,滾動升級結束。在整個升級過程當中,服務一直處於可用狀態。而且能夠在任意時刻回滾到舊版本。
咱們之因此不會直接將應用定義爲Pod,而是定義爲 Deployment 的一個重要緣由就是由於只有將應用定義成 Deployment 時才能支持滾動升級。當 Deployment 中的容器須要升級更新時,Deployment 會先建立一個新的 ReplicaSet 及Pod,而後中止並刪除舊的 ReplicaSet 中的一個Pod,接着再新建一個新版本Pod,而後再刪除一箇舊版本的Pod......以此實現滾動式的更新,因此在更新過程當中應用能夠實現不中斷地服務。
假設咱們上面介紹的 Deployment 建立了,Pod 也運行起來了。如何才能訪問到咱們的應用呢?
最直接想到的方法就是直接經過 Pod的 ip + 端口號去訪問,但若是實例數不少呢?好,拿到全部的 Pod - ip 列表,配置到負載均衡器中,輪詢訪問。但上面咱們說過,Pod 可能會死掉,甚至 Pod 所在的 Node 也可能宕機,Kubernetes 會自動幫咱們從新建立新的Pod。再者每次更新服務的時候也會重建 Pod。而每一個 Pod 都有本身的 ip。因此 Pod 的ip 是不穩定的,會常常變化的,不可能每次ip變化都去修改一下負載均衡中的ip列表。
面對這種變化咱們就要藉助另外一個概念:Service。它就是來專門解決這個問題的。無論Deployment的Pod有多少個,無論它是更新、銷燬仍是重建,Service老是能發現並維護好它的ip列表。Service對外也提供了多種入口:
NodeIP:NodePort
。spec.externlName
設定)。好,看似服務訪問的問題解決了。但你們有沒有想過,Service是如何知道它負責哪些 Pod 呢?是如何跟蹤這些 Pod 變化的?
最容易想到的方法是使用 Deployment 的名字。一個 Service 對應一個 Deployment 。固然這樣確實能夠實現。但Kubernetes 使用了一個更加靈活、通用的設計 - Label 標籤,經過給 Pod 打標籤,Service 能夠只負責一個 Deployment 的 Pod 也能夠負責多個 Deployment 的 Pod 了。Deployment 和 Service 就能夠經過 Label 解耦了。
關於Kubernetes的認證與受權機制內容比較多也比較複雜,因此這裏引用一些文章做爲參考:
也能夠直接翻閱官方文檔: