天天看點

帶你讀《Kubernetes進階實戰》之三:資源管理基礎

點選這裡檢視第一章:Kubernetes快速入門 點選這裡檢視第二章:資源管理基礎

第3章:資源管理基礎

Kubernetes系統的API Server基于HTTP/HTTPS接收并響應用戶端的操作請求,它提供了一種“基于資源”(resource-based)的RESTful風格的程式設計接口,将叢集的各種元件都抽象成為标準的REST資源,如Node、Namespace和Pod等,并支援通過标準的HTTP方法以JSON為資料序列化方案進行資源管理操作。本章将着重描述Kubernetes的資源管理方式。

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所示。

帶你讀《Kubernetes進階實戰》之三:資源管理基礎

圖3-1 集合、資源和子資源

Kubernetes系統将一切事物都抽象為API資源,其遵循REST架構風格組織并管理這些資源及其對象,同時還支援通過标準的HTTP方法(POST、PUT、PATCH、DELETE和GET)對資源進行增、删、改、查等管理操作。不過,在Kubernetes系統的語境中,“資源”用于表示“對象”的集合,例如,Pod資源可用于描述所有Pod類型的對象,但本書将不加差別地使用資源、對象和資源對象,并将它們統統了解為資源類型生成的執行個體—對象。

3.1.1 Kubernetes的資源對象

依據資源的主要功能作為分類标準,Kubernetes的API對象大體可分為工作負載(Workload)、發現和負載均衡(Discovery & LB)、配置和存儲(Conf?ig & Storage)、叢集(Cluster)以及中繼資料(Metadata)五個類别。它們基本上都是圍繞一個核心目的而設計:如何更好地運作和豐富Pod資源,進而為容器化應用提供更靈活、更完善的操作與管理元件,如圖3-2所示。

帶你讀《Kubernetes進階實戰》之三:資源管理基礎

圖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,還有日志收集程序—如f?luentd和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和Conf?igMap等資源屬于名稱空間級别,可由相應的項目管理者所管理。然而,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)、使用Conf?igMap資源儲存應用配置、使用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進階實戰》之三:資源管理基礎

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///namespaces//”的路徑,如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 Def?inition,CRD)。

3.1.3 通路Kubernetes REST API

以程式設計的方式通路Kubernetes REST API有助于了解其流式化的叢集管理機制,一種常用的方式是使用curl作為HTTP用戶端直接通過API Server在叢集上操作資源對象模拟請求和響應的過程。不過,由kubeadm部署的Kubernetes叢集預設僅支援HTTPS的通路接口,它需進行一系列的認證檢查,好在使用者也可以借助kubectl proxy指令在本地主機上為API Server啟動一個代理網關,由它支援使用HTTP進行通信,其工作邏輯如圖3-3所示。

例如,于本地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節中重點介紹。

3.2 對象類資源格式

Kubernetes API僅接受及響應JSON格式的資料(JSON對象),同時,為了便于使用,它也允許使用者提供YAML格式的POST對象,但API Server需要事先自行将其轉換為JSON格式後方能送出。API Server接受和傳回的所有JSON對象都遵循同一個模式,它們都具有kind和apiVersion字段,用于辨別對象所屬的資源類型、API群組及相關的版本。

進一步地,大多數的對象或清單類型的資源還需要具有三個嵌套型的字段metadata、spec和status。其中metadata字段為資源提供中繼資料資訊,如名稱、隸屬的名稱空間和标簽等;spec則用于定義使用者期望的狀态,不同的資源類型,其狀态的意義也各有不同,例如Pod資源最為核心的功能在于運作容器;而status則記錄着活動對象的目前狀态資訊,它由Kubernetes系統自行維護,對使用者來說為隻讀字段。

每個資源通常僅接受并傳回單一類型的資料,而一種類型可以被多個反映特定用例的資源所接受或傳回。例如對于Pod類型的資源來說,使用者可建立、更新或删除Pod對象,然而,每個Pod對象的metadata、spec和status字段的值卻又是各自獨立的對象型資料,它們可被單獨操作,尤其是status對象,是由Kubernetes系統單獨進行自動更新,而不能由使用者手動操作它。

3.2.1 資源配置清單

3.1節中曾使用curl指令通過代理的方式于API Server上請求到了kube-system這個Namespace活動對象的狀态資訊,事實上,使用者也可以直接使用“kubectl get TYPE/NAME -o yaml”指令擷取任何一個對象的YAML格式的配置清單,或者使用“kubectl get TYPE/NAME -o json”指令擷取JSON格式的配置清單。例如,可使用下面的指令擷取kube-system的狀态:

~]$ kubectl get namespace kube-system -o yaml
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: 2018-08-11T02:33:23Z
  name: kube-system
  resourceVersion: "33"
  selfLink: /api/v1/namespaces/kube-system
  uid: eb6bf659-9d0e-11e8-bf0d-000c29ab0f5b
