1. 程式人生 > >kubernetes基礎——一文讀懂k8s

kubernetes基礎——一文讀懂k8s

容器

容器與虛擬機器對比圖(左邊為容器、右邊為虛擬機器)

  容器技術是虛擬化技術的一種,以Docker為例,Docker利用Linux的LXC(LinuX Containers)技術、CGroup(Controll Group)技術和AUFS(Advance UnionFileSystem)技術等,通過對程序和資源加以限制,進行調控,隔離出來一套供程式執行的環境。 我們把這一環境稱為“容器”,把構建該“容器”的“只讀模板”,稱之為“映象”。
  容器是獨立的、隔離的,不同容器間不能直接通訊,容器與宿主機也是隔離開來的,容器不能直接感知到宿主機的存在,同時宿主機也無法直接窺探容器內部。
  雖然容器與宿主機在環境上,邏輯上是隔離的,但容器與宿主機共享核心,容器直接依賴於宿主機Linux系統的核心,這與虛擬機器不同,後者是在宿主機的作業系統上,虛擬化一套硬體環境,然後在此環境上執行需要的作業系統。容器技術常用來在宿主機上隔離出環境來部署應用(用容器化技術部署的應用稱為 “容器化應用”

),而虛擬機器常用來執行一個與宿主機不同的作業系統,從而執行特定的軟體。
  容器非常輕量級,無論是啟動速度,資源佔用情況,靈活性等均優於虛擬機器。容器的特性給開發生產提供了非常大的便利:

  • DevOps理念,開發者可以使用同一個映象,在開發環境、測試環境和生產環境構建相同的容器,即相同的程式執行環境,這樣可以大大減少前期的環境部署時間,可以有效避免由於各個環境不一致而造成的災難。
  • “容器”與“微服務”常是一起出現的一組名詞,有了容器技術以後,可以更加方便的部署微服務,例如,可以把評論服務部署到一個容器裡,把閱讀的服務部署到另一個容器,這樣在一個服務崩潰時不至於影響到其它服務,再者,容器啟動速度快,可以在極短時間內恢復。
  • 很多時候,一些環境、工具需要複用,這時候容器是個很好的選擇,我們可以把環境和工具打包成映象,需要的時候用來構建容器使用。在Docker的映象倉庫上,也有很多官方的或第三方的映象,這些映象都是別人已經打包好的工具或者環境,我們只需一條命令,就可以把映象拉取下來並構建容器啟動,免去了自己動手開發部署的麻煩。

Docker技術解析

叢集

  計算機是獨立的,但我們可以通過一系列技術、軟體,把分散的算力有效的集中起來,把多臺獨立的計算機當做一個整體來使用,而且這些計算機實現相同的業務,這就是叢集。

分散式

  分散式就是把一個系統拆分開來部署到不同機器,與叢集相同的是,兩者都需要多臺伺服器,不同點是分散式並不強調實現相同的業務。貌似網上大多數資料,對於叢集和分散式的區分,都執著於兩者是否實現相同的業務,即不同伺服器運行同一份功能就是叢集,執行不同功能就是分散式。個人看法是,叢集強調的是“集”、“統一的概念”,是物理上的、環境上的概念,只要是多臺計算機搞在一起就是叢集;而分散式,更多的是描述應用系統的部署方式,把一個系統拆開部署到不同伺服器,就是分散式。這裡有一篇關於分散式和叢集的文章——淺談叢集與分散式的區別

微服務

  有必要提一下微服務,使用kubernetes可以更加便捷地部署微服務應用。微服務和分散式都強調“拆”、“分”,但微服務描述的是應用系統的架構,即怎麼樣把系統拆分,拆成多“微”,這是微服務需要考慮的;而分散式,強調的是“分佈”,即系統的部署方式,該怎麼把系統的模組分佈好,從而提高容災能力、高可用性。當“微服務”應用部署到一臺伺服器上,它就是“微服務應用”,當把“微服務”應用的模組分開來部署到不同伺服器,那麼它也成了“分散式應用”。
  關於“叢集”、“分散式”、“微服務”三者的聯絡與區別——微服務,分散式,叢集三者區別聯絡

