- Kubernetes進階實戰
- 馬永亮
- 5003字
- 2019-03-13 14:20:38
3.1 資源對象及API群組
REST是Representational State Transfer的縮寫,意為“表征狀態轉移”,它是一種程序架構風格,基本元素為資源(resource)、表征(representation)和行為(action)。資源即對象,一個資源通常意味著一個附帶類型和關聯數據、支持的操作方法以及與其他對象的關系的對象,它們是持有狀態的事物,即REST中的S(State)。REST組件通過使用“表征”來捕獲資源的當前或預期狀態并在組件之間傳輸該表征從而對資源執行操作。表征是一個字節序列,由數據、描述數據的元數據以及偶爾描述元數據的元數據組成(通常用于驗證消息的完整性),表征還有一些其他常用但不太精確的名稱,如文檔、文件和HTTP消息實體等。表征的數據格式稱為媒體類型(media type),常用的有JSON或XML。API客戶端不能直接訪問資源,它們需要執行“動作”(action)來改變資源的狀態,于是資源的狀態從一種形式“轉移”(Transfer)為另一種形式。
資源可以分組為集合(collection),每個集合只包含單一類型的資源,并且各資源間是無序的。當然,資源也可以不屬于任何集合,它們稱為單體資源。事實上,集合本身也是資源,它可以部署于全局級別,位于API的頂層,也可以包含于某個資源中,表現為“子集合”。集合、資源、子集合及子資源間的關系如圖3-1所示。

圖3-1 集合、資源和子資源
Kubernetes系統將一切事物都抽象為API資源,其遵循REST架構風格組織并管理這些資源及其對象,同時還支持通過標準的HTTP方法(POST、PUT、PATCH、DELETE和GET)對資源進行增、刪、改、查等管理操作。不過,在Kubernetes系統的語境中,“資源”用于表示“對象”的集合,例如,Pod資源可用于描述所有Pod類型的對象,但本書將不加區別地使用資源、對象和資源對象,并將它們統統理解為資源類型生成的實例——對象。
3.1.1 Kubernetes的資源對象
依據資源的主要功能作為分類標準,Kubernetes的API對象大體可分為工作負載(Workload)、發現和負載均衡(Discovery & LB)、配置和存儲(Config & Storage)、集群(Cluster)以及元數據(Metadata)五個類別。它們基本上都是圍繞一個核心目的而設計:如何更好地運行和豐富Pod資源,從而為容器化應用提供更靈活、更完善的操作與管理組件,如圖3-2所示。

