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