spec:
  finalizers:      
  • kubernetes

    status:

phase: Active

除了極少數的資源之外,Kubernetes系統上的絕大多數資源都是由其使用者所建立的。建立時,需要以與上述輸出結果中類似的方式以YAML或JSON序列化方案定義資源的相關配置資料,即使用者期望的目标狀态,而後再由Kubernetes的底層元件確定活動對象的運作時狀态與使用者提供的配置清單中定義的狀态無限接近。是以,資源的建立要通過使用者提供的資源配置清單來進行,其格式類似于kubectl get指令擷取到的YAML或JSON形式的輸出結果。不過,status字段對使用者來說為隻讀字段,它由Kubernetes叢集自動維護。例如,下面就是一個建立Namespace資源時提供的資源配置清單示例,它僅提供了幾個必要的字段:

apiVersion: v1
kind: Namespace
metadata:
  name: dev
spec:
  finalizers:      
  • 将如上所述配置清單中的内容儲存于檔案中,使用“kubectl create -f /PATH/TO/FILE”指令即可将其建立到叢集中。建立完成後檢視其YAML或JSON格式的輸出結果,可以看到Kubernetes會補全其大部分的字段,并提供相應的資料。事實上,Kubernetes的大多數資源都能夠以類似的方式進行建立和檢視,而且它們幾乎都遵循類似的組織結構,下面的指令顯示了第2章中使用kubectl run指令建立的Deployment資源對象myapp的狀态資訊:
~]$ kubectl get deployment myapp -o yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
……
  name: myapp
spec:
  replicas: 3
  selector:      
matchLabels:
  run: myapp           

……

……

為了節約篇幅,上面的輸出結果省去了大部分内容,僅保留了其主體結構。從指令結果可以看出,它也遵循Kubernetes API标準的資源組織格式,由apiVersion、kind、metadata、spec和status五個核心字段組成,隻是spec字段中嵌套的内容與Namespace資源幾乎完全不同。

事實上,對幾乎所有的資源來說,apiVersion、kind和metadata字段的功能基本上都是相同的,但spec則用于資源的期望狀态,而資源之是以存在類型上的不同,也在于它們的嵌套屬性存在顯著差别,它由使用者定義和維護。而status字段則用于記錄活動對象的目前狀态,它要與使用者在spec中定義的期望狀态相同,或者正處于轉換為與其相同的過程中。

3.2.2 metadata嵌套字段

metadata字段用于描述對象的屬性資訊,其内嵌多個字段用于定義資源的中繼資料,例如name和labels等,這些字段大體可分為必要字段和可選字段兩大類。名稱空間級别的資源的必選字段包括如下三項。

namespace:指定目前對象隸屬的名稱空間,預設值為default。

name:設定目前對象的名稱,在其所屬的名稱空間的同一類型中必須唯一。

uid:目前對象的唯一辨別符,其唯一性僅發生在特定的時間段和名稱空間中;此辨別符主要是用于差別擁有同樣名字的“已删除”和“重新建立”的同一個名稱的對象。

可選字段通常是指由Kubernetes系統自行維護和設定,或者存在預設,或者本身允許使用空值等類型的字段,常用的有如下幾個:

labels:設定用于辨別目前對象的标簽,鍵值資料,常被用作挑選條件。

annotations:非辨別型鍵值資料,用來作為挑選條件,用于labels的補充。

resourceVersion:目前對象的内部版本辨別符,用于讓用戶端确定對象變動與否。

generation:用于辨別目前對象目标狀态的代别。

creationTimestamp:目前對象建立日期的時間戳。

deletionTimestamp:目前對象删除日期的時間戳。

此外,使用者通過配置清單建立資源時,通常僅需要給出必選字段,可選字段可按需指定,對于使用者未明确定義的嵌套字段,則需要由一系列的f?inalizer元件自動予以填充。而使用者需要對資源建立的目标資源對象進行強制校驗,或者在修改時需要用到initializer元件完成,例如,為每個待建立的Pod對象添加一個Sidecar容器等。不同的資源類型也會存在一些專有的嵌套字段,例如,Conf?igMap資源還支援使用clusterName等。

3.2.3 spec和status字段

Kubernetes用spec來描述所期望的對象應該具有的狀态,而用status字段來記錄對象在系統上的目前狀态,是以status字段僅對活動對象才有意義。這兩個字段都屬于嵌套類型的字段。在定義資源配置清單時,spec是必須定義的字段,用于描述對象的目标狀态,即使用者期望對象需要表現出來的特征。status字段則記錄了對象的目前狀态(或實際狀态),此字段值由Kubernetes系統負責填充或更新,使用者不能手動進行定義。Master的controller-manager通過相應的控制器元件動态管理并確定對象的實際狀态比對使用者所期望的狀态,它是一種調和(reconciliation)配置系統。