kubernetes

  "kubernetes"這個詞比較長,常簡寫成k8s,"8"表示中間的8個字母。k8s是谷歌開源的用於管理 “容器化應用” 和服務的平臺,可用於自動部署、擴充套件和管理“容器化(containerized)應用程式”。可以通過一條命令或一份配置檔案實現自動建立容器並部署應用,還提供應用容器的自動化管理功能(自動擴容、自動縮容)。k8s支援搭建叢集,因此,k8s也是容器化叢集管理平臺,它旨在提供“跨主機叢集的自動部署、擴充套件以及執行應用程式容器的平臺”,它支援一系列容器工具, 包括Docker等。通過k8s以及容器引擎(Docker或rtk或其它),可以非常方便快速地搭建叢集環境。這樣部署出來的叢集有一個特點——容器化,在叢集中部署的應用,都是採用容器化的方式進行部署,即把應用放到容器中執行,至於這個容器是在叢集中哪個節點執行,就交由叢集管理人員和k8s控制。
  通過k8s,能夠進行應用的自動化部署和擴縮容,k8s可以根據事先配置好的配置檔案,實時監控容器的執行狀態,當容器出現問題時,k8s會自動地重建容器,當負載上升時,k8s會自動擴容,建立新的容器。k8s會盡量地維持容器的數量,當容器出現問題不能執行時,它會被刪除,同時k8s會新建容器,以滿足配置檔案指定的容器數量要求。這裡說“容器”其實並不恰當,因為k8s的基本排程單位是“pod”,下文會介紹。
  以上都是比較籠統的說法,可以用稍微專業一點的術語來描述,k8s根據其特點,可以歸納成如下的功能:

  • 跨主機的自動化容器編排管理平臺
      k8s以“Pod”為基本單位跨主機管理容器,“Pod”是一組(或一個)容器的集合。k8s監控叢集中各個節點(主機)上Pod的健康狀態,能夠利用使用者配置的“控制器”,及時地剔除不健康的Pod,同時建立新的健康的Pod來替代原來的Pod,這整個過程都是自動化的,使用者只需配置Pod的“控制器”,其餘操作均由k8s系統完成。
      Pod“控制器”一般包含“replicas”屬性,在介紹該屬性前,先引入“副本”的概念——一個Pod可以被複製成多份,每一份可被稱之為一個“副本”,這些“副本”除了一些描述性的資訊(Pod的名字、uid等)不一樣以外,其它資訊都是一樣的,譬如Pod內部的容器、容器數量、容器裡面執行的應用等的這些資訊都是一樣的,這些副本提供同樣的功能。“replicas”屬性則指定了特定Pod的副本的數量,噹噹前叢集中該Pod的數量與該屬性指定的值不一致時,k8s會採取一些策略去使得當前狀態滿足配置的要求。
      Pod是要被分配到節點(主機)中去執行的,至於要被分配到那個節點去,可以由使用者去配置,預設情況下,k8s系統會根據各個節點的資源狀況(當前資源的分配情況、資源的最大配額等資訊),採取合適的分配策略對Pod進行排程,對資源進行排程。這裡的資源是指CPU資源、記憶體資源等等。

  • 微服務部署平臺
      鑑於k8s有以上所描述的如此優良的特性,使用k8s來部署微服務應用是極佳的,k8s也提供了很多可以實行微服務部署的功能。
      可以基於上述的k8s的Pod編排技術,實現微服務的服務編排、服務快速部署。
      k8s提供了service的概念,service是對Pod訪問方式的抽象,service就是“服務”,service與一組Pod掛鉤,Pod實現某些功能,service就是利用Pod的“功能”,利用“Pod”的能動性,對外提供“服務”。service對請求進行路由,負載均衡到它後面與之掛鉤的Pod。利用service,可以實現微服務的服務自動發現和路由。
      k8s的一些Pod“控制器”可以提供Pod的“滾動更新”功能,如果你的應用升級了,譬如原來應用是v1版本,現在的版本是v2,那麼可以通過僅僅一條命令或一份配置檔案,讓k8s來自動地滾動更新應用。k8s會刪除一個v1的Pod,然後新建一個v2的Pod……這樣反覆交替操作,直至所有v1Pod被v2Pod代替,這樣就實現了不停機的應用滾動更新。k8s會儲存應用的更新記錄,在需要“回滾降級”時,同樣可以通過僅僅一條命令或者一個配置檔案實現。
      服務伸縮。當遇到類似“雙十一”這樣的時效性的業務需求時,可以充分利用到k8s了。如上面提到的“replicas”屬性,該屬性可以用來指定Pod的副本數量,當業務量增大時,可以修改該屬性值,讓k8s建立更多的Pod來處理請求,相應的,當業務量減少時,為了節約資源,可以減少該屬性的值。這樣就實現了服務的動態伸縮,使用者只需修改配置,實際操作交由k8s負責。

