Kubernetes筆記(3) - 資源管理基礎

語言: CN / TW / HK

Kubernetes系統將一切事物都抽象為API資源,其遵循REST架構風格組織並管理這些資源及其物件,同時還支援通過標準的HTTP方法(POST、PUT、PATCH、DELETE和GET)對資源進行增、刪、改、查等管理操作。 Kubernetes的資源物件大體可分為

  • 工作負載(Workload)
  • 服務發現和負載均衡(Discovery & LB)
  • 配置和儲存(Config & Storage)
  • 叢集(Cluster)
  • 元資料(Metadata)

資源物件及API群組

工作負載

Pod是工作負載型資源中的基礎資源,它負責執行容器,併為其解決環境性的依賴。它被Pod控制器管理,但由於應用程式有無狀態和有狀態的區分,它們對環境的依賴及工作特性有很大的不同,因此分屬兩種不同型別的Pod控制器來管理。 管理無狀態應用的控制器:

  • ReplicationController
  • ReplicaSet
  • Deployment

ReplicationController和ReplicaSet的作用都是確保每個Pod副本在任一時刻都符合目標數量。但ReplicationController是上一代的控制器,已基本廢棄。 Deployment用於管理無狀態的持久化應用,例如HTTP伺服器;它用於為Pod和ReplicaSet提供宣告式更新,是建構在ReplicaSet之上的更為高階的控制器。

管理有狀態應用的控制器:

  • StatefulSet

StatefulSet用於管理有狀態的持久化應用,如database服務程式;其與Deployment的不同之處在於StatefulSet會為每個Pod建立一個獨有的永續性識別符號,並會確保各Pod之間的順序性。

另外還有兩個比較特別的Workload控制器:

  • DaemonSet
  • Job控制器

DaemonSet常用於執行叢集儲存守護程序——如glusterd和ceph,還有日誌收集程序——如fluentd和logstash,以及監控程序——如Prometheus的Node Exporter、collectd、Datadog agent和Ganglia的gmond等。‰

Job控制器用於管理執行完成後即可終止的應用,例如批處理作業任務。

服務發現和負載均衡

Kubernetes使用標準的資源物件來負責服務發現和負載均衡,包括:

  • Service資源
  • Endpoint資源
  • Ingress資源

配置與儲存

Docker使用Volume來進行資料的持久化,K8S也為此提供了 Volume資源,而且它基於標準的CSI(Container Storage Interface)介面,支援多種型別的儲存系統。

另外,Docker在啟動容器時需要注入環境變數,K8S也為此提供了ConfigMap資源,它可以環境變數或儲存卷的方式接入到Pod資源的容器中,並且可被多個同類的Pod共享引用。Secret資源則用於提供密碼等敏感配置資訊。

叢集級資源

上述資源都屬於名稱空間級別,可由相應的專案管理員所管理。Kubernetes還存在一些叢集級別的資源,用於定義叢集自身配置資訊,它們僅應該由叢集管理員進行操作。

  • Namespace: 資源物件名稱的作用範圍,絕大多數物件都隸屬於某個名稱空間,預設屬於default.
  • Node: Kubernetes叢集的工作節點,其識別符號在當前叢集中必須是唯一的.
  • Role: 名稱空間級別的由規則組成的許可權集合,可被RoleBinding引用.
  • ClusterRole: Cluster級別的由規則組成的許可權集合,可被RoleBinding和ClusterRoleBinding引用.
  • RoleBinding: 將Role中的許可許可權繫結在一個或一組使用者之上,它隸屬於且僅能作用於一個名稱空間.
  • ClusterRoleBinding: 將ClusterRole中定義的許可許可權繫結在一個或一組使用者之上;它能夠引用全域性名稱空間中的ClusterRole,並能通過Subject新增相關資訊.

元資料型資源

元資料型資源用於為叢集內部的其他資源配置其行為或特性,如HorizontalPodAutoscaler資源可用於自動伸縮工作負載型別的資源物件的規模,Pod模板資源可用於為pod資源的建立預製模板,而LimitRange則可為名稱空間的資源設定其CPU和記憶體等系統級資源的數量限制等。

資源在API中的組織形式

除了kubectl,也可以使用curl、postman等工具作為HTTP客戶端直接通過API Server在叢集上操作資源物件,但是Kubernetes叢集預設僅支援HTTPS的訪問介面,它需進行一系列的認證檢查,所以首先需要在本地主機上為API Server啟動一個代理閘道器

kubectl proxy --port=8080

然後就可以發起請求了,比如獲取叢集的namespace list:

curl localhost:8080/api/v1/namespaces 

與執行這樣的命令得到的結果相同:

kubectl get namespaces -o json

所有的response都包含相同的一級欄位:kind、apiVersion、metadata、spec、status。 其中kind、apiVersion分別表示物件所屬的資源型別和API的版本。

metadata欄位

metadata欄位用於描述物件的屬性資訊,其內嵌多個欄位用於定義資源的元資料,例如name和labels等。這些欄位分為必要欄位和可選欄位兩大類。比如名稱空間級別的資源的必選欄位包括有

  • namespace:指定當前物件隸屬的名稱空間,預設值為default。‰
  • name:設定當前物件的名稱,在其所屬的名稱空間的同一型別中必須唯一。‰
  • uid:當前物件的唯一識別符號,其唯一性僅發生在特定的時間段和名稱空間中

可選欄位通常是指由Kubernetes系統自行維護和設定,或者存在預設值,或者本身允許留空。使用者通過配置清單建立資源時,通常僅需要給出必選欄位,可選欄位可按需指定,對於使用者未明確定義的巢狀欄位,則需要由一系列的finalizer元件自動予以填充。

spec和status欄位