例如,Deployment是一種用于描述叢集中運作的應用的對象,是以,建立Deployment類型的對象時,需要為目标Deployment對象設定spec,指定期望需要運作的Pod副本數量、使用的标簽選擇器以及Pod模闆等。Kubernetes系統讀取待建立的Deployment對象的spec以及系統上相應的活動對象的目前狀态,必要時進行對象更新以確定status字段吻合spec字段中期望的狀态。如果這其中任一執行個體出現問題(status字段值發生了變化),那麼Kubernetes系統則需要及時對spec和status字段的差異做出響應,例如,補足缺失的Pod副本數目等。

spec字段嵌套的字段對于不同的對象類型來說各不相同,具體需要參照Kubernetes API參考手冊中的說明分别進行擷取,核心資源對象的常用配置字段将會在本書後面的章節中進行講解。

3.2.4 資源配置清單格式文檔

定義資源配置清單時,盡管apiVersion、kind和metadata有章可循,但spec字段對不同的資源來說卻是千差萬别的,是以使用者需要參考Kubernetes API的參考文檔來了解各種可用屬性字段。好在,Kubernetes在系統上内建了相關的文檔,使用者可以使用“kubectl explain”指令直接擷取相關的使用幫助,它将根據給出的對象類型或相應的嵌套字段來顯示相關的下一級文檔。例如,要了解Pod資源的一級字段,可以使用類似如下的指令,指令結果會輸出支援使用的各一組字段及其說明:

~]$ kubectl explain pods      

需要了解某一級字段表示的對象之下的二級對象字段時,隻需要指定其一級字段的對象名稱即可,三級和四級字段對象等的檢視方式依此類推。例如檢視Pod資源的Spec對象支援嵌套使用的二級字段,可使用類似如下的指令:

~]$ kubectl explain pods.spec
RESOURCE: spec       

對象的spec字段的文檔通常包含RESOURCE、DESCRIPTION和FIELDS幾節,其中FIELDS節中給出了可嵌套使用的字段、資料類型及功能描述。例如,上面指令的結果顯示在FIELDS中的containers字段的資料類型是一個對象清單([]Object),而且是一個必選字段。任何值為對象類型資料的字段都會嵌套一到多個下一級字段,例如,Pod對象中的每個容器也是對象類型資料,它同樣包含嵌套字段,但容器不支援單獨建立,而是要包含于Pod對象的上下文中,其詳細資訊可通過三級字段來擷取,指令及其結果示例如下:

~]$ kubectl explain pods.spec.containers
RESOURCE: containers <[]Object>      

DESCRIPTION:

List of containers belonging to the pod. Containers cannot currently be added           

or removed. There must be at least one container in a Pod. Cannot be updated.

A single application container that you want to run within a pod.
           

FIELDS:

args <[]string>

Arguments to the entrypoint. The docker image's CMD is used if this is not 
     provided. ……
           

command <[]string>

Entrypoint array. Not executed within a shell. The docker image's
 ENTRYPOINT is used if this is not provided. ……
           

env <[]Object>

List of environment variables to set in the container. Cannot be updated.
           

内建文檔大大降低了使用者手動建立資源配置清單的難度,嘗試使用某個資源類型時,explain也的确是使用者的常用指令之一。熟悉各常用字段的功用之後,以同類型的現有活動對象的清單為模闆可以更快地生成目标資源的配置檔案,指令格式為“kubectl get TYPE NAME -o yaml --export”,其中--export選項用于省略輸出由系統生成的資訊。例如,基于現在的Deployment資源對象myapp生成配置模闆deploy-demo.yaml檔案,可以使用如下指令:

~]$ kubectl get deployment myapp -o yaml --export > deploy-demo.yaml      

通過資源清單檔案管理資源對象較之直接通過指令行進行操作有着諸多優勢,具體包括指令行的操作方式僅支援部分資源對象的部分屬性,而資源清單支援配置資源的所有屬性字段,而且使用配置清單檔案還能夠進行版本追蹤、複審等進階功能的操作。本書後續章節中的大部分資源管理操作都會借助于資源配置檔案進行。

3.2.5 資源對象管理方式

Kubernetes的API Server遵循聲明式程式設計(declarative programming)範式而設計,側重于建構程式程式邏輯而無須使用者描述其實作流程,使用者隻需要設定期望的狀态,系統即能自行确定需要執行的操作以確定達到使用者期望的狀态。例如,期望某Deployment控制器管理三個Pod資源對象時,而系統觀察到的目前數量卻是兩個,于是系統就會知道需要建立一個新的Pod資源來滿足此期望。Kubernetes的自愈、自治等功能都依賴于其聲明式機制。

與此對應的另一種範式稱為陳述式程式設計(imperative programming),代碼側重于通過建立一種告訴計算機如何執行操作的算法來更改程式狀态的語句來完成,它與硬體的工作方式密切相關,通常,代碼将使用條件語句、循環和類繼承等控制結構。為了便于使用者使用,Kubernetes的API Server也支援陳述式範式,它直接通過指令及其選項完成對象的管理操作,前面用到的run、expose、delete和get等指令都屬于此類,執行時使用者需要告訴系統要做什麼,例如,使用run指令建立一個有着3個Pod對象副本的Deployment對象,或者通過delete指令删除一個名為myapp的Service對象。

