大蕉說k8s(開篇)No.181
- 2020 年 2 月 25 日
- 筆記
Kubernetes,全名還是有點長的,業界縮寫是 k8s,後續我也用k8s來代替全名。關於k8s,官方的介紹是這樣的
Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.
k8s是一個提供 自動化部署、自動化擴縮容以及管理容器化應用的開源系統。
怎麼理解呢?就是首先,k8s 是開源的,這是毋庸置疑的。其次呢,k8s 管理的對象是 容器化的應用,也就是說普通的非容器化的應用它不管。第三呢,它提供了 自動化部署和自動化擴縮容 的能力。
這三條合起來,可以實現一個普遍的現有系統自動化運維能力。
至於為什麼用容器來作為運行基礎,每個人有每個人的看法,我的看法比較勢利,就是為了提高資源利用率,人和機器利用率,主要是機器。
直接部署在物理主機上或者雲主機上是這樣的,所有 App 公用作業系統以及硬體資源,各個App間可能互相影響,無法隔離,這確實是資源利用最高效的方式。

虛擬機部署方式是這樣的,好處是各個應用隔離非常徹底,缺點就是都要在主機作業系統上,跑多一層作業系統,資源浪費比較嚴重。

容器化部署是這樣的,好處就是App間隔離非常好,公用底層作業系統資源利用率蠻高,每個App都有自己的環境和資源分配。目前比較主流的開源容器技術有兩,一是 Docker,二是Rocket。(小提問,Docker需要我來講嗎?)

總得來說,k8s選擇容器技術作為最基礎運行單位,有著一定的考慮,比較重點的原因是容器技術可以做到 App 間隔離,以及相對於虛擬機的資源利用率。但是還有更加核心的一點,就是容器鏡像。
有了容器鏡像,開發者在本地運行的環境,跟放在服務端運行的環境可以保持 幾乎 100% 一致,本地的表現是怎樣的,打包成鏡像後在服務端運行的表現就是怎樣的。另外一方面,因為鏡像很標準包含了應用所需的所有環境,應用可以在調度下,非常非常方便地進行水平擴容和縮容。
聊完基礎的,聊聊 k8s 整體的大框架,圖取自《kubernetes 實戰》。

大的組件是這樣的,我先大概講一下各自的用途,後面每個組件詳細說說,我們把 Kubernetes 當成小區公寓管理員,那麼 Docker 可以認為是一個個的商品房套間里的一個房間。整個k8s 調度可以這樣理解,一個是 status 狀態,一個是 spec 期待,我們會有一個監控的程式,一直看著集群有任何一個部署的單元的狀態,如果當前的狀態跟期待值有區別,將會按照定義好的方式,把它搞到狀態值跟期待值一致。
比如我定義了
spec: 3隻?
status: 2 只 ?
可以看到,當前的狀態不對,需要再搞1 只?。那麼管理員不管是現場生1隻?,還是去路上撿1 只?,都要把它搞到 3隻?,而且還要品種一樣。這讓管理應用集群的小夥子壓力小多了。
Namespace: 命名空間,隔離用的,不同 NameSpace 相當於不同的單元。比如一單元二單元, 小區單元間默認是不互通的(當然也有辦法打通,比如通過 Service)。
Deployment: 部署,我們最常見的應用就會部署在這裡啦,他相當於一個套間,其中包含 Pod (整個套間,可能包含多個容器,荷蘭?和中華田園?要分房間) 和 Volume (存儲間)。
Pod: 部署的最小單位,一個 Pod 相當於整個套間,這個 Pod 要麼完全起來要麼完全沒起來,起了一半的都算沒起。k8s 的調度也是基於 Pod 維度的,也就是說,一旦一個 Pod 的 一個容器壞掉了要換,k8s 不會只換一個容器,會直接換掉整個 Pod (1 個?間壞了,整套公寓都要換掉)。
Volume: 在k8s 中,存儲是伴隨著目錄的,如果沒有特殊外部存儲,那麼一個容器的啟動會新建一個目錄,並且在銷毀的時候會把它刪掉,也就是說你連?粑粑可能都見不到。而看不到?粑粑是很難受的,排查問題都沒法排查。所以我們可以把外部存儲掛載進來。常見的有三種,一種是本地空目錄,一種是主機目錄,另外一種是 PV (Persistent Volume 持久化卷)。
ConfigMap: 我們會把幾乎所有的配置放在 ConfigMap 中,是典型的 kv 存儲。這樣維護起來很簡單,也不需要每次啟動容器的時候手動改配置。
Secret: 跟ConfigMap 是一模一樣的,區別就是只有在運行時的時候可以由程式獲取到,其他時間任何人都是看不見的。
DaemonSet: 後台程式,跟 Deployment 沒什麼區別,會一直在後台運行,會在每一個加入集群的節點中都啟動一個,保證自己是啟動的,一般會是一些守護容器或者監控或者代理容器。
StatefulSet: 跟 Deployment 沒什麼區別 ,區別點有兩個,第一個是 StatefulSet 是有唯一固定的標識的。Deployment 來說殺掉一個 1 號 Pod,可能會創建一個8 號 Pod 來代替。但是 StatefulSet 殺掉一個 1 號 Pod,也會創建一個一樣的 1 號 Pod 來代替。第二個是會配合外部固定的持久化存儲使用,保證新創建的 Pod 數據也是跟原來的 Pod 保持一致。一般 Mysql 這類需要固定存儲的會用這類存儲。
CrobJob: 內容跟 Deployment 差不多,區別點就是Deployment 會一直運行著,CrobJob 會定時運行,運行完成就殺掉自己。
Job: 跟 CrobJob 一樣,區別就是運行一次就殺掉自己,一般沒人用。
LabelSelector: 標籤選擇器,k8s 內部基本所有資源篩選都會通過打標籤的形式。比如Pod 選擇部署的節點,Service 服務選擇提供服務的 Pod。定義的形式就是典型的字元串 kv。比如 wealth : rich,height : 180,outlook : hansome。
Service: 選擇一批 Pod 作為服務提供者,並且與集群的 dns 聯動,生成統一的域名,集群內一般通訊都通過 Service 進行。特定的 Service 比如 Ingress 和 Nginx 還可以對外暴露埠進行服務提供。比如 Service 名叫荷蘭?,會尋找 Label 為荷蘭?的 Pod,然後直接把它們暴露給需要服務的人。
其他沒什麼好說的,基礎概念說完了。如果你只能記住一句話,那麼就記住這個叭。Pod 是最基礎部署單元,有很多個容器,帶了一定的標籤,可以通過 Service 對外提供服務。