深入剖析Kubernetes:容器编排与 Kubernetes 核心特性剖析
容器本質
一個“容器”,實際上是一個由 Linux Namespace、Linux Cgroups 和 rootfs 三種技術構建出來的進程的隔離環境。
從這個結構中我們不難看出,一個正在運行的 Linux 容器,其實可以被“一分為二”地看待:
一組聯合掛載在 /var/lib/docker/aufs/mnt 上的 rootfs,這一部分我們稱為“容器鏡像”(Container Image),是容器的靜態視圖;
一個由 Namespace+Cgroups 構成的隔離環境,這一部分我們稱為“容器運行時”(Container Runtime),是容器的動態視圖。
更進一步地說,作為一名開發者,我并不關心容器運行時的差異。因為,在整個“開發 - 測試 - 發布”的流程中,真正承載著容器信息進行傳遞的,是容器鏡像,而不是容器運行時。
Kubernetes 項目要解決的問題是什么?
編排?調度?容器云?還是集群管理?
實際上,這個問題到目前為止都沒有固定的答案。因為在不同的發展階段,Kubernetes 需要著重解決的問題是不同的。
但是,對于大多數用戶來說,他們希望 Kubernetes 項目帶來的體驗是確定的:現在我有了應用的容器鏡像,請幫我在一個給定的集群上把這個應用運行起來。
更進一步地說,我還希望 Kubernetes 能給我提供路由網關、水平擴展、監控、備份、災難恢復等一系列運維能力。
Kubernetes 項目的架構?
我們可以看到,Kubernetes 項目的架構,跟它的原型項目 Borg 非常類似,都由 Master 和 Node 兩種節點組成,而這兩種角色分別對應著控制節點和計算節點。
其中,控制節點,即 Master 節點,由三個緊密協作的獨立組件組合而成,它們分別是
負責 API 服務的 kube-apiserver、
負責調度的 kube-scheduler,
以及負責容器編排的 kube-controller-manager。
整個集群的持久化數據,則由 kube-apiserver 處理后保存在 Ectd 中。
而計算節點上最核心的部分,則是一個叫作 kubelet 的組件。
在 Kubernetes 項目中,kubelet 主要負責同容器運行時(比如 Docker 項目)打交道。而這個交互所依賴的,是一個稱作 CRI(Container Runtime Interface)的遠程調用接口,這個接口定義了容器運行時的各項核心操作,比如:啟動一個容器需要的所有參數。
這也是為何,Kubernetes 項目并不關心你部署的是什么容器運行時、使用的什么技術實現,只要你的這個容器運行時能夠運行標準的容器鏡像,它就可以通過實現 CRI 接入到 Kubernetes 項目當中。
而具體的容器運行時,比如 Docker 項目,則一般通過 OCI 這個容器運行時規范同底層的 Linux 操作系統進行交互,即:把 CRI 請求翻譯成對 Linux 操作系統的調用(操作 Linux Namespace 和 Cgroups 等)。
此外,kubelet 還通過 gRPC 協議同一個叫作 Device Plugin 的插件進行交互。這個插件,是 Kubernetes 項目用來管理 GPU 等宿主機物理設備的主要組件,也是基于 Kubernetes 項目進行機器學習訓練、高性能作業支持等工作必須關注的功能。
而kubelet 的另一個重要功能,則是調用網絡插件和存儲插件為容器配置網絡和持久化存儲。這兩個插件與 kubelet 進行交互的接口,分別是 CNI(Container Networking Interface)和 CSI(Container Storage Interface)。
可以說,kubelet 完全就是為了實現 Kubernetes 項目對容器的管理能力而重新實現的一個組件
Borg 對于 Kubernetes 項目的指導作用又體現在哪里呢?
答案是,Master 節點。
雖然在 Master 節點的實現細節上 Borg 項目與 Kubernetes 項目不盡相同,但它們的出發點卻高度一致,即:如何編排、管理、調度用戶提交的作業?
所以,Borg 項目完全可以把 Docker 鏡像看做是一種新的應用打包方式。這樣,Borg 團隊過去在大規模作業管理與編排上的經驗就可以直接“套”在 Kubernetes 項目上了。
這些經驗最主要的表現就是,從一開始,Kubernetes 項目就沒有像同時期的各種“容器云”項目那樣,把 Docker 作為整個架構的核心,而僅僅把它作為最底層的一個容器運行時實現。
而 Kubernetes 項目要著重解決的問題,則來自于 Borg 的研究人員在論文中提到的一個非常重要的觀點:
運行在大規模集群中的各種任務之間,實際上存在著各種各樣的關系。這些關系的處理,才是作業編排和管理系統最困難的地方。
事實也正是如此。
其實,這種任務與任務之間的關系,在我們平常的各種技術場景中隨處可見。比如,一個 Web 應用與數據庫之間的訪問關系,一個負載均衡器和它的后端服務之間的代理關系,一個門戶應用與授權組件之間的調用關系。
更進一步地說,同屬于一個服務單位的不同功能之間,也完全可能存在這樣的關系。比如,一個 Web 應用與日志搜集組件之間的文件交換關系。
而在容器技術普及之前,傳統虛擬機環境對這種關系的處理方法都是比較“粗粒度”的。你會經常發現很多功能并不相關的應用被一股腦兒地部署在同一臺虛擬機中,只是因為它們之間偶爾會互相發起幾個 HTTP 請求。
更常見的情況則是,一個應用被部署在虛擬機里之后,你還得手動維護很多跟它協作的守護進程(Daemon),用來處理它的日志搜集、災難恢復、數據備份等輔助工作。
但容器技術出現以后,你就不難發現,在“功能單位”的劃分上,容器有著獨一無二的“細粒度”優勢:畢竟容器的本質,只是一個進程而已。
也就是說,只要你愿意,那些原先擁擠在同一個虛擬機里的各個應用、組件、守護進程,都可以被分別做成鏡像,然后運行在一個個專屬的容器中。它們之間互不干涉,擁有各自的資源配額,可以被調度在整個集群里的任何一臺機器上。而這,正是一個 PaaS 系統最理想的工作狀態,也是所謂“微服務”思想得以落地的先決條件。
當然,如果只做到“封裝微服務、調度單容器”這一層次,Docker Swarm 項目就已經綽綽有余了。如果再加上 Compose 項目,你甚至還具備了處理一些簡單依賴關系的能力,比如:一個“Web 容器”和它要訪問的數據庫“DB 容器”。
在 Compose 項目中,你可以為這樣的兩個容器定義一個“link”,而 Docker 項目則會負責維護這個“link”關系,其具體做法是:Docker 會在 Web 容器中,將 DB 容器的 IP 地址、端口等信息以環境變量的方式注入進去,供應用進程使用,
DB_NAME=/web/dbDB_PORT=tcp://172.17.0.5:5432DB_PORT_5432_TCP=tcp://172.17.0.5:5432DB_PORT_5432_TCP_PROTO=tcpDB_PORT_5432_TCP_PORT=5432DB_PORT_5432_TCP_ADDR=172.17.0.5而當 DB 容器發生變化時(比如,鏡像更新,被遷移到其他宿主機上等等),這些環境變量的值會由 Docker 項目自動更新。這就是平臺項目自動地處理容器間關系的典型例子。
可是,如果我們現在的需求是,要求這個項目能夠處理前面提到的所有類型的關系,甚至還要能夠支持未來可能出現的更多種類的關系呢?
這時,“link”這種單獨針對一種案例設計的解決方案就太過簡單了。如果你做過架構方面的工作,就會深有感觸:一旦要追求項目的普適性,那就一定要從頂層開始做好設計。
所以,Kubernetes 項目最主要的設計思想是,從更宏觀的角度,以統一的方式來定義任務之間的各種關系,并且為將來支持更多種類的關系留有余地。
比如,Kubernetes 項目對容器間的“訪問”進行了分類,首先總結出了一類非常常見的“緊密交互”的關系,即:這些應用之間需要非常頻繁的交互和訪問;又或者,它們會直接通過本地文件進行信息交換。
圍繞著容器和 Pod 不斷向真實的技術場景擴展,我們就能夠摸索出一幅如下所示的 Kubernetes 項目核心功能的“全景圖”。
Kubernetes 項目核心功能的“全景圖”?
在 Kubernetes 項目中,我們所推崇的使用方法是:
- 首先,通過一個“編排對象”,比如 Pod、Job、CronJob 等,來描述你試圖管理的應用;
- 然后,再為它定義一些“服務對象”,比如 Service、Secret、Horizontal Pod Autoscaler(自動水平擴展器)等。這些對象,會負責具體的平臺級功能。
這種使用方法,就是所謂的“聲明式 API”。這種 API 對應的“編排對象”和“服務對象”,都是 Kubernetes 項目中的 API 對象(API Object)。
過去很多的集群管理項目(比如 Yarn、Mesos,以及 Swarm)所擅長的,都是把一個容器,按照某種規則,放置在某個最佳節點上運行起來。這種功能,我們稱為“調度”。
而 Kubernetes 項目所擅長的,是按照用戶的意愿和整個系統的規則,完全自動化地處理好容器之間的各種關系。這種功能,就是我們經常聽到的一個概念:編排。
所以說,Kubernetes 項目的本質,是為用戶提供一個具有普遍意義的容器編排工具。
總結
以上是生活随笔為你收集整理的深入剖析Kubernetes:容器编排与 Kubernetes 核心特性剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【系统架构】三大主流软件负载均衡器(LV
- 下一篇: 昨日比赛心得