綜述
學習Kubernetes時,發現它的概念和術語仍是比較多的,光靠啃官方文檔比較晦澀。因此邊學習邊整理,對主要的概念和術語作一下分類及簡要說明。感受把重要概念都理解了,對Kubernetes的設計思想,總體框架也就有了初步的認識。node
從功能上來講,我把Kubernetes的概念或術語大概分爲如下三類:數據庫

- 組件:指實際在集羣中運行的Kubernetes程序集,分爲Master組件、Node組件及附加組件。
- 對象:對象是一個抽象的概念實體,Kubernetes把應用、運行場景、功能、集羣狀態等都抽象成一個個對象,並經過API對這些對象進行管理,從而管理整個集羣的狀態。
- 標識:對組件和對象的各類表示方式,例如命名、標籤、註釋等。標識是KubernetesAPI與操做對象間的紐帶。
組件
Master組件
Master組件提供了k8s管理集羣的核心功能,k8s經過Master組件實現整個集羣的調度管理,它就像集羣的大腦,會根據集羣當前的狀態,不斷進行調整,使集羣一直保持在指望的狀態。Master組件包括如下幾個進程:ubuntu
Etcd
Etcd是Kubernetes集羣的基礎組件,用於保存集羣全部的元數據信息、配置信息、對象狀態等。安全
Node組件
運行Node組件的節點稱爲Node節點,是k8s集羣實際的工做負載節點。Node節點能夠是物理機、虛擬機或任何能夠運行Node組件的設備。全部的業務應用都運行在Node節點中。Node組件包括如下幾個部分:架構
- Kubelet
kubelet負責實際的容器管理,Kubernetes經過apiserver給kubelet發送Pod管理請求,同時把Pod及Node的運行狀態彙報給apiserver。
- kube-proxy
kube-proxy負責集羣內部的請求轉發及負載均衡工做。它經過Service對象的配置信息,爲Pod建立代理服務,實現請求從Service到Pod的路由轉發。
- 容器運行時
實際的容器運行引擎。Kubernetes其實支持其餘的容器技術好比rkt,可是Docker相比與它們處於絕對的優點地位。因此,Kubernetes生態中的容器也基本特指指Docker容器。負載均衡
對象
在說明對象以前,先區分下Kubernetes中的三個名詞:對象(objects)、資源(resources)和工做負載(workload).框架
- 對象:指的是KubernetesAPI中定義好的操做對象,是抽象概念。
- 資源:抽象API對象被建立後,對象就被實例化了。實例化後的對象被稱爲資源。
- 工做負載:特指有運行容器的資源,例如Deployment資源就是工做負載,而service資源不是。
Kubernetes集羣爲每一個對象維護三類信息:對象元數據(ObjectMeta)、指望狀態(Desired State)與實際狀態(Autual State),元數據指對象的基本信息,好比命名、標籤、註釋等等,用於識別對象;指望狀態通常由用戶配置spec來描述的;實際狀態是由集羣各個組件上報的集羣實際的運行狀況。Kubernetes努力使每一個對象的實際狀態與指望狀態相匹配,從而使整個集羣的狀態與用戶配置的指望狀態一致。
Kubernetes對象通常用yaml文件來描述,有幾個個字段是必須的:運維
- apiVersion: 建立該對象所使用的 Kubernetes API 的版本
- kind: 想要建立的對象的類型
- metadata: 幫助識別對象惟一性的數據,包括一個 name 字符串、UID 和可選的 namespace
- spec: 對象指望狀態的描述
用戶經過命令行工具kubectl來操做這些對象,Kubectl吧yaml轉換成JSON格式來執行API請求。下面是一個POD對象的描述文件示例及註釋:分佈式
apiVersion: v1
kind: Pod # 對象名稱
metadata: # 對象的基本信息
name: pod-example # 對象惟一標示
spec: # 指望狀態
containers: # 指定pod中運行的容器鏡像及運行參數(相似Dockerfile)
- name: ubuntu
image: ubuntu:trusty
command: ["echo"]
args: ["Hello World"]
其中,kind字段描述對象類型"Pod",spec以前是對象的ObjectMeta,spec開始,就是對象指望狀態的描述。
根據官方API對象參考文檔的分類,下面咱們把對象分爲幾大類來分別簡要說明。計劃之後的文章,會結合實際操做,對各個重要對象作更深刻的說明。
Workloads 資源對象
- workloads類的對象用於管理運行容器實例
- Pod:
Pod是Kubernetes裏最重要的對象,也是Kubernetes集羣中運行部署應用或服務的最小單位。Pod對象描述一個Pod由哪些容器鏡像構成,以及這些容器應該怎麼運行。類比傳統的業務架構,Pod更接近於虛擬機的角色而不是應用進程的角色。
- ReplicaSet:
ReplicaSet對象是對Pod的更高一層抽象,它用來管理一組相同POD副本,並確保這組相同Pod的數量始終與用戶指望一致,並實現Pod的高可用。即若是有容器異常退出,ReplicaSet會自動建立新的Pod來替代,保證Pod數量永遠與用戶配置一致。
- Deployment:
Deployment對象是Kubernetes中最經常使用的對象之一,用於部署無狀態服務。它在ReplicaSet對象的基礎上,又作了一層抽象。經過管理多組ReplicaSet對象,來實現POD的滾動升級、回滾、擴容縮容等。
- StatefulSet:
不一樣於Deployment,StatefulSet對象顧名思義是對有狀態服務的一種抽象。因此,StatefulSet對象在定義時,相比與Deployment多了一些與狀態相關的內容,好比持久化存儲、服務對外的不變的惟一標示、部署、擴容、滾動升級時確保有序等等。
- DaemonSet:
DaemonSet對象是Kubernetes對守護進程的抽象。當咱們須要集羣中的每一個Node都跑一些如日誌收集、監控等守護進程時,就能夠把這類型進程包裝成Pod,並用調用DaemonSet來部署了。DaemonSet作的事情其實和Deployment差很少,只不過Deployment對象部署的Pod,會根據集羣狀況,在不一樣Node間自動調度。而DaemonSet會指定的NODE上(默認是集羣全部Node),都部署定義Pod,確保這些NODE都有跑着守護進程Pod。
- Job、CronJob:
除了上面幾個對象所抽象描述的應用工做場景外,實際業務場景中,還有一類應用或服務並不須要一直運行,好比一些一次性任務,或須要定時執行的任務。這種不須要長時間運行的任務,完成了就能夠退出的服務,就能夠用Job對象來定義。CronJob和Job對象的關係,和Deployment與ReplicaSet的關係很像,能夠類比來理解。首先,Job也是直接用於管理Pod的,同時能夠定義這個一次性任務Pod的執行時間、超時時間、錯誤處理(重啓仍是生成新Pod)等任務屬性。而CronJob管理是用來管理Job,相似crobtab,它能夠經過yaml文件中的schedule字段配置具體時間,來控制指定Job定時執行,從而實現定時執行特定的一次性任務。
Discovery & LB 資源對象
- 該類對象用於服務發現和負載均衡的對象
而Service對象就是用來解決這兩個問題的。它用固定的VIP或DNS名稱和指定標識的一組Pod對應起來,無論Pod IP怎麼變,Service對外的VIP都不會變化,而且,自動的將請求在這組Pod中負載均衡。
Config & Storage 資源對象
- 該類對象用於初始化容器配置及持久化容器存儲的對象
- Volume:
前面說到,Pod裏的不一樣容器能夠共享存儲,這個共享存儲就靠Volume來配置的。要注意的是,這裏Volume與Docker中的定義不用,Kubernetes中Volume跟Pod生命週期一致,Pod終止了,該Pod掛載的Volume就失效了(根據掛載volume的類型不一樣,數據可能丟失也可能不丟失)。
- PV,PVC:
Volume能夠支持多種類型的存儲,除了直接在Volume字段中去聲明全部存儲細節,K8S還抽象出了PV和PVC對象。簡單來講PV是對具體存儲資源的描述,好比存儲類型、地址、訪問帳戶等;而PVC,是對怎麼使用資源的方法的描述,好比只讀只寫,須要的空間等;而Pod經過Volume字段掛載具體要使用的PVC。PV和PVC是獨立於Pod單獨定義的,這樣,就把共享存儲的配置、分割、掛載等操做都解耦了。好比,一個NFS遷移後ip地址變了,存儲管理員只須要修改PV中的配置,而不用關心具體哪一個業務POD在使用這個NFS。
- ConfigMap,Securet
K8S中除了常見的存儲,還有一類特殊的Volume,不是爲了Pod存放數據,而是爲了給Pod提供數據的。ConfigMap和Secret對象就是用來定義這類型的Volume。簡單來講,能夠將它們理解爲一份Key:Value格式的數據,Pod能夠經過Volume掛載它們,將這份數據保存成文件隨時調用。惟一的區別是,ConfigMap對象保存的數據是明文,通常做爲應用配置文件;而Secret對象保存的對象要求是通過Base64轉碼的,用於提供數據庫密碼等對安全要求比較高的配置。不過這些配置,直接在作容器鏡像時就配置不就行了,爲啥要畫蛇添足呢?緣由和上面PV和PVC同樣,都是爲了儘量解耦業務核心與常常可能變化的依賴配置。好比數據庫更換了帳號,只須要修改Secret對象,不用從新去構建容器鏡像。
Cluster resources objects
- 該類對象定義整個K8S集羣運行方式的對象
- Namespace
Kubernetes做爲一個集羣管理平臺,爲不一樣用戶劃分不一樣權限管理,例如多租戶等,是必備的功能。而不一樣用戶做用域的隔離,就是靠Namespace對象實現的。Namespace是Kubernetes項目中的一個邏輯管理單位,不一樣Namespace的API對象,在調用API進行操做是,是相互隔離開的。經過不一樣用戶角色與Namespace關聯,從而實現權限管理。
Metadata resources
- 除了上述分類外的其餘對象都歸爲這一類,通常用來管理集羣的特殊功能好比彈性伸縮等
- Horizontal Pod Autoscaling
容器做爲一個輕量級的承載應用的技術,快速啓動和快速部署是它的優勢之一。天然的,根據業務負載自動擴縮容等需求,在容器集羣的可行性和效率就能夠變得很高。而Kubernetes中 Horizontal Pod Autoscaling對象,就是用於進行POD自動水平縮放的,這也是Kubernetes最能體現運維優點的特性之一。
Horizontal Pod Autoscaling具體的操做對象是Deployment和ReplicaSet,經過不一樣循環獲取每一個Pod的資源狀況,好比CPU利用率,並根據設定的目標利率來計算目前須要的Pod副本縮放的比例,而後經過訪問相應的Deployment或ReplicaSet對象,來對Pod數量進行自動縮放,從而提升了集羣資源總體利用率。
標識
標識是Kubernetes中最重要的概念,由於它是全部API的操做與操做對象間的紐帶。Kubernetes中的標識主要有如下幾種:
- Label
Label能夠說是Kubernetes中最最重要的核心概念,一個Lable是一個KEY=Value的鍵值對。任何對象資源均可以有一個或多個Label,而同個Label,也能夠配置在多個對象上。而後重點來了,大多數API對象的yaml字段中,都有Label Selector字段,能夠實現對Label中的key或value的多維度選擇,例如in、not in、and、or等等。這樣,Kubernetes對API做用對象就能進行多維度,細粒度的選擇,從而實現比較精細化的容器編排調度工做,好比,對全部"ENV:release"執行擴容操做,或者把部分請求灰度到有"ver:v1.14.0"的pod上等等。Label把資源對象和應用、基礎設施都解耦了,你不用關心這個Pod具體在那個Node上運行,也不用關心具體是什麼應用用了哪一個容器鏡像,只要Label符合Label Selector,就能夠經過API調用統一進行操做。
- Names
除了Label,全部資源對象確定還必須有一個全局惟一的標識,即Names字段。
- Annotation
Annotation很好理解,與一般意義的註釋同樣,用於描述做者、版本、配置說明等等任何須要的信息,須要說明的是,Annotation也必須是Key:Value格式的。
總結
經過上面對Kubernetes重要概念的說明,咱們能夠大體梳理出Kubernetes的一些設計理念:
- Kubernetes對容器應用進行了抽象,例如把一個容器或強關聯的一組容器抽象爲Pod,把各種存儲都抽象成Volume,把一組Pod抽象成Service等等基礎對象。
- 在基礎對象的層面上,Kubernetes又對應用使用場景,作了一層抽象。極客時間的Kubernetes課程有一張圖畫的很好:
能夠看到,Kubernetes中各個對象實際就是對生產業務場景的各種需求的抽象。
- 抽象出各種型對象之後,用戶能夠經過yaml文件(或直接命令行調用API)來描述這些對象的指望狀態,確認了各對象些指望狀態的集合,也就確認了整個集羣的指望狀態。這些全部的操做,都是聲明式的,而不是命令集羣要怎麼作
- Kubernetes經過控制器循環不斷將各組件收集來的集羣實際狀態與各對象的指望狀態對比,並自動化的將集羣實際狀態向指望狀態轉移,這個過程,也就是Kubernetes最核心的概念:編排。
本文對Kubernetes中的重要概念作了分類和簡要,後面的文章會結合集羣的實際操做,對每一個概念作更詳細的說明。