條分縷析帶你充分理解Kubernetes的各個細節與部分:它是什麼,它如何解決容器編排問題,它包含哪些你必須掌握的關鍵對象,以及如何快速上手部署使用Kubernetes。前端
容器的好處不勝枚舉:一致的運行時環境、節省磁盤空間、低開銷、良好的隔離性,等等。瞭解完這些優點,您以及您的同事可能都開始躍躍欲試要把應用程序打包到容器中並準備運行它。而後忽然之間或許您會發現,容器運行起來以後有一些問題也接踵而來,您須要一種方法來管理全部正在運行的容器及其生命週期:它們如何相互鏈接,它們應該運行在什麼硬件之上,它們如何獲取數據存儲,容器因各類緣由中止運行的話您該如何處理錯誤······nginx
這就是Kubernetes大顯身手的地方了。後端
在本文中,咱們將瞭解Kubernetes是什麼,它如何解決容器編排問題,它背後是由哪些理論支撐,如何將該理論直接與實際操做綁定,最終幫助您充分理解Kubernetes的各個細節與部分。設計模式
Kubernetes: 歷史瀏覽器
Kubernetes,也被稱爲k8s(k... 8個字母...和s)或kube,是希臘語中的單詞,意爲州長、舵手或船長。拿真正的航海的情景來理解,大型船舶裝載着大量現實生活的容器,而船長或舵手則是負責船舶的人。所以,在信息技術的語境下,Kubernetes就是Docker容器的船長、編排者。安全
Kubernetes最初是谷歌公司在內部使用的,基於谷歌運行容器15年的經驗,Kubernetes於2014年開始做爲Google的開源項目提供給社區。四年過去,Kubernetes飛速發展,下載及使用量驚人,被大量的中小型企業用戶用於開發或生產環境,並已成爲業界公認的容器編排管理的標準框架。網絡
Kubernetes的發展勢頭架構
Kubernetes的增加態勢驚人,在GitHub上擁有超過40,000顆星,在2018年擁有超過60,000個commit,而且比GitHub上的任何其餘項目都有更多的pull request和issue。其增加背後的部分緣由是其不凡的可擴展性和強大的設計模式,這些咱們將在後文中進一步解讀。您能夠在此連接瞭解一些大型軟件公司的Kubernetes應用案例:負載均衡
https://kubernetes.io/case-studies/框架
Kubernetes提供的服務
讓咱們來看看是什麼功能及特性讓Kubernetes吸引到業界的如此關注。
Kubernetes的核心是以容器爲中心的管理環境。它表明用戶的工做負載來編排計算、網絡和存儲基礎架構。這提供了平臺即服務(PaaS)的簡單性和基礎架構即服務(IaaS)的靈活性,並實現了跨基礎架構提供商的可移植性。Kubernetes不只僅是一個編排系統。實際上,它讓用戶再也不須要「編排」。「編排」的技術定義是「執行定義的工做流程」:首先執行A,而後運行B,而後運行C。而有了Kubernetes以後,Kubernetes由一組獨立的、可組合的控制流程組成,這些流程可將當前狀態持續推向所需狀態。而你是如何從A進行到C的,在此可有可無。並且,用戶也再也不須要集中控制,整個系統也變得更易於使用、功能更強大、可擴展性更佳。
Kubernetes的基本概念
要使用Kubernetes,您可使用Kubernetes API對象來描述集羣的所需狀態:您想要運行的應用程序或服務,它們使用的容器鏡像、副本數量,您但願提供的網絡和磁盤資源等等。您能夠經過使用Kubernetes API——kubectl(一般經過命令行界面)建立對象來設置所需的狀態。您還能夠直接使用Kubernetes API與集羣交互,並設置或修改所需的狀態。
設置完所需狀態後,Kubernetes控制面板會讓集羣的當前狀態與所需狀態相匹配。爲此,Kubernetes會自動執行各類任務,例如啓動或從新啓動容器、擴展給定應用程序的副本數量等等。
基本的Kubernetes對象包括: - 節點 - Pod - 服務 - 卷 - 命名空間
此外,Kubernetes包含許多稱爲controller的高級抽象。controller基於基本對象構建,並提供其餘功能和便利的特性。它們包括:
ReplicaSet
Deployment
StatefulSet
DaemonSet
Job
下文中咱們會逐個介紹這些概念,而後再嘗試一些動手練習。
節 點
節點( Node)是Kubernetes中的worker machine,之前稱爲minion。節點能夠是虛擬機(VM)或物理機(具體取決於集羣)。每一個節點都包含運行pod所需的服務,並由主組件管理。你能夠這樣理解節點:節點對於pod就像是Hypervisor對於虛擬機。
Pod
Pod是Kubernetes的基本構建塊,它是您建立或部署的Kubernetes對象模型中最小和最簡單的單元。一個Pod表明着一個部署單元:Kubernetes中的單個應用程序實例,可能包含單個容器或少許緊密組合並共享資源的容器。
Docker是Kubernetes Pod中最經常使用的容器運行時,但Pods也支持其餘容器運行時。
Kubernetes集羣中的Pod主要以兩種方式使用:第一種是運行單個容器的Pod 。「one-container-per-Pod」模式是最多見的Kubernetes用例; 在這種狀況下,您能夠將Pod視爲單個容器的打包,由Kubernetes而非容器來管理 Pods。第二種是運行多個須要協同工做的容器的Pod。一個Pod可能包含了一個應用程序,這個應用程序是由多個緊密耦合而且須要共享資源的容器組成的。這些共存的容器可能造成一個單一的內聚服務單元——一個容器負責從共享卷將文件公開,而另外一個單獨的「sidecar」容器負責刷新或更新這些文件。該Pod 將這些容器和存儲資源一塊兒封裝爲一個可管理的實體。
Pod爲其組成容器提供兩種共享資源:網絡和存儲。
網絡:每一個Pod都分配了一個惟一的IP地址。一個Pod中的全部容器都共享網絡命名空間,包括IP地址和網絡端口。Pod內的容器可使用localhost相互通訊。當Pod內的容器與Pod外的實體通訊時,它們必須協調如何使用共享網絡資源(例如端口)。
存儲:Pod能夠指定一組共享存儲卷。Pod中的全部容器均可以訪問共享卷,容許這些容器共享數據。若是須要從新啓動其中一個容器,卷還可讓Pod中的持久數據一直保存着。
服 務
Kubernetes Pods不是不變的,它們被建立又被殺死後並不會重生。即便每一個Pod都有本身的IP地址,你也不能徹底期望它會隨着時間推移卻永不改變。這會產生一個問題,若是一組Pods(好比說後端)爲Kubernetes集羣中的另外一組Pods(好比說前端)提供了功能,那些前端pod如何可以與後端pod保持可靠的通訊?
這就是服務發揮做用的地方。
Kubernetes服務定義了一個邏輯集Pods和訪問它們的策略(有時稱爲微服務),一般由Label Selector肯定。
例如,若是你有一個帶有3個Pod的後端應用程序,那些pod是可替代的,前端並不關心它們使用哪一個後端。雖然Pods組成後端集的實際狀況可能會發生變化,但前端客戶端不該該知道這一點,也不須要跟蹤後端列表自己。該Service抽象可實現這種分離。
對那些處於一樣的Kubernetes集羣中的應用,Kubernetes提供了一個簡單的Endpoints API,每當服務中的一套Pods改變時,API就會相應地更新。對於集羣外的應用程序,Kubernetes提供基於虛擬IP的橋接器,Services可將其重定向到後端Pods。
卷
容器中的磁盤文件是否是永久的,這會給運行在容器中的應用程序帶來一些問題。首先,當容器崩潰時,它將由Kubernetes從新啓動,但文件會丟失,由於容器老是以乾淨狀態啓動的。其次,當在一個pod中運行多個容器時,一般須要在這些容器之間共享文件。Kubernetes Volume就是來解決這兩個問題的。
從本質上講,卷只是一個目錄,可能包含一些數據,在Pod中,它能夠訪問容器。該目錄是如何造成的、支持它的介質是什麼以及它的內容,是由所使用的特定卷類型決定的。
Kubernetes卷具備明確的生命週期,與建立它的Pod的生命週期相同。總而言之,一個卷超過了在Pod中運行的任何容器,而且在容器重啓時保留了數據。一般,當一個Pod再也不存在時,卷也將不復存在。Kubernetes支持多種類型的卷,而且Pod能夠同時使用任意數量的卷。
命名空間
Kubernetes支持由同一物理集羣支持的多個虛擬集羣。這些虛擬集羣稱爲命名空間。
命名空間提供了名稱範圍。在一個命名空間內,每一個資源名稱都須要是惟一的,不過跨命名空間時就沒有這種要求了。
沒有必要只是爲了分離略有不一樣的資源而使用多個命名空間,好比說同一軟件的不一樣版本:能夠用標籤來區分同一命名空間內的不一樣資源。
ReplicaSet
ReplicaSet確保一次運行指定數量的pod副本。換句話說,ReplicaSet確保pod或同類pod組始終可用。可是,Deployment是一個更高級別的概念,它能夠管理ReplicaSets,併爲Pods提供聲明性更新以及許多其餘有用的功能。所以,除非您須要自定義更新編排或根本不須要更新,不然我建議您使用Deployments而不是直接使用ReplicaSets。
這實際上意味着您可能永遠不須要直接操縱ReplicaSet對象,而是可使用Deployment做爲替代。
Deployment
Deployment controller爲Pods和ReplicaSets提供聲明性更新。
您在Deployment對象中描述了所需狀態,Deployment controller就將以受控速率將現階段實際狀態更改成所需狀態。您能夠定義Deployments來建立新的ReplicaSets,或刪除現有的Deployments並使用新的Deployments來使用全部資源。
StatefulSets
StatefulSet用於管理有狀態應用程序,它管理一組Pods的部署和擴展,並提供有關這些Pod 的排序和惟一性的保證。
StatefulSet的運行模式和controller相同。您能夠在StatefulSet對象中定義所需的狀態,StatefulSet controller就會進行各類必要的更新以從當前狀態到達更新爲所需狀態。和Deployment相似,StatefulSet管理那些基於相同容器規範的Pods。與Deployment不一樣的是,StatefulSet爲每一個Pods保留一個粘性身份。這些Pods是根據相同的規範建立的,但不可互換:每一個都有一個永久的標識符,不論如何從新調度,這個標識都保持不變。
DaemonSet
DaemonSet確保全部(或某些)節點運行Pod的副本。隨着節點添加到羣集中,Pod會隨之添加。當將節點從集羣中刪除後,Pods就成爲了垃圾。此時,刪除一個DaemonSet就將清理它所建立的Pods。
DaemonSet的一些典型用途有:
在每一個節點上運行集羣存儲daemon,例如glusterd、ceph。
在每一個節點上運行日誌收集daemon,例如fluentd或logstash。
在每一個節點上運行節點監控daemon,例如Prometheus Node Exporter或collectd。
Job
job建立一個或多個pod,並確保在須要的時候成功終止指定數量的pod。Pods成功完成後,job會追蹤順利完成的狀況。當達到指定數量時,job自己的任務就完成了。刪除Job將清除它所建立的Pods。
一個簡單的例子是建立一個Job對象,以即可靠地運行一個對象Pod。若是第一個Pod失敗或被刪除(例如因爲節點硬件故障或節點重啓),那麼該Job對象將啓動一個新Pod。
實際操做中的挑戰
如今您已經瞭解了Kubernetes中的關鍵對象及概念了,很明顯,想要玩轉Kubernetes須要瞭解大量的信息。當你嘗試使用Kubernetes時,可能會遇到以下挑戰:
如何在不一樣的基礎架構中一致地部署?
如何跨多個集羣(和名稱空間)實現和管理訪問控制?
如何與中央身份驗證系統集成?
如何分區集羣以更有效地使用資源?
如何管理多租戶、多個專用和共享集羣?
如何建立高可用集羣?
如何跨集羣/命名空間實施安全策略?
如何良好地進行監控,以確保有足夠的可見性來檢測和解決問題?
如何跟上Kubernetes快速發展的步伐?
這就是Rancher能夠幫助您的地方。Rancher是一個100%開源的容器管理平臺,用於在生產中運行Kubernetes。經過Rancher,你能夠:
擁有易於使用的kubernetes配置和部署界面;
跨多個集羣和雲的基礎架構管理;
自動部署最新的kubernetes版本;
工做負載、RBAC、政策和項目管理;
24x7企業級支持。
Rancher能夠成爲一個單一控制點,而您能夠在多種、多個基礎架構上運行多個Kubernetes集羣:
上手Rancher和Kubernetes
如今讓咱們看看如何在Rancher的幫助下輕鬆使用前文描述的Kubernetes對象。首先,您須要一個Rancher實例。按照本指南,在幾分鐘以內便可啓動一個Rancher實例並使用它建立一個Kubernetes集羣:
https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/deployment/quickstart-manual-setup/
啓動集羣后,您應該在Rancher中看到Kubernetes集羣的資源:
要從第一個Kubernetes對象——節點開始,請單擊頂部菜單上的Nodes。你應該能夠組成了你的Kubernetes集羣的Nodes的總體狀況:
在那裏,您還能夠看到已從Kubernetes集羣部署到每一個節點的pod的數量。這些pod由Kubernetes和Rancher內部系統使用。一般狀況下你不須要處理那些。
下面讓咱們繼續Pod的例子。要作到這一點,轉到Kubernetes集羣的Default項目,而後進入Workloads選項卡。下面讓咱們部署一個工做負載。點擊Deploy並將Name和Docker image設置爲nginx,剩下的一切都使用默認值,而後點擊Launch。
建立後,Workloads選項卡會顯示nginx工做負載。
若是單擊nginx工做負載,您將會看到Rancher實際建立了一個Deployment,就像Kubernetes推薦的那樣用來管理ReplicaSet,您還將看到該ReplicaSet建立的Pod:
如今你有一個Deployment,它將確保咱們所需的狀態在集羣中正確顯示。如今,點擊Scale附近+號,將此Workload擴容到3。一旦你這樣作,你應該能當即看到另外2個Pods被建立出來,另外還多了2個ReplicaSet來縮放事件。使用Pod右側菜單,嘗試刪除其中一個pod,並注意ReplicaSet是如何從新建立它以匹配所需狀態的。
如今,您的應用程序已啓動並運行,而且已經擴展到3個實例。下一個問題是,您如何訪問它?在這裏,咱們將嘗試使用下一個Kubernetes對象——服務。爲了暴露咱們的nginx工做負載,咱們須要先編輯它,從Workload右側菜單中選擇Edit。您將看到Deploy Workload頁面,且已填好了您的nginx工做負載的詳細信息:
請注意,如今您有3個pod在Scalable Deployment旁邊,可是當您啓動時,默認值爲1。這是由於你的擴展工做剛完成不久。
如今單擊Add Port,並按以下所示填充值:
將Publish the container port值設置爲80;
Protocol仍爲TCP;
將As a值設置爲Layer-4 Load Balancer;
將On listening port值設置爲80。
而後自信地點擊Upgrade吧!這將在您的雲提供商中建立一個外部負載均衡器,並將流量引至您的Kubernetes集羣內的nginx Pods中。要對此進行測試,請再次訪問nginx工做負載概述頁面,如今您應該看到Endpoints旁的80/tcp連接:
若是點擊80/tcp,它會導向您剛剛建立的負載均衡器的外部IP,而且向您展現一個默認的nginx頁面,確認一切都按預期正常工做。
至此,你已經搞定了上半篇文章中介紹的大多數Kubernetes對象。你能夠在Rancher中好好玩玩卷和命名空間,相信您必定能很快掌握如何經過Rancher更簡單快捷地使用它們。至於StatefulSet、DaemonSet和Job,它們和Deployments很是相似,你一樣能夠在Workloads選項卡中經過選擇Workload type來建立它們。
結 語
讓咱們回顧一下你在上面的動手練習中所作的一切。你已經建立了咱們描述的大多數Kubernetes對象:
一、最開始,你在Rancher中建立了kubernetes集羣;
二、而後你瀏覽了集羣的Nodes;
三、你創造了一個Workload;
四、你已經看到了一個Workload實際上建立了3個獨立的Kubernetes對象:一個Deployment管理着 ReplicaSet,同時按需保持着所需數量的Pods正常運行;
五、在那以後你擴展了你的Deployment數量,並觀察它是如何改變了ReplicaSet並相應地擴展Pods的數量的;
六、最後你建立了一個Load Balancer類型的Service類型,用於平衡Pods之間的客戶端請求。
全部這些均可以經過Rancher輕鬆完成,您只需進行一些點擊的操做,無需在本地安裝任何軟件來複制身份驗證配置或在終端中運行命令行。您只需一個瀏覽器,玩轉Kubernetes唾手可得。