久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

如何對Kubernetes對象的狀態(tài)進(jìn)行管理

154次閱讀
沒有評論

共計 6555 個字符,預(yù)計需要花費 17 分鐘才能閱讀完成。

這篇文章的內(nèi)容主要圍繞如何對 Kubernetes 對象的狀態(tài)進(jìn)行管理進(jìn)行講述,文章內(nèi)容清晰易懂,條理清晰,非常適合新手學(xué)習(xí),值得大家去閱讀。感興趣的朋友可以跟隨丸趣 TV 小編一起閱讀吧。希望大家通過這篇文章有所收獲!

我們下面主要聚焦于探究如何對 Kubernetes  對象的狀態(tài)以一種可靠,持久的方式進(jìn)行管理。之前的文章中提到過  API Server 自身是無狀態(tài)的,并且它是唯一能夠與分布式存儲 etcd 直接通信的組件。

etcd 的簡要說明

在 *nix 操作系統(tǒng)中,我們一般使用 /etc 來存儲相關(guān)配置數(shù)據(jù)。實際上 etcd 的名字就是由此發(fā)展而來,在 etc 后面加上個”d”表示”distributed”分布式。任何分布式系統(tǒng)都需要有像 etcd 這樣能夠存儲系統(tǒng)數(shù)據(jù)的東西,使其能夠以一致和可靠的方式檢索相關(guān)數(shù)據(jù)。為了能實現(xiàn)分布式的數(shù)據(jù)訪問,etcd 使用 Raft  協(xié)議。從概念上講,etcd 支持的數(shù)據(jù)模型是鍵值(key-value)存儲。在 etcd2 中,各個 key 是以層次結(jié)構(gòu)存在,而在 etcd3 中這個就變成了遍布模型,但同時也保持了層次結(jié)構(gòu)方式的兼容性。

使用容器化版本的 etcd,我們可以創(chuàng)建上面的樹,然后按如下方式檢索它:

$ docker run –rm -d -p 2379:2379 \

 –name test-etcd3 quay.io/coreos/etcd:v3.1.0 /usr/local/bin/etcd \

 –advertise-client-urls http://0.0.0.0:2379 –listen-client-urls http://0.0.0.0:2379

$ curl localhost:2379/v2/keys/foo -XPUT -d value= some value

$ curl localhost:2379/v2/keys/bar/this -XPUT -d value=42

$ curl localhost:2379/v2/keys/bar/that -XPUT -d value=take

$ http localhost:2379/v2/keys/?recursive=true

HTTP/1.1 200 OK

Content-Length: 327

Content-Type: application/json

Date: Tue, 06 Jun 2017 12:28:28 GMT

X-Etcd-Cluster-Id: 10e5e39849dab251

X-Etcd-Index: 6

X-Raft-Index: 7

X-Raft-Term: 2

{

  action : get ,

  node : {

  dir : true,

  nodes : [

  {

  createdIndex : 4,

  key : /foo ,

    modifiedIndex : 4,

  value : some value

  },

  {

  createdIndex : 5,

  dir : true,

  key : /bar ,

  modifiedIndex : 5,

  nodes : [

  {

  createdIndex : 5,

  key : /bar/this ,

  modifiedIndex : 5,

  value : 42

  },

  {

    createdIndex : 6,

  key : /bar/that ,

  modifiedIndex : 6,

  value : take

  }

  ]

  }

  ]

  }

}

現(xiàn)在我們已經(jīng)大致了解了 etcd 是如何工作的,接下去我們繼續(xù)討論 etcd 在 Kubernetes 是如何被使用的。

集群中的 etcd

在 Kubernetes 中,etcd 是控制平面中的一耳光獨立組成部分。在 Kubernetes1.5.2 版本之前,我們使用的是 etcd2 版本,而在 Kubernetes1.5.2 版本之后我們就轉(zhuǎn)向使用 etcd3 版本了。值得注意的是在 Kubernetes1.5.x 版本中 etcd 依舊使用的是 v2 的 API 模型,之后這將開始變?yōu)?v3 的 API 模型,包括使用的數(shù)據(jù)模型。站在開發(fā)者角度而言這個似乎沒什么直接影響,因為 API Server 與存儲之前是抽象交互,而并不關(guān)心后端存儲的實現(xiàn)是 etcd v2 還是 v3。但是如果是站在集群管理員的角度來看,還是需要知道 etcd 使用的是哪個版本,因為集群管理員需要日常對數(shù)據(jù)進(jìn)行一些備份,恢復(fù)的維護(hù)操作。

