在集群環(huán)境中運(yùn)行Docker,需要解決和容器管理相關(guān)的很多問題,例如調(diào)度,生命周期及監(jiān)控狀態(tài),服務(wù)發(fā)現(xiàn),監(jiān)控,認(rèn)證,容器聚合等。之所以要使用Kubernetes,就是為了解決Docker所無法解決的問題。Kubernetes是在集群中多個主機(jī)間管理容器化應(yīng)用的開源系統(tǒng),可以讓部署容器化或者以微服務(wù)為基礎(chǔ)的架構(gòu)的應(yīng)用變得簡單易行,Kubernetes是輕量級的簡單的系統(tǒng),可以在公有云,私有云以及混合云中部署。
其具有模塊化,可插拔化,可掛接化以及可組合化等特點(diǎn)。Kubernetes提供了容器的自動恢復(fù),自動重啟以及自動復(fù)制功能,在Kubernetes架構(gòu)中,Master作為管理節(jié)點(diǎn)發(fā)揮作用,所有的用戶可以將不同的容器和應(yīng)用通過Master節(jié)點(diǎn)部署到不同的工作節(jié)點(diǎn)上,Kubernetes在不同的工作節(jié)點(diǎn)上打包或者調(diào)用具體的應(yīng)用,使用Kubectl CLI,可以和Kubernetes進(jìn)行交互。例如執(zhí)行“kubectl get nodes”命令,列出當(dāng)前所有的工作節(jié)點(diǎn)。
執(zhí) 行“kubectl get events”命令,了解當(dāng)前集群發(fā)生的事件信息。
對于PODs來說,其實(shí)際上是創(chuàng)建,調(diào)度以及管理的最小單元,是共存的一組容器的集合。在同一個PODs之中的容器共享了PID,網(wǎng)絡(luò),IPC,UTS命名空間以及存儲卷。設(shè)計(jì)PODs的目的在于更好的進(jìn)行資源共享以及容器間的通訊,便于更好的管理容器。
注 意 :PODs是 一 個 短暫存在的對象,其生命周期包 括 Penging,Running,Succeeded,F(xiàn)ailed等狀態(tài)。
例如,在由三個節(jié)點(diǎn)組成的Kubernetes集群中,包括一個Master節(jié)點(diǎn)和兩個工作節(jié)點(diǎn)。
在Master上 執(zhí) 行“vi pod.yaml”命令,在其中顯示具體的版本號,對應(yīng)的對象類型為POD,對象所需的屬性值,容器的相關(guān)信息(例如應(yīng)用類型,監(jiān)聽端口等)。
執(zhí) 行“kubectl create-f pod.yaml pods/nginx”命令,就基于“pod.yaml”創(chuàng)建了一個PODs對象,這里使用的容器鏡像為Nginx。
執(zhí) 行“kubectl get nodes”命令,可以看到該P(yáng)ODs已經(jīng)出于運(yùn)行狀態(tài)。
執(zhí)行“kubel delte pods nginx”命令,可以刪除上述PODs。
執(zhí) 行“k u b e c t l describe pods xxx”命令,可以查看指定PODs的詳細(xì)信息,“xxx”為PODs的名稱。
執(zhí) 行“kubectl logs xxx”命令,可以查看指定PODs的日志信息。
當(dāng)容器Crash時,其中的數(shù)據(jù)就會丟失。Kubernetes的Volumes可以解決數(shù)據(jù)持久化的問題,同時讓PODs中的容器共享數(shù)據(jù)。其生命周期和定義它的PODs的生命周期是一致的。當(dāng)一個PODs停止退出時,Volumes也會停止退出。Volume支持諸 如 EmptyDir,Hostpath,gcePersistentDisk,NFS,Glusterfs。sectrets等 很多類型的數(shù)據(jù)卷。即使容器Crash后,數(shù)據(jù)卷是不會被刪除的。
例 如,執(zhí) 行“vi pod.yaml”命令,在其中依次輸 入“apiVersion:V1”,“kind :Pod”,“metadata:”,“name:redis”,“spec:”,“- n a m e:r e d i s”,“ V o l u m e M o u n t”,“ -name:redis-persistentstorage”,“mountPath:/data/redis”,“volumes:”,“-name:redis-persistentstorage”,“empty: {}”行,定義了其存儲卷信息。當(dāng)其被PODs創(chuàng)建時,會產(chǎn)生一個空的文件夾,并將其映射到容器中。執(zhí)行“kubectl create -f pod.yaml pods/redis”命令,創(chuàng)建該 PODs。執(zhí) 行“kubectl get pods redis -o yaml”命令,可以查看更加詳細(xì)的信息,在其中可以看到數(shù)據(jù)掛載點(diǎn)信息,從而實(shí)現(xiàn)了數(shù)據(jù)的持久化。
對于Labels來說,其用來標(biāo)示對象的Key/Value對,可以組織并選擇對象子集,Label讓用戶可以映射自己應(yīng)用的組織結(jié)構(gòu),而不需要存儲這些映射表。Label不需要提供唯一性,多個對象可以使用相同的Label,通過Label選擇器,用戶可以指定一些對象子集來進(jìn)行分組合并。例如執(zhí)行“vi labels.yaml”命 令,在 其中 的“metadata:”欄 中 添加“l(fā)abel:”,“app:nginx”行,來 聲 明 該Label。 執(zhí)行“kubectl create -f labels.yaml pods/redis”命令,創(chuàng)建帶Label的PODs。例 如 執(zhí) 行“kubectl get pods -l app=nginx”命令, 則只顯示指定的PODs。
當(dāng)維護(hù)節(jié)點(diǎn)或者節(jié)點(diǎn)出錯時,利用Replicatuion Controllers(簡 稱 RC),可以將PODs調(diào)度到其他正常節(jié)點(diǎn)上運(yùn)行。Replicatuion Controllers可以在任一時刻確保運(yùn)行指定數(shù)量的PODs,其實(shí)現(xiàn)了容器的重新調(diào)度機(jī)制,可以監(jiān)控運(yùn)行在多個節(jié)點(diǎn)上的多個PODs。Replicatuion Controllers讓規(guī)模的調(diào)整變得比較簡單,實(shí)現(xiàn)多發(fā)布版本跟蹤功能,還可以逐個替換PODs的方法實(shí)現(xiàn)在線升級。
執(zhí) 行“vi rc.yaml”命令,在其中的“replicas:”欄中顯示指定PODs的數(shù)量。 在“Selector:”欄 中顯示具體Label信息。在“template:”欄中顯示PODs的定義信息。執(zhí)行“kubectl create -f rc.yaml”命令,創(chuàng)建該 RC,執(zhí)行“kubectl get rc”命令查看該RC的信息。執(zhí)行“kubectl get pods -l app=xxx”命令,顯示指定Label值的PODs的信息。這里的“xxx”為指定Label名稱。即使將其中一個 POD刪 除,Replicatuion Controllers也會按照指定數(shù)量重啟合乎數(shù)量的PODs。
每個PODs都擁有自己的IP,而且這些IP并不固定,當(dāng)一些PODs為另外的PODs提供服務(wù),那么如何進(jìn)行發(fā)現(xiàn)呢?利用Kubernetes提供的Services,可以有效解決該問題。Services抽象了一些列的POD并定義了其訪問規(guī)則,為每一個服務(wù)提供了固定的虛擬的IP和DNS域名,通過環(huán)境變量和DNS的方式可以發(fā)現(xiàn)服務(wù)。注意,只能在工作節(jié)點(diǎn)上訪問該虛擬IP。
Services可以實(shí)現(xiàn)簡單的負(fù)載均衡,其定義了PODs的訪問方式,包括ClusterIP(只能在當(dāng)前集群內(nèi)訪問),NodePort(在使用ClusterIP的同時,在集群每個節(jié)點(diǎn)上暴露一個服務(wù)的接口,外部用戶利用該節(jié)點(diǎn)的IP地址和該端口進(jìn)行訪問)和LoadBanlancer(要求云服務(wù)商提供支持)等。例如執(zhí)行“vi service.yaml”命令,在“metadata:”欄中輸入“name:xxx”行,為其進(jìn)行命名。在“spec:”欄中定義了監(jiān)聽端口號,對應(yīng)的映射端口以及協(xié)議類型,在“selector:”欄中定義選擇器,指明為哪些PODs服務(wù)。執(zhí) 行“kubectl create -f service.yaml”命令,創(chuàng)建該Service。
執(zhí) 行“kubectl get services”命令,列出所有的Service信息。例如,在某個工作節(jié)點(diǎn)上執(zhí)行“curl http://xxx.xxx.xxx.xxx:yyy”地址,可以訪問指定Service提供的的服務(wù),“xxx”表 示 該 Service的虛擬 IP,“yy”為具體的端口號。當(dāng)然,Kubernetes還包括其他一些概念,例如Names用來命名一個對象,Namespaces實(shí)現(xiàn)了命名空間的功能,Kubernetes是支持多租戶的,為了保證每個租戶的對象是相互隔離的,可以為其定義各自的命名空間。利用Annotations可以定義一些Key-Value資源,用于處理一些非選擇的非過濾的參數(shù)。
Kubernetes的調(diào)度器只會將容器調(diào)度到有足夠CPU,內(nèi)存等資源可用的節(jié)點(diǎn)上,可以通過指定Resources來指明PODs所使用的最大資源信息,最好為每個對象設(shè)置其可用的資源的限定值,這樣可以保證為集群中的多個應(yīng)用合理的分配資源。
例 如, 執(zhí) 行“vi resource.yaml”命 令,在“resources:”欄中定義CPU和內(nèi)存的使用量。
利 用Kubernetes提供的健康監(jiān)測機(jī)制,可以及時檢測到發(fā)生錯誤的應(yīng)用并并重啟對應(yīng)的PODs。這就包括了Liveness和ReadinessProbes檢測功能。
例 如, 執(zhí) 行“vi liveness.yaml”命 令,在“l(fā)ivenessProbe:”行中定義了檢測機(jī)制。
例如,使用“httpGet”命令來訪問特定的地址,同時在“initialDelaySeconds:”欄中定義間隔時間,這樣就可以定義執(zhí)行檢測操作。
如果返回錯誤的檢測代碼,就會重啟對應(yīng)的PODs。當(dāng)工作節(jié)點(diǎn)上的應(yīng)用因?yàn)槭⊥顺鰰r,Kubernetes可以保證其以安全干凈的方式(例如將內(nèi)存中的數(shù)據(jù)保存等)退出。
例如,執(zhí)行“vi aqiut.yaml”命令,可以定義鉤子函 數(shù),在“l(fā)ifecycle:”欄中定義具體的參數(shù),例如在“preStop:”項(xiàng)中定義具體的命令。
例如,對于Nginx應(yīng)用來說,可以設(shè)置“command:["/usr/sbin/nginx","-s","quit"]” 命 令, 讓Nginx安全退出,其會在Kubernetes發(fā)出退出指令之前運(yùn)行。
許多應(yīng)用需要創(chuàng)建多個資源,管理多個資源可以將其簡單的合并到一個文件當(dāng)中。最好是將同一個應(yīng)用相關(guān)的所有資源放置在同一個配置文件中,并將和此應(yīng)用相關(guān)的所有文件保存到同一路徑下。
在很多情況下,會使用多個Label來標(biāo)識一個對象。為了避免服務(wù)的持續(xù)運(yùn)行,需要使用到在線應(yīng)用升級和回退的機(jī)制。例如執(zhí)行“kubectl run Testspec ”命令,創(chuàng)建名為“Testspec”的RC對象。
執(zhí)行“kubectl get rc”命令,查看該RC對象。
執(zhí) 行“kubectl get pods”命令,顯示其默認(rèn)只存在于一個PODs上。
在Master節(jié)點(diǎn)上執(zhí)行“kubectl scale rc Testspec --replicas=7”命令,動態(tài)調(diào)整當(dāng)前運(yùn)行的PODS的數(shù)量(例如7個)。
執(zhí) 行“vi shengji.yaml” 命 令,在 其 中 依次 輸 入“apiVersion:V1”,“kind:Service”,“metadata:”,“name:Testspec”,“l(fā)abels:”,“app:Testspec”,“spec:”,“type:NodePort”,“selector:”,“ a p p:T e s t s p e c”,“ports:”,“-name:http”,“modePort:21769”,“port:80”,“protocol:TCP”等 行,編輯該Service的信息,指定其名稱和使用的Label信息,并且在每個工作節(jié)點(diǎn)上為其分配指定的端口。
執(zhí) 行“kubectl create-f shengji.yaml”命令,來創(chuàng)建該Service。
在工作節(jié)點(diǎn)上執(zhí)行“while true do curl -s http://xxx:21769/| grep-o-e 'Version: Testspec [0-9].[0-9]'.[0-9]';sleep 1;done”命令,每隔1秒從指定位置的服務(wù)的虛擬IP上獲取具體的版本信息。
在Master節(jié)點(diǎn)上執(zhí)行“kubectl rollingupdate Testspec -updateperiod=5s -image=b.gcr.io/kuar/ Testspec:3.0.0”命令,就會每隔3秒鐘替換掉舊的PODs生成新版本的PODs。
在上述工作節(jié)點(diǎn)再次嗎執(zhí)行以上命令,可以看到新的版本已經(jīng)產(chǎn)生了。
這樣,就可以在服務(wù)不間斷的情況下,對鏡像進(jìn)行升級。
當(dāng)然,有些對象是需要實(shí)時更新的,利用Kubernetes的實(shí)時更新機(jī)制,可以在線將實(shí)時的修改寫入到目標(biāo)對象中。
當(dāng)容器出現(xiàn)問題時,為了保證其中的數(shù)據(jù)不丟失,就需要在容器外保存修改后的數(shù)據(jù)。對于關(guān)鍵的數(shù)據(jù),最好將其保存在網(wǎng)絡(luò)存儲中。對于諸如密鑰等敏感信息,將其打包到容器內(nèi)是不行的,利用Kubernetes提供的Secrets機(jī)制,可以安全存儲這些敏感的數(shù)據(jù)。
例如執(zhí)行“vi secret.yaml” 命 令,在 其 中 的“data:”欄中可以定義賬戶名,密碼的信息。例如“password: xxx” 等。 執(zhí)行“kubectl create -f secret.yaml”命令,來創(chuàng)建該Secret對象。
執(zhí) 行“kubectl get secret”命令,顯示Screct對象信息。
如何在應(yīng)用中使用Secret對象呢?例如執(zhí)行“vi secretapp.yaml”命令,打開某個YAML文件,在其中定義了RC對象,主要用于實(shí)現(xiàn)Redis的應(yīng)用。在其中的“volumes:”欄中可以定義多個邏輯卷,例如“emptyDIr:{}”等。 在 其 中 輸 入“-n a m e: a p p s c r e c t”,“secrect:”,“secrectName:screct1”等行,可以使用特定的Screct邏輯卷,這樣就以文件的形式將其映射到了Redis的容器中。