Kubernetes權威指南(第2版)_第1頁
Kubernetes權威指南(第2版)_第2頁
Kubernetes權威指南(第2版)_第3頁
Kubernetes權威指南(第2版)_第4頁
Kubernetes權威指南(第2版)_第5頁
已閱讀5頁,還剩566頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

Kubernetes權威指南從Docker到Kubernetes實踐全接觸(第2版)目錄\h第1章Kubernetes入門\h1.1Kubernetes是什么\h1.2為什么要用Kubernetes\h1.3從一個簡單的例子開始\h1.3.1環(huán)境準備\h1.3.2啟動MySQL服務\h1.3.3啟動Tomcat應用\h1.3.4通過瀏覽器訪問網(wǎng)頁\h1.4Kubernetes基本概念和術語\h1.4.1Master\h1.4.2Node\h1.4.3Pod\h1.4.4Label(標簽)\h1.4.5ReplicationController(RC)\h1.4.6Deployment\h1.4.7HorizontalPodAutoscaler(HPA)\h1.4.8Service(服務)\h1.4.9Volume(存儲卷)\h1.4.10PersistentVolume\h1.4.11Namespace(命名空間)\h1.4.12Annotation(注解)\h1.4.13小結\h第2章Kubernetes實踐指南\h2.1Kubernetes安裝與配置\h2.1.1安裝Kubernetes\h2.1.2配置和啟動Kubernetes服務\h2.1.3Kubernetes集群的安全設置\h2.1.4Kubernetes的版本升級\h2.1.5內(nèi)網(wǎng)中的Kubernetes相關配置\h2.1.6Kubernetes核心服務配置詳解\h2.1.7Kubernetes集群網(wǎng)絡配置方案\h2.2kubectl命令行工具用法詳解\h2.2.1kubectl用法概述\h2.2.2kubectl子命令詳解\h2.2.3kubectl參數(shù)列表\h2.2.4kubectl輸出格式\h2.2.5kubectl操作示例\h2.3Guestbook示例:HelloWorld\h2.3.1創(chuàng)建redis-masterRC和Service\h2.3.2創(chuàng)建redis-slaveRC和Service\h2.3.3創(chuàng)建frontendRC和Service\h2.3.4通過瀏覽器訪問frontend頁面\h2.4深入掌握Pod\h2.4.1Pod定義詳解\h2.4.2Pod的基本用法\h2.4.3靜態(tài)Pod\h2.4.4Pod容器共享Volume\h2.4.5Pod的配置管理\h2.4.6Pod生命周期和重啟策略\h2.4.7Pod健康檢查\h2.4.8玩轉Pod調度\h2.4.9Pod的擴容和縮容\h2.4.10Pod的滾動升級\h2.5深入掌握Service\h2.5.1Service定義詳解\h2.5.2Service基本用法\h2.5.3集群外部訪問Pod或Service\h2.5.4DNS服務搭建指南\h2.5.5Ingress:HTTP7層路由機制\h第3章Kubernetes核心原理\h3.1KubernetesAPIServer原理分析\h3.1.1KubernetesAPIServer概述\h3.1.2獨特的KubernetesProxyAPI接口\h3.1.3集群功能模塊之間的通信\h3.2ControllerManager原理分析\h3.2.1ReplicationController\h3.2.2NodeController\h3.2.3ResourceQuotaController\h3.2.4NamespaceController\h3.2.5ServiceController與EndpointController\h3.3Scheduler原理分析\h3.4kubelet運行機制分析\h3.4.1節(jié)點管理\h3.4.2Pod管理\h3.4.3容器健康檢查\h3.4.4cAdvisor資源監(jiān)控\h3.5kube-proxy運行機制分析\h3.6深入分析集群安全機制\h3.6.1APIServer認證\h3.6.2APIServer授權\h3.6.3AdmissionControl準入控制\h3.6.4ServiceAccount\h3.6.5Secret私密憑據(jù)\h3.7網(wǎng)絡原理\h3.7.1Kubernetes網(wǎng)絡模型\h3.7.2Docker的網(wǎng)絡基礎\h3.7.3Docker的網(wǎng)絡實現(xiàn)\h3.7.4Kubernetes的網(wǎng)絡實現(xiàn)\h3.7.5開源的網(wǎng)絡組件\h3.7.6網(wǎng)絡實戰(zhàn)\h第4章Kubernetes開發(fā)指南\h4.1REST簡述\h4.2KubernetesAPI詳解\h4.2.1KubernetesAPI概述\h4.2.2API版本\h4.2.3API詳細說明\h4.2.4API響應說明\h4.3使用Java程序訪問KubernetesAPI\h4.3.1Jersey\h4.3.2Fabric8\h4.3.3使用說明\h第5章Kubernetes運維指南\h5.1Kubernetes集群管理指南\h5.1.1Node的管理\h5.1.2更新資源對象的Label\h5.1.3Namespace:集群環(huán)境共享與隔離\h5.1.4Kubernetes資源管理\h5.1.5Kubernetes集群高可用部署方案\h5.1.6Kubernetes集群監(jiān)控\h5.1.7kubelet的垃圾回收(GC)機制\h5.2Kubernetes高級案例\h5.2.1ElasticSearch日志搜集查詢和展現(xiàn)案例\h5.2.2Cassandra集群部署案例\h5.3TroubleShooting指導\h5.3.1查看系統(tǒng)Event事件\h5.3.2查看容器日志\h5.3.3查看Kubernetes服務日志\h5.3.4常見問題\h5.3.5尋求幫助\h5.4Kubernetesv1.3開發(fā)中的新功能\h5.4.1PetSet(有狀態(tài)的容器)\h5.4.2InitContainer(初始化容器)\h5.4.3ClusterFederation(集群聯(lián)邦)\h第6章Kubernetes源碼導讀\h6.1Kubernetes源碼結構和編譯步驟\h6.2kube-apiserver進程源碼分析\h6.2.1進程啟動過程\h6.2.2關鍵代碼分析\h6.2.3設計總結\h6.3kube-controller-manager進程源碼分析\h6.3.1進程啟動過程\h6.3.2關鍵代碼分析\h6.3.3設計總結\h6.4kube-scheduler進程源碼分析\h6.4.1進程啟動過程\h6.4.2關鍵代碼分析\h6.4.3設計總結\h6.5kubelet進程源碼分析\h6.5.1進程啟動過程\h6.5.2關鍵代碼分析\h6.5.3設計總結\h6.6kube-proxy進程源碼分析\h6.6.1進程啟動過程\h6.6.2關鍵代碼分析\h6.6.3設計總結\h6.7kubectl進程源碼分析\h6.7.1kubectlcreate命令\h6.7.2rolling-update命令第1章Kubernetes入門1.1Kubernetes是什么Kubernetes是什么?首先,它是一個全新的基于容器技術的分布式架構領先方案。這個方案雖然還很新,但它是谷歌十幾年以來大規(guī)模應用容器技術的經(jīng)驗積累和升華的一個重要成果。確切地說,Kubernetes是谷歌嚴格保密十幾年的秘密武器——Borg的一個開源版本。Borg是谷歌的一個久負盛名的內(nèi)部使用的大規(guī)模集群管理系統(tǒng),它基于容器技術,目的是實現(xiàn)資源管理的自動化,以及跨多個數(shù)據(jù)中心的資源利用率的最大化。十幾年來,谷歌一直通過Borg系統(tǒng)管理著數(shù)量龐大的應用程序集群。由于谷歌員工都簽署了保密協(xié)議,即便離職也不能泄露Borg的內(nèi)部設計,所以外界一直無法了解關于它的更多信息。直到2015年4月,傳聞許久的Borg論文伴隨Kubernetes的高調宣傳被谷歌首次公開,大家才得以了解它的更多內(nèi)幕。正是由于站在Borg這個前輩的肩膀上,吸取了Borg過去十年間的經(jīng)驗與教訓,所以Kubernetes一經(jīng)開源就一鳴驚人,并迅速稱霸了容器技術領域。其次,如果我們的系統(tǒng)設計遵循了Kubernetes的設計思想,那么傳統(tǒng)系統(tǒng)架構中那些和業(yè)務沒有多大關系的底層代碼或功能模塊,都可以立刻從我們的視線中消失,我們不必再費心于負載均衡器的選型和部署實施問題,不必再考慮引入或自己開發(fā)一個復雜的服務治理框架,不必再頭疼于服務監(jiān)控和故障處理模塊的開發(fā)??傊?,使用Kubernetes提供的解決方案,我們不僅節(jié)省了不少于30%的開發(fā)成本,同時可以將精力更加集中于業(yè)務本身,而且由于Kubernetes提供了強大的自動化機制,所以系統(tǒng)后期的運維難度和運維成本大幅度降低。然后,Kubernetes是一個開放的開發(fā)平臺。與J2EE不同,它不局限于任何一種語言,沒有限定任何編程接口,所以不論是用Java、Go、C++還是用Python編寫的服務,都可以毫無困難地映射為Kubernetes的Service,并通過標準的TCP通信協(xié)議進行交互。此外,由于Kubernetes平臺對現(xiàn)有的編程語言、編程框架、中間件沒有任何侵入性,因此現(xiàn)有的系統(tǒng)也很容易改造升級并遷移到Kubernetes平臺上。最后,Kubernetes是一個完備的分布式系統(tǒng)支撐平臺。Kubernetes具有完備的集群管理能力,包括多層次的安全防護和準入機制、多租戶應用支撐能力、透明的服務注冊和服務發(fā)現(xiàn)機制、內(nèi)建智能負載均衡器、強大的故障發(fā)現(xiàn)和自我修復能力、服務滾動升級和在線擴容能力、可擴展的資源自動調度機制,以及多粒度的資源配額管理能力。同時,Kubernetes提供了完善的管理工具,這些工具涵蓋了包括開發(fā)、部署測試、運維監(jiān)控在內(nèi)的各個環(huán)節(jié)。因此,Kubernetes是一個全新的基于容器技術的分布式架構解決方案,并且是一個一站式的完備的分布式系統(tǒng)開發(fā)和支撐平臺。在正式開始本章的HelloWorld之旅之前,我們首先要學習Kubernetes的一些基本知識,這樣我們才能理解Kubernetes提供的解決方案。在Kubernetes中,Service(服務)是分布式集群架構的核心,一個Service對象擁有如下關鍵特征。擁有一個唯一指定的名字(比如mysql-server)。擁有一個虛擬IP(ClusterIP、ServiceIP或VIP)和端口號。能夠提供某種遠程服務能力。被映射到了提供這種服務能力的一組容器應用上。Service的服務進程目前都基于Socket通信方式對外提供服務,比如Redis、Memcache、MySQL、WebServer,或者是實現(xiàn)了某個具體業(yè)務的一個特定的TCPServer進程。雖然一個Service通常由多個相關的服務進程來提供服務,每個服務進程都有一個獨立的Endpoint(IP+Port)訪問點,但Kubernetes能夠讓我們通過Service(虛擬ClusterIP+ServicePort)連接到指定的Service上。有了Kubernetes內(nèi)建的透明負載均衡和故障恢復機制,不管后端有多少服務進程,也不管某個服務進程是否會由于發(fā)生故障而重新部署到其他機器,都不會影響到我們對服務的正常調用。更重要的是這個Service本身一旦創(chuàng)建就不再變化,這意味著,在Kubernetes集群中,我們再也不用為了服務的IP地址變來變?nèi)サ膯栴}而頭疼了。容器提供了強大的隔離功能,所以有必要把為Service提供服務的這組進程放入容器中進行隔離。為此,Kubernetes設計了Pod對象,將每個服務進程包裝到相應的Pod中,使其成為Pod中運行的一個容器(Container)。為了建立Service和Pod間的關聯(lián)關系,Kubernetes首先給每個Pod貼上一個標簽(Label),給運行MySQL的Pod貼上name=mysql標簽,給運行PHP的Pod貼上name=php標簽,然后給相應的Service定義標簽選擇器(LabelSelector),比如MySQLService的標簽選擇器的選擇條件為name=mysql,意為該Service要作用于所有包含name=mysqlLabel的Pod上。這樣一來,就巧妙地解決了Service與Pod的關聯(lián)問題。說到Pod,我們這里先簡單介紹其概念。首先,Pod運行在一個我們稱之為節(jié)點(Node)的環(huán)境中,這個節(jié)點既可以是物理機,也可以是私有云或者公有云中的一個虛擬機,通常在一個節(jié)點上運行幾百個Pod;其次,每個Pod里運行著一個特殊的被稱之為Pause的容器,其他容器則為業(yè)務容器,這些業(yè)務容器共享Pause容器的網(wǎng)絡棧和Volume掛載卷,因此它們之間的通信和數(shù)據(jù)交換更為高效,在設計時我們可以充分利用這一特性將一組密切相關的服務進程放入同一個Pod中;最后,需要注意的是,并不是每個Pod和它里面運行的容器都能“映射”到一個Service上,只有那些提供服務(無論是對內(nèi)還是對外)的一組Pod才會被“映射”成一個服務。在集群管理方面,Kubernetes將集群中的機器劃分為一個Master節(jié)點和一群工作節(jié)點(Node)。其中,在Master節(jié)點上運行著集群管理相關的一組進程kube-apiserver、kube-controller-manager和kube-scheduler,這些進程實現(xiàn)了整個集群的資源管理、Pod調度、彈性伸縮、安全控制、系統(tǒng)監(jiān)控和糾錯等管理功能,并且都是全自動完成的。Node作為集群中的工作節(jié)點,運行真正的應用程序,在Node上Kubernetes管理的最小運行單元是Pod。Node上運行著Kubernetes的kubelet、kube-proxy服務進程,這些服務進程負責Pod的創(chuàng)建、啟動、監(jiān)控、重啟、銷毀,以及實現(xiàn)軟件模式的負載均衡器。最后,我們再來看看傳統(tǒng)的IT系統(tǒng)中服務擴容和服務升級這兩個難題,以及Kubernetes所提供的全新解決思路。服務的擴容涉及資源分配(選擇哪個節(jié)點進行擴容)、實例部署和啟動等環(huán)節(jié),在一個復雜的業(yè)務系統(tǒng)中,這兩個問題基本上靠人工一步步操作才得以完成,費時費力又難以保證實施質量。在Kubernetes集群中,你只需為需要擴容的Service關聯(lián)的Pod創(chuàng)建一個ReplicationController(簡稱RC),則該Service的擴容以至于后來的Service升級等頭疼問題都迎刃而解。在一個RC定義文件中包括以下3個關鍵信息。目標Pod的定義。目標Pod需要運行的副本數(shù)量(Replicas)。要監(jiān)控的目標Pod的標簽(Label)。在創(chuàng)建好RC(系統(tǒng)將自動創(chuàng)建好Pod)后,Kubernetes會通過RC中定義的Label篩選出對應的Pod實例并實時監(jiān)控其狀態(tài)和數(shù)量,如果實例數(shù)量少于定義的副本數(shù)量(Replicas),則會根據(jù)RC中定義的Pod模板來創(chuàng)建一個新的Pod,然后將此Pod調度到合適的Node上啟動運行,直到Pod實例的數(shù)量達到預定目標。這個過程完全是自動化的,無須人工干預。有了RC,服務的擴容就變成了一個純粹的簡單數(shù)字游戲了,只要修改RC中的副本數(shù)量即可。后續(xù)的Service升級也將通過修改RC來自動完成。以將在第2章介紹的PHP+Redis留言板應用為例,只要為PHP留言板程序(frontend)創(chuàng)建一個有3個副本的RC+Service,為Redis讀寫分離集群創(chuàng)建兩個RC:寫節(jié)點(redis-master)創(chuàng)建一個單副本的RC+Service,讀節(jié)點(redis-slaver)創(chuàng)建一個有兩個副本的RC+Service,就可以分分鐘完成整個集群的搭建過程了,是不是很簡單?1.2為什么要用Kubernetes使用Kubernetes的理由很多,最根本的一個理由就是:IT從來都是一個由新技術驅動的行業(yè)。Docker這個新興的容器化技術當前已經(jīng)被很多公司所采用,其從單機走向集群已成為必然,而云計算的蓬勃發(fā)展正在加速這一進程。Kubernetes作為當前唯一被業(yè)界廣泛認可和看好的Docker分布式系統(tǒng)解決方案,可以預見,在未來幾年內(nèi),會有大量的新系統(tǒng)選擇它,不管這些系統(tǒng)是運行在企業(yè)本地服務器上還是被托管到公有云上。使用了Kubernetes又會收獲哪些好處呢?首先,最直接的感受就是我們可以“輕裝上陣”地開發(fā)復雜系統(tǒng)了。以前動不動就需要十幾個人而且團隊里需要不少技術達人一起分工協(xié)作才能設計實現(xiàn)和運維的分布式系統(tǒng),在采用Kubernetes解決方案之后,只需一個精悍的小團隊就能輕松應對。在這個團隊里,一名架構師專注于系統(tǒng)中“服務組件”的提煉,幾名開發(fā)工程師專注于業(yè)務代碼的開發(fā),一名系統(tǒng)兼運維工程師負責Kubernetes的部署和運維,從此再也不用“996”了,這并不是因為我們少做了什么,而是因為Kubernetes已經(jīng)幫我們做了很多。其次,使用Kubernetes就是在全面擁抱微服務架構。微服務架構的核心是將一個巨大的單體應用分解為很多小的互相連接的微服務,一個微服務背后可能有多個實例副本在支撐,副本的數(shù)量可能會隨著系統(tǒng)的負荷變化而進行調整,內(nèi)嵌的負載均衡器在這里發(fā)揮了重要作用。微服務架構使得每個服務都可以由專門的開發(fā)團隊來開發(fā),開發(fā)者可以自由選擇開發(fā)技術,這對于大規(guī)模團隊來說很有價值,另外每個微服務獨立開發(fā)、升級、擴展,因此系統(tǒng)具備很高的穩(wěn)定性和快速迭代進化能力。谷歌、亞馬遜、eBay、NetFlix等眾多大型互聯(lián)網(wǎng)公司都采用了微服務架構,此次谷歌更是將微服務架構的基礎設施直接打包到Kubernetes解決方案中,讓我們有機會直接應用微服務架構解決復雜業(yè)務系統(tǒng)的架構問題。然后,我們的系統(tǒng)可以隨時隨地整體“搬遷”到公有云上。Kubernetes最初的目標就是運行在谷歌自家的公有云GCE中,未來會支持更多的公有云及基于OpenStack的私有云。同時,在Kubernetes的架構方案中,底層網(wǎng)絡的細節(jié)完全被屏蔽,基于服務的ClusterIP甚至都無須我們改變運行期的配置文件,就能將系統(tǒng)從物理機環(huán)境中無縫遷移到公有云中,或者在服務高峰期將部分服務對應的Pod副本放入公有云中以提升系統(tǒng)的吞吐量,不僅節(jié)省了公司的硬件投入,還大大改善了客戶體驗。我們所熟知的鐵道部的12306購票系統(tǒng),在春節(jié)高峰期就租用了阿里云進行分流。最后,Kubernetes系統(tǒng)架構具備了超強的橫向擴容能力。對于互聯(lián)網(wǎng)公司來說,用戶規(guī)模就等價于資產(chǎn),誰擁有更多的用戶,誰就能在競爭中勝出,因此超強的橫向擴容能力是互聯(lián)網(wǎng)業(yè)務系統(tǒng)的關鍵指標之一。不用修改代碼,一個Kubernetes集群即可從只包含幾個Node的小集群平滑擴展到擁有上百個Node的大規(guī)模集群,我們利用Kubernetes提供的工具,甚至可以在線完成集群擴容。只要我們的微服務設計得好,結合硬件或者公有云資源的線性增加,系統(tǒng)就能夠承受大量用戶并發(fā)訪問所帶來的巨大壓力。1.3從一個簡單的例子開始考慮到本書第1版中的PHP+Redis留言板的HelloWorld例子對于絕大多數(shù)剛接觸Kubernetes的人來說比較復雜,難以順利上手和實踐,所以我們在此將這個例子替換成一個簡單得多的JavaWeb應用,可以讓新手快速上手和實踐。此JavaWeb應用的結構比較簡單,是一個運行在Tomcat里的WebApp,如圖1.1所示,JSP頁面通過JDBC直接訪問MySQL數(shù)據(jù)庫并展示數(shù)據(jù)。為了演示和簡化的目的,只要程序正確連接到了數(shù)據(jù)庫上,它就會自動完成對應的Table的創(chuàng)建與初始化數(shù)據(jù)的準備工作。所以,當我們通過瀏覽器訪問此應用的時候,就會顯示一個表格的頁面,數(shù)據(jù)則來自數(shù)據(jù)庫。圖1.1JavaWeb應用的架構組成此應用需要啟動兩個容器:WebApp容器和MySQL容器,并且WebApp容器需要訪問MySQL容器。在Docker時代,假設我們在一個宿主機上啟動了這兩個容器,則我們需要把MySQL容器的IP地址通過環(huán)境變量的方式注入WebApp容器里;同時,需要將WebApp容器的8080端口映射到宿主機的8080端口,以便能在外部訪問。在本章的這個例子里,我們看看在Kubernetes時代是如何完成這個目標的。1.3.1環(huán)境準備首先,我們開始準備Kubernetes的安裝和相關鏡像下載,本書建議采用VirtualBox或者VMwareWorkstation在本機虛擬一個64位的CentOS7虛擬機作為學習環(huán)境,虛擬機采用NAT的網(wǎng)絡模式以便能夠連接外網(wǎng),然后按照以下步驟快速安裝Kubernetes。(1)關閉CentOS自帶的防火墻服務:#systemctldisablefirewalld