spec來描述所期望的物件應該具有的狀態,status欄位則用來記錄物件的當前狀態。在定義資源配置清單時,spec是必須定義的欄位,status欄位則由Kubernetes負責填充或更新,使用者不能手動進行定義。

 上述欄位的子節點的內容隨資源的種類不同而有較大的區別,可以使用kubectl explain來具體檢視,比如

kubectl explain pods
kubectl explain pods.spec

資源物件管理

整體來說,K8S提供了兩類資源管理的方式:陳述式和宣告式 陳述式側重於告訴計算機如何執行操作,run、expose、delete和get等命令都屬於此類; 宣告式側重於構建程式邏輯而無須詳細描述其實現流程,使用者只需要設定期望的狀態,系統即能自行確定需要執行的操作以確保達到使用者期望的狀態,所有的操作都通過apply命令來完成。

kubectl命令能夠讀取.yaml .yml或.json為格式的檔案。-f選項可以指定配置清單的路徑、URL或目錄,且可重複使用多次。如果指定的目錄路徑存在子目錄中時,可使用-R選項來遞迴獲取子目錄中的配置清單。

可以為每個資源使用專用的配置清單,也可以將多個相關的資源(例如,屬於同一個應用或微服務)組織在同一個配置清單中。不過,如果是YAML格式的配置清單,多個資源彼此之間要使用“---”符號作為單獨的一行進行資源分割

管理namespace資源

namespace資源屬於叢集級別的資源,用於將叢集分隔為多個隔離的邏輯分割槽以配置給不同的使用者、租戶、環境或專案使用,namespace下又包含了pod、service等資源。 Kubernetes的namespace資源與Linux系統的名稱空間是各自獨立的概念。前者僅用於限制資源物件名稱的作用域。 kubectl get namespaces命令可檢視所有的namespaces資源,kube-system主要用於執行系統級資源,而default下則包含那些未指定名稱空間的資源。 kubectl describe namespaces <namespace>命令可檢視指定namespace的詳細資訊。 檢視namespace級別的資源需要指定namespace名稱,比如

kubect get pods -n kube-system
宣告式建立namespace資源

使用apply命令基於以下配置清單建立namespace資源

3_namespace-example.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: dev
spec:
  finalizers:
  - kubernetes
~ kubectl apply -f 3_namespace-example.yaml 
namespace/dev created

建立namespace資源所需的屬性較少,簡單起見,kubectl為其提供了一個封裝的專用陳述式命令kubectl create namespace <namespace>

刪除Namespace資源

刪除Namespace資源會級聯刪除其包含的所有其他資源物件

kubectl delete namespace dev

也可以為其指定--force --grace-period 選項

管理pod資源

首先定義如下資源清單: 3_pod-example.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-example
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1

建立Pod資源 陳述式物件配置方式:

kubectl create -f 3_pod-example.yaml

宣告式物件配置方式:

kubectl apply -f 3_pod-example.yaml

檢視pod狀態

kubectl get -f 3_pod-example.yaml
或
kubectl get pod pod-example

同時可以使用-o yaml/json選項獲取詳細的資源清單。 describe命令可檢視活動物件的詳細資訊。

kubectl describe -f 3_pod-example.yaml 
或
kubectl describe pod pod-example

更新Pod資源 對於活動物件,並非其每個屬性值都支援修改,比如無法修改Pod資源物件的metadata.name欄位,除非刪除並重建它。對於那些支援修改的屬性,比如,容器的image欄位,可將其完整的配置清單匯出於配置檔案中並更新相應的配置資料,而後使用replace命令基於陳述式物件配置的管理機制進行資源物件的更新。

~ kubectl get pods pod-example -o yaml > pod-example-update.yaml
將image修改為ikubernetes/myapp:v2後執行:
~ kubectl replace -f pod-example-update.yaml
操作成功會提示:
pod/pod-example replaced

上述使用了陳述式物件配置方式更新活動物件的配置,replace命令要重構整個資源物件,所以它必須基於完整格式的配置資訊才能進行活動物件的完全替換。若要基於此前的配置檔案進行替換,就必須使用--force選項刪除此前的活動物件,而後再進行新建操作。

~ kubectl replace -f 3_pod-example.yaml --force
pod "pod-example" deleted
pod/pod-example replaced

後面介紹會介紹更推薦的宣告式管理方式。 刪除Pod資源 陳述式命令方式:

kubectl delete pod pod-example

陳述式物件配置管理方式:

kubectl delete -f 3_pod-example.yaml

陳述式物件配置 VS 宣告式

陳述式命令、陳述式物件配置、宣告式三種管理K8S資源的方式中,後兩種都是使用配置清單,但它們區別較大: 陳述式物件配置管理機制中,同時指定的多個資源必須進行同一種操作,而且其replace命令是通過完全替換現有的活動物件來進行資源的更新操作,對於生產環境來說,這並非理想的選擇。 宣告式物件配置操作在管理資源物件時將配置資訊保存於目標物件的註解中,並通過比較活動物件的當前配置、前一次管理操作時保存於註解中的配置,以及當前命令提供的配置生成更新補丁從而完成活動物件的補丁式更新操作。 比如要更新pod映象,只需要修改最初的3_pod-example.yaml,然後apply,系統就會進行補丁式更新操作。 而資源物件的刪除操作依然可以使用apply命令,但要同時使用--prune選項,命令的格式為“kubectl apply -f <directory/> --prune -l <labels>”。但這個命令要慎用,因為它將基於標籤選擇器過濾出所有符合條件的物件,並檢查由-f指定的目錄中是否存在某配置檔案已經定義了相應的資源物件,那些不存在相應定義的資源物件將被刪除。因此,刪除資源物件的操作依然建議使用陳述式物件配置方式。

學習資料

《Kubernetes實戰進階》 馬永亮著

分享到: