使用者:九千鴉/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]

對象[編輯]

對象有兩個內嵌對象字段:specstatusstatus 用於表示對象的當前狀態,通過以下命令可以查看到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文件)的方式,更新PodReplicaSet[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[編輯]

CronJob控制器 在特定時間或按特定間隔運行任務,就像Cron工具。[21]

設計[編輯]

開發者使用 Kubernetes 有兩種方式:使用命令行工具(如:kubectlkubeadm)、客戶端庫。而這兩種方式均是基於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]

  • kubelet,作為節點的代理者,用於與 Master 進行通信,並管理着容器。[22][28]
  • kube-proxy,一種網絡代理,將 Kubernetes 的網絡服務代理到每個節點上。
  • 容器運行時(Container Runtime),用於操作容器,如:Docker[22][28]

網絡[編輯]

服務[編輯]

服務有五種類型:[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]

日誌架構[編輯]

容器化應用寫入 stdoutstderr 的任何數據,都會被容器引擎捕獲並被重定向到某個位置。[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地址和域名來提供服務發現機制,並且以輪循調度英語Round-robin DNS的方式將流量負載均衡到能與選擇器匹配的pod的IP地址的網絡連接上(即使是故障導致pod從一台機器移動到另一台機器)。[47] 默認情況下,服務任務會暴露在集群中(例如,多個後端pod可能被分組成一個服務,前端pod的請求在它們之間負載平衡);除此以外,服務任務也可以暴露在集群外部(例如,從客戶端訪問前端pod)。[53]

參考文獻[編輯]

  1. ^ PaaS将吞噬云计算?Kubernetes的市场冲击波-InfoQ. www.infoq.cn. [2020-03-31]. 
  2. ^ 2.0 2.1 2.2 2.3 2.4 Concepts. kubernetes.io. [2020-03-31] (英語). 
  3. ^ 3.0 3.1 Kubernetes API Overview. kubernetes.io. [2020-03-31] (英語). 
  4. ^ 4.0 4.1 Understanding Kubernetes Objects. kubernetes.io. [2020-04-08] (英語). 
  5. ^ Pod Overview. kubernetes.io. [2020-04-01] (英語). 
  6. ^ Pod | Kubernetes Engine Documentation. Google Cloud. [2020-04-13] (英語). 
  7. ^ 7.0 7.1 Using a Service to Expose Your App. kubernetes.io. [2020-04-12] (英語). 
  8. ^ DNS for Services and Pods. kubernetes.io. [2020-04-09] (英語). 
  9. ^ 9.0 9.1 Service. kubernetes.io. [2020-04-09] (英語). 
  10. ^ 没有选择器的服务. kubernetes.io. [2020-04-10] (英語). 
  11. ^ Labels and Selectors. kubernetes.io. [2020-04-04] (英語). 
  12. ^ ReplicationController. kubernetes.io. [2020-05-03] (英語). 
  13. ^ ReplicaSet. kubernetes.io. [2020-05-03] (英語). 
  14. ^ DaemonSet. kubernetes.io. [2020-05-03] (英語). 
  15. ^ DaemonSet | Kubernetes Engine Documentation. Google Cloud. [2020-05-03] (英語). 
  16. ^ Using kubectl to Create a Deployment. kubernetes.io. [2020-04-11] (英語). 
  17. ^ kubernetes/kubernetes. GitHub. [2020-04-14] (英語). 
  18. ^ Declarative Management of Kubernetes Objects Using Configuration Files. kubernetes.io. [2020-04-14] (英語). 
  19. ^ Pod | Kubernetes Engine Documentation. Google Cloud. [2020-04-14] (英語). 
  20. ^ Running a job | Kubernetes Engine Documentation. Google Cloud. [2020-05-02] (英語). 
  21. ^ CronJob. kubernetes.io. [2020-05-03] (英語). 
  22. ^ 22.0 22.1 22.2 22.3 22.4 Using Minikube to Create a Cluster. kubernetes.io. [2020-04-11] (英語). 
  23. ^ 23.0 23.1 Introduction to Kubernetes architecture. www.redhat.com. [2020-04-20] (英語). 
  24. ^ 24.0 24.1 Kubernetes Components. kubernetes.io. [2020-04-29] (英語). 
  25. ^ Controllers. kubernetes.io. [2020-04-20] (英語). 
  26. ^ Kubernetes 组件. kubernetes.io. [2020-04-29] (中文). 
  27. ^ Kubernetes Components. kubernetes.io. [2020-03-31] (英語). 
  28. ^ 28.0 28.1 node-components. kubernetes.io. [2020-04-12] (英語). 
  29. ^ Service. kubernetes.io. [2020-05-03] (英語). 
  30. ^ Exposing applications using services | Kubernetes Engine Documentation. Google Cloud. [2020-05-15] (英語). 
  31. ^ publishing-services-service-types. kubernetes.io. [2020-04-12] (英語). 
  32. ^ Storage overview | Kubernetes Engine Documentation. Google Cloud. [2020-04-14] (英語). 
  33. ^ 33.0 33.1 Volumes | Kubernetes Engine Documentation. Google Cloud. [2020-04-13] (英語). 
  34. ^ 34.0 34.1 34.2 Volumes. kubernetes.io. [2020-04-13] (中文). 
  35. ^ Health checks overview | Load Balancing. Google Cloud. [2020-04-17] (英語). 
  36. ^ 36.0 36.1 36.2 36.3 36.4 36.5 Configure Liveness, Readiness and Startup Probes. kubernetes.io. [2020-04-16] (英語). 
  37. ^ Pod Lifecycle. kubernetes.io. [2020-04-17] (英語). 
  38. ^ 日志架构. kubernetes.io. [2020-04-18] (中文). 
  39. ^ Get a Shell to a Running Container. kubernetes.io. [2020-04-02] (英語). 
  40. ^ directly-accessing-the-rest-api. kubernetes.io. [2020-04-02] (英語). 
  41. ^ programmatic-access-to-the-api. kubernetes.io. [2020-04-02] (英語). 
  42. ^ 42.0 42.1 Kubernetes Components. kubernetes.io. [2020-03-31] (英語). 
  43. ^ The container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
  44. ^ Kubernetes 组件. kubernetes.io. [2020-03-31] (中文). 
  45. ^ Accessing Clusters. kubernetes.io. [2020-04-02] (英語). 
  46. ^ 46.0 46.1 46.2 46.3 46.4 An Introduction to Kubernetes. DigitalOcean. [24 September 2015]. 
  47. ^ 47.0 47.1 Langemak, Jon. Kubernetes 101 – Networking. Das Blinken Lichten. 2015-02-11 [2015-11-02]. 
  48. ^ Strachan, James. Kubernetes for Developers. Medium (publishing platform). 2015-05-21 [2015-11-02]. 
  49. ^ Surana, Ramit. Containerizing Docker on Kubernetes. LinkedIn. 2015-09-16 [2015-11-02]. 
  50. ^ 50.0 50.1 Intro: Docker and Kubernetes training - Day 2. Red Hat. 2015-10-20 [2015-11-02]. (原始內容存檔於2015-10-29). 
  51. ^ 51.0 51.1 Overview of a Replication Controller. Documentation. CoreOS. [2015-11-02]. 
  52. ^ Sanders, Jake. Kubernetes: Exciting Experimental Features. Livewyer. 2015-10-02 [2015-11-02]. 
  53. ^ Langemak, Jon. Kubernetes 101 – External Access Into The Cluster. Das Blinken Lichten. 2015-02-15 [2015-11-02].