#systemctlstopfirewalld

(2)安裝etcd和Kubernetes軟件(會自動安裝Docker軟件):#yuminstall-yetcdkubernetes

(3)安裝好軟件后,修改兩個配置文件(其他配置文件使用系統(tǒng)默認的配置參數(shù)即可)。Docker配置文件為/etc/sysconfig/docker,其中OPTIONS的內(nèi)容設置為:OPTIONS='--selinux-enabled=false--insecure-registrygcr.io'

Kubernetesapiserver配置文件為/etc/kubernetes/apiserver,把--admission_control參數(shù)中的ServiceAccount刪除。(4)按順序啟動所有的服務:#systemctlstartetcd

#systemctlstartdocker

#systemctlstartkube-apiserver

#systemctlstartkube-controller-manager

#systemctlstartkube-scheduler

#systemctlstartkubelet

#systemctlstartkube-proxy

至此,一個單機版的Kubernetes集群環(huán)境就安裝啟動完成了。接下來,我們可以在這個單機版的Kubernetes集群中上手練習了。注:本書示例中的Docker鏡像下載地址為/u/kubeguide/。1.3.2啟動MySQL服務首先為MySQL服務創(chuàng)建一個RC定義文件:mysql-rc.yaml,下面給出了該文件的完整內(nèi)容和解釋,如圖1.2所示。圖1.2RC的定義和解說圖yaml定義文件中的kind屬性,用來表明此資源對象的類型,比如這里的值為“ReplicationController”,表示這是一個RC;spec一節(jié)中是RC的相關屬性定義,比如spec.selector是RC的Pod標簽(Label)選擇器,即監(jiān)控和管理擁有這些標簽的Pod實例,確保當前集群上始終有且僅有replicas個Pod實例在運行,這里我們設置replicas=1表示只能運行一個MySQLPod實例。當集群中運行的Pod數(shù)量小于replicas時,RC會根據(jù)spec.template一節(jié)中定義的Pod模板來生成一個新的Pod實例,spec.template.metadata.labels指定了該Pod的標簽,需要特別注意的是:這里的labels必須匹配之前的spec.selector,否則此RC每次創(chuàng)建了一個無法匹配Label的Pod,就會不停地嘗試創(chuàng)建新的Pod,最終陷入“只為他人做嫁衣”的悲慘世界中,永無翻身之時。創(chuàng)建好redis-master-controller.yaml文件以后,為了將它發(fā)布到Kubernetes集群中,我們在Master節(jié)點執(zhí)行命令:#kubectlcreate-fmysql-rc.yaml