你可以 API Server 的相關(guān)啟動項中配置使用 etcd 的方式,API Server 的 etcd 相關(guān)啟動項參數(shù)如下所示:

$ kube-apiserver -h

–etcd-cafile string  SSL Certificate Authority file used to secure etcd communication.

–etcd-certfile string SSL certification file used to secure etcd communication.

–etcd-keyfile string  SSL key file used to secure etcd communication.

–etcd-quorum-read  If true, enable quorum read.

–etcd-servers  List of etcd servers to connect with (scheme://ip:port) …

Kubernetes  存儲在 etcd 中的數(shù)據(jù),是以 JSON 字符串或 Protocol Buffers  格式存儲。下面我們來看一個具體的例子:在 apiserver-sandbox 的命名空間中創(chuàng)建一個 webserver 的 pod。然后我們使用  etcdctl 工具來查看相關(guān) etcd(在本環(huán)節(jié)中 etcd 版本為 3.1.0)數(shù)據(jù)。

$ cat pod.yaml

apiVersion: v1

kind: Pod

metadata:

  name: webserver

spec:

  containers:

  – name: nginx

  image: tomaskral/nonroot-nginx

  ports:

  – containerPort: 80

$ kubectl create -f pod.yaml

$ etcdctl ls /

/kubernetes.io

/openshift.io

$ etcdctl get /kubernetes.io/pods/apiserver-sandbox/webserver

{

  kind : Pod ,

  apiVersion : v1 ,

  metadata : {

  name : webserver ,

下面我們來看一下這個 pod 對象是如何最終存儲到 etcd 中,通過 kubectl create -f pod.yaml 的方式。下圖描繪了這個總體流程:

1. 
客戶端(比如 kubectl)提供一個理想狀態(tài)的對象,比如以 YAML 格式,v1 版本提供。

2. 
Kubectl 將 YAML 轉(zhuǎn)換為 JSON 格式,并發(fā)送。

3. 
對應(yīng)同類型對象的不同版本,API Server 執(zhí)行無損耗轉(zhuǎn)換。對于老版本中不存在的字段則存儲在 annotations 中。

4. 
API Server 將接受到的對象轉(zhuǎn)換為規(guī)范存儲版本,這個版本由 API Server 指定,一般是最新的穩(wěn)定版本,比如 v1。

5. 
最后將對象通過 JSON
或 protobuf 方式解析為一個 value,通過一個特定的 key 存入 etcd 當(dāng)中。

我們可以通過配置  kube-apiserver 的啟動參數(shù) –storage-media-type 來決定想要序列化數(shù)據(jù)存入 etcd 的格式,默認(rèn)情況下為 application/vnd.kubernetes.protobuf 格式。我們也可以通過配置 –storage-versions 啟動參數(shù),來確定存入 etcd 的每個群組 Group 對象的默認(rèn)版本號。

現(xiàn)在讓我們來看看無損轉(zhuǎn)換是如何進(jìn)行的,我們將使用 Kubernetes  對象 Horizontal Pod Autoscaling (HPA) 來列舉說明。HPA 顧名思義是指通過監(jiān)控資源的使用情況結(jié)合 ReplicationController 控制 Pod 的伸縮。

首先我們期待一個 API 代理(以便于我們能夠在本地直接訪問它),并啟動 ReplicationController,以及 HPA 。

$ kubectl proxy –port=8080

$ kubectl create -f https://raw.githubusercontent.com/mhausenblas/kbe/master/specs/rcs/rc.yaml

kubectl autoscale rc rcex –min=2 –max=5 –cpu-percent=80

kubectl get hpa/rcex -o yaml

現(xiàn)在,你能夠使用 httpie
——當(dāng)然你也能夠使用 curl 的方式——向 API server  請求獲取 HPA 對象使用當(dāng)前的穩(wěn)定版本(autoscaling/v1),或者使用之前的版本(extensions/v1beta1),獲取的兩個版本的區(qū)別如下所示:

$ http localhost:8080/apis/extensions/v1beta1/namespaces/api-server-deepdive/horizontalpodautoscalers/rcex hpa-v1beta1.json

$ http localhost:8080/apis/autoscaling/v1/namespaces/api-server-deepdive/horizontalpodautoscalers/rcex hpa-v1.json

$ diff -u hpa-v1beta1.json hpa-v1.json

{

  kind : HorizontalPodAutoscaler ,

–  apiVersion : extensions/v1beta1 ,

+  apiVersion : autoscaling/v1 ,

  metadata : {

  name : rcex ,

  namespace : api-server-deepdive ,

–  selfLink : /apis/extensions/v1beta1/namespaces/api-server-deepdive/horizontalpodautoscalers/rcex ,

+  selfLink : /apis/autoscaling/v1/namespaces/api-server-deepdive/horizontalpodautoscalers/rcex ,

  uid : ad7efe42-50ed-11e7-9882-5254009543f6 ,

  resourceVersion : 267762 ,

  creationTimestamp : 2017-06-14T10:39:00Z

  },

  spec : {

–  scaleRef : {

+  scaleTargetRef : {

  kind : ReplicationController ,

  name : rcex ,

–  apiVersion : v1 ,

–  subresource : scale

+  apiVersion : v1

  },

  minReplicas : 2,

  maxReplicas : 5,

–  cpuUtilization : {

–  targetPercentage : 80

–  }

+  targetCPUUtilizationPercentage : 80

我們能夠看到 HorizontalPodAutoscale 的版本從 v1beta1 變?yōu)榱?v1。API server 能夠在不同的版本之前無損耗轉(zhuǎn)換,不論在 etcd 中實際存的是哪個版本。

在了解整個存儲流程之后,我們下面來探究一下 API server 如何將數(shù)據(jù)進(jìn)行編碼,解碼存入 etcd 中以 JSON  或 protobuf 的方式,同時也考慮到 etcd 的版本。

API Server 將所有已知的 Kubernetes 對象類型保存在名為 Scheme 的 Go 類型注冊表(registry)中。在此注冊表中,定義每種了 Kubernetes 對象的類型以及如何轉(zhuǎn)換它們,如何創(chuàng)建新對象,以及如何將對象編碼和解碼為 JSON 或 protobuf。

當(dāng) API Server 從客戶端接收到一個對象時,比如 kubectl,通過 HTTP 路徑,能夠知道這個對象的具體版本號。首先會為這個對象使用對應(yīng)的版本 Scheme 創(chuàng)建一個空對象,然后通過 JSON 或 protobuf 將 HTTP 傳過來的對象內(nèi)容進(jìn)行解碼轉(zhuǎn)換。解碼完成后創(chuàng)建對象,存入 etcd 中。

在 API 中可能會有很多版本,如果要支持每個版本之間的直接轉(zhuǎn)換,這樣往往處理起來比較麻煩。比如某個 API 下面有三個版本,那么它就要支持一個版本到另兩個版本的直接轉(zhuǎn)換(比如 v1
v1alpha1, v1
v1beta1, v1beta1
v1alpha1)。為了避免這個問題,在 API server 中有一個特別的  “internal”  版本。當(dāng)兩個版本之間需要轉(zhuǎn)換時,先轉(zhuǎn)換為 internal 版本,再轉(zhuǎn)換為相應(yīng)轉(zhuǎn)換的版本。這樣的話,每個版本只要支持能夠轉(zhuǎn)換為 internal 版本,那么就能夠與其它任何版本進(jìn)行間接的轉(zhuǎn)換。所以一個對象先轉(zhuǎn)換為 internal 版本,然后在轉(zhuǎn)換為穩(wěn)定的 v1 版本,然后在存入 etcd 中。

v1beta1
internal
v1

在轉(zhuǎn)換的第一步中,如果某些字段用戶沒有賦值指定,那么這些會被賦為一個默認(rèn)值。比如在 v1beta1  中肯定沒有在 v1 版本新增的一個字段。在這種情況下,用戶肯定無法在 v1beta1  版本為這個字段賦值。這時候,在轉(zhuǎn)換的第一步中,我們會為這個字段賦一個默認(rèn)值以生成一個有效的 internal。

校驗及準(zhǔn)入

在轉(zhuǎn)換過程中有兩個重要的步驟,如下圖所示:

v1beta1
internal
?  | 
?  | 
?  v1 
json/yaml
etcd

  admission  validation

準(zhǔn)入和校驗是創(chuàng)建和更新對象存入 etcd 之前必須通過的步驟。它們的一些規(guī)則如下所示:

1. 
準(zhǔn)入(Admission):查看集群中的一些約束條件是否允許創(chuàng)建或更新此對象,并根據(jù)此集群的相關(guān)配置為對象設(shè)置一些默認(rèn)值。在 Kubernetes 有很多這種約束條件,下面列舉一些例子:

NamespaceLifecycle:如果命名空間不存在,則拒絕該命名空間下的所有傳入請求。

LimitRanger:強(qiáng)制限制命名空間中資源的使用率。

ServiceAccount:為 pod 創(chuàng)建  service account 。

DefaultStorageClass:如果用戶沒有為 PersistentVolumeClaims 賦值,那么將它設(shè)置為一個默認(rèn)值。

ResourceQuota:對群集上的當(dāng)前用戶強(qiáng)制執(zhí)行配額約束,如果配額不足,可能會拒絕請求。

2. 
校驗(Validation):檢查傳入對象(在創(chuàng)建和更新期間)是否格式是否合法以及相關(guān)值是否有效。比如:

1. 
檢查必填字段是否已填。

2. 
檢查字符串格式是否正確(比如只允許小寫形式)。

3. 
是否有些字段存在沖突(比如,有兩個容器的名字一樣)。

校驗(Validation)并不關(guān)心其它類型的對象實例,換言之,它只關(guān)心每個對象的靜態(tài)檢查,無關(guān)集群配置。

準(zhǔn)入(Admission)可以用 flag
–admission-control= plugins 來啟動或禁用。它們中的大多數(shù)可以有集群管理配置。此外,在 Kubernetes 1.7 中可以用 webhook 機(jī)制來擴(kuò)展準(zhǔn)入機(jī)制,使用控制器來實現(xiàn)對對象的傳統(tǒng)的校驗。

遷移存儲對象

關(guān)于存儲對象遷移的最后說明:當(dāng) Kubernetes 需要升級到新的版本時,根據(jù)每個版本的相關(guān)文檔步驟備份相關(guān)集群的數(shù)據(jù)是至關(guān)重要的。這一方面是由于 etcd2 到 etcd3 的轉(zhuǎn)變,另一方面是由于 Kubernetes  對象的 Kind 及 version 的不斷發(fā)展。

在 etcd 中,每個對象是首選存儲版本(preferred storage version)存在的。但是,隨著時間的推移,etcd 存儲中的對象可能以一個非常老的版本存在。如果在將來某個時間這個對象版本被廢棄了,那么將無法再解碼它的 protobuf  或 JSON。因此,在集群升級之前需要重寫,遷移這些數(shù)據(jù)。

感謝你的閱讀,相信你對“如何對 Kubernetes 對象的狀態(tài)進(jìn)行管理”這一問題有一定的了解,快去動手實踐吧,如果想了解更多相關(guān)知識點,可以關(guān)注丸趣 TV 網(wǎng)站!丸趣 TV 小編會繼續(xù)為大家?guī)砀玫奈恼拢?/p>

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-08-03發(fā)表,共計6555字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 肥东县| 天镇县| 安义县| 晋州市| 皮山县| 容城县| 留坝县| 深圳市| 青阳县| 高安市| 炎陵县| 玉环县| 东平县| 临桂县| 永安市| 汽车| 连州市| 澳门| 福州市| 涿州市| 通许县| 读书| 邯郸市| 漳浦县| 涪陵区| 永登县| 武平县| 张家口市| 二手房| 阳朔县| 宁德市| 时尚| 河源市| 揭阳市| 凌源市| 台中县| 双柏县| 松溪县| 平遥县| 苍山县| 林甸县|