Kubernetes
是一個開源的容器編排引擎,用來對容器化應用進行自動化部署、 擴縮和管理。然而並不是全部項目都須要微服務化,也並不是全部項目須要Kubernetes
,例如管理後臺、定時任務服務、非分佈式數據庫等就沒有必要容器化部署,Kubernetes
更適合部署分佈式微服務應用。java
這兩天筆者看完了《Kubernetes
源碼剖析》這本書,因爲Kubernetes
是用go
語言編寫,不少Java
程序員可能沒學過go
語言,爲了分享這本書,筆者摘錄了書中的一些關鍵知識點整理成這篇文章,也但願經過這篇文章幫助你們理解Kubernetes
。程序員
(以前公司內部技術分享畫的學習路線思惟導圖)算法
Kubernetes架構
(圖片來源:《
Kubernetes
源碼剖析》.Kubernetes
架構圖)數據庫
Kubernetes
系統採用C/S
架構設計,系統架構分爲Master
、Node
兩部分,Master
爲Server
端(主控節點),Node
爲Client
端(工做節點)。後端
Master
主控節點做爲集羣的大腦負責管理全部工做節點(Node
)、負責調度Pod
運行在哪些工做節點上、負責控制集羣運行過程當中的全部狀態,其中節點表示雲虛擬服務器。api
Node
工做節點負責管理容器、監控和上報運行在本節點上的全部Pod
的運行狀態。服務器
運行在Master
主控節點上的組件有kube-apiserver
、kube-controller-manager
、kube-scheduler
組件。微信
kube-apiserver
負責將Kubernetes
「資源組/資源版本/資源」以RESTful
風格的形式對外暴露並提供服務。集羣中的全部組件都經過kube-apiserver
組件操做資源對象。kube-apiserver
組件也是集羣中惟一與Etcd
集羣進行交互的核心組件。網絡
kube-controller-manager
管理Kubernetes
集羣中的節點(Node
)、Pod
副本、服務、端點(Endpoint
)、命名空間(Namespace
)、服務帳戶(ServiceAccount
)等。負責確保Kubernetes
系統的實際狀態收斂到所需狀態,其默認提供了一些控制器(Controller
),例如DeploymentControllers
控制器、StatefulSet
控制器、Namespace
控制器及PersistentVolume
控制器等,每一個控制器經過kube-apiserver
組件提供的接口實時監控整個集羣每一個資源對象的當前狀態,當發生故障而致使系統狀態出現變化時,嘗試將系統狀態修復到指望狀態。架構
kube-scheduler
調度器組件負責在Kubernetes
集羣中爲一個Pod
資源對象找到合適的節點並在該節點上運行。調度器每次只調度一個Pod
資源對象,爲每個Pod
資源對象尋找合適節點的過程是一個調度週期。調度器組件監控整個集羣的Pod
資源對象和Node
資源對象,在監控到新的Pod
資源對象時經過調度算法爲其選擇最優節點。
運行在Node
工做節點上的組件有kubelet
、kube-proxy
、container
組件。
kubelet
負責接收、處理、上報kube-apiserver
組件下發的任務。kubelet
進程啓動時會向kube-apiserver
註冊節點(Node
)自身信息。它主要負責所在節點(Node
)上的Pod
資源對象的建立、修改、監控、刪除、驅逐及Pod
生命週期管理等。kubelet
組件實現了3
種開放接口,分別是CRI
(容器運行時接口)、CNI
(容器網絡接口)和CSI
(容器存儲接口)。
kube-proxy
做爲節點上的網絡代理,運行在每一個Kubernetes
節點上。它監控kube-apiserver
的服務和端點資源變化,並經過iptables/ipvs
等配置負載均衡器,爲一組Pod
提供統一的TCP/UDP
流量轉發和負載均衡功能,但只會向Kubernetes
服務及其後端Pod
發出請求。
資源概念
在kubernetes
中,資源是最核心的概念,整個生態系統都圍繞資源運做。Kubernetes
本質上是一個資源控制系統,負責註冊、管理、調度資源並維護資源的狀態。
Kubernetes
將資源分組和版本化:
Group
:資源組Version
:資源版本Resource
:資源Kind
:資源種類(分類)
資源對象與資源操做方法:
資源對象(
Resource Object
):一個資源對象包含的字段有資源組、資源版本、資源種類;資源操做方法(
Verbs
):每個資源都擁有資源操做方法,實現對Etcd
的CURD
操做,kubernetes
支持的8
種資源操做方法是create
、delete
、deletecollection
、get
、list
、patch
、update
、watch
。
Kubernetes
支持兩類資源組,分別是擁有組名的資源組和沒有組名的資源組:
擁有組名的資源組:其表現形式爲
<group>/<version>/<resource>
,例如apps/v1/deployments
;沒有組名的資源組:核心資源組,其表現形式爲
<version>/<resource>
,例如/v1/pods
。
Kubernetes
提供的Restful API
使用GVR
(資源分組/資源版本/資源)生成path
,以下表格示例:
PATH | 資源 | 資源操做方法 |
---|---|---|
/api/v1/configmaps | ConfigMap | create,delete,deletecollection,get,list,patch,update,watch |
/api/v1/pods | Pod | create,delete,deletecollection,get,list,patch,update,watch |
/api/v1/services | Service | create,delete,deletecollection,get,list,patch,update,watch |
...... |
擁有組名的資源組的path
以/apis
爲前綴,沒有組名的資源組的path
以/api
爲前綴。以/api/v1/configmaps
爲例,v1
爲資源版本號、configmaps
爲資源名稱。
資源還能夠擁有子資源,例如pods
有logs
子資源。用kubectl
查詢日記則命令爲kubectl logs [pod]
,對應API
的path
爲:/api/v1/pods/logs
。
kubernetes
支持8
種資源操做方法,但並不是每種資源都須要支持8
種資源操做方法。如pods/logs
子資源就只擁有get
操做方法,由於日誌只須要執行查看操做。
Kubernetes
系統支持命名空間(Namespace
),每一個命名空間至關於一個「虛擬集羣」,不一樣命名空間之間能夠進行隔離。命名空間經常使用於劃分不一樣的環境,例如生產環境、測試環境、開發環境等使用不一樣的命名空間進行劃分,也可用於劃分無關聯的項目,如用於劃分項目A
、項目B
。
資源對象描述文件定義
Kubernetes
資源可分爲內置資源和自定義資源,它們都經過資源對象描述文件進行定義。一個資源對象須要用5
個字段來描述,分別是Group/Version
、Kind
、MetaData
、Spec
、Status
。
以Service
資源描述文件爲例,配置以下:
apiVersion: v1
kind: Service
metadata:
name: test-service
namespace: default
spec:
....
apiVersion
:即Group/Version
,Service
在覈心資源組,因此沒有資源組名,v1
爲資源版本;Kind
:資源種類;MetaData
:定義元數據信息,如資源名稱、命名空間;Spec
:描述Service
的指望狀態;Status
:描述資源對象的實際狀態,隱藏的,不須要配置,由Kubernetes
系統提供和更新。
Pod調度
Pod
資源對象支持優先級與搶佔機制。當kube-scheduler
調度器運行時,根據Pod
資源對象的優先級進行調度,高優先級的Pod
資源對象排在調度隊列的前面,優先得到合適的節點(Node
),再爲低優先級的Pod
資源對象選擇合適的節點。
當高優先級的Pod
資源對象沒有找到合適的節點時,調度器會嘗試搶佔低優先級的Pod
資源對象的節點,搶佔過程是將低優先級的Pod
資源對象從所在的節點上驅逐走,使高優先級的Pod
資源對象運行在該節點上,被驅逐走的低優先級的Pod
資源對象會從新進入調度隊列並等待再次選擇合適的節點。
在默認的狀況下,若不啓用優先級功能,則現有Pod
資源對象的優先級都爲0
。爲Pod
資源配置優先級的步驟以下:
1
、經過PriorityClass
資源對象描述文件建立PriorityClass
資源對象,配置文件以下:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: MainResourceHighPriority
value: 10000
globalDefault: false
description: "highest priority"
value
:表示優先級,值越高優先級越高;globalDefault
:是否爲全局默認,當Pod
沒有指定使用的優先級時默認使用此優先級。2
、修改Pod
資源對象描述文件,爲Pod
指定優先級
經過Deployment
配置Pod
資源時,只須要在Deployment
描述文件的Spec
下的Spec
添加一項名爲priorityClassName
的配置,以下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-server
namespace: default
spec:
replicas: 1
# 配置pod
spec:
containers:
- name: test-server-pod
image: test-server:latest
imagePullPolicy: IfNotPresent
ports:
- name: http-port
containerPort: 8080
envFrom:
- configMapRef:
name: common-config
serviceAccountName: admin-sa
priorityClassName: MainResourceHighPriority
親和性調度
與調度相關的還有親和性調度。kube-scheduler
調度器自動爲Pod
資源對象選擇全局最優或局部最優節點(即節點的硬件資源足夠多、節點負載足夠小等)。在生產環境中,通常但願可以更多地干預Pod
資源對象的調度,例如,將不須要依賴GPU
硬件資源的Pod
資源對象分配給沒有GPU
硬件資源的節點,將須要依賴GPU
硬件資源的Pod
資源對象分配給具備GPU
硬件資源的節點。開發者只須要在這些節點上打上相應的標籤,而後調度器就能夠經過標籤進行Pod
資源對象的調度,這種調度策略被稱爲親和性和反親和性調度。
親和性(
Affinity
):用於多業務就近部署,例如容許將兩個業務(如廣告點擊服務
與IP查詢服務
)的Pod
資源對象儘量地調度到同一個節點上,減小網絡開銷;反親和性(
Anti-Affinity
):容許將一個業務的Pod
資源對象的多副本實例調度到不一樣的節點上,以實現高可用性,例如訂單服務的POD
指望有三個副本,將三個副本部署在不一樣的節點上。
Pod
資源對象目前支持兩種親和性和一種反親和性:
NodeAffinity
:節點親和性,將某個Pod
資源對象調度到特定的節點上,如須要GPU
的POD
調度到有GPU
的節點上;PodAffinity
:Pod
資源對象親和性,將某個Pod
資源對象調度到與另外一個Pod
資源對象相鄰的位置,例如調度到同一主機,調度到同一硬件集羣,調度到同一機房,以縮短網絡傳輸延時;PodAntiAffinity
:Pod
資源對象反親和性,將一個Pod
資源對象的多副本實例調度到不一樣的節點上,調度到不一樣的硬件集羣上等,這樣能夠下降風險並提高Pod
資源對象的可用性。
內置調度算法
kube-scheduler
調度器默認提供了兩類調度算法,分別是預選調度算法和優選調度算法。
預選調度算法:檢查節點是否符合運行「待調度
Pod
資源對象」的條件,若是符合條件,則將其加入可用節點列表;優選調度算法:爲每個可用節點計算出一個最終分數,
kube-scheduler
調度器會將分數最高的節點做爲最優運行「待調度Pod
資源對象」的節點。
參考文獻
[1]鄭東旭.Kubernetes源碼剖析[M].電子工業出版社:北京,2020
[2]Kubernetes官方文檔.https://kubernetes.io
![](http://static.javashuo.com/static/loading.gif)
本文分享自微信公衆號 - Java藝術(javaskill)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。