replicationcontroller"mysql"created

接下來,我們用kubectl命令查看剛剛創(chuàng)建的RC:#kubectlgetrc

NAMEDESIREDCURRENTAGE

mysql117m

查看Pod的創(chuàng)建情況時,可以運行下面的命令:#kubectlgetpods

NAMEREADYSTATUSRESTARTSAGE

mysql-c95jc1/1Running09m

我們看到一個名為mysql-xxxxx的Pod實例,這是Kubernetes根據(jù)mysql這個RC的定義自動創(chuàng)建的Pod。由于Pod的調度和創(chuàng)建需要花費一定的時間,比如需要一定的時間來確定調度到哪個節(jié)點上,以及下載Pod里容器的鏡像需要一段時間,所以一開始我們看到Pod的狀態(tài)將顯示為Pending。當Pod成功創(chuàng)建完成以后,狀態(tài)最終會被更新為Running。我們通過dockerps指令查看正在運行的容器,發(fā)現(xiàn)提供MySQL服務的Pod容器已經(jīng)創(chuàng)建并正常運行了,此外,你會發(fā)現(xiàn)MySQLPod對應的容器還多創(chuàng)建了一個來自谷歌的pause容器,這就是Pod的“根容器”,詳見1.4.3節(jié)的說明。#dockerps|grepmysql

72ca992535b4mysql"docker-entrypoint.sh"12minutesagoUp12minutesk8s_mysql.86dc506e_mysql-c95jc_default_511d6705-5051-11e6-a9d8-000c29ed42c1_9f89d0b4

76c1790aad27gcr.io/google_containers/pause-amd64:3.0"/pause"12minutesagoUp12minutesk8s_POD.16b20365_mysql-c95jc_default_511d6705-5051-11e6-a9d8-000c29ed42c1_28520aba

最后,我們創(chuàng)建一個與之關聯(lián)的KubernetesService——MySQL的定義文件(文件名為mysql-svc.yaml),完整的內(nèi)容和解釋如圖1.3所示。圖1.3Service的定義和解說圖其中,是Service的服務名(ServiceName);port屬性則定義了Service的虛端口;spec.selector確定了哪些Pod副本(實例)對應到本服務。類似地,我們通過kubectlcreate命令創(chuàng)建Service對象。運行kubectl命令,創(chuàng)建service:#kubectlcreate-fmysql-svc.yaml

service"mysql"created

運行kubectl命令,可以查看到剛剛創(chuàng)建的service:#kubectlgetsvc

NAMECLUSTER-IPEXTERNAL-IPPORT(S)AGE

mysql43<none>3306/TCP48s

