使用者:九千鴉/k8s
概括
編輯Kubernetes 與傳統的 PaaS 不同,它更多的被稱為 容器的PaaS 或者 CaaS(Containers as a service,容器即服務)。[1]
概念
編輯Kubernetes 包含一系列抽象概念,這些抽象概念用於表示系統的狀態,這包括:已部署的容器化應用和工作負載的抽象概念、與之相關的網絡和磁盤資源的抽象、集群運行的其他信息的抽象。[2]
工作节点
|--------------┐
Pod 1 Pod 2
| |
容器1 容器2
容器2 容器3
IP 10.1.0.1 IP 10.1.0.2
Kubernetes API
編輯Kubernetes API是REST API,是 Kubernetes 的基礎組件。組件間的操作和通信,以及外部用戶命令都是通過該API完成的,因此,Kubernetes平台里的任何對象都可以說是該API的執行對象。該API由 API服務器(kube-apiserver)管理。[3]
對象
編輯
對象有兩個內嵌對象字段:spec
和 status
。 status
用於表示對象的當前狀態,通過以下命令可以查看到pod的當前狀態:[4]
# 通过以下命令可以获得status
# kubectl get pods
# kubectl describe pods [Pod名称]
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-app 1/1 Running 0 20h
spec
表示集群期待的狀態(Desired State)。用戶可以使用YAML文件部署應用(創建對象),spec
字段則表示要部署的應用有什麼特徵。[4] 以下YAML文件描述了一個高級對象(Deployment),字段詳情可查看該網站。
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment # 对象的类型
metadata: # 该Deployment对象的元数据
name: nginx-deployment
spec:
selector: # Pods的标签选择器。选择哪些Pods受该Deployment管理。
matchLabels:
app: nginx
replicas: 2 # 希望运行2个pod
template:
metadata: # Pods对象的元数据
labels: # Pods对象的标签
app: nginx
spec:
containers:
- name: nginx # Pod的容器名为nginx
image: nginx:1.14.2 # 从Docker Hub拉去的镜像
ports:
- containerPort: 80
基礎對象
編輯Pod
編輯Pod(英語:豆莢)是最小單元(atomic unit)。Pod封裝了一個或若干個容器(Docker容器是最常用的容器),各容器可共享同一IP地址和端口、存儲資源(存儲卷)。但通常,一個Pod只會裝載一個容器,除非各容器間需要使用文件系統(存儲資源)進行通訊。[5][6]
雖然Pod擁有獨立的IP地址,但是該IP地址無法暴露在集群之外。此時,需要 服務 該對象進行幫助。[7]
服務
編輯服務(service),可以理解為邏輯上的Pod。通過服務的DNS名稱名(DNS name)可以找到服務,再通過服務可以調用Pod。[8] 調用方 通過調用服務的方式,避免了調用方與Pod的耦合,這樣當Pod宕機時,也不會影響到調用方,這也可用於負載均衡、服務發現等場景。[9]
选择一个Endpoint进行调用
|-----------| -------- Endpoint 1 -----> [Pod 1 暴露端口:80 IP:10.244.0.25]
| | [10.244.0.25:80]
调用 --> | service | -------- Endpoint 2 -----> [Pod 2 暴露端口:80 IP:10.244.0.26]
|10.96.92.53| [10.244.0.26:80]
|-----------| -------- Endpoint 3 -----> [Pod 3 暴露端口:80 IP:10.244.0.27]
[10.244.0.27:80]
服務也是擁有IP地址(稱為cluster IP)[9],通過kubectl get service
可查看到。服務沒有通過選擇器(selector)選擇Pod時,Endpoint對象 將無法被自動生成,服務將無法調用;另外,可通過直接指定 IP和端口 的方式,生成Endpoint對象,從而調用服務。[10] 可通過kubectl get endpoints
的方式查看Endpoint對象。
服務定義文件格式為 YAML(推薦) 和 JSON,示例如下:[7]
apiVersion: v1
kind: Service
metadata:
name: redis-master # DNS名
labels:
app: redis
role: master
tier: backend
spec:
ports:
- port: 6666 # 该服务暴露给外界的端口
targetPort: 6379 # Pods暴露的端口
selector: # 标签选择器,用于服务连接的Pod
app: redis
role: master
tier: backend
標籤和選擇器
編輯標籤(label)是鍵值對,用於存儲對象的數據。這些數據是特意展示給用戶看,具有意義和標誌性。 用戶通過 選擇器(全稱:標籤選擇器,Label selector)匹配標籤,API 將可找到匹配對象。[11]
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
高級對象
編輯高級對象 是依賴於控制器 ,而控制器是建立於基礎對象之上,並為之添加功能性和方便性。[2]
ReplicationController
編輯ReplicationController 用於確保Pod的數量正常。[12]
ReplicaSet
編輯ReplicaSet 是 ReplicationController 的升級版本,ReplicaSet 的標籤選擇器更加靈活。[13]
DaemonSet
編輯DaemonSet(Daemon:守護進程) 為了每一個節點分配有且只有一個Pod,使用場景有:[14][15]
- 存儲用的守護進程。
- 日誌收集的守護進程。
- 節點監控的守護進程。
Deployment
編輯Deployment控制器 提供了聲明式(使用YAML文件)的方式,更新Pod和ReplicaSet。[16][17][18] Deployment控制器可以管理其 Pod 組件的生命周期,還可以執行橫向擴縮以根據需要更改 Pod 的數量。[19]
下例為查看deployment對象:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
frontend 1/1 1 1 5d4h
Job
編輯Job控制器用於執行非持續性的任務(即任務是可執行完畢的),例如使用Pod發送一封郵件,發送完畢後Job控制器會被標記完成,失敗的話則重新發送一封郵件。Job控制器可創建單個或者多個Pod,如果創建多個Pod的話,將以並行的方式執行。[20]
CronJob
編輯設計
編輯開發者使用 Kubernetes 有兩種方式:使用命令行工具(如:kubectl 、 kubeadm)、客戶端庫。而這兩種方式均是基於Kubernetes API。[3]
當開發者想要部署 應用,那麼需要通過命令行工具等方式要告訴Master,Master將會調度Pod(Pod裝載着容器化的應用)到工作節點上。[22]
|-----------------------------------------------------------------------|
| cluster |
| Control Plane Components |
| Master node Work node |
| |------------------------| |--------------------| |
| | kube-apiserver | | kubelet | |
| | kube-scheduler | | kubelet-proxy | |
| | kube-contoller-manager | | Container runtime | |
| | etcd | | [ Pods ] | |
| |------------------------| |--------------------| |
| |
|-----------------------------------------------------------------------|
Control Plane
編輯控制平面(英語:Control Plane)位於主節點(Master node),包含主控件組(Master)、etcd。控制平面 通常用於與工作節點進行交互。[23]
Masters
編輯由於Master是由三個進程組成的,所以可以翻譯為「主控件組」。Master所在的工作節點將會被指定為 主節點。[2]主控組件包含的三個進程分別是:kube-apiserver、kube-controller-manager 和 kube-scheduler。[2]主控組件負責管理集群。[22]
- kube-apiserver(API server), 用於與(集群的)外界進行通訊。API server將會判斷接請求是否有效,如果有效就會處理。
kubectl
等命令行實質就是和該組件通訊。[23] - kube-scheduler,用於調度資源。觀察是否存在新創建的Pod沒有指派到節點,如果存在的話,則將其指派到其中一個節點上。[24]
- kube-controller-manager,通過控制器進行維護集群。從API server接收到的命令,將會修改集群某些對象的期待狀態(desired state),控制器觀察到這些期待狀態的變化,就會將這些對象的當前狀態(current state)變為期待狀態(desired state)。[25][22][24]
- Node controller:負責監視節點,當節點宕不可用時,進行通知。
- Replication controller:負責維護每一個replication controller對象所關聯的Pod數量。
- Endpoints controller:負責填充 Endpoints對象。
- Service Account & Token controllers:創建默認的賬號和API訪問令牌。
|--------------------|
command--> | kube-apiserver | ---> change object's
|--------------------| desired state
∧
|| watch
|---------------------------|
change object's <--- | kube-contoller-manager |
current state |---------------------------|
etc
編輯一致性和高可用的鍵值存儲軟件,用於備份k8s的所有集群。[26]
cloud-controller-manager
編輯在v1.11版本(2018年),cloud-controller-manager用於雲服務提供商
####TODO
工作節點
編輯節點(Node)默認表示 工作節點,而不代表 主節點。工作節點 運行着容器化的應用。 工作節點裝載着 Pod ,Pod是application workload的構成要素。[27]
網絡
編輯服務
編輯服務有五種類型:[29]
- ClusterIP(默認類型):只能在集群里訪問服務。
- NodePort:通過每個節點IP的某一特定端口,訪問服務(Node=節點,Port=端口)。
- LoadBalancer:通過雲服務商的負載均衡器,訪問服務。
- ExternalName:該服務 為外部 DNS 名稱提供內部別名。內部客戶端使用內部 DNS 名稱發出請求,然後請求會被重定向到外部名稱。[30]
通過節點IP地址進行暴露服務,可使用;通過雲服務提供商的負載均衡器暴露服務,則使用LoadBalancer
;[31]而當服務不在集群內,在集群之外,可以使用ExternalName
模式的服務進行重定向。
存儲
編輯存儲方案有很多。託管式的有如:網絡附加存儲(NAS)、數據庫、文件服務器;非託管式的則利用Kubernetes 存儲抽象,如:卷。[32]
卷
編輯對於應用而言,將數據寫入容器中的磁盤文件是最簡單的途徑,但這種方法存在缺陷。如果容器因其他任何原因崩潰或停止,文件將會丟失。此外,一個容器內的文件不可供同一 Pod 中運行的其他容器訪問。 卷(Volume)可以解決這兩個問題。[33][34]
臨時卷
編輯臨時卷 與Pod的生命周期一樣,隨着包裹其的Pod終止或被刪除時,該卷也會隨之終止或刪除。[33][34]
持久性卷
編輯持久性卷(Persistent Volumes),在 Pod 被移除時,系統只是卸載該卷,數據將保留,並可將其數據傳遞到另一個 Pod。[34]
健康檢查
編輯K8s的對於容器的健康檢查(Health Check)有三種:存活探測(Liveness Probe)、就緒探測(Readiness Probe)、啟動探測(Startup Probe)。[35][36] 執行順序如下
启动容器 --> Startup Probe ------> Readiness Probe
|----> Liveness Probe
存活探測
編輯存活探測(Liveness Probe):當不符合條件時,容器將會被重啟。通常用於遇到Bug,無法進行下去的情況,如:死鎖。[36]
常見的存活探測如下:根據命令、根據HTTP返回碼、根據TCP是否連接成功。可用於判定命令是否執行成功,當失敗且返回值為非0時,容器將會被重啟;對於HTTP服務,可通過發送HTTP請求,並根據是否 400>返回码>=200
,判斷是否存活;對於TCP連接,則在指定的時間內觀察容器是否能連接成功,如果不能則重啟容器。[36]
就緒探測
編輯就緒探測(Readiness Probe):當符合條件時,容器將被視為已就緒。就緒探測的一個用途:當一個Pod的所有容器就緒後,將會告訴 服務 該Pod可被使用。[36]
通過TCP進行就緒探測,那麼會循環進行TCP連接,直到連接成功,容器將會被視為就緒。通過命令行方式進行就緒探測,當返回值為0時,容器將會被視為就緒。[36]
啟動探測
編輯啟動探測(Startup Probe):當符合條件時,容器被視為已啟動。當應用需要長時間進行啟動時,啟動探測 會在一定時間內不斷地探測應用是否啟動成功,當應用啟動成功後,存活探測或就緒探測 可被啟動;超過探測時間的話,容器將會被殺死,並且根據 restartPolicy
來做出相應操作。[36] [37]
日誌架構
編輯容器化應用寫入 stdout
和 stderr
的任何數據,都會被容器引擎捕獲並被重定向到某個位置。[38] 如:Docker容器 的日誌,可以在節點上查找得到。
常見問題
編輯連接應用
編輯Dashboard
編輯Dashboard 是關於Kubernetes用戶接口相關操作的網頁。通過Dashboard,用戶可以對容器化應用進行部署、查看的概覽信息、故障排除,以及管理集群資源。
直接連接
編輯通常想要在Pod里運行命令,會通過使用 kubectl exec [Pod名字] [命令]
命令,這與Docker一樣。[39] 如果想要通過HTTP協議連接Pod(REST API),則可運行代理模式的 kubectl ,[40] 也可以編程的方式去訪問 REST API。[41]
控制平面
編輯控制平面(Control Plane)管理着集群中的 工作節 和 Pod。在生產環境裡,控制平面 經常會 連接(runs across)若干個計算機。[42]
容器編排層暴露出來的
The container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
Control Plane [43]。
控制平面組件 用於對集群進行全局決策(如:調度),並檢測和響應集群事件(例如,當不滿足部署的 replicas
字段時,啟動新的 pod)。雖然 控制平面組件 可在集群中的任何節點上運行,但通常會安裝在同一機器上。[42][44]
kube-scheduler
編輯kube-controller-manager
編輯etcd
編輯集群中的工作節點,將會運行着兩個進程:[2]
- kubelet,用於與 master節點 進行通信。
- kube-proxy,一種網絡代理,將 Kubernetes 的網絡服務代理到每個節點上。
其他
編輯代理服務器
編輯通過 kubectl proxy
該命令將會運行一個反向代理,通過該代理,我們能直接訪問 REST API (通過CURL或瀏覽器訪問的方式)。[45] 再通過 http://代理地址/api/v1/namespaces/default/pods/应用地址/proxy
的方式方問
如若想訪問應用的其他端口,則應使用 kubectl port-forward
,建立端口轉發,如:調試數據庫。
設計
編輯Kubernetes在設計結構上定義了一系列的構建模塊,其目的是為了提供一個可以共同提供部署、維護和擴展應用程序的機制。組成Kubernetes的組件設計概念為鬆耦合和可擴展的,這樣可以使之滿足多種不同的工作負載。可擴展性在很大程度上由Kubernetes API提供,此API主要被作為擴展的內部組件以及Kubernetes上運行的容器來使用。[46]
對象
編輯Pod
編輯Kubernetes的基本調度單元稱為「pod」。通過該種抽象類別可以把更高級別的抽象內容增加到容器化組件。一個pod一般包含一個或多個容器,這樣可以保證它們一直位於主機上,並且可以共享資源。[46]Kubernetes中的每個pod都被分配一個唯一的(在集群內的)IP地址就可以允許應用程序使用同一端口,而避免了發生衝突的問題。[47] Pod可以定義一個卷,例如本地磁盤目錄或網絡磁盤,並將其暴露在pod中的一個容器之中。[48]。pod可以通過Kubernetes API手動管理,也可以委託給控制器來實現自動管理。[46]
標籤和選擇器
編輯Kubernetes使客戶端(用戶或內部組件)將稱為「標籤」的鍵值對附加到系統中的任何API對象,如pod和節點。相應地,「標籤選擇器」是針對匹配對象的標籤的查詢方法。[46]
標籤和選擇器是Kubernetes中的主要分組機制,用於確定操作適用的組件。[49]
例如,如果應用程序的Pods具有系統的標籤 tier
(比如"front-end
"、"back-end
") 和一個 release_track
(比如"canary
"、"production
"),那麼對所有"back-end
" 和 "canary
" 節點的操作可以使用如下所示的標籤選擇器:[50]
tier=back-end AND release_track=canary
控制器
編輯控制器是通過管理一組pod來實現來將實際集群狀態轉移到所需集群狀態的對帳循環機制[51]。一種控制器指的是一組具有相同特徵的「複製控制器」,控制器通過在集群中運行指定數量的pod副本來處理複製和縮放。在基礎節點出現故障的情況下,它還可以用於處理創建替換pod。[51]其它控制器也是核心Kubernetes系統的一部分,包括「DaemonSet控制器」為每台機器(或機器的一些子集)上運行的單個pod,和用於運行pod的「作業控制器」。[52] 控制器管理的pod組由作為控制器定義的部分的標籤選擇器來確定。[50]
服務
編輯Kubernetes服務本質是一組協同工作的pod,類同多層架構應用中的一層。構成服務的pod組通過標籤選擇器來定義。[46]Kubernetes通過給服務分配靜態IP地址和域名來提供服務發現機制,並且以輪循調度的方式將流量負載均衡到能與選擇器匹配的pod的IP地址的網絡連接上(即使是故障導致pod從一台機器移動到另一台機器)。[47] 默認情況下,服務任務會暴露在集群中(例如,多個後端pod可能被分組成一個服務,前端pod的請求在它們之間負載平衡);除此以外,服務任務也可以暴露在集群外部(例如,從客戶端訪問前端pod)。[53]
參考文獻
編輯- ^ PaaS将吞噬云计算?Kubernetes的市场冲击波-InfoQ. www.infoq.cn. [2020-03-31].
- ^ 2.0 2.1 2.2 2.3 2.4 Concepts. kubernetes.io. [2020-03-31] (英語).
- ^ 3.0 3.1 Kubernetes API Overview. kubernetes.io. [2020-03-31] (英語).
- ^ 4.0 4.1 Understanding Kubernetes Objects. kubernetes.io. [2020-04-08] (英語).
- ^ Pod Overview. kubernetes.io. [2020-04-01] (英語).
- ^ Pod | Kubernetes Engine Documentation. Google Cloud. [2020-04-13] (英語).
- ^ 7.0 7.1 Using a Service to Expose Your App. kubernetes.io. [2020-04-12] (英語).
- ^ DNS for Services and Pods. kubernetes.io. [2020-04-09] (英語).
- ^ 9.0 9.1 Service. kubernetes.io. [2020-04-09] (英語).
- ^ 没有选择器的服务. kubernetes.io. [2020-04-10] (英語).
- ^ Labels and Selectors. kubernetes.io. [2020-04-04] (英語).
- ^ ReplicationController. kubernetes.io. [2020-05-03] (英語).
- ^ ReplicaSet. kubernetes.io. [2020-05-03] (英語).
- ^ DaemonSet. kubernetes.io. [2020-05-03] (英語).
- ^ DaemonSet | Kubernetes Engine Documentation. Google Cloud. [2020-05-03] (英語).
- ^ Using kubectl to Create a Deployment. kubernetes.io. [2020-04-11] (英語).
- ^ kubernetes/kubernetes. GitHub. [2020-04-14] (英語).
- ^ Declarative Management of Kubernetes Objects Using Configuration Files. kubernetes.io. [2020-04-14] (英語).
- ^ Pod | Kubernetes Engine Documentation. Google Cloud. [2020-04-14] (英語).
- ^ Running a job | Kubernetes Engine Documentation. Google Cloud. [2020-05-02] (英語).
- ^ CronJob. kubernetes.io. [2020-05-03] (英語).
- ^ 22.0 22.1 22.2 22.3 22.4 Using Minikube to Create a Cluster. kubernetes.io. [2020-04-11] (英語).
- ^ 23.0 23.1 Introduction to Kubernetes architecture. www.redhat.com. [2020-04-20] (英語).
- ^ 24.0 24.1 Kubernetes Components. kubernetes.io. [2020-04-29] (英語).
- ^ Controllers. kubernetes.io. [2020-04-20] (英語).
- ^ Kubernetes 组件. kubernetes.io. [2020-04-29] (中文).
- ^ Kubernetes Components. kubernetes.io. [2020-03-31] (英語).
- ^ 28.0 28.1 node-components. kubernetes.io. [2020-04-12] (英語).
- ^ Service. kubernetes.io. [2020-05-03] (英語).
- ^ Exposing applications using services | Kubernetes Engine Documentation. Google Cloud. [2020-05-15] (英語).
- ^ publishing-services-service-types. kubernetes.io. [2020-04-12] (英語).
- ^ Storage overview | Kubernetes Engine Documentation. Google Cloud. [2020-04-14] (英語).
- ^ 33.0 33.1 Volumes | Kubernetes Engine Documentation. Google Cloud. [2020-04-13] (英語).
- ^ 34.0 34.1 34.2 Volumes. kubernetes.io. [2020-04-13] (中文).
- ^ Health checks overview | Load Balancing. Google Cloud. [2020-04-17] (英語).
- ^ 36.0 36.1 36.2 36.3 36.4 36.5 Configure Liveness, Readiness and Startup Probes. kubernetes.io. [2020-04-16] (英語).
- ^ Pod Lifecycle. kubernetes.io. [2020-04-17] (英語).
- ^ 日志架构. kubernetes.io. [2020-04-18] (中文).
- ^ Get a Shell to a Running Container. kubernetes.io. [2020-04-02] (英語).
- ^ directly-accessing-the-rest-api. kubernetes.io. [2020-04-02] (英語).
- ^ programmatic-access-to-the-api. kubernetes.io. [2020-04-02] (英語).
- ^ 42.0 42.1 Kubernetes Components. kubernetes.io. [2020-03-31] (英語).
- ^ The container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
- ^ Kubernetes 组件. kubernetes.io. [2020-03-31] (中文).
- ^ Accessing Clusters. kubernetes.io. [2020-04-02] (英語).
- ^ 46.0 46.1 46.2 46.3 46.4 An Introduction to Kubernetes. DigitalOcean. [24 September 2015].
- ^ 47.0 47.1 Langemak, Jon. Kubernetes 101 – Networking. Das Blinken Lichten. 2015-02-11 [2015-11-02].
- ^ Strachan, James. Kubernetes for Developers. Medium (publishing platform). 2015-05-21 [2015-11-02].
- ^ Surana, Ramit. Containerizing Docker on Kubernetes. LinkedIn. 2015-09-16 [2015-11-02].
- ^ 50.0 50.1 Intro: Docker and Kubernetes training - Day 2. Red Hat. 2015-10-20 [2015-11-02]. (原始內容存檔於2015-10-29).
- ^ 51.0 51.1 Overview of a Replication Controller. Documentation. CoreOS. [2015-11-02].
- ^ Sanders, Jake. Kubernetes: Exciting Experimental Features. Livewyer. 2015-10-02 [2015-11-02].
- ^ Langemak, Jon. Kubernetes 101 – External Access Into The Cluster. Das Blinken Lichten. 2015-02-15 [2015-11-02].