Kubernetes系統的大部分API對象都有着spec和status兩個字段,其中,spec用于讓使用者定義所期望的狀态,系統從中讀出相關的定義;而status則是系統觀察并負責寫入的目前狀态,使用者可以從中擷取相關的資訊。Kubernetes系統通過控制器監控着系統對象,由其負責讓系統目前的狀态無限接近使用者所期望的狀态。

kubectl的指令由此可以分為三類:陳述式指令(imperative command)、陳述式對象配置(imperative object conf?iguration)和聲明式對象配置(declarative object conf?iguration)。第一種方式即此前用到的run、expose、delete和get等指令,它們直接作用于Kubernetes系統上的活動對象,簡單易用,但不支援代碼複用、修改複審及審計日志等功能,這些功能的使用通常要依賴于資源配置檔案,這些檔案也稱為資源清單。在這種模式下,使用者可以通路每個對象的完整模式,但使用者還需要深入學習Kubernetes API。

如3.2.4節所述,資源清單本質上是一個JSON或YAML格式的文本檔案,由資源對象的配置資訊組成,支援使用Git等進行版本控制。而使用者可以資源清單為基礎,在Kubernetes系統上以陳述式或聲明式進行資源對象管理,如圖3-4所示。

帶你讀《Kubernetes進階實戰》之三:資源管理基礎

圖3-4 基于資源配置清單管理對象

陳述式管理方式包括create、delete、get和replace等指令,與陳述式指令的不同之處在于,它通過資源配置清單讀取需要管理的目标資源對象。陳述式對象配置的管理操作直接作用于活動對象,即便僅修改配置清單中的極小一部分内容,使用replace指令進行的對象更新也将會導緻整個對象被替換。進一步地,混合使用陳述式指令進行清單檔案帶外修改時,必然會導緻使用者丢失活動對象的目前狀态。

聲明式對象配置并不直接指明要進行的對象管理操作,而是提供配置清單檔案給Kubernetes系統,并委托系統跟蹤活動對象的狀态變動。資源對象的建立、删除及修改操作全部通過唯一的指令apply來完成,并且每次操作時,提供給指令的配置資訊都将儲存于對象的注解資訊(kubectl.kubernetes.io/last-applied-conf?iguration)中,并通過對比檢查活動對象的目前狀态、注解中的配置資訊及資源清單中的配置資訊三方進行變更合并,進而實作僅修改變動字段的進階更新檔機制。

陳述式對象配置相較于聲明式對象配置來說,其缺點在于同一目錄下的配置檔案必須同時進行同一種操作,例如,要麼都建立,要麼都更新等,而且其他使用者的更新也必須反映在配置檔案中,不然其更新在一下次的更新中将會被覆寫。是以,聲明式對象配置是優先推薦給使用者使用的管理機制。

然而,對于新手來說,陳述式指令的配置方式最易于上手,對系統有所了解後易于切換為使用陳述式對象配置管理方式。是以,若推薦給進階使用者則推薦使用聲明式配置,并建議同時使用版本控制系統存儲所期望的狀态,以及跨對象的曆史資訊,并啟用變更複審機制。另外,推薦使用借助于kube-applier等一類的項目實作自動化聲明式配置,使用者将配置推送到Git倉庫中,然後借助此類工具即能将其自動同步于Kubernetes叢集上。

3.3 kubectl指令與資源管理

API Server是Kubernetes叢集的網關,使用者和管理者以及其他用戶端僅能通過此網關接口與叢集進行互動。API是面向程式員的通路接口,目前可較好地支援Golang和Python程式設計語言,當然,終端使用者更為常用的是通用指令行工具kubectl。通路叢集之前,各類用戶端需要了解叢集的位置并擁有通路叢集的憑據才能擷取通路許可。使用kubeadm進行叢集初始化時,kubeadm init自動生成的/etc/kubernetes/admin.conf檔案是用戶端接入目前叢集時使用的kubeconf?ig檔案,它内建了用于通路Kubernetes叢集的最高管理權限的使用者賬号及相關的認證憑據,可由kubectl直接使用。

3.3.1 資源管理操作概述

資源的管理操作可簡單歸結為增、删、改、查四種,kubectl提供了一系列的子指令用于執行此類任務,如create、delete、patch、apply、replace、edit、get等,其中有些指令必須基于資源清單來進行,如apply和replace指令,也有些指令既可基于清單檔案進行,也可實時作用于活動資源之上,如create、get、patch和delete等。