圖3-2 Kubernetes常用資源對象
工作負載型資源用于確保Pod資源對象能夠更好地運行容器化應用,具有同一種負載的各Pod對象需要以負載均衡的方式服務于各請求,而各種容器化應用彼此之間需要彼此“發現”以完成工作協同。Pod資源具有生命周期,存儲型資源能夠為重構的Pod對象提供持久化的數據存儲機制,共享同一配置的Pod資源可從配置型資源中統一獲取配置改動信息,這些資源作為配置中心為管理容器化應用的配置文件提供了極為便捷的管理機制。集群型資源為管理集群本身的工作特性提供了配置接口,而元數據型資源則用于配置集群內部的其他資源的行為。
(1)工作負載型資源
Pod是工作負載型資源中的基礎資源,它負責運行容器,并為其解決環境性的依賴,例如,向容器注入共享的或持久化的存儲卷、配置信息或密鑰數據等。但Pod可能會因為資源超限或節點故障等原因而終止,這些非正常終止的Pod資源需要被重建,不過,這類工作將由工作負載型的控制器來完成,它們通常也稱為pod控制器。
應用程序分為無狀態和有狀態兩種類型,它們對環境的依賴及工作特性有很大的不同,因此分屬兩種不同類型的Pod控制器來管理,ReplicationController、ReplicaSet和Deployment負責管理無狀態應用,StatefulSet用于管控有狀態類應用。ReplicationController是上一代的控制器,其功能由ReplicaSet和Deployment負責實現,因此幾近于廢棄。還有些應用較為獨特,它們需要在集群中的每個節點上運行單個Pod資源,負責收集日志或運行系統服務等任務,這些Pod資源的管理則屬于DaemonSet控制器的分內之事。另外,有些容器化應用需要繼續運行以為守護進程不間斷地提供服務,而有些則應該在正常完成后退出,這些在正常完成后就應該退出的容器化應用則由Job控制器負責管控。下面是各Pod控制器更為詳細的說明。
?□ReplicationController:用于確保每個Pod副本在任一時刻均能滿足目標數量,換言之,它用于保證每個容器或容器組總是運行并且可訪問;它是上一代的無狀態Pod應用控制器,建議讀者使用新型控制器Deployment和ReplicaSet來取代它。
?□ReplicaSet:新一代ReplicationController,它與ReplicationController的唯一不同之處僅在于支持的標簽選擇器不同,ReplicationController只支持等值選擇器,而ReplicaSet還額外支持基于集合的選擇器。
?□Deployment:用于管理無狀態的持久化應用,例如HTTP服務器;它用于為Pod和ReplicaSet提供聲明式更新,是建構在ReplicaSet之上的更為高級的控制器。
?□StatefulSet:用于管理有狀態的持久化應用,如database服務程序;其與Deployment的不同之處在于StatefulSet會為每個Pod創建一個獨有的持久性標識符,并會確保各Pod之間的順序性。
?□DaemonSet:用于確保每個節點都運行了某Pod的一個副本,新增的節點一樣會被添加此類Pod;在節點移除時,此類Pod會被回收;DaemonSet常用于運行集群存儲守護進程——如glusterd和ceph,還有日志收集進程——如fluentd和logstash,以及監控進程——如Prometheus的Node Exporter、collectd、Datadog agent和Ganglia的gmond等。
?□Job:用于管理運行完成后即可終止的應用,例如批處理作業任務;換句話講,Job創建一個或多個Pod,并確保其符合目標數量,直到Pod正常結束而終止。
(2)發現和負載均衡
Pod資源可能會因為任何意外故障而被重建,于是它需要固定的可被“發現”的方式。另外,Pod資源僅在集群內可見,它的客戶端也可能是集群內的其他Pod資源,若要開放給外部網絡中的用戶訪問,則需要事先將其暴露到集群外部,并且要為同一種工作負載的訪問流量進行負載均衡。Kubernetes使用標準的資源對象來解決此類問題,它們是用于為工作負載添加發現機制及負載均衡功能的Service資源和Endpoint資源,以及通過七層代理實現請求流量負載均衡的Ingress資源。
(3)配置與存儲
Docker容器分層聯合掛載的方式決定了不宜在容器內部存儲需要持久化的數據,于是它通過引入掛載外部存儲卷的方式來解決此類問題,而Kubernetes則為此設計了Volume資源,它支持眾多類型的存儲設備或存儲系統,如GlusterFS、CEPH RBD和Flocker等。另外,新版本的Kubernetes還支持通過標準的CSI(Container Storage Interface)統一存儲接口以及擴展支持更多類型的存儲系統。
另外,基于鏡像構建容器應用時,其配置信息于鏡像制作時焙入,從而為不同的環境定制配置就變得較為困難。Docker使用環境變量等作為解決方案,但這么一來就得于容器啟動時將值傳入,且無法在運行時修改。ConfigMap資源能夠以環境變量或存儲卷的方式接入到Pod資源的容器中,并且可被多個同類的Pod共享引用,從而實現“一次修改,多處生效”。不過,這種方式不適于存儲敏感數據,如私鑰、密碼等,那是另一個資源類型Secret的功能。
(4)集群級資源
Pod、Deployment、Service和ConfigMap等資源屬于名稱空間級別,可由相應的項目管理員所管理。然而,Kubernetes還存在一些集群級別的資源,用于定義集群自身配置信息的對象,它們僅應該由集群管理員進行操作。集群級資源主要包含以下幾種類型。
?□Namespace:資源對象名稱的作用范圍,絕大多數對象都隸屬于某個名稱空間,默認時隸屬于“default”。
?□Node:Kubernetes集群的工作節點,其標識符在當前集群中必須是唯一的。
?□Role:名稱空間級別的由規則組成的權限集合,可被RoleBinding引用。
?□ClusterRole:Cluster級別的由規則組成的權限集合,可被RoleBinding和ClusterRole Binding引用。
?□RoleBinding:將Role中的許可權限綁定在一個或一組用戶之上,它隸屬于且僅能作用于一個名稱空間;綁定時,可以引用同一名稱空間中的Role,也可以引用全局名稱空間中的ClusterRole。
?□ClusterRoleBinding:將ClusterRole中定義的許可權限綁定在一個或一組用戶之上;它能夠引用全局名稱空間中的ClusterRole,并能通過Subject添加相關信息。
(5)元數據型資源
此類資源對象用于為集群內部的其他資源配置其行為或特性,如HorizontalPodAutoscaler資源可用于自動伸縮工作負載類型的資源對象的規模,Pod模板資源可用于為pod資源的創建預制模板,而LimitRange則可為名稱空間的資源設置其CPU和內存等系統級資源的數量限制等。
提示
一個應用通常需要多個資源的支撐,例如,使用Deployment資源管理應用實例(Pod)、使用ConfigMap資源保存應用配置、使用Service或Ingress資源暴露服務、使用Volume資源提供外部存儲等。
本書后面篇幅的主體部分就展開介紹這些資源類型,它們是將容器化應用托管運行于Kubernetes集群的重要工具組件。
3.1.2 資源及其在API中的組織形式
在Kubernetes上,資源對象代表了系統上的持久類實體,Kubernetes用這些持久類實體來表達集群的狀態,包括容器化的應用程序正運行于哪些節點,每個應用程序有哪些資源可用,以及每個應用程序各自的行為策略,如重啟、升級及容錯策略等。一個對象可能會包含多個資源,用戶可對這些資源執行增、刪、改、查等管理操作。Kubernetes通常利用標準的RESTful術語來描述API概念。
?□資源類型(resource type)是指在URL中使用的名稱,如Pod、Namespace和Service等,其URL格式為“GROUP/VERSION/RESOURCE”,如apps/v1/deployment。
?□所有資源類型都有一個對應的JSON表示格式,稱為“種類”(kind);客戶端創建對象必須以JSON提交對象的配置信息。
?□隸屬于同一種資源類型的對象組成的列表稱為“集合”(collection),如PodList。
?□某種類型的單個實例稱為“資源”(resource)或“對象”(object),如名為pod-demo的Pod對象。
kind代表著資源對象所屬的類型,如Namespace、Deployment、Service及Pod等,而這些資源類型大體又可以分為三個類別,具體如下。
?□對象(Object)類:對象表示Kubernetes系統上的持久化實體,一個對象可能包含多個資源,客戶端可用它執行多種操作。Namespace、Deployment、Service及Pod等都屬于這個類別。
?□列表(List)類:列表通常是指同一類型資源的集合,如PodLists、NodeLists等。
?□簡單(Simple)類:常用于在對象上執行某種特殊操作,或者管理非持久化的實體,如/binding或/status等。
Kubernetes絕大多數的API資源類型都是“對象”,它們代表著集群中某個概念的實例。有一小部分的API資源類型為“虛擬”(virtual)類型,它們用于表達一類“操作”(operation)。所有的對象型資源都擁有一個獨有的名稱標識以實現其冪等的創建及獲取操作,不過,虛擬型資源無須獲取或不依賴于冪等性時也可以不使用專用標識符。
有些資源類型隸屬于集群范疇,如Namespace和PersistentVolume,而多數資源類型則受限于名稱空間,如Pod、Deployment和Service等。名稱空間級別的資源的URL路徑中含有其所屬空間的名稱,這些資源對象在名稱空間被刪除時會被一并刪除,并且這些資源對象的訪問也將受控于其所屬的名稱空間級別的授權審查。
Kubernetes將API分割為多個邏輯組合,稱為API群組,它們支持單獨啟用或禁用,并能夠再次分解。API Server支持在不同的群組中使用不同的版本,允許各組以不同的速度演進,而且也支持同一群組同時存在不同的版本,如apps/v1、apps/v1beta2和apps/v1beta1,也因此能夠在不同的群組中使用同名的資源類型,從而能在穩定版本的群組及新的實驗群組中以不同的特性同時使用同一個資源類型。群組化管理的API使得其可以更輕松地進行擴展。當前系統的API Server上的相關信息可通過“kubectl api-versions”命令獲取。命令結果中顯示的不少API群組在后續的章節中配置資源清單時會多次用到:
[root@master~]# kubectl api-versions admissionregistration.k8s.io/v1beta1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 apiregistration.k8s.io/v1beta1 apps/v1 apps/v1beta1 apps/v1beta2 authentication.k8s.io/v1 authentication.k8s.io/v1beta1 authorization.k8s.io/v1 authorization.k8s.io/v1beta1 autoscaling/v1 autoscaling/v2beta1 batch/v1 batch/v1beta1 certificates.k8s.io/v1beta1 events.k8s.io/v1beta1 extensions/v1beta1 networking.k8s.io/v1 policy/v1beta1 rbac.authorization.k8s.io/v1 rbac.authorization.k8s.io/v1beta1 scheduling.k8s.io/v1beta1 storage.k8s.io/v1 storage.k8s.io/v1beta1 v1
Kubernetes的API以層級結構組織在一起,每個API群組表現為一個以“/apis”為根路徑的REST路徑,不過核心群組core有一個專用的簡化路徑“/api/v1”。目前,常用的API群組可歸為如下兩類。
?□核心群組(core group):REST路徑為/api/v1,在資源的配置信息apiVersion字段中引用時可以不指定路徑,而僅給出版本,如“apiVersion: v1”。
?□命名的群組(named group):REST路徑為/apis/$GROUP_NAME/$VERSION,例如/apis/apps/v1,它在apiVersion字段中引用的格式為“apiVersion: $GROUP_NAME/$VERSION”,如“apiVersion: apps/v1”。
總結起來,名稱空間級別的每一個資源類型在API中的URL路徑表示都可簡單抽象為形如“/apis/<group>/<version>/namespaces/<namespace>/<kind-plural>”的路徑,如default名稱空間中Deployment類型的路徑為/apis/apps/v1/namespaces/default/deployments,通過此路徑可獲取到default名稱空間中所有Deployment對象的列表:
~]$ kubectl get --raw /apis/apps/v1/namespaces/default/deployments | jq .
{
"kind": "DeploymentList",
"apiVersion": "apps/v1",
……
"items": [……]
}
另外,Kubernetes還支持用戶自定義資源類型,目前常用的方式有三種:一是修改Kubernetes源代碼自定義類型;二是創建一個自定義的API Server,并將其聚合至集群中;三是使用自定義資源(Custom Resource Definition, CRD)。
3.1.3 訪問Kubernetes REST API
以編程的方式訪問Kubernetes REST API有助于了解其流式化的集群管理機制,一種常用的方式是使用curl作為HTTP客戶端直接通過API Server在集群上操作資源對象模擬請求和響應的過程。不過,由kubeadm部署的Kubernetes集群默認僅支持HTTPS的訪問接口,它需進行一系列的認證檢查,好在用戶也可以借助kubectl proxy命令在本地主機上為API Server啟動一個代理網關,由它支持使用HTTP進行通信,其工作邏輯如圖3-3所示。