k8s架構圖

更多資料:

  • 一文讀懂kubernetes

  • k8s-整體概述和架構。

  • 乾貨滿滿!10分鐘看懂Docker和K8S

  • 萬維百科kubernetes

k8s基礎概念解析

Pod

  Pod是k8s的基本排程單位,Pod包含一個或一組Container(容器),這些Container共享Pod的IP(k8s中每一個Pod都有各自的IP,這些IP被稱作PodIP),所以一個Pod內的Container可以通過localhost+各自的埠進行通訊,跨Pod的容器之間的通訊,則通過對應的PodIP+埠進行。再次提到,Pod是k8s的基本排程單位,所以要想執行一個Container,必須先為其建立一個Pod。
  Pod是容器的執行環境,而我們的應用程式是部署在容器裡的,對於k8s的初學者,可以先把Pod簡單地看作為應用的執行容器,把Pod看作是應用在k8s上部署的最小單位。

更多資料:

  • k8s官方文件Pod部分

Service

  PodIP是在叢集內部的IP,外網無法訪問,相應的,Pod也是不能被外部訪問的,Pod只能在叢集內部被直接訪問,那麼如何在外網訪問Pod裡面部署的網站、應用?那就是上文提到的service。
  service是對Pod訪問方式的一種抽象。當請求傳送給service,service再把請求路由到與之掛鉤的Pod。在k8s中,service被用來給Pod暴露(expose)服務,service暴露的服務不僅僅是用來給外網訪問,內網也是可以使用的。預設情況下,service被配置為ClusterIp模式,在該模式下,也是隻有叢集內部的網路才能訪問到該service,要想真正的實現外網訪問service,需要把service訪問方式配置為NodePort或用其它方式(ingress、loadbalancer等)。
  service降低了k8s中Pod的耦合度。使用服務的Pod(稱為“前端”frontend)和提供服務的Pod(稱為“後端”backend)不是耦合在一起的。backend隨時會變動(Pod可能因為某些原因被銷燬又重建),frontend並不關心它實際上呼叫哪個backend副本,他只關心service的狀態,而backend的狀態,則轉交給了service去跟蹤。

更多資料:

  • k8s官方文件Service部分

Node(節點)

  一個node,就是k8s叢集中的一個伺服器,node分為Master Node和Worker Node。

Master Node

  顧名思義,Master Node就是叢集中的控制中心,負責整個叢集的控制、管理。預設情況下,在部署叢集時master會被分配一個名為NoSchedule的Taint(汙點),這個taint使得master節點不能被排程,也就是說新建Pod時,Pod不會被分配到master節點。

Worker Node

  Worker Node用於承載應用的執行,k8s會根據配置檔案中的策略,對worker node進行排程,把pod分配到合適的worker node。


CRI(容器執行時介面)

  全稱"Container-Runtime-Interface",是一個介面,用來操作容器的介面。k8s通過CRI對容器進行操作,建立、啟停容器等。安裝kubeadm時會自動安裝cri-tool。
  從v1.6.0起,Kubernetes開始允許使用CRI。預設的容器執行時是Docker。其他的容器執行時有:containerd (containerd 的內建 CRI 外掛)、cri-o、frakti、rkt。


CNI(容器網路介面)

  全稱"Container-Network-Interface",各種網路外掛(network-plugin),如flannel、GCE等實現了該介面。cni用於給pod分配ip,用來劃分網段,用來分配子網,用來管理k8s叢集內部的網路模型。其配置檔案裡包含"--pod-network-cidr"引數,該引數表示用"cidr"(計算機網路基礎的知識)給pod分配ip,引數的數值表示ip的字首,比如flannel官方配置檔案中的預設值為10.244.0.0/16,把10.244.0.0轉換成二進位制表示,取前面16位,即為給pod分配的ip的字首。

更多資料:

  • k8s官方文件網路部分

k8s元件簡介

Kubectl(叢集控制器)

  kubectl全稱"Kubernetes-Controller",運行於master節點,kubectl更像是“kubernetes-client”,類似於k8s的客戶端,是k8s的控制工具,是一個命令列工具,是使用者管理k8s叢集的介面,負責把使用者的指令傳給API Server,用於叢集中資源的增刪查改,注意,kubeclt只是個互動介面,並不負責實際上的資源的增刪查改。
  在k8s中的所有內容都被抽象為“資源”,如Pod、Service、Node等都是資源。“資源”的例項可以稱為“資源物件”,如某個具體的Pod、某個具體的Node。k8s中的資源有很多種,kubectl可以通過配置檔案來建立這些“資源物件”,配置檔案更像是描述物件“屬性”的檔案,配置檔案格式可以是“JSON”或“YAML”,不過常用的是“YAML”。

