1、K8S是如何對容器編排?
在K8S集群中,容器並非最小的單位,K8S集群中最小的調度單位是Pod,容器則被封裝在Pod之中。由此可知,一個容器或多個容器可以同屬於在一個Pod之中。
2、Pod是怎么創建出來的?
Pod並不是無緣無故跑出來的,它是一個抽象的邏輯概念,那么Pod是如何創建的呢?Pod是由Pod控制器進行管理控制,其代表性的Pod控制器有Deployment、StatefulSet等。
3、Pod資源組成的應用如何提供外部訪問的?
Pod組成的應用是通過Service這類抽象資源提供內部和外部訪問的,但是service的外部訪問需要端口的映射,帶來的是端口映射的麻煩和操作的繁瑣。為此還有一種提供外部訪問的資源叫做Ingress。
4、Service又是怎么關聯到Pod呢?
在上面說的Pod是由Pod控制器進行管理控制,對Pod資源對象的期望狀態進行自動管理。而在Pod控制器是通過一個YAML的文件進行定義Pod資源對象的。在該文件中,還會對Pod資源對象進行打標簽,用於Pod的辨識,而Servcie就是通過標簽選擇器,關聯至同一標簽類型的Pod資源對象。這樣就實現了從service-->pod-->container的一個過程。
5、Pod的怎么創建邏輯流程是怎樣的?
(1)客戶端提交創建請求,可以通過API Server的Restful API,也可以使用kubectl命令行工具。支持的數據類型包括JSON和YAML。
(2)API Server處理用戶請求,存儲Pod數據到etcd。
(3)調度器通過API Server查看未綁定的Pod。嘗試為Pod分配主機。
(4)過濾主機 (調度預選):調度器用一組規則過濾掉不符合要求的主機。比如Pod指定了所需要的資源量,那么可用資源比Pod需要的資源量少的主機會被過濾掉。
(5)主機打分(調度優選):對第一步篩選出的符合要求的主機進行打分,在主機打分階段,調度器會考慮一些整體優化策略,比如把容一個Replication Controller的副本分布到不同的主機上,使用最低負載的主機等。
(6)選擇主機:選擇打分最高的主機,進行binding操作,結果存儲到etcd中。
(7)kubelet根據調度結果執行Pod創建操作: 綁定成功后,scheduler會調用APIServer的API在etcd中創建一個boundpod對象,描述在一個工作節點上綁定運行的所有pod信息。運行在每個工作節點上的kubelet也會定期與etcd同步boundpod信息,一旦發現應該在該工作節點上運行的boundpod對象沒有更新,則調用Docker API創建並啟動pod內的容器。
三、各類接口是如何調用
當我們通過kubectrl create命令創建一個RC資源對象時,kubectrl通過create rc這個rest接口將數據提交到api server,
隨后api server將數據寫入etcd里持久保存,與此同時,controller manager 在watch 所有的rc資源對象,因此一旦有rc對象被寫入到etcd中,controller manager就得到了通知,
它會讀取rc的定義,然后比較rc中所控制的pod的實際副本數與期待值的差異,然后采取對應的行動。
此刻,controller manager發現集群中還沒有對應的pod實例,就根據rc里的pod模板(template)定義,
創建一個pod並通過apiserver保存到etcd中。
類似地,scheduler進程在watch所有pod,一旦它發現系統產生了一個新生的pod,
就開始執行調度邏輯,為它安排一個新家(node),如果一切順利,此pod就被安排到某個node節點上,即binding to a node。
接下來,scheduler進程就把這個信息及pod狀態更新到etcd里,最后目標node節點上的kubelet監聽到有新的pod被安排到自己這里來了,
於是就是安排pod里的定義,拉取容器的鏡像並且創建對應的容器,當容器成功創建后,kubelet進程再把pod的狀態更新為running並通過api server更新到etcd中。
如果此pod還有對應的service,那么接下來就輪到kube-proxy出場了,每個node上的kube-proxy進程會監聽所有service及這些service對應的pod實例的變化,一旦發現有變化,就會在所在node節點上的iptables里增加或者刪除對應的nat轉發規則,最終實現了service的智能負載均衡功能,這一切都是自動完成的,無須人工干預。
如果某個node宕機,則會發生什么事情呢?假如某個node宕機一段時間,則因為此節點上再沒有kubelet進程定時匯報這些pod的狀態,因此這個node上的所有pod實例會被判定為失敗狀態,此時controller manager會將這些pod刪除並產生新的pod實例,於是這些pod就會被調度到其它node上產生,從而系統自動恢復。
1、准備好一個包含應用程序的Deployment的yml文件,然后通過kubectl客戶端工具發送給ApiServer。
2、ApiServer接收到客戶端的請求並將資源內容存儲到數據庫(etcd)中。
3、Controller組件(包括scheduler、replication、endpoint)監控資源變化並作出反應。
4、ReplicaSet檢查數據庫變化,創建期望數量的pod實例。
5、Scheduler再次檢查數據庫變化,發現尚未被分配到具體執行節點(node)的Pod,然后根據一組相關規則將pod分配到可以運行它們的節點上,並更新數據庫,記錄pod分配情況。
6、Kubelete監控數據庫變化,管理后續pod的生命周期,發現被分配到它所在的節點上運行的那些pod。如果找到新pod,則會在該節點上運行這個新pod。
7、kuberproxy運行在集群各個主機上,管理網絡通信,如服務發現、負載均衡。例如當有數據發送到主機時,將其路由到正確的pod或容器。對於從主機上發出的數據,它可以基於請求地址發現遠程服務器,並將數據正確路由,在某些情況下會使用輪訓調度算法(Round-robin)將請求發送到集群中的多個實例。