kubectl指令能夠讀取任何以.yaml、.yml或.json為字尾的檔案(可稱為配置清單或配置檔案,後文将不加差別地使用這兩個術語)。實踐中,使用者既可以為每個資源使用專用的清單檔案,也可以将多個相關的資源(例如,屬于同一個應用或微服務)組織在同一個清單檔案中。不過,如果是YAML格式的清單檔案,多個資源彼此之間要使用“---”符号作為單獨的一行進行資源分割。這樣,多個資源就将以清單檔案中定義的次序被create、apply等子指令調用。

kubectl的多數子指令支援使用“-f”選項指定使用的清單檔案路徑或URL,也可以是存儲有清單檔案的目錄,另外,此選項在同一指令中也可重複使用多次。如果指定的目錄路徑存在子目錄中時,那麼可按需同時使用“-R”選項以遞歸擷取子目錄中的配置清單。

再者,支援使用标簽和注解是Kubernetes系統的一大特色,它為資源管理機制增色不少,而且delete和get等指令能夠基于标簽挑選目标對象,有些資源甚至必須依賴于标簽才能正常使用和工作,例如Service和Pod控制器Deployment等資源對象。子指令label用于管理資源标簽,而管理資源注解的子指令則是annotate。

就地更新(修改)現有的資源也是一種常見的操作。apply指令通過比較資源在清單檔案中的版本及前一次的版本執行更新操作,它不會對未定義的屬性産生額外的作用。edit指令相當于先使用get指令擷取資源配置,通過互動式編輯器修改後再自動使用apply指令将其應用。patch指令基于JSON更新檔、JSON合并更新檔及政策合并更新檔對資源進行就地更新操作。

為了利用apply指令的優勢,使用者應該總是使用apply指令或create --save-conf?ig指令建立資源。

3.3.2 kubectl的基本用法

kubectl是最常用的用戶端工具之一,它提供了基于指令行通路Kubernetes API的簡潔方式,能夠滿足對Kubernetes的絕大部分的操作需求。例如,需要建立資源對象時,kubectl會将JSON格式的清單内容以POST方式送出至API Server。本節主要描述kubectl的基本功能。

如果要單獨部署kubectl,Kubernetes也提供了相應的單獨發行包,或者适配于各平台的程式管理器的相關程式包,如rpm包或deb包等,使用者根據平台類型的不同擷取相比對的版本安裝完成即可,操作步驟類似于前面的安裝方法,是以這裡不再給出其具體過程。

kubectl是Kubernetes系統的指令行用戶端工具,特性豐富且功能強大,是Kubernetes管理者最常用的叢集管理工具。其最基本的文法格式為“kubectl [command] [TYPE] [NAME] [f?lags]”,其中各部分的簡要說明如下。

1)command:對資源執行相應操作的子指令,如get、create、delete、run等;常用的核心子指令如表3-1所示。

2)TYPE:要操作的資源對象的類型,如pods、services等;類型名稱區分字元大小寫,但支援使用簡寫格式。

3)NAME:對象名稱,區分字元大小寫;省略時,則表示指定TYPE的所有資源對象;另外,也可以直接使用“TYPE/NAME”的格式來表示資源對象。

4)f?lags:指令行選項,如“-s”或“--server”;另外,get等指令在輸出時還有一個常用的标志“-o ”用于指定輸出格式,如表3-1所示。

表3-1 kubectl的子指令清單

帶你讀《Kubernetes進階實戰》之三:資源管理基礎
帶你讀《Kubernetes進階實戰》之三:資源管理基礎

指令 指令類别 功能說明

create 基礎指令(初級) 通過檔案或标準輸入建立資源

expose 基于rc、service、deployment或pod建立Service資源

run 通過建立Deployment在叢集中運作指定的鏡像

set 設定指定資源的特定屬性

get 基礎指令(中級) 顯示一個或多個資源

explain 列印資源文檔

edit 編輯資源

delete 基于檔案名、stdin、資源或名字,以及資源和選擇器删除資源

rollout 部署指令 管理資源的滾動更新

rolling-update 對ReplicationController執行滾動更新

scale 伸縮Deployment、ReplicaSet、RC或Job的規模

autoscale 對Deployment、ReplicaSet或RC進行自動伸縮

certif?icate 叢集管理指令 配置數字證書資源

cluster-info 列印叢集資訊

top 列印資源(CPU/Memory/Storage)使用率

cordon 将指定node設定為“不可用”(unschedulable)狀态

uncordon 将指定node設定為“可用”(schedulable)狀态

drain “排幹”指定的node的負載以進入“維護”模式

taint 為node聲明污點及标準行為

describe 排錯及調試指令 顯示指定的資源或資源組的詳細資訊

logs 顯示一個Pod内某容器的日志

attach 附加終端至一個運作中的容器

exec 在容器中執行指定指令

port-forward 将本地的一個或多個端口轉發至指定的Pod

proxy 建立能夠通路Kubernetes API Server的代理

cp 在容器間複制檔案或目錄

auth 列印授權資訊

apply 進階指令 基于檔案或stdin将配置應用于資源

patch 使用政策合并更新檔更新資源字段

