初識k8s

瞭解Linux中的六種namespace

linux實現了mount、UTS、IPC、network、pid、user這六種namespace。

一個“容器”,實際上是一個由 Linux Namespace、Linux Cgroups 和 rootfs 三種技術構建出來的進程的隔離環境

從這個結構中不難看出,一個正在運行的 Linux 容器,其實可以被“一分爲二”地看待:
1
一組聯合掛載在 /var/lib/docker/aufs/mnt 上的 rootfs,這一部分稱爲“容器鏡像”(Container Image),是容器的靜態視圖;
2
一個由 Namespace+Cgroups 構成的隔離環境,這一部分稱爲“容器運行時”(Container Runtime),是容器的動態視圖。

更進一步地說,作爲一名開發者,我並不關心容器運行時的差異。因爲,在整個“開發 - 測試 - 發佈”的流程中,真正承載着容器信息進行傳遞的,是容器鏡像,而不是容器運行時。

這個重要假設,正是容器技術圈在 Docker 項目成功後不久,就迅速走向了“容器編排”這個“上層建築”的主要原因:作爲一家雲服務商或者基礎設施提供商,我只要能夠將用戶提交的 Docker 鏡像以容器的方式運行起來,就能成爲這個非常熱鬧的容器生態圖上的一個承載點,從而將整個容器技術棧上的價值,沉澱在我的這個節點上。

更重要的是,只要從我這個承載點向 Docker 鏡像製作者和使用者方向回溯,整條路徑上的各個服務節點,比如 CI/CD、監控、安全、網絡、存儲等等,都有我可以發揮和盈利的餘地。這個邏輯,正是所有云計算提供商如此熱衷於容器技術的重要原因:通過容器鏡像,它們可以和潛在用戶(即,開發者)直接關聯起來。

從一個開發者和單一的容器鏡像,到無數開發者和龐大的容器集羣,容器技術實現了從“容器”到“容器雲”的飛躍,標誌着它真正得到了市場和生態的認可。

這樣,容器就從一個開發者手裏的小工具,一躍成爲了雲計算領域的絕對主角;而能夠定義容器組織和管理規範的“容器編排”技術,則當仁不讓地坐上了容器技術領域的“頭把交椅”。

這其中,最具代表性的容器編排工具,當屬 Docker 公司的 Compose+Swarm 組合,以及 Google 與 RedHat 公司共同主導的 Kubernetes 項目

一、首先,Kubernetes 項目要解決的問題是什麼?

編排?調度?容器雲?還是集羣管理?
實際上,這個問題到目前爲止都沒有固定的答案。因爲在不同的發展階段,Kubernetes 需要着重解決的問題是不同的。

但是,對於大多數用戶來說,他們希望 Kubernetes 項目帶來的體驗是確定的:現在我有了應用的容器鏡像,請幫我在一個給定的集羣上把這個應用運行起來。
更進一步地說,我還希望 Kubernetes 能給我提供路由網關、水平擴展、監控、備份、災難恢復等一系列運維能力。等一下,這些功能聽起來好像有些耳熟?這不就是經典 PaaS(比如,Cloud Foundry)項目的能力嗎?

而且,有了 Docker 之後,我根本不需要什麼 Kubernetes、PaaS,只要使用 Docker 公司的 Compose+Swarm 項目,就完全可以很方便地 DIY 出這些功能了!
所以說,如果 Kubernetes 項目只是停留在拉取用戶鏡像、運行容器,以及提供常見的運維功能的話,那麼別說跟“原生”的 Docker Swarm 項目競爭了,哪怕跟經典的 PaaS 項目相比也難有什麼優勢可言。

而實際上,在定義核心功能的過程中,Kubernetes 項目正是依託着 Borg 項目的理論優勢,纔在短短几個月內迅速站穩了腳跟,進而確定了一個如下圖所示的全局架構:

image

我們可以看到,Kubernetes 項目的架構,跟它的原型項目 Borg 非常類似,都由 Master 和 Node 兩種節點組成,而這兩種角色分別對應着控制節點和計算節點。
其中,控制節點,即 Master 節點,由三個緊密協作的獨立組件組合而成,它們分別是負責 API 服務的 kube-apiserver、負責調度的 kube-scheduler,以及負責容器編排的 kube-controller-manager。整個集羣的持久化數據,則由 kube-apiserver 處理後保存在 Etcd 中。

二、而計算節點上最核心的部分,則是一個叫作 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 這個奇怪的名字,來自於 Borg 項目裏的同源組件 Borglet。不過,如果你瀏覽過 Borg 論文的話,就會發現,這個命名方式可能是 kubelet 組件與 Borglet 組件的唯一相似之處。因爲 Borg 項目,並不支持我們這裏所講的容器技術,而只是簡單地使用了 Linux Cgroups 對進程進行限制。

這就意味着,像 Docker 這樣的“容器鏡像”在 Borg 中是不存在的,Borglet 組件也自然不需要像 kubelet 這樣考慮如何同 Docker 進行交互、如何對容器鏡像進行管理的問題,也不需要支持 CRI、CNI、CSI 等諸多容器技術接口。

可以說,kubelet 完全就是爲了實現 Kubernetes 項目對容器的管理能力而重新實現的一個組件,與 Borg 之間並沒有直接的傳承關係。

三、Kubernetes 項目核心功能的“全景圖”

image

四、總結

首先,我和你一起回顧了容器的核心知識,說明了容器其實可以分爲兩個部分:容器運行時和容器鏡像。

然後,我重點介紹了 Kubernetes 項目的架構,詳細講解了它如何使用“聲明式 API”來描述容器化業務和容器間關係的設計思想。

實際上,過去很多的集羣管理項目(比如 Yarn、Mesos,以及 Swarm)所擅長的,都是把一個容器,按照某種規則,放置在某個最佳節點上運行起來。這種功能,我們稱爲“調度”。

而 Kubernetes 項目所擅長的,是按照用戶的意願和整個系統的規則,完全自動化地處理好容器之間的各種關係。這種功能,就是我們經常聽到的一個概念:編排。
所以說,Kubernetes 項目的本質,是爲用戶提供一個具有普遍意義的容器編排工具。

不過,更重要的是,Kubernetes 項目爲用戶提供的不僅限於一個工具。它真正的價值,乃在於提供了一套基於容器構建分佈式系統的基礎依賴。關於這一點,相信你會在今後的學習中,體會的越來越深。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章