圖3-3 kubectl在本地代理API Server
例如,于本地127.0.0.1的8080端口上啟動API Server的一個代理網關:
~]$ kubectl proxy --port=8080 Starting to serve on 127.0.0.1:8080
而后即可于另一終端使用curl一類的客戶端工具對此套接字地址發起訪問請求,例如,請求Kubernetes集群上的NamespaceList資源對象,即列出集群上所有的Namespace對象:
~]$ curl localhost:8080/api/v1/namespaces/ { "kind": "NamespaceList", "apiVersion": "v1", …… }
或者使用JSON的命令行處理器jq命令對響應的JSON數據流進行內容過濾,例如,下面的命令僅用于顯示相關的NamespaceList對象中的各成員對象:
~]$ curl -s localhost:8080/api/v1/namespaces/ | jq .items[].metadata.name "default" "kube-public" "kube-system"
給出特定的Namespace資源對象的名稱則能夠直接獲取相應的資源信息,以kube-system名稱空間為例:
~]$ curl -s localhost:8080/api/v1/namespaces/kube-system { "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "kube-system", "selfLink": "/api/v1/namespaces/kube-system", "uid": "eb6bf659-9d0e-11e8-bf0d-000c29ab0f5b", "resourceVersion": "33", "creationTimestamp": "2018-08-11T02:33:23Z" }, "spec": { "finalizers": [ "kubernetes" ] }, "status": { "phase": "Active" }
上述命令響應的結果中展現了Kubernetes大多數資源對象的資源配置格式,它是一個JSON序列化的數據結構,具有kind、apiVersion、metadata、spec和status五個一級字段,各字段的意義和功能將在3.2節中重點介紹。
- Python科學計算(第2版)
- C語言程序設計(第3版)
- 三維圖形化C++趣味編程
- 微信小程序開發解析
- PhpStorm Cookbook
- Statistical Application Development with R and Python(Second Edition)
- Troubleshooting Citrix XenApp?
- 官方 Scratch 3.0 編程趣味卡:讓孩子們愛上編程(全彩)
- Visual Basic程序設計實驗指導及考試指南
- Java高級程序設計
- Python全棧開發:數據分析
- 高性能MVVM框架的設計與實現:San
- Python Natural Language Processing
- CorelDRAW X6中文版應用教程(第二版)
- C#入門經典(第7版):C# 6.0 & Visual Studio 2015(.NET開發經典名著)