更多資料:

  • k8s中各種資源和物件的簡述

Kubelet(節點代理)

  執行在worker節點上,在使用kubeadm初始化叢集時,master節點也需要kubelet。Kubelet全稱"Kubernetes-Lifecycle-Event-Trigger",也是Kubernetes中最主要的控制器,kubelet被稱為"Node Agent",意思是“節點上的代理”。如果說kubectl是決策者,那麼kubelet相當於是管理者、執行者;如果說kubectl是總裁,那麼kubelet就是各個分公司的總經理。

kubelet的主要工作如下:

  • pod管理:kubelet會監測本節點上pod、container的健康,出錯時會根據配置檔案的重啟策略,對pod、container進行重啟。 kubelet還會定期通過API Server獲取本節點上的pod、container狀態的期望值,然後呼叫容器執行時介面,對container進行排程,已達到期望。

  • 資源監控:kubelet監控本節點資源使用情況,定時向master報告,知道整個叢集所有節點的資源情況,對於pod的排程和正常執行至關重要。


API Server(閘道器)

  API Server執行在master節點。對於整個k8s叢集,可以把kubectl看做前端,看作叢集管理員與k8s叢集互動的介面。API Server則相當於後端的"Controller",負責對各個元件(包括kubectl)發來的請求進行分發、處理。各個元件都直接與API Server進行通訊,也只能與API Server通訊。
  API Server提供了叢集管理的介面,提供了資源的增刪查改的介面,這個介面也可以直接說是API(web開發中的“API”)。值得一提的是,這些API都是是RESTful風格的API,這與k8s“萬物皆資源”的理念相符。
  另外,API Server也作為叢集的閘道器。預設情況,客戶端通過API Server對叢集進行訪問時,客戶端需要通過認證,並使用API Server作為訪問Node和Pod(以及service)的堡壘和代理/通道。


Etcd(叢集資訊儲存)

  執行在Master節點。etcd與zookeeper相似但又不同,在分散式中經常會見到,是一個鍵值儲存倉庫,用於配置共享和服務發現。接著上面講的,etcd相當於後端中的資料庫,用於儲存叢集中的所有狀態,包括各個節點的資訊,叢集中的資源狀態等等。etcd的watch機制可以在資訊發生變化時,快速的通知叢集中相關的元件。


Scheduler(排程器)

  執行在Master節點。scheduler元件為容器自動選擇執行的主機(node)。依據請求資源的可用性,服務請求的質量等約束條件,scheduler監控還未繫結到node的pod,對其進行繫結。Kubernetes也支援使用者自己提供的排程器,Scheduler負責根據排程策略自動將Pod部署到合適Node中,排程策略分為預選策略和優選策略,Pod的整個排程過程分為兩步:

1)預選Node:遍歷叢集中所有的Node,按照具體的預選策略篩選出符合要求的Node列表。如沒有Node符合預選策略規則,該Pod就會被掛起,直到叢集中出現符合要求的Node。

2)優選Node:預選Node列表的基礎上,按照優選策略為待選的Node進行打分和排序,從中獲取最優Node。


Controller-Manager(管理控制中心)

  執行在Master節點。Controller-Manager用於執行大部分的叢集層次的功能,它既執行生命週期功能(例如:名稱空間建立和生命週期、事件垃圾收集、已終止垃圾收集、級聯刪除垃圾收集、node垃圾收集),也執行API業務邏輯(例如:pod的彈性擴容)。控制管理提供自愈能力、擴容、應用生命週期管理、服務發現、路由、服務繫結和提供。Kubernetes預設提供Replication Controller、Node Controller、Namespace Controller、Service Controller、Endpoints Controller、Persistent Controller、DaemonSet Controller等控制器。
  Controller-Manager負責叢集內的Node、Pod副本、服務端點(Endpoint)、名稱空間(Namespace)、服務賬號(ServiceAccount)、資源定額(ResourceQuota)的管理,當某個Node意外宕機時,Controller Manager會及時發現並執行自動化修復流程,確保叢集始終處於預期的工作狀態。


友情連結

  • k8s元件
  • 在阿里雲ECS的Ubuntu環境下部署單節點k8s叢集
  • 部署k8s的圖形化管理平臺kubernetes-dashboard