【個人Linux,我作主!】kubernetes基礎概念

(1)Kubernetes各個組件
Kubernetes是一個集羣,集羣的角色不是對等的,有主節點master和工做節點node之分,而主節點之上有三個組件運行守護進程,分別是API Server,Scheduler,Controller-Manager。而在node之上,有kubelet主要是和API Server進行交互的核心組件,而docker做爲容器引擎來運行Pod中的容器而建立的。爲了可以統一管理同一個集羣中大量的資源,因此咱們須要給元數據添加一個Label,它是一個key、value類型的數據,定義完Label標籤後咱們就可使用Lable Selector標籤選擇器來根據條件挑選出符合的Pod資源。
Pod自己是須要由控制器來管理,而不是由人手工來管理的,事實上在K8S上Pod有兩類,(1)第一種是自主式Pod,是指自我管理的,由API Server接收之後藉助於調度器將其調度至指定的node節點,由node啓動此Pod,若是Pod中的容器出現了故障須要重啓容器,那是由kubelet來完成,可是節點故障了,這個Pod也就消失了,沒法實現全局調度;(2)因此咱們建議使用第二種即控制器管理的Pod,這樣會使Pod成爲有生命週期的對象,由調度器將其調度至集羣中的某節點運行之後,任務一終止它也就停了,可是有一些任務,好比nginx或者tomcat這一類服務若是運行爲容器的話它是須要隨時處於運行狀態,一旦出現故障須要馬上反應到或進行重啓或進行重建,這樣就須要K8S平臺提供的Pod控制器。
對於控制器管理的Pod來講,Pod有不少種,最先的一種名爲ReplicationController即副本控制器,當咱們啓動一個控制器後,ReplicationController能夠控制同一類Pod對象的各類副本,一旦副本的數量少了就會加一個補夠,ReplicationController還可以實現其它任務滾動更新,例如更新當前管理的2個Pod控制器,它先建立一個新版本的Pod,並容許在更新過程當中臨時超出2個Pod的限制,此時會有3個Pod同時運行,更新完第3個Pod後,此時再刪除第1個Pod,這樣就實現了保證最終是控制器要求的2個Pod的目標,這就是滾動更新概念,並且它也支持滾動更新的逆轉即回滾操做。早期的時候只有ReplicationController一種版本的控制器,到了K8S的新版本後,又有了新的控制器ReplicaSet,可是這個控制器不直接使用,它有一個聲明式更新的控制器Deployment來作管理,可是Deployment只能管理無狀態的應用,若是是有狀態的應用須要使用StatefulSet有狀態副本集,若是須要在每個node上運行一個副本而不是隨影運行還須要一個DaemonSet,若是已經做業則須要Job,週期性的任務計劃做業Cronjob,這些控制器的類型是分別用於確保不一樣類型的Pod資源,來用符合用戶所指望的方式進行運行。另外Deployment控制器還支持二級控制器HPA(HorizontalPodAutoscaler)水平Pod自動伸縮控制器。
【個人Linux,我作主!】kubernetes基礎概念
Pod是有生命週期的,隨時都會有Pod離去,隨時都會有新的Pod加進來,假如他們提供的是同一種服務,咱們客戶端是沒辦法經過固定的手段來訪問這些Pod的,由於這些Pod隨時都會被替換掉,因此這裏就須要用到服務發現機制了。K8S爲每一組提供同類服務的Pod和它的客戶端之間添加了一箇中間層,這個中間層是固定的,這個中間層就叫service,service只要不刪除,它的地址就是固定的,這個服務是一個調度器,能提供一個穩定的訪問入口,一旦一個Pod宕機了,沒有關係新建一個Pod,這個Pod會和service關聯起來,做爲service後端可用Pod之一,在Pod上有一個固定的元數據Label,只要建立了Pod,它的Label是統一的,都能被service識別,因此客戶端的請求到達service,由service代理至後端Pod來實現,因此客戶端始終看到的可用服務是service的地址,而這個service組件其實是一個iptables的DNAT規則,裝完K8S後還須要安裝部署一個DNS的Pod以確保各service名稱可以被解析,因此咱們把它稱爲系統架構級的Pod,它們被稱爲集羣的AddOns附加組件。
iptables已經把負載均衡的功能交給IPVS實現了,所以service背後的Pod使用DNAT來實如今調度效果上可能不太盡如人意,所以在1.11版當中已經把iptables規則進一步改爲了IPVS規則,當你建立了一個service規則也就生成了一條IPVS規則,只不過是NAT模型的IPVS,所以支持用戶本身指定的調度算法。
咱們把全部應用程序運行在K8S之上,假設咱們以NMT的形式來運行,其中N是T的客戶端,可是T不止一個Pod,這些Pod若是須要被N訪問,能夠在T前加一個Service,把全部請求調度代理至內部的T,因此T不須要開放至互聯網訪問,一樣每個T須要訪問M,因此M也應該提供一個固定的訪問入口,所以在M前也須要添加一個Service,這個Service是爲M提供固定訪問入口的,各個T上的應用程序訪問的是M的Service, 由這個Service調度至後端的M上來。對於N來講,它的客戶端主要來自集羣外部,只有一小部分來自集羣內部,因此也須要爲N添加Service,Service的地址是一個僅存在於iptables或IPVS規則中的地址,怎麼可以被客戶端真正訪問?爲了可以組織出來一個K8S的集羣,咱們須要物理節點,因此用戶的請求先到達物理服務器的地址,由物理服務器再轉發代理至Service,全部外部客戶端先去訪問節點,由於只有節點纔是邊界,若是邊界也是私網地址,那麼能夠在外部建立一個外置的調度器,這個調度器能夠調度至邊界的任何一個節點上的,這個節點的端口只能有一個端口來轉發至服務的端口,由服務再轉發至Nginx的端口,從外置調度器至Nginx如此造成了三次調度。
【個人Linux,我作主!】kubernetes基礎概念
咱們發現外置的服務器已經脫離了K8S的控制了,它不能被K8S的命令來進行建立了,不能經過命令建立也就沒法作到LBaaS(負載均衡即服務)架構。所以咱們把K8S運行在阿里雲或者亞馬遜雲的雲計算環境虛擬機之上,多個虛擬機組成一個K8S集羣,咱們知道雲計算環境是支持LBaaS的,因此K8S是能夠對外調用底層的雲計算環境,這樣雲計算環境給咱們的環境建立一個軟件的外置調度器,從而完成將請求接入進來。
而NTM這些服務中,例如Tomcat服務對應的這一組Pod不是由用戶手動建立的,而是由控制器建立的,Nginx由Nginx控制器建立,MySQL由MySQL控制器建立,一個控制器一般只管理一部分組件,控制器則是根據標籤來識別本身的Pod夠不夠。
每個Service要想基於名稱被客戶端訪問和發現須要靠DNS服務,DNS服務自身也是一個Pod,這個DNS服務也須要有Service,同時還須要有控制器來經過標籤控制建立訪問。這就是咱們的K8S集羣的集羣組成核心組件。
【個人Linux,我作主!】kubernetes基礎概念
在K8S中,要求的網絡模型有3種,第一是每個Pod運行在同一個網絡中,第二是Service是另一個網絡,它是一個虛擬的地址,第三是各節點的網段也是一個單獨的網絡。因此接入外部訪問時首先到達節點網絡,由節點網絡代理至Service集羣網絡,再由Service集羣網絡代理至Pod的網絡。
在K8S上還存在着三類通訊,(1)由於一個Pod內會有多個容器,同一個Pod內的多個容器間使用lo迴環地址通訊,(2)各Pod之間的通訊,使用Overlay Network疊加網絡,經過隧道的方式來轉發二層報文,雖然跨主機但好像工做在同一個二層網絡中同樣,咱們能夠轉發對方的二層報文或隧道轉發對方的三層報文從而實現疊加網絡,(3)咱們客戶端和服務端的Pod之間訪問時,由於考慮到Pod是有生命週期的,因此中間是經過Service,即Pod與Service之間的通訊,可是Pod與Service不在同一個網絡沒法直接通訊,Service地址只不過是主機上的iptables規則中的地址,因此只須要有網關指向容器,每個docker宿主機上都得有iptables或者IPVS規則,可是Service怎麼能改變全部節點上的相關地址和規則呢?這就須要一個專門的組件來實現,這個組件是運行在node之上的守護進程,它被稱爲kube-proxy,它負責隨時與API Server進行通訊,由於每個Pod發生變化的時候,這個結果是會保存在API Server中的,而API Server通訊內容發生改變後會生成一個通知事件,事件能夠被任何關聯的組件接收到例如kube-proxy,一旦發現某一Service背後的Pod發生了改變,那麼對應的由kube-proxy負責在本地把那個地址反映到iptables或者IPVS規則中,因此Service的管理是靠kube-proxy來實現的。
【個人Linux,我作主!】kubernetes基礎概念
這麼一來咱們發現API Server會存整個集羣中各個相關狀態的信息,因此各個master之間須要一個共享存儲,這個存儲咱們稱爲K8S的DB,這個DB叫作etcd,而etcd是一個鍵值存儲的數據庫系統,由於整個集羣的數據都在etcd上,因此etcd須要作高可用。etcd通訊一個端口用來實現集羣內部通訊。另外一個端口用來實現向客戶端提供服務,也就意味着內部通訊須要一個點對點通訊的證書來配置https,然後向客戶端提供服務的時候http要想加密靠另一套證書來實現,一樣K8S的API Server也是須要將https加密進行通訊,這個是K8S的客戶端和副本之間的通訊,並且最好與etcd不要使用同一個CA來簽署的。
因此etcd內部通訊須要一套CA來簽署證書,etcd爲了向客戶端API Server提供服務須要一套CA來簽署證書,而API Server爲了想客戶端提供服務須要另一套CA來簽署證書,而API Server與各node節點上的kubelet集羣代理進行通訊也須要一套CA來簽署證書,而API Server與各node節點上的kube-proxy進行通訊也須要一套CA來簽署證書。因此想要手動部署K8S足夠安全總共須要5套CA認證。
【個人Linux,我作主!】kubernetes基礎概念
(2)Kubernetes的網絡
整個API Server主要是由三類節點組成,第一類是API master,同時須要至少3個節點多高可用,第二類是etcd用來存儲集羣狀態數據,一樣也須要至少3個節點多高可用,最後第三類是node節點。它們彼此之間都是http或https進行通訊,然後咱們就能夠在node之上運行Pod了,而Pod與Pod之間要通訊,Pod內部的容器之間要通訊,Pod與Service要通訊,Pod與集羣外的客戶端要通訊,因此咱們要構建出多個網絡來。節點有節點的網絡,Service有Service的集羣網絡,Pod有Pod的網絡。K8S經過CNI插件體系來接入外部的網絡服務解決方案,CNI即爲容器網絡接口,只要是一個網絡服務提供商,能遵循CNI這個開發規範,那麼它就能做爲K8S的網絡解決方案來使用,這些網絡解決方案能夠以附加組件的方式託管運行在集羣之上,網絡解決方案能夠以Pod運行,而後爲其餘Pod提供網絡解決方案,這個Pod一般是一個特殊Pod。雖然託管運行在集羣之上但它們須要共享節點的網絡名稱空間,這樣從而能夠實現以容器的方式來運行,實行系統管理之事。
目前能做爲CNI插件的很是多,而常見的插件是flannel。其實咱們的網絡通常須要兩類功能,第一個就是提供網絡功能,給Pod、Service提供IP地址,第二個則是提供網絡策略,其實Pod和Pod之間是能夠直接通訊的,可是咱們通常會經過Service來代理進行通訊,由於Nginx的Pod和Tomcat的Pod之間在進行通訊的時候,T隨時會發生變更,一旦發生變更後則N就沒法和T再進行通訊了,因此使用Service來代理進行通訊是爲了解決Pod有生命週期的問題。若是我在一個K8S之上託管了2萬個Pod,這2萬個Pod均可以直接通訊,可是若是這些Pod不屬於同一家公司,那麼別人能夠任意訪問你的服務甚至劫持你的服務都有可能,因此在多租戶的場景中這是很是危險的狀況,因此須要用到網絡策略中的隔離功能,網絡策略須要施加一些條件來隔離不一樣的Pod讓彼此間不能互相訪問。
K8S中另一個重要的組件就是名稱空間,整個K8S做爲一個統一的集羣存在,裏面運行2萬個Pod程序,此時能夠把它切割成多個空間,一類Pod只運行在一個空間中,可是這個空間並非真正意義上的網絡邊界,只是管理上的邊界,例如第一個是開發環境的空間,第二個是生產環境的空間,未來咱們要刪除一個環境可使用網絡名稱空間直接進行移除,因此它爲咱們提供了一個管理的邊界。可是Pod之間是沒有邊界的,因此網絡策略容許咱們去定義名稱空間和名稱空間之間甚至是同一個名稱空間的Pod之間是否能夠互相訪問,經過生成iptables規則來隔離它們彼此間的互相訪問,這就是網絡策略。對於K8S來講網絡策略和網絡功能是兩個不一樣維度的東西,flannel只能實現其中的網絡配置,而第二種CNI則是calico,它同時支持網絡配置和網絡策略,可是calico的使用和實現起來比較難,並且calico能基於BGP協議來實現直接路由的通訊,而flannel是純粹的疊加網絡實現,calico是一個三層隧道網絡,也能夠直接使用爲BGP協議的路由直通模型。flannel和calico是目前最流行的兩種網絡解決方案,若是咱們想同時實現簡單的網絡配置而且有網絡策略的話就須要使用第三方的項目插件canel,它既能夠實現簡單的網絡配置的功能,也能夠實現網絡策略的需求,它是flannell和calico結合在一塊兒生成的新的項目。
【個人Linux,我作主!】kubernetes基礎概念
整個K8S有三個網絡,第一是節點網路,各節點進行通訊,第二Pod網絡,節點之上有Pod,Pod之間經過疊加也罷,直接路由也罷,可以直接進行通訊,第三個是Service集羣網絡,由kube-proxy負責管控和生成,讓Pod和Pod之間能夠通訊是藉助一箇中間層來實現,原本Pod和Pod之間是在同一個網段的,但後來咱們不得不借助於Service,而Service和Pod又不在同一個網段,下降了效率,可是對管理來講倒是有必要的。node

—————— 本文至此結束,感謝閱讀 ——————nginx

相關文章
相關標籤/搜索