replace 基于檔案或stdin替換一個資源

convert 為不同的API版本轉換配置檔案

label 設定指令 更新指定資源的label

annotate 更新資源的annotation

completion 輸出指定的shell(如bash)的補全碼

version 其他指令 列印Kubernetes服務端和用戶端的版本資訊

api-versions 以“group/version”格式列印伺服器支援的API版本資訊

conf?ig 配置kubeconf?ig檔案的内容

plugin 運作指令行插件

help 列印任一指令的幫助資訊

kubectl指令還包含了多種不同的輸出格式(如表3-2所示),它們為使用者提供了非常靈活的自定義輸出機制,如輸出為YAML或JSON格式等。

表3-2 kubectl get指令的常用輸出格式

帶你讀《Kubernetes進階實戰》之三:資源管理基礎

輸出格式 格式說明

-o wide 顯示資源的額外資訊

-o name 僅列印資源的名稱

-o yaml YAML格式化輸出API對象資訊

-o json JSON格式化輸出API對象資訊

-o go-template 以自定義的go模闆格式化輸出API對象資訊

-o custom-columns 自定義要輸出的字段

此外,kubectl指令還有許多通用的選項,這個可以使用“kubectl options”指令來擷取。下面列舉幾個比較常用指令。

-s或--server:指定API Server的位址和端口。

--kubeconf?ig:使用的kubeconf?ig檔案路徑,預設為~/.kube/conf?ig。

--namespace:指令執行的目标名稱空間。

kubectl的部分子指令在第2章已經多次提到,餘下的大多數指令在後續的章節中還會用到,對于它們的使用說明也将在首次用到時進行展開說明。

3.4 管理名稱空間資源

名稱空間(Namespace)是Kubernetes叢集級别的資源,用于将叢集分隔為多個隔離的邏輯分區以配置給不同的使用者、租戶、環境或項目使用,例如,可以為development、qa和production應用環境分别建立各自的名稱空間。

Kubernetes的絕大多數資源都隸屬于名稱空間級别(另一個是全局級别或叢集級别),名稱空間資源為這類的資源名稱提供了隔離的作用域,同一名稱空間内的同一類型資源名必須是唯一的,但跨名稱空間時并無此限制。不過,Kubernetes還是有一些資源隸屬于叢集級别的,如Node、Namespace和PersistentVolume等資源,它們不屬于任何名稱空間,是以資源對象的名稱必須全局唯一。

Kubernetes的名稱空間資源不同于Linux系統的名稱空間,它們是各自獨立的概念。另外,Kubernetes名稱空間并不能實作Pod間的通信隔離,它僅用于限制資源對象名稱的作用域。

3.4.1 檢視名稱空間及其資源對象

Kubernetes叢集預設提供了幾個名稱空間用于特定的目的,例如,kube-system主要用于運作系統級資源,而default則為那些未指定名稱空間的資源操作提供一個預設值,前面章節中的絕大多數資源管理操作都在default名稱空間中進行。“kubectl get namespaces”指令則可以檢視namespaces資源:

~]$ kubectl get namespaces
NAME          STATUS    AGE
default       Active    6d
kube-public   Active    6d
kube-system   Active    6d      

也可以使用“kubectl describe namespaces”指令檢視特定名稱空間的詳細資訊,例如:

~]$ kubectl describe namespaces default      

kubectl的資源檢視指令在多數情況下應該針對特定的名稱空間來進行,為其使用“-n”或“--namespace”選項即可,例如,檢視kube-system下的所有Pod資源:

~]$ kubectl get pods -n kube-system
NAME                                 READY    STATUS     RESTARTS    AGE
etcd-master.ikubernetes.io           1/1      Running    1           6d
kube-apiserver-master.ikubernetes.io 1/1      Running    1           6d
……      

指令結果顯示出kube-system與default名稱空間的Pod資源對象并不相同,這正是Namespace資源的名稱隔離功能的展現。有了Namespace對象,使用者再也不必精心安排資源名稱,也不用擔心誤操作了其他使用者的資源。

3.4.2 管理Namespace資源

Namespace是Kubernetes API的标準資源類型之一,如3.2.1節中所述,它的配置主要有kind、apiVersion、metadata和spec等一級字段組成。将3.2.1節中的名稱空間配置清單儲存于配置檔案中,使用陳述式對象配置指令create或聲明式對象配置指令apply便能完成建立:

~]$ kubectl apply -f namespace-example.yaml
namespace/dev created      

名稱空間資源屬性較少(通常隻需要指定名稱即可),簡單起見,kubectl為其提供了一個封裝的專用陳述式指令“kubectl create namespace”。Namespace資源的名稱僅能由字母、數字、連接配接線、下劃線等字元組成。例如,下面的指令可用于建立名為qa的Namespace對象:

~]$ kubectl create namespace qa
namespace/qa created      

namespace資源的名稱僅能由字母、數字、連接配接線、下劃線等字元組成。