注意到MySQL服務被分配了一個值為43的ClusterIP地址,這是一個虛地址,隨后,Kubernetes集群中其他新創(chuàng)建的Pod就可以通過Service的ClusterIP+端口號6379來連接和訪問它了。在通常情況下,ClusterIP是在Service創(chuàng)建后由Kubernetes系統(tǒng)自動分配的,其他Pod無法預先知道某個Service的ClusterIP地址,因此需要一個服務發(fā)現(xiàn)機制來找到這個服務。為此,最初的時候,Kubernetes巧妙地使用了Linux環(huán)境變量(EnvironmentVariable)來解決這個問題,后面會詳細說明其機制?,F(xiàn)在我們只需知道,根據(jù)Service的唯一名字,容器可以從環(huán)境變量中獲取到Service對應的ClusterIP地址和端口,從而發(fā)起TCP/IP連接請求了。1.3.3啟動Tomcat應用上面我們定義和啟動了MySQL服務,接下來我們采用同樣的步驟,完成Tomcat應用的啟動過程。首先,創(chuàng)建對應的RC文件myweb-rc.yaml,內(nèi)容如下:kind:ReplicationController

metadata:

name:myweb

spec:

replicas:5

selector:

app:myweb

template:

metadata:

labels:

app:myweb

spec:

containers:

-name:myweb

image:kubeguide/tomcat-app:v1

ports:

-containerPort:8080

env:

-name:MYSQL_SERVICE_HOST

value:'mysql'

-name:MYSQL_SERVICE_PORT

value:'3306'

注意到上面RC對應的Tomcat容器里引用了MYSQL_SERVICE_HOST=mysql這個環(huán)境變量,而“mysql”恰好是我們之前定義的MySQL服務的服務名,運行下面的命令,完成RC的創(chuàng)建和驗證工作:#kubectlcreate-fmyweb-rc.yaml

replicationcontroller"myweb"created

#kubectlgetpods

NAMEREADYSTATUSRESTARTSAGE

mysql-c95jc1/1Running02h

myweb-g9pmm1/1Running03s

最后,創(chuàng)建對應的Service。以下是完整的yaml定義文件(myweb-svc.yaml):apiVersion:v1

kind:Service

metadata:

name:myweb

spec:

type:NodePort

ports:

-port:8080

nodePort:30001

selector:

app:myweb

注意type=NodePort和nodePort=30001的兩個屬性,表明此Service開啟了NodePort方式的外網(wǎng)訪問模式,在Kubernetes集群之外,比如在本機的瀏覽器里,可以通過30001這個端口訪問myweb(對應到8080的虛端口上)。運行kubectlcreate命令進行創(chuàng)建:#kubectlcreate-fmyweb-svc.yaml

Youhaveexposedyourserviceonanexternalportonallnodesinyour

cluster.Ifyouwanttoexposethisservicetotheexternalinternet,youmay

needtosetupfirewallrulesfortheserviceport(s)(tcp:30001)toservetraffic.

Seehttp://releases.k8s.io/release-1.3/docs/user-guide/services-firewalls.mdformoredetails.

service"myweb"created

我們看到上面有提示信息,意思是需要把30001這個端口在防火墻上打開,以便外部的訪問能穿過防火墻。運行kubectl命令,查看創(chuàng)建的Service:#kubectlgetservices

NAMECLUSTER-IPEXTERNAL-IPPORT(S)AGE

mysql43<none>3306/TCP44m

myweb15<nodes>8080/TCP4m

kubernetes<none>443/TCP16d

