原創文章,歡迎轉載。轉載請註明:轉載自IT人故事會,謝謝! 原文連結地址:『高階篇』docker之瞭解kubernetes(31)
最後一個服務編排工具的學習k8s。kubernetes其實源於希臘語意思(舵手,領航員)。猶豫不太好擠也不太好寫,就有了另一個名稱叫k8s,kubernetes是谷歌在2014年開始實施的一個專案,當時google已經有了大規模服務容器管理的經驗,內部Borg系統,負責對google內部的一些服務進行排程和管理,它的目的是讓使用者不必操心資源管理的問題,讓他們專注自己的核心業務, 並且最大化資料中心的利用率。
什麼是k8s
我們假設有個住戶社群,k8s就相當於這個社群的大房東,社群裡面有一棟一棟的大樓,大樓可以看做虛擬機器器,俗稱的VM,大樓裡面有很多的住戶,每個住戶就代表一個pod,那每個住戶如何找到他們的位置呢?每個住戶如何找到他們的位置就是通過門牌號,我們就理解為IP的位置,在每個住戶裡面有非常多的家庭成員,爸爸,媽媽,兄弟姐妹,爺爺奶奶,姥爺姥姥,女兒兒子,這些角色就可以理解為container,在這個pod裡面的成員,就共享了這個房間裡面的資源,水電網路,那些資源就可以把它理解成計算資源,ipu,記憶體,硬碟。對於大房東k8s,他最主要的功能就是管理,每個住戶Pod使用多少資源,那為了就是讓整棟大樓,會更有效率的使用很多資源,舉例來說:A棟大樓住了太多的住戶,太多的Pod,他們直接肯定會相互競爭資源的問題,那它就可以協調某一些pod,就是某一些住戶搬到B大樓去,這樣會讓變得更加的均衡使用。
- k8s
官網:kubernetes.io/ k8s是一個自動開源系統,自動化部署,擴縮容,管理容器化的應用。 相比前面的mesos 和swarm,k8s的目的非常的單純和明確,簡單的來說他的目的就是為了服務編排,沒有別的。這麼明確的明確的目的。雖然目的簡單但專注所以專業,非常靈活的使用方式,它考慮到服務服務落地過程中可能遇到的各種各樣的問題,各種各樣的場景,所以從簡單的入手,吃透它。瞭解它的所有元件,然後回過頭看它的架構。
- k8s 叢集的樣子
這張圖簡單的描述了,k8s叢集的樣子,k8s肯定也需要一個叢集,服務排程服務編排肯定要有機器,所以需要叢集,中間的七邊行是Master節點,可以理解為安裝了核心元件的,另外的六邊形標識的是Node節點,在k8s裡面叫worker節點,然後每個節點裡面有個kubelet服務和docker服務,
多了2個綠色部分,在master裡面Deployment。在Node中就是Containerized app就是容器化的應用。圖例就是在Master部署了一個Deployment,在三個節點選中了其中的一個部署了應用。Node中的藍色圓圈標識的是pod。
pod 是k8s中非常重要的一個概念,所有的應用和服務都是執行在pod裡面的,pod是k8s中最小的一個單元,可以理解為k8s的一個原子,pod裡面就是容器。
- 第一個pod有獨立的IP地址,一個容器
- 第二個pod有獨立的Ip地址,一個容器,一個磁碟儲存
- 第三個pod有獨立的Ip地址,兩個容器,一個磁碟儲存,這2個容器可以共享IP的,共享網路,共享磁碟的。
- 第三個pod有獨立的Ip地址,三個容器,2個的磁碟儲存,這3個容器可以共享IP的,共享網路,共享磁碟的。
PS:通過上邊的4個小圖,可以明白同一個pod裡面可以有任意多個容器和儲存。
知道了pod執行了容器,pod自己執行在哪裡啊。執行在node,通過kubelet來進行的,排程kuelet把pod執行起來。一個node上面可以執行多個pod。只要資源足夠可以建立多個pod。
service
- 中間是master節點
- 其餘的是node節點
- 下面的這個node,裡面執行了一個pod,pod的外邊,有一層虛線,虛線標識service,pod的Ip(10.10.10.1),service(10.10.9.1),service和pod的Ip不同,pod是具體執行在一個node上的,如果pod或者node突然掛掉了,編排工具肯定在其他的node節點下重新起一個pod,這個pod肯定的ip也就變了。所以就需要一個serivce的概念,當pod出問題了,產生一個新的pod,新的pod就是一個新的ip,我們就可以通過service的方式找到pod。
- serivce的Ip跟service的生命週期是一致的,如果service不被刪除的話,IP一直不發生變化。
- 上邊這個2個node,三個pod,其實就是從一個例項變成了3個例項,進行了擴容,對外提供想通的服務,這時這個service,ip就有了另外2個作用,除了可以定位pod的地址,可以對pod地址進行負載均衡,進行輪詢,
service的概念基本瞭解了,怎麼確定哪些pod屬於一個service,提出一個service的概念,service可能有一個或者是多個pod組成,如何定義service,怎麼定義service。在k8s上通過Master的Label Selector的方式,比如s:app=A,s:app=B,有這種標籤的確定輸入pod等於A 或者pod等於B,所有標籤一樣的都屬於我的小弟。這樣service和pod的耦合就非常鬆。
PS:(梳理概念)pod裡面包括N個容器,service裡面包括pod,Deployment可能包括service或者是pod。
deployment完成應用擴容
- Master裡面釋出了一個Deplyment,想給service 進行擴容
- 其實內部是擴容的pod,service只是一個邏輯存在的東西
- 把一組pod形成一個邏輯組就是service,擴容完成後,其他兩個節點就有了pod例項。
- service就開始對外的負載均衡endpoint找到對應的pod
滾動更新,停掉了一箇舊的pod,啟動一個新的pod,這時service既有新的,也有舊的存在,直到所有的舊的都更新完畢才結束。所有的更新和擴容的過程serivce的Ip始終是保持不變的。
k8s的整體架構
首先從整體上看,上邊這塊就是Master節點,下面有兩塊都是worker節點,master裡面部署的都是k8s的核心模組,虛線框代表的是API Server,提供了資源的核心模組,提供了認證授權和k8s的訪問控制,可以通過kubectl或者自己開發的userClient,restApi的形式訪問API server。從而完成整個叢集的訪問。
- ControllerManager負責維護叢集的狀態,比如故障檢測,擴縮容,滾動更新等等。
- Scheduler負責資源的排程,按照預定的策略把pod排程到指定的node節點
- ETCD 用做已執行儲存,pod,service的叢集等資訊,k8s需要持久化的資料都儲存在這個上邊。
- Kubelet負責維護當前節點上的容器的生命和volumes,網路。
- 每個Node上可以執行一個kube-proxy,負責service 提供內部的服務發現和負載均衡,為service方法做個落地的功能。
- kube-dns負責整個叢集的dns服務,這個元件不是必須的,一般通過名字訪問比較方便。
- dashboard叢集資料的GUI介面。
PS:全過程梳理
- kubectl 發起一個請求,請求經過認證。
- scheduler的策略和評分計算得到目標的node。
- APIServer請求Node,通過kublet把這個Node執行pod起來。
- APIServer把資訊傳送給ETCD儲存起來。
- pod執行起來之後,通過ControllerManager管理每個pod的狀態,如果突然掛了,就想辦法建立一個pod。給pod分個獨立的ip地址,可以在整個叢集內使用這個ip來訪問它。但是pod的ip是易變的,異常重啟和升級的時候,不可能關注某個pod的Ip的。
- 下面虛線的部分表示的是一個service,service裡面有3個pod,不在虛線裡面的是單獨存在的pod,並沒有提供service的入口,完成service的具體工作的模組就是kube-proxy,在每個node上都有一個kube-proxy,然後給service分配一個ip,可以訪問service裡面的pod,所以kube-proxy對應的service都會有一個ip的指向,負載均衡的訪問他們。
- kube-proxy(service) 可以把埠和ip直接暴露在node上。外邊的請求可以訪問node上的ip就可以關聯到這個service上了。
- kube-dns 就是為了方便名字直接訪問node節點。任何一個pod都可以通過名字來進行訪問。
k8s的設計理念
瞭解設計理念可以更深入的瞭解k8s,設計實在太好了,非常值得我們學習和借鑑。
- API設計原則
- 所有的api都是宣告式的(對於重複的操作是穩定的,所有的物件都是名詞,不是動詞,使用者很容易的期望使用者的樣子,當前的系統是否滿足需求,明確使用者的目的,用系統管理的業務意圖觸發設計)
- 控制機的設計原則(假定各種可能存在錯誤的可能,並做容錯處理,出現區域性錯誤和臨時錯誤是很正常的事情,錯誤可能存在於物理故障磁碟,外部系統的故障啊,系統本身的程式碼問題,考慮到任何可能的錯誤,並且做容錯處理,每個模組出現錯誤後,恢復處理,在系統中不可能保證每個模組始終是連線的,因此任何一個模組都要有自動修復的能力,保證連線不到其他模組而形成的自我崩潰。很多情況下可以做到優雅的降級,要求在設計的過程中,有基本功能和高階功能,同時不會導致高階功能的崩潰,影響到這個模組 的使用,更容易的引入高階功能,而會導致高階功能影響基本功能。)
- k8s網路
- CNI
- Flannel,Calico,Weave
- Pod網路
- scheduler-preselect
- NodiskConflict 掛載衝突
- checkNodeMemMemoryPressure 記憶體的壓力
- Nodeselect 節點的選擇器
- FitRescoure CPU,記憶體的限制
- Affinity 滿足pod的連線狀態的限制
- scheduler-optimize-select
優先規則,對node進行打分,通過優先函式進行預選規則,每個優先函式可以返回0-10的函式,分數越高,這臺主機越適合,對應一個權重。
- selectorSpreadPriority
- LeastRequestedPriority
- AffinityPriority
- pod內部通訊
- 同一個node上的不同pod通訊
通過pod的Ip來進行訪問
- 不同的node,不同的pod通訊
滿足pod,ip不能衝突
k8s的服務發現
- kube-proxy(ClusterIp)
每個服務,所有的pod給虛擬Ip,虛擬Ip只能在內部訪問
- kube-proxy(NodePort)
服務暴露到節點,外部的可以通過NodeIp 訪問pod
- kube-DNS
負責叢集內部的dns解析,內部之間可以通過名稱訪問pod。
PS:k8s的理論就講這麼多,重點還是實踐,下次開始搭建k8s叢集