實踐中,不建議混用不同類别的管理方式。考慮到聲明式對象配置管理機制的強大功能,強烈推薦使用者使用apply和patch等指令進行資源建立及修改一類的管理操作。

使用kubectl管理資源時,如果一并提供了名稱空間選項,就表示此管理操作僅針對指定名稱空間進行,而删除Namespace資源會級聯删除其包含的所有其他資源對象。表3-3給出了幾個常用的指令格式。

表3-3 結合名稱空間使用的删除指令

帶你讀《Kubernetes進階實戰》之三:資源管理基礎

指令格式 功能

kubectl delete TYPE RESOURCE -n NS 删除指定名稱空間内的指定資源

kubectl delete TYPE --all -n NS 删除指定名稱空間内的指定類型的所有資源

kubectl delete all -n NS 删除指定名稱空間内的所有資源

kubectl delete all --all 删除所有名稱空間中的所有資源

需要再次指出的是,Namespace對象僅用于資源對象名稱的隔離,它自身并不能隔絕跨名稱空間的Pod間通信,那是網絡政策(network policy)資源的功能。

3.5 Pod資源的基礎管理操作

Pod是Kubernetes API中的核心資源類型,它可以定義在JSON或YAML格式的資源清單中,由資源管理指令進行陳述式或聲明式管理。建立時,使用者通過create或apply指令将請求送出到API Server并将其儲存至叢集狀态存儲系統etcd中,而後由排程器将其排程至最佳目标節點,并被相應節點的kubelet借助于容器引擎建立并啟動。這種由使用者直接通過API建立的Pod對象也稱為自主式Pod。

3.5.1 陳述式對象配置管理方式

陳述式對象配置管理機制,是由使用者通過配置檔案指定要管理的目标資源對象,而後再由使用者借助于指令直接指定Kubernetes系統要執行的管理操作的管理方式,常用的指令有create、delete、replace、get和describe等。

1.建立Pod資源

Pod是标準的Kubernetes API資源,在配置清單中使用kind、apiVersion、metadata和spec字段進行定義,status字段在對象建立後由系統自行維護。Pod對象的核心功用在于運作容器化應用,在其spec字段中嵌套的必選字段是containers,它的值是一個容器對象清單,支援嵌套建立一到多個容器。下面是一個Pod資源清單示例檔案,在spec中定義的期望的狀态是在Pod對象中基于ikubernetes/myapp: v1鏡像運作一個名為myapp的容器:

apiVersion: v1
kind: Pod
metadata:
  name: pod-example
spec:
  containers:      
  • name: myapp

    image: ikubernetes/myapp:v1

    把上面的内容儲存于配置檔案中,使用“kubectl [COMMAND] -f /PATH/TO/YAML_FILE”指令以陳述式對象配置進行資源對象的建立,下面是相應的指令及響應結果:      
~]$ kubectl create -f pod-example.yaml
pod/pod-example created      

如果讀者熟悉JSON,也可以直接将清單檔案定義為JSON格式;YAML格式的清單檔案本身也是由API Server事先将其轉換為JSON格式而後才進行應用的。

指令的傳回資訊表示目标Pod對象pod-example得以成功建立。事實上,create指令中的-f選項也支援使用目錄路徑或URL,而且目标路徑為目錄時,還支援使用-R選項進行子目錄遞歸。另外,--record選項可以将指令本身記錄為目标對象的注解資訊kubernetes.io/change-cause,而--save-conf?ig則能夠将提供給指令的資源對象配置資訊儲存于對象的注解資訊kubectl.kubernetes.io/last-applied-conf?iguration中,後一個指令的功用與聲明式對象配置指令apply的功能相近。

2.檢視Pod狀态

get指令預設顯示資源對象最為關鍵的狀态資訊,而describe等指令則能夠列印出Kubernetes資源對象的詳細狀态。不過,雖然建立時給出的資源清單檔案較為簡潔,但“kubectl get”指令既可以使用“-o yaml”或“-o json”選項輸出資源對象的配置資料及狀态,也能夠借助于“--custom-columns”選項自定義要顯示的字段:

~]$ kubectl get -f pod-example.yaml
NAME          READY     STATUS    RESTARTS    AGE
pod-example   1/1       Running   0           1m
~]$ kubectl get -f pod-example.yaml -o custom-columns=NAME:metadata.name,STATUS:status.phase
NAME          STATUS
pod-example   Running      

使用“-o yaml”或“-o json”選項時,get指令能夠傳回資源對象的中繼資料、期望的狀态及目前狀态資料資訊,而要列印活動對象的詳細資訊,則需要describe指令,它可根據資源清單、資源名或卷标等方式過濾輸出符合條件的資源對象的資訊。指令格式為“kubectl describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)”。例如,顯示pod-example的詳細資訊,可使用類似如下的指令:

~]$ kubectl describe -f pod-example.yaml

