容器與虛擬機對比圖(左邊爲容器、右邊爲虛擬機)html
容器技術是虛擬化技術的一種,以Docker爲例,Docker利用Linux的LXC(LinuX Containers)技術、CGroup(Controll Group)技術和AUFS(Advance UnionFileSystem)技術等,經過對進程和資源加以限制,進行調控,隔離出來一套供程序運行的環境。 咱們把這一環境稱爲「容器」,把構建該「容器」的「只讀模板」,稱之爲「鏡像」。
容器是獨立的、隔離的,不一樣容器間不能直接通訊,容器與宿主機也是隔離開來的,容器不能直接感知到宿主機的存在,同時宿主機也沒法直接窺探容器內部。
雖然容器與宿主機在環境上,邏輯上是隔離的,但容器與宿主機共享內核,容器直接依賴於宿主機Linux系統的內核,這與虛擬機不一樣,後者是在宿主機的操做系統上,虛擬化一套硬件環境,而後在此環境上運行須要的操做系統。容器技術經常使用來在宿主機上隔離出環境來部署應用(用容器化技術部署的應用稱爲 「容器化應用」 ),而虛擬機經常使用來運行一個與宿主機不一樣的操做系統,從而運行特定的軟件。
容器很是輕量級,不管是啓動速度,資源佔用狀況,靈活性等均優於虛擬機。容器的特性給開發生產提供了很是大的便利:前端
Docker技術解析node
計算機是獨立的,但咱們能夠經過一系列技術、軟件,把分散的算力有效的集中起來,把多臺獨立的計算機當作一個總體來使用,並且這些計算機實現相同的業務,這就是集羣。web
分佈式就是把一個系統拆分開來部署到不一樣機器,與集羣相同的是,二者都須要多臺服務器,不一樣點是分佈式並不強調實現相同的業務。貌似網上大多數資料,對於集羣和分佈式的區分,都執着於二者是否實現相同的業務,即不一樣服務器運行同一份功能就是集羣,運行不一樣功能就是分佈式。我的見解是,集羣強調的是「集」、「統一的概念」,是物理上的、環境上的概念,只要是多臺計算機搞在一塊兒就是集羣;而分佈式,更多的是描述應用系統的部署方式,把一個系統拆開部署到不一樣服務器,就是分佈式。這裏有一篇關於分佈式和集羣的文章——淺談集羣與分佈式的區別數據庫
有必要提一下微服務,使用kubernetes能夠更加便捷地部署微服務應用。微服務和分佈式都強調「拆」、「分」,但微服務描述的是應用系統的架構,即怎麼樣把系統拆分,拆成多「微」,這是微服務須要考慮的;而分佈式,強調的是「分佈」,即系統的部署方式,該怎麼把系統的模塊分佈好,從而提升容災能力、高可用性。當「微服務」應用部署到一臺服務器上,它就是「微服務應用」,當把「微服務」應用的模塊分開來部署到不一樣服務器,那麼它也成了「分佈式應用」。
關於「集羣」、「分佈式」、「微服務」三者的聯繫與區別——微服務,分佈式,集羣三者區別聯繫後端
"kubernetes"這個詞比較長,常簡寫成k8s,"8"表示中間的8個字母。k8s是谷歌開源的用於管理 「容器化應用」 和服務的平臺,可用於自動部署、擴展和管理「容器化(containerized)應用程序」。能夠經過一條命令或一份配置文件實現自動建立容器並部署應用,還提供應用容器的自動化管理功能(自動擴容、自動縮容)。k8s支持搭建集羣,所以,k8s也是容器化集羣管理平臺,它旨在提供「跨主機集羣的自動部署、擴展以及運行應用程序容器的平臺」,它支持一系列容器工具, 包括Docker等。經過k8s以及容器引擎(Docker或rtk或其它),能夠很是方便快速地搭建集羣環境。這樣部署出來的集羣有一個特色——容器化,在集羣中部署的應用,都是採用容器化的方式進行部署,即把應用放到容器中運行,至於這個容器是在集羣中哪一個節點運行,就交由集羣管理人員和k8s控制。
經過k8s,可以進行應用的自動化部署和擴縮容,k8s能夠根據事先配置好的配置文件,實時監控容器的運行狀態,當容器出現問題時,k8s會自動地重建容器,當負載上升時,k8s會自動擴容,建立新的容器。k8s會盡可能地維持容器的數量,當容器出現問題不能運行時,它會被刪除,同時k8s會新建容器,以知足配置文件指定的容器數量要求。這裏說「容器」其實並不恰當,由於k8s的基本調度單位是「pod」,下文會介紹。
以上都是比較籠統的說法,能夠用稍微專業一點的術語來描述,k8s根據其特色,能夠概括成以下的功能:api
跨主機的自動化容器編排管理平臺
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負責。網絡
更多資料:架構
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上部署的最小單位。
更多資料:
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去跟蹤。
更多資料:
一個node,就是k8s集羣中的一個服務器,node分爲Master Node和Worker Node。
顧名思義,Master Node就是集羣中的控制中心,負責整個集羣的控制、管理。默認狀況下,在部署集羣時master會被分配一個名爲NoSchedule的Taint(污點),這個taint使得master節點不能被調度,也就是說新建Pod時,Pod不會被分配到master節點。
Worker Node用於承載應用的運行,k8s會根據配置文件中的策略,對worker node進行調度,把pod分配到合適的worker node。
全稱"Container-Runtime-Interface",是一個接口,用來操做容器的接口。k8s經過CRI對容器進行操做,建立、啓停容器等。安裝kubeadm時會自動安裝cri-tool。
從v1.6.0起,Kubernetes開始容許使用CRI。默認的容器運行時是Docker。其餘的容器運行時有:containerd (containerd 的內置 CRI 插件)、cri-o、frakti、rkt。
全稱"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的前綴。
更多資料:
kubectl全稱"Kubernetes-Controller",運行於master節點,kubectl更像是「kubernetes-client」,相似於k8s的客戶端,是k8s的控制工具,是一個命令行工具,是用戶管理k8s集羣的接口,負責把用戶的指令傳給API Server,用於集羣中資源的增刪查改,注意,kubeclt只是個交互接口,並不負責實際上的資源的增刪查改。
在k8s中的全部內容都被抽象爲「資源」,如Pod、Service、Node等都是資源。「資源」的實例能夠稱爲「資源對象」,如某個具體的Pod、某個具體的Node。k8s中的資源有不少種,kubectl能夠經過配置文件來建立這些「資源對象」,配置文件更像是描述對象「屬性」的文件,配置文件格式能夠是「JSON」或「YAML」,不過經常使用的是「YAML」。
更多資料:
運行在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運行在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)的堡壘和代理/通道。
運行在Master節點。etcd與zookeeper類似但又不一樣,在分佈式中常常會見到,是一個鍵值存儲倉庫,用於配置共享和服務發現。接着上面講的,etcd至關於後端中的數據庫,用於存儲集羣中的全部狀態,包括各個節點的信息,集羣中的資源狀態等等。etcd的watch機制能夠在信息發生變化時,快速的通知集羣中相關的組件。
運行在Master節點。scheduler組件爲容器自動選擇運行的主機(node)。依據請求資源的可用性,服務請求的質量等約束條件,scheduler監控還未綁定到node的pod,對其進行綁定。Kubernetes也支持用戶本身提供的調度器,Scheduler負責根據調度策略自動將Pod部署到合適Node中,調度策略分爲預選策略和優選策略,Pod的整個調度過程分爲兩步:
1)預選Node:遍歷集羣中全部的Node,按照具體的預選策略篩選出符合要求的Node列表。如沒有Node符合預選策略規則,該Pod就會被掛起,直到集羣中出現符合要求的Node。
2)優選Node:預選Node列表的基礎上,按照優選策略爲待選的Node進行打分和排序,從中獲取最優Node。
運行在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會及時發現並執行自動化修復流程,確保集羣始終處於預期的工做狀態。