至此,我們的第1個Kubernetes例子搭建完成了,在下一節(jié)中我們驗證結果。1.3.4通過瀏覽器訪問網(wǎng)頁經(jīng)過上面的幾個步驟,我們終于成功實現(xiàn)了Kubernetes上第1個例子的部署搭建工作?,F(xiàn)在一起來見證成果吧,在你的筆記本上打開瀏覽器,輸入http://虛擬機IP:30001/demo/。比如虛機IP為31(可以通過#ipa命令進行查詢),在瀏覽器里輸入地址31:30001/demo/后,看到了如圖1.4所示的網(wǎng)頁界面,那么恭喜你,之前的努力沒有白費,順利闖關成功!圖1.4通過瀏覽器訪問Tomcat應用如果看不到這個網(wǎng)頁,那么可能有幾個原因:比如防火墻的問題,無法訪問30001端口,或者因為你是通過代理上網(wǎng)的,瀏覽器錯把虛擬機的IP地址當成遠程地址了??梢栽谔摂M機上直接運行curllocalhost:30001來驗證此端口是否能被訪問,如果還是不能訪問,那么這肯定不是機器的問題……接下來可以嘗試單擊“Add…”按鈕添加一條記錄并提交,如圖1.5所示,提交以后,數(shù)據(jù)就被寫入MySQL數(shù)據(jù)庫中了。至此,我們終于完成了Kubernetes上的Tomcat例子,這個例子并不是很復雜。我們也看到,相對于傳統(tǒng)的分布式應用的部署方式,在Kubernetes之上我們僅僅通過一些很容易理解的配置文件和相關的簡單命令就完成了對整個集群的部署,這讓我們驚詫于Kubernetes的創(chuàng)新和強大。圖1.5在留言板網(wǎng)頁添加新的留言下一節(jié),我們將開始對Kubernetes中的基本概念和術語進行全面學習,在這之前,讀者可以繼續(xù)研究下這個例子里的一些拓展內(nèi)容,如下所述。研究RC、Service等文件的格式。熟悉kubectl的子命令。手工停止某個Service對應的容器進程,然后觀察有什么現(xiàn)象發(fā)生。修改RC文件,改變副本數(shù)量,重新發(fā)布,觀察結果。1.4Kubernetes基本概念和術語Kubernetes中的大部分概念如Node、Pod、ReplicationController、Service等都可以看作一種“資源對象”,幾乎所有的資源對象都可以通過Kubernetes提供的kubectl工具(或者API編程調用)執(zhí)行增、刪、改、查等操作并將其保存在etcd中持久化存儲。從這個角度來看,Kubernetes其實是一個高度自動化的資源控制系統(tǒng),它通過跟蹤對比etcd庫里保存的“資源期望狀態(tài)”與當前環(huán)境中的“實際資源狀態(tài)”的差異來實現(xiàn)自動控制和自動糾錯的高級功能。1.4.1MasterKubernetes里的Master指的是集群控制節(jié)點,每個Kubernetes集群里需要有一個Master節(jié)點來負責整個集群的管理和控制,基本上Kubernetes所有的控制命令都是發(fā)給它,它來負責具體的執(zhí)行過程,我們后面所有執(zhí)行的命令基本都是在Master節(jié)點上運行的。Master節(jié)點通常會占據(jù)一個獨立的X86服務器(或者一個虛擬機),一個主要的原因是它太重要了,它是整個集群的“首腦”,如果它宕機或者不可用,那么我們所有的控制命令都將失效。Master節(jié)點上運行著以下一組關鍵進程。KubernetesAPIServer(kube-apiserver),提供了HTTPRest接口的關鍵服務進程,是Kubernetes里所有資源的增、刪、改、查等操作的唯一入口,也是集群控制的入口進程。KubernetesControllerManager(kube-controller-manager),Kubernetes里所有資源對象的自動化控制中心,可以理解為資源對象的“大總管”。KubernetesScheduler(kube-scheduler),負責資源調度(Pod調度)的進程,相當于公交公司的“調度室”。其實Master節(jié)點上往往還啟動了一個etcdServer進程,因為Kubernetes里的所有資源對象的數(shù)據(jù)全部是保存在etcd中的。1.4.2Node除了Master,Kubernetes集群中的其他機器被稱為Node節(jié)點,在較早的版本中也被稱為Minion。與Master一樣,Node節(jié)點可以是一臺物理主機,也可以是一臺虛擬機。Node節(jié)點才是Kubernetes集群中的工作負載節(jié)點,每個Node都會被Master分配一些工作負載(Docker容器),當某個Node宕機時,其上的工作負載會被Master自動轉移到其他節(jié)點上去。每個Node節(jié)點上都運行著以下一組關鍵進程。kubelet:負責Pod對應的容器的創(chuàng)建、啟停等任務,同時與Master節(jié)點密切協(xié)作,實現(xiàn)集群管理的基本功能。kube-proxy:實現(xiàn)KubernetesService的通信與負載均衡機制的重要組件。DockerEngine(docker):Docker引擎,負責本機的容器創(chuàng)建和管理工作。Node節(jié)點可以在運行期間動態(tài)增加到Kubernetes集群中,前提是這個節(jié)點上已經(jīng)正確安裝、配置和啟動了上述關鍵進程,在默認情況下kubelet會向Master注冊自己,這也是Kubernetes推薦的Node管理方式。一旦Node被納入集群管理范圍,kubelet進程就會定時向Master節(jié)點匯報自身的情報,例如操作系統(tǒng)、Docker版本、機器的CPU和內(nèi)存情況,以及之前有哪些Pod在運行等,這樣Master可以獲知每個Node的資源使用情況,并實現(xiàn)高效均衡的資源調度策略。而某個Node超過指定時間不上報信息時,會被Master判定為“失聯(lián)”,Node的狀態(tài)被標記為不可用(NotReady),隨后Master會觸發(fā)“工作負載大轉移”的自動流程。我們可以執(zhí)行下述命令查看集群中有多少個Node:#kubectlgetnodes

NAMESTATUSAGE

kubernetes-minion1Ready2d

然后,通過kubectldescribenode<node_name>來查看某個Node的詳細信息:$kubectldescribenodekubernetes-minion1

Name:k8s-node-1

Labels:beta.kubernetes.io/arch=amd64

beta.kubernetes.io/os=linux

kubernetes.io/hostname=k8s-node-1

Taints:<none>

CreationTimestamp:Wed,06Jul201611:46:41+0800

Phase:

Conditions:

TypeStatusLastHeartbeatTimexxxxOutOfDiskFalseSat,09Jul201608:17:39+0800Wed…..

MemoryPressureFalseSat,09Jul201608:17:39+0800Wed……

ReadyTrueSat,09Jul201608:17:39+0800Wed……

Addresses:31,31

Capacity:

alpha.kubernetes.io/nvidia-gpu:0

cpu:4

memory:1868692Ki

pods:110

Allocatable:

alpha.kubernetes.io/nvidia-gpu:0

cpu:4

memory:1868692Ki

pods:110

SystemInfo:

MachineID:6e4e2af2afeb42b9aac47d866aa56ca0

SystemUUID:564D63D3-9664-3393-A3DC-9CD424ED42C1

BootID:b0c34f9f-76ab-478e-9771-bd4fe6e98880

KernelVersion:3.10.0-327.22.2.el7.x86_64

OSImage:CentOSLinux7(Core)

OperatingSystem:linux

Architecture:amd64

ContainerRuntimeVersion:docker://1.11.2

KubeletVersion:v1.3.0

Kube-ProxyVersion:v1.3.0

ExternalID:k8s-node-1

Non-terminatedPods:(1intotal)

NamespaceNameCPURequestsCPULimitsMemoryxxx

--------------------------------------------------

kube-systemkube-dns-v11-wxdhf310m(7%)310m(7%)170Mi(9%)

Allocatedresources:

(Totallimitsmaybeover100percent,i.e.,overcommitted.Moreinfo:

CPURequestsCPULimitsMemoryRequestsMemoryLimits

--------------------------------------------------

310m(7%)310m(7%)170Mi(9%)170Mi(9%)

Noevents.

上述命令展示了Node的如下關鍵信息。Node基本信息:名稱、標簽、創(chuàng)建時間等。Node當前的運行狀態(tài),Node啟動以后會做一系列的自檢工作,比如磁盤是否滿了,如果滿了就標注OutOfDisk=True,否則繼續(xù)檢查內(nèi)存是否不足(MemoryPressure=True),最后一切正常,就切換為Ready狀態(tài)(Ready=True),這種情況表示Node處于健康狀態(tài),可以在其上創(chuàng)建新的Pod。Node的主機地址與主機名。Node上的資源總量:描述Node可用的系統(tǒng)資源,包括CPU、內(nèi)存數(shù)量、最大可調度Pod數(shù)量等,注意到目前Kubernetes已經(jīng)實驗性地支持GPU資源分配了(alpha.kubernetes.io/nvidia-gpu=0)。Node可分配資源量:描述Node當前可用于分配的資源量。主機系統(tǒng)信息:包括主機的唯一標識UUID、Linuxkernel版本號、操作系統(tǒng)類型與版本、Kubernetes版本號、kubelet與kube-proxy的版本號等。當前正在運行的Pod列表概要信息。已分配的資源使用概要信息,例如資源申請的最低、最大允許使用量占系統(tǒng)總量的百分比。Node相關的Event信息。1.4.3PodPod是Kubernetes的最重要也最基本的概念,如圖1.6所示是Pod的組成示意圖,我們看到每個Pod都有一個特殊的被稱為“根容器”的Pause容器。Pause容器對應的鏡像屬于Kubernetes平臺的一部分,除了Pause容器,每個Pod還包含一個或多個緊密相關的用戶業(yè)務容器。圖1.6Pod的組成與容器的關系為什么Kubernetes會設計出一個全新的Pod的概念并且Pod有這樣特殊的組成結構?原因之一:在一組容器作為一個單元的情況下,我們難以對“整體”簡單地進行判斷及有效地進行行動。比如,一個容器死亡了,此時算是整體死亡么?是N/M的死亡率么?引入業(yè)務無關并且不易死亡的Pause容器作為Pod的根容器,以它的狀態(tài)代表整個容器組的狀態(tài),就簡單、巧妙地解決了這個難題。原因之二:Pod里的多個業(yè)務容器共享Pause容器的IP,共享Pause容器掛接的Volume,這樣既簡化了密切關聯(lián)的業(yè)務容器之間的通信問題,也很好地解決了它們之間的文件共享問題。Kubernetes為每個Pod都分配了唯一的IP地址,稱之為PodIP,一個Pod里的多個容器共享PodIP地址。Kubernetes要求底層網(wǎng)絡支持集群內(nèi)任意兩個Pod之間的TCP/IP直接通信,這通常采用虛擬二層網(wǎng)絡技術來實現(xiàn),例如Flannel、Openvswitch等,因此我們需要牢記一點:在Kubernetes里,一個Pod里的容器與另外主機上的Pod容器能夠直接通信。Pod其實有兩種類型:普通的Pod及靜態(tài)Pod(staticPod),后者比較特殊,它并不存放在Kubernetes的etcd存儲里,而是存放在某個具體的Node上的一個具體文件中,并且只在此Node上啟動運行。而普通的Pod一旦被創(chuàng)建,就會被放入到etcd中存儲,隨后會被KubernetesMaster調度到某個具體的Node上并進行綁定(Binding),隨后該Pod被對應的Node上的kubelet進程實例化成一組相關的Docker容器并啟動起來。在默認情況下,當Pod里的某個容器停止時,Kubernetes會自動檢測到這個問題并且重新啟動這個Pod(重啟Pod里的所有容器),如果Pod所在的Node宕機,則會將這個Node上的所有Pod重新調度到其他節(jié)點上。Pod、容器與Node的關系如圖1.7所示。圖1.7Pod、容器與Node的關系Kubernetes里的所有資源對象都可以采用yaml或者JSON格式的文件來定義或描述,下面是我們在之前HelloWorld例子里用到的myweb這個Pod的資源定義文件:apiVersion:v1

kind:Pod

metadata:

name:myweb

labels:

name:myweb

spec:

containers:

-name:myweb

image:kubeguide/tomcat-app:v1

ports:

-containerPort:8080

env:

-name:MYSQL_SERVICE_HOST

value:'mysql'

-name:MYSQL_SERVICE_PORT

value:'3306'

Kind為Pod表明這是一個Pod的定義,metadata里的name屬性為Pod的名字,metadata里還能定義資源對象的標簽(Label),這里聲明myweb擁有一個name=myweb的標簽(Label)。Pod里所包含的容器組的定義則在spec一節(jié)中聲明,這里定義了一個名字為myweb、對應鏡像為kubeguide/tomcat-app:v1的容器,該容器注入了名為MYSQL_SERVICE_HOST=‘mysql’和MYSQL_SERVICE_PORT=‘3306’的環(huán)境變量(env關鍵字),并且在8080端口(containerPort)上啟動容器進程。Pod的IP加上這里的容器端口(containerPort),就組成了一個新的概念——Endpoint,它代表著此Pod里的一個服務進程的對外通信地址。一個Pod也存在著具有多個Endpoint的情況,比如當我們把Tomcat定義為一個Pod的時候,可以對外暴露管理端口與服務端口這兩個Endpoint。我們所熟悉的DockerVolume在Kubernetes里也有對應的概念——PodVolume,后者有一些擴展,比如可以用分布式文件系統(tǒng)GlusterFS實現(xiàn)后端存儲功能;PodVolume是定義在Pod之上,然后被各個容器掛載到自己的文件系統(tǒng)中的。這里順便提一下Kubernetes的Event概念,Event是一個事件的記錄,記錄了事件的最早產(chǎn)生時間、最后重現(xiàn)時間、重復次數(shù)、發(fā)起者、類型,以及導致此事件的原因等眾多信息。Event通常會關聯(lián)到某個具體的資源對象上,是排查故障的重要參考信息,之前我們看到Node的描述信息包括了Event,而Pod同樣有Event記錄,當我們發(fā)現(xiàn)某個Pod遲遲無法創(chuàng)建時,可以用kubectldescribepodxxxx來查看它的描述信息,用來定位問題的原因,比如下面這個Event記錄信息表明Pod里的一個容器被探針檢測為失敗一次:Events:

FirstSeenLastSeenCountFromSubobjectPathTypeReasonMessage

------------------------------------------------------------

10h12m32{kubeletk8s-node-1}spec.containers{kube2sky}WarningUnhealthyLivenessprobefailed:Get:8080/healthz:net/http:requestcanceled(Client.Timeoutexceededwhileawaitingheaders)

每個Pod都可以對其能使用的服務器上的計算資源設置限額,當前可以設置限額的計算資源有CPU與Memory兩種,其中CPU的資源單位為CPU(Core)的數(shù)量,是一個絕對值而非相對值。一個CPU的配額對于絕大多數(shù)容器來說是相當大的一個資源配額了,所以,在Kubernetes里,通常以千分之一的CPU配額為最小單位,用m來表示。通常一個容器的CPU配額被定義為100~300m,即占用0.1~0.3個CPU。由于CPU配額是一個絕對值,所以無論在擁有一個Core的機器上,還是在擁有48個Core的機器上,100m這個配額所代表的CPU的使用量都是一樣的。與CPU配額類似,Memory配額也是一個絕對值,它的單位是內(nèi)存字節(jié)數(shù)。在Kubernetes里,一個計算資源進行配額限定需要設定以下兩個參數(shù)。Requests:該資源的最小申請量,系統(tǒng)必須滿足要求。Limits:該資源最大允許使用的量,不能被突破,當容器試圖使用超過這個量的資源時,可能會被KubernetesKill并重啟。通常我們會把Request設置為一個比較小的數(shù)值,符合容器平時的工作負載情況下的資源需求,而把Limit設置為峰值負載情況下資源占用的最大量。比如下面這段定義,表明MySQL容器申請最少0.25個CPU及64MiB內(nèi)存,在運行過程中MySQL容器所能使用的資源配額為0.5個CPU及128MiB內(nèi)存:spec:

containers:

-name:db

image:mysql

resources:

requests:

memory:"64Mi"

cpu:"250m"

limits:

memory:"128Mi"

cpu:"500m"

本節(jié)最后,筆者給出Pod及Pod周邊對象的示意圖作為總結,如圖1.8所示,后面部分還會涉及這張圖里的對象和概念,以進一步加強理解。圖1.8Pod及周邊對象1.4.4Label(標簽)Label是Kubernetes系統(tǒng)中另外一個核心概念。一個Label是一個key=value的鍵值對,其中key與value由用戶自己指定。Label可以附加到各種資源對象上,例如Node、Pod、Service、RC等,一個資源對象可以定義任意數(shù)量的Label,同一個Label也可以被添加到任意數(shù)量的資源對象上去,Label通常在資源對象定義時確定,也可以在對象創(chuàng)建后動態(tài)添加或者刪除。我們可以通過給指定的資源對象捆綁一個或多個不同的Label來實現(xiàn)多維度的資源分組管理功能,以便于靈活、方便地進行資源分配、調度、配置、部署等管理工作。例如:部署不同版本的應用到不同的環(huán)境中;或者監(jiān)控和分析應用(日志記錄、監(jiān)控、告警)等。一些常用的Label示例如下。版本標簽:“release”:“stable”,“release”:“canary”...環(huán)境標簽:“environment”:“dev”,“environment”:“qa”,“environment”:“production”架構標簽:“tier”:“frontend”,“tier”:“backend”,“tier”:“middleware”分區(qū)標簽:“partition”:“customerA”,“partition”:“customerB”...質量管控標簽:“track”:“daily”,“track”:“weekly”Label相當于我們熟悉的“標簽”,給某個資源對象定義一個Label,就相當于給它打了一個標簽,隨后可以通過LabelSelector(標簽選擇器)查詢和篩選擁有某些Label的資源對象,Kubernetes通過這種方式實現(xiàn)了類似SQL的簡單又通用的對象查詢機制。LabelSelector可以被類比為SQL語句中的where查詢條件,例如,name=redis-slave這個LabelSelector作用于Pod時,可以被類比為select*frompodwherepod’sname=‘redis-slave’這樣的語句。當前有兩種LabelSelector的表達式:基于等式的(Equality-based)和基于集合的(Set-based),前者采用“等式類”的表達式匹配標簽,下面是一些具體的例子。name=redis-slave:匹配所有具有標簽name=redis-slave的資源對象。env!=production:匹配所有不具有標簽env=production的資源對象,比如env=test就是滿足此條件的標簽之一。而后者則使用集合操作的表達式匹配標簽,下面是一些具體的例子。namein(redis-master,redis-slave):匹配所有具有標簽name=redis-master或者name=redis-slave的資源對象。namenotin(php-frontend):匹配所有不具有標簽name=php-frontend的資源對象??梢酝ㄟ^多個LabelSelector表達式的組合實現(xiàn)復雜的條件選擇,多個表達式之間用“,”進行分隔即可,幾個條件之間是“AND”的關系,即同時滿足多個條件,比如下面的例子:name=redis-slave,env!=production

namenotin(php-frontend),env!=production

LabelSelector在Kubernetes中的重要使用場景有以下幾處。kube-controller進程通過資源對象RC上定義的LabelSelector來篩選要監(jiān)控的Pod副本的數(shù)量,從而實現(xiàn)Pod副本的數(shù)量始終符合預期設定的全自動控制流程。kube-proxy進程通過Service的LabelSelector來選擇對應的Pod,自動建立起每個Service到對應Pod的請求轉發(fā)路由表,從而實現(xiàn)Service的智能負載均衡機制。通過對某些Node定義特定的Label,并且在Pod定義文件中使用NodeSelector這種標簽調度策略,kube-scheduler進程可以實現(xiàn)Pod“定向調度”的特性。在前面的留言板例子中,我們只使用了一個name=XXX的LabelSelector。讓我們看一個更復雜的例子。假設為Pod定義了3個Label:release、env和role,不同的Pod定義了不同的Label值,如圖1.9所示,如果我們設置了“role=frontend”的LabelSelector,則會選取到Node1和Node2上的Pod。而設置“release=beta”的LabelSelector,則會選取到Node2和Node3上的Pod,如圖1.10所示。圖1.9LabelSelector的作用范圍1圖1.10LabelSelector的作用范圍2總結:使用Label可以給對象創(chuàng)建多組標簽,Label和LabelSelector共同構成了Kubernetes系統(tǒng)中最核心的應用模型,使得被管理對象能夠被精細地分組管理,同時實現(xiàn)了整個集群的高可用性。1.4.5ReplicationController(RC)之前已經(jīng)對ReplicationController(以后簡稱RC)的定義和作用做了一些說明,本節(jié)對RC的概念進行深入描述。RC是Kubernetes系統(tǒng)中的核心概念之一,簡單來說,它其實是定義了一個期望的場景,即聲明某種Pod的副本數(shù)量在任意時刻都符合某個預期值,所以RC的定義包括如下幾個部分。Pod期待的副本數(shù)(replicas)。用于篩選目標Pod的LabelSelector。當Pod的副本數(shù)量小于預期數(shù)量的時候,用于創(chuàng)建新Pod的Pod模板(template)。下面是一個完整的RC定義的例子,即確保擁有tier=frontend標簽的這個Pod(運行Tomcat容器)在整個Kubernetes集群中始終只有一個副本。apiVersion:v1

kind:ReplicationController

metadata:

name:frontend

spec:

replicas:1

selector:

tier:frontend

template:

metadata:

labels:

app:app-demo

tier:frontend

spec:

containers:

-name:tomcat-demo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論