對于Pod資源對象來說,它能夠傳回活動對象的中繼資料、目前狀态、容器清單及各容器的詳情、存儲卷對象清單、QoS類别、事件及相關資訊,這些詳情對于了解目标資源對象的狀态或進行錯誤排查等操作來說至關重要。

3.更新Pod資源

對于活動對象,并非其每個屬性值都支援修改,例如,Pod資源對象的metadata.name字段就不支援修改,除非删除并重建它。對于那些支援修改的屬性,比如,容器的image字段,可将其完整的配置清單導出于配置檔案中并更新相應的配置資料,而後使用replace指令基于陳述式對象配置的管理機制進行資源對象的更新。例如,将前面建立pod-example時使用的資源清單中的image值修改為“ikubernetes/myapp: v2”,而後執行更新操作:

~]$ kubectl get pods pod-example -o yaml > pod-example-update.yaml
~]$ sed -i 's@(image:).*@ikubernetes/myapp:v2@' pod-example-update.yaml
~]$ kubectl replace -f pod-example-update.yaml
pod/pod-example replaced      

更新活動對象的配置時,replace指令要重構整個資源對象,故此它必須基于完整格式的配置資訊才能進行活動對象的完全替換。若要基于此前的配置檔案進行替換,就必須使用--force選項删除此前的活動對象,而後再進行建立操作,否則指令會傳回錯誤資訊。例如,将前面第一步“建立Pod資源”内的配置清單中的鏡像修改為“ikubernetes/myapp: v2”後再進行強制替換,指令如下:

~]$ kubectl replace -f pod-example.yaml --force
pod "pod-example" deleted
pod/pod-example replaced      

4.删除Pod資源

陳述式對象配置管理方式下的删除操作與建立、檢視及更新操作類似,為delete指令使用-f選項指定配置清單即可,例如,删除pod-example.yaml檔案中定義的Pod資源對象:

~]$ kubectl delete -f pod-example.yaml
pod "pod-example" deleted      

之後再次列印相關配置清單中定義的資源對象即可驗正其删除的結果,例如:

~]$ kubectl get -f pod-example.yaml
No resources found.
Error from server (NotFound): pods "pod-example" not found      

3.5.2 聲明式對象配置管理方式

陳述式對象配置管理機制中,同時指定的多個資源必須進行同一種操作,而且其replace指令是通過完全替換現有的活動對象來進行資源的更新操作,對于生産環境來說,這并非理想的選擇。聲明式對象配置操作在管理資源對象時将配置資訊儲存于目标對象的注解中,并通過比較活動對象的目前配置、前一次管理操作時儲存于注解中的配置,以及目前指令提供的配置生成更新更新檔進而完成活動對象的更新檔式更新操作。此類管理操作的常用指令有apply和patch等。

例如,建立3.5.1節中定義的主容器使用“ikubernetes/myapp: v1”鏡像的Pod資源對象,還可以使用如下指令進行:

~]$ kubectl apply -f pod-example.yaml
pod/pod-example created      

而更新對象的操作,可在直接修改原有資源清單檔案後再次對其執行apply指令來完成,例如,修改Pod資源配置清單中的鏡像檔案為“ikubernetes/myapp: v2”後再次執行如上的apply指令:

~]$ kubectl apply -f pod-example.yaml
pod/pod-example configured      

指令結果顯示資源重新配置完成并且已經生效。事實上,此類操作也完全能夠使用patch指令直接進行更新檔操作。而資源對象的删除操作依然可以使用apply指令,但要同時使用--prune選項,指令的格式為“kubectl apply -f --prune -l ”。需要注意的是,此指令異常兇險,因為它将基于标簽選擇器過濾出所有符合條件的對象,并檢查由-f指定的目錄中是否存在某配置檔案已經定義了相應的資源對象,那些不存在相應定義的資源對象将被删除。是以,删除資源對象的操作依然建議使用陳述式對象配置方式的指令“kubectl delete”進行,這樣的指令格式操作目标明确且不易出現偏差。

3.6 本章小結

本章介紹了Kubernetes系統上常用的資源對象類型及其管理方式,在說明kubectl指令行工具的基礎用法後借助于Namespace資源對象簡單說明了其使用方式,具體如下。

Kubernetes提供了RESTful風格的API,它将各類元件均抽象為“資源”,并通過屬性指派完成執行個體化。

Kubernetes API支援的資源類型衆多,包括Node、Namespace、Pod、Service、Deployment、Conf?igMap等上百種。

标準格式的資源配置大多都是由kind、apiVersion、metadata、spec和status等一級屬性字段組成,其中spec是由使用者定義的期望狀态,而status則是由系統維護的目前狀态。

Kubernetes API主要提供的是聲明式對象配置接口,但它也支援陳述式指令及陳述式對象配置的管理方式。

kubectl指令功能衆多,它将通過子指令完成不同的任務,如create、delete、edit、replace、apply等。

Namespace和Pod是Kubernetes系統的基礎資源類型。

繼續閱讀