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

API Basics怎么實現(xiàn)

157次閱讀
沒有評論

共計 13808 個字符,預計需要花費 35 分鐘才能閱讀完成。

本文丸趣 TV 小編為大家詳細介紹“API Basics 怎么實現(xiàn)”,內(nèi)容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“API Basics 怎么實現(xiàn)”文章能幫助大家解決疑惑,下面跟著丸趣 TV 小編的思路慢慢深入,一起來學習新知識吧。

Introduction

所謂的云原生應用,能夠清楚自己運行在 k8s 上,并且使用 k8s api 和資源當作其擴展。

一方面,云原生應用能夠輕便地在不同的云上遷移。另一方面,受益于 k8s 提供的簡潔可定義聲明式 api。

Extension Patterns

cloud providers: in-tree controller manager:

kubelet: network, devices, storage, container runtimes

extend kubectl with plugins

extensions in the API server, dynamic admission control with webhook

Custom resources and custom controllers.

custom apiserver

scheduler extensions.

Controllers and operators

controller: 實現(xiàn)了一個控制循環(huán),從 API server 監(jiān)聽到的集群狀態(tài),并且把當前狀態(tài)調整到預期狀態(tài)。

operator: 是指 controller+ 自定義資源的方式,去做像應用生命周期管理相關的一些操作。

the controller loop

讀取資源的狀態(tài),更傾向于事件驅動。

改變集群或外部集群的對象的狀態(tài)。

通過 apiserver 更新存儲在 etcd 中資源的狀態(tài)。

重復循環(huán)。回到步驟 1.

不管 controller 的實現(xiàn)復雜與否,這三步驟都是一致的。讀取資源狀態(tài) - 改變 the world- 更新資源狀態(tài)。

informers:

負責 watch 期望的狀態(tài),實現(xiàn) resync 機制加強周期性的調諧,通常用來確保集群狀態(tài)和存在內(nèi)存中的期望狀態(tài)不飄動。

work queues:

在 client-go 的 workqueue 包中實現(xiàn)了,為 event handler 提供 work queues 來“存儲”狀態(tài)變更操作的隊列及其各種重試操作。當更新當前資源對象狀態(tài)出錯時,資源需要重新被排序。

Events

k8s 的控制面通過事件驅動 進行解耦,其他分布式系統(tǒng)通過遠程過程調用來觸發(fā)各種行為。controller 通過 watch k8s 對象的變化對 APISERVER 的增、刪、改請求。

example:

用戶 創(chuàng)建一個 dp 時,dp controller 通過 dp informer 創(chuàng)建一個 rs。

rs controller 通過 rs informer 創(chuàng)建一個新的 rs,并且創(chuàng)建一個 pod 對象。

scheduler 通過 pod informer 觀測到新的 pod,且它的 spec.nodeName 為空,就把這個 pod 放入調度隊列。

與此同時,kubelet 通過 pod informer 觀測到新的 pod,且它的 spec.nodeName 為空。所以并沒有 match 到 kubelet 的 nodeName,會忽略這個 pod 繼續(xù)等待下一次事件。

scheduler 從 workqueue 中拿出 pod,并且通過更新 spec.nodeName 字段,調度到有足夠資源的指定 node,并且寫入 apiserver。

kubelet 因為 pod update 事件,繼續(xù)比較 spec.NodeName 和其本身的 nodeName. 當 match 之后,通過啟動 pod 的 container,并且把 container 啟動的狀態(tài)信息寫入 pod status, 返回存儲到 apiserver。

rs controller 注意到 pod 改變。

最后 pod 銷毀時,kubelet watch 到 pod 事件并且將 pod 狀態(tài)設置為“terminated”狀態(tài),并更新到 apiserver。

rs controller 觀測到結束的 pod,決定這個 pod 一定需要被替換。于是通過 apiserver 刪除 terminated 狀態(tài)的 pod,并且創(chuàng)建一個新的。

一系列獨立的控制循環(huán),通過 watch apiserver 中對象的變化,并且這些變更事件通過 informers 來觸發(fā)變更。

watch events 和 event 對象是兩個東西:

前者通過在 apiserver 和 controllers 之間建立 http streaming 的鏈接用來驅動 informers.

后者是一種資源,像 pod,dp,services 這些,帶有特殊的時效屬性并且自動從 etcd 里消失。

Edge-driven triggers or Level-driven triggers 

前者是基于某個狀態(tài)值變更的瞬間去觸發(fā) handler,后者是在某個時間段內(nèi)、狀態(tài)被驗證與期望值相符,則去觸發(fā) handler。

后者更像是一種 polling 輪詢,能否擴容到指定數(shù)量、控制器注意到變更的延遲依賴于 polling 輪詢的時間間隔以及 apiserver 的響應時間。與很多異步的控制器相關,最終系統(tǒng)需要花費一段時間才能達到預期狀態(tài)。

前者效率更高,延遲則依賴在控制器處理事件時,運行的工作線程。因此 k8s 基于事件驅動,即 edge-driven triggers.

reconciliation with resync:每 5 分鐘持續(xù)調諧。

edge-triggered, level-driven

level-triggering-and-reconciliation

Changing Cluster Objects or the External worldOptimistic Concurrency

單體式:

二階段:

共享狀態(tài):

并行調度架構:

新一代的并發(fā)調度架構依賴共享狀態(tài),使用樂觀并發(fā)控制達到實現(xiàn)可擴展和性能可伸縮。

k8s 中樂觀鎖的場景是:

retry loop 中,獲取了 foo 對象最新的狀態(tài)后,嘗試根據(jù) foo spec 更新 real world 和 foo status, 實際修改的操作在 Update 事件之前執(zhí)行。

通過 client.Get 返回的 foo 對象,包含資源的版本,ObjectMeta 結構體。這個結構體會在 client.Update 調用時,通過寫操作更新 etcd 的數(shù)據(jù)。所謂的資源版本,在 etcd 中存儲的實際上是 string,int 鍵值對。etcd 維護了一個計數(shù)器 counter,每次 key 的值被修改時,counter 值加一。

在 API machinery 代碼中,資源版本的處理像是任意的 string,實際上還是遵循一些規(guī)則。實際的實現(xiàn)細節(jié)在 etcd 存儲后端。

essence: 控制器中的沖突錯誤十分常見,處理和期待十分優(yōu)雅。

Operators

operator 是一種針對特定應用的控制器,擴展了 k8s API 的創(chuàng)建、配置、管理復雜的有狀態(tài)應用的實例。

一個 operator 包括一個 CRD+ controller。

Kubernetes API Basics

apiserver 作為擋在存儲 etcd 前的唯一組件,跟 etcd 進行直接交互。主要職責是作為 k8s api 的 server 和集群組件的 proxy。

伺服 API 意味著 讀取狀態(tài)和 操作狀態(tài)。

聲明式狀態(tài)管理

通過比較期望狀態(tài)的 spec 和當前實際狀態(tài)的值,

例如:當你在 dp 的聲明 yaml 里指定 20 個副本數(shù),dp controller 讀到 dp spec 并且創(chuàng)建 rs, 實際去接管 rs- 即特定個數(shù)的 pods。如果有任何副本跪了,dp controller 會讓你在狀態(tài)中感知到。

APIServer Processes Requests

DefaultBuildHandlerChain()

WithPanicRecovery(): 處理恢復和日志 panic

Basics of client-go

Repos

ClientLibrary

k8s 項目提供 client-go(https://github.com/kubernetes/client-go) 作為用戶的開發(fā)工具集,提供了多種類型的 API 支持,以及包含許多通用庫代碼。

K8S API Types

client-go 管理了客戶端接口,像 PODS,services,deployments 這些接口,在這個 repo 中維護 (https://github.com/kubernetes/api),pod 等的類型在 k8s.io/api/core/v1/types.go 中定義,而這些文件均由 code gen 自動生成維護。

// Pod is a collection of containers that can run on a host. This resource is created
// by clients and scheduled onto hosts.
type Pod struct {
 metav1.TypeMeta `json: ,inline `
 // Standard object s metadata.
 // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
 // +optional
 metav1.ObjectMeta `json: metadata,omitempty  protobuf: bytes,1,opt,name=metadata `
 // Specification of the desired behavior of the pod.
 // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
 // +optional
 Spec PodSpec `json: spec,omitempty  protobuf: bytes,2,opt,name=spec `
 // Most recently observed status of the pod.
 // This data may not be up to date.
 // Populated by the system.
 // Read-only.
 // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
 // +optional
 Status PodStatus `json: status,omitempty  protobuf: bytes,3,opt,name=status `

}

API machinery

第三個 repo(https://github.com/kubernetes/apimachinery) 包含所有通用的構建模塊,不僅限于容器管理,還包括其他構建 APIs。在 pkg/api/meta/v1 下可以查看到許多 API 類型的定義,包括如下:

ObjectMeta: Name + Namespaces + ResourceVersion + Labels + Annotations

TypeMeta : Kind + APIVersion

GetOptions,

ListOptions

構建模塊用來創(chuàng)建 k8s 客戶端對象,代表在 k8s 集群中能訪問的資源。

版本和兼容

k8s 的 api 是按版本區(qū)分的,一方面 client 的不同版本去訪問 API server,如果版本不匹配,請求會失敗。client 與特定的版本綁定,應用開發(fā)者需要選擇正確的

其版本與 k8s 版本對應關系如圖:

| Branch | Canonical source code location | Maintenance status |
| `release-1.4` | Kubernetes main repo, 1.4 branch | = - |
| `release-1.5` | Kubernetes main repo, 1.5 branch | = - |
| `release-2.0` | Kubernetes main repo, 1.5 branch | = - |
| `release-3.0` | Kubernetes main repo, 1.6 branch | = - |
| `release-4.0` | Kubernetes main repo, 1.7 branch | = - |
| `release-5.0` | Kubernetes main repo, 1.8 branch | = - |
| `release-6.0` | Kubernetes main repo, 1.9 branch | = - |
| `release-7.0` | Kubernetes main repo, 1.10 branch | = - |
| `release-8.0` | Kubernetes main repo, 1.11 branch | =- |
| `release-9.0` | Kubernetes main repo, 1.12 branch | =- |
| `release-10.0` | Kubernetes main repo, 1.13 branch | =- |
| `release-11.0` | Kubernetes main repo, 1.14 branch | ? |
| `release-12.0` | Kubernetes main repo, 1.15 branch | ? |
| `release-13.0` | Kubernetes main repo, 1.16 branch | ? |
| `release-14.0` | Kubernetes main repo, 1.17 branch | ? |
| client-go HEAD | Kubernetes main repo, master branch | ? |

Key:

? Changes in main Kubernetes repo are actively published to client-go by a bot

= Maintenance is manual, only severe security bugs will be patched.

– Deprecated; please upgrade.

你看代碼有哪些用的較多的公用庫呀:  sharedInformer、workqueue、event、leaderelection、rest、scheme、flowcontrol、codec

K8S objects in Go

k8s 資源是一種 kind 的實例,在 API server 作為一種資源結構體提供服務。

k8s 中的 object 實現(xiàn)了 runtime.Object 接口,來自于 k8s.io/apimachinery/pkg/runtime 包。其中,schema.ObjectKind 主要實現(xiàn)的另一個接口,來自于 k8s.io/apimachinery/pkg/runtime/schema.

這些 Go 實現(xiàn)的 object 作為數(shù)據(jù)結構主要是用來返回和設置 GroupVersionKind, 以及用來深度拷貝。

type Object interface { 
 GetObjectKind () schema.ObjectKind 
 DeepCopyObject () Object } nbsp;
type ObjectKind interface { 
// SetGroupVersionKind sets or clears the intended serialized kind of an 
// object. Passing kind nil should clear the current setting. 
 SetGroupVersionKind ( kind GroupVersionKind ) 
// GroupVersionKind returns the stored group, version, and kind of an // object, or nil if the object does not expose or provide these fields. 
 GroupVersionKind () GroupVersionKind } nbsp;

TypeMeta

通過嵌套 metav1.TypeMeta(k8s.io/apimachinery/meta/v1) 來實現(xiàn) k8s 對象 schema.ObjectMeta(k8s.io/api) 的 getter 和 setter 類型。

// TypeMeta describes an individual object in an API response or request
// with strings representing the type of the object and its API schema version.
// Structures that are versioned or persisted should inline TypeMeta.
// +k8s:deepcopy-gen=false
type TypeMeta struct {
 // Kind is a string value representing the REST resource this object represents.
 // Servers may infer this from the endpoint the client submits requests to.
 // Cannot be updated.
 // In CamelCase.
 // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
 // +optional
 Kind string `json: kind,omitempty  protobuf: bytes,1,opt,name=kind `
 // APIVersion defines the versioned schema of this representation of an object.
 // Servers should convert recognized schemas to the latest internal value, and
 // may reject unrecognized values.
 // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
 // +optional
 APIVersion string `json: apiVersion,omitempty  protobuf: bytes,2,opt,name=apiVersion `
}
// Pod is a collection of containers that can run on a host. This resource is created
// by clients and scheduled onto hosts.
type Pod struct {
 metav1.TypeMeta `json: ,inline `
 // Standard object s metadata.
 // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
 // +optional
 metav1.ObjectMeta `json: metadata,omitempty  protobuf: bytes,1,opt,name=metadata `
 // Specification of the desired behavior of the pod.
 // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
 // +optional
 Spec PodSpec `json: spec,omitempty  protobuf: bytes,2,opt,name=spec `
 // Most recently observed status of the pod.
 // This data may not be up to date.
 // Populated by the system.
 // Read-only.
 // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
 // +optional
 Status PodStatus `json: status,omitempty  protobuf: bytes,3,opt,name=status `

}

基于 client-go 的應用這些字段在內(nèi)存中值為空,在實際序列化成 json 或者 pb 時,才會有實際的值。而這些約定在版本序列中自動實現(xiàn)。

ObjectMeta

出了 TypeMeta,大部分 top-level 對象還會包括 metav1.ObjectMeta,來自 k8s.io/apimachinery/pkg/meta/v1。

(staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go)

type ObjectMeta struct { 
Name string `json: name,omitempty ` 
Namespace string `json: namespace,omitempty ` 
UID types.UID `json: uid,omitempty ` 
ResourceVersion string `json: resourceVersion,omitempty ` CreationTimestamp Time `json: creationTimestamp,omitempty ` DeletionTimestamp * Time `json: deletionTimestamp,omitempty ` 
Labels map [ string ] string `json: labels,omitempty ` 
Annotations map [ string ] string `json: annotations,omitempty ` 
... 
}

metav1.ObjectMeta 基本包含所有元數(shù)據(jù)信息,像 name,namespace,resource version, 一些時間戳,以及 labels 和 annotation. 其中 client-go 并不能對 resource version 進行讀寫,但卻是整個 k8s 代碼中核心工作的重要信息.

它作為 ObjectMeta 信息的一部分,來源于 etcd 里所有數(shù)據(jù)的 key 字段。

Client Sets

kubernetes.NewForConfig(config) 返回一個 client set, 用它可以訪問定義在 k8s.io/api 中的大部分 API groups 和 resources,除了 APIServices(aggregated API servers) 和 CRD。

clientSet 主接口如下:

type Interface interface { Discovery() discovery.DiscoveryInterface
 AdmissionregistrationV1alpha1() admissionregistrationv1alpha1.AdmissionregistrationV1alpha1Interface
 AdmissionregistrationV1beta1() admissionregistrationv1beta1.AdmissionregistrationV1beta1Interface
 // Deprecated: please explicitly pick a version if possible.
 Admissionregistration() admissionregistrationv1beta1.AdmissionregistrationV1beta1Interface
 AppsV1beta1() appsv1beta1.AppsV1beta1Interface
 AppsV1beta2() appsv1beta2.AppsV1beta2Interface
 AppsV1() appsv1.AppsV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Apps() appsv1.AppsV1Interface
 AuthenticationV1() authenticationv1.AuthenticationV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Authentication() authenticationv1.AuthenticationV1Interface
 AuthenticationV1beta1() authenticationv1beta1.AuthenticationV1beta1Interface
 AuthorizationV1() authorizationv1.AuthorizationV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Authorization() authorizationv1.AuthorizationV1Interface
 AuthorizationV1beta1() authorizationv1beta1.AuthorizationV1beta1Interface
 AutoscalingV1() autoscalingv1.AutoscalingV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Autoscaling() autoscalingv1.AutoscalingV1Interface
 AutoscalingV2beta1() autoscalingv2beta1.AutoscalingV2beta1Interface
 BatchV1() batchv1.BatchV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Batch() batchv1.BatchV1Interface
 BatchV1beta1() batchv1beta1.BatchV1beta1Interface
 BatchV2alpha1() batchv2alpha1.BatchV2alpha1Interface
 CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta1Interface
 // Deprecated: please explicitly pick a version if possible.
 Certificates() certificatesv1beta1.CertificatesV1beta1Interface
 CoreV1() corev1.CoreV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Core() corev1.CoreV1Interface
 EventsV1beta1() eventsv1beta1.EventsV1beta1Interface
 // Deprecated: please explicitly pick a version if possible.
 Events() eventsv1beta1.EventsV1beta1Interface
 ExtensionsV1beta1() extensionsv1beta1.ExtensionsV1beta1Interface
 // Deprecated: please explicitly pick a version if possible.
 Extensions() extensionsv1beta1.ExtensionsV1beta1Interface
 NetworkingV1() networkingv1.NetworkingV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Networking() networkingv1.NetworkingV1Interface
 PolicyV1beta1() policyv1beta1.PolicyV1beta1Interface
 // Deprecated: please explicitly pick a version if possible.
 Policy() policyv1beta1.PolicyV1beta1Interface
 RbacV1() rbacv1.RbacV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Rbac() rbacv1.RbacV1Interface
 RbacV1beta1() rbacv1beta1.RbacV1beta1Interface
 RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface
 SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface
 SchedulingV1beta1() schedulingv1beta1.SchedulingV1beta1Interface
 // Deprecated: please explicitly pick a version if possible.
 Scheduling() schedulingv1beta1.SchedulingV1beta1Interface
 SettingsV1alpha1() settingsv1alpha1.SettingsV1alpha1Interface
 // Deprecated: please explicitly pick a version if possible.
 Settings() settingsv1alpha1.SettingsV1alpha1Interface
 StorageV1beta1() storagev1beta1.StorageV1beta1Interface
 StorageV1() storagev1.StorageV1Interface
 // Deprecated: please explicitly pick a version if possible.
 Storage() storagev1.StorageV1Interface
 StorageV1alpha1() storagev1alpha1.StorageV1alpha1Interface}

在這個接口中存在一些沒有版本的方法:appsv1beta1.AppsV1beta1Interface。

在過去 k8s 有所謂的內(nèi)部客戶端,為了對象在內(nèi)存中存在的更加通用,并且遵循在需要的時候再定義的規(guī)范。這種規(guī)范為了從實際使用的 API 版本中抽象 controller 代碼,同時方便切換不同版本。事實上,為了遵循這種規(guī)范,增加了大量的復雜性,付出了不太值得的代價。此外,在 client 和 APIServer 之間的交互,并沒有自動協(xié)商的機制。盡管存在內(nèi)部的版本和客戶端,controller 硬編碼到指定版本導致并沒有很好兼容。在最近的版本,k8s 代碼盡量避免用到這些內(nèi)部版本。

所有 clientset 可以訪問 discovery client,被用作 RESTMappers;

type AppsV1beta1Interface interface { RESTClient() rest.Interface
 ControllerRevisionsGetter
 DeploymentsGetter
 ScalesGetter
 StatefulSetsGetter
}

在每個 GroupVersion(AppsV1beta1) 下我們發(fā)現(xiàn) API group 的資源都存在通用的 RESTClient

讀到這里,這篇“API Basics 怎么實現(xiàn)”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內(nèi)容的文章,歡迎關注丸趣 TV 行業(yè)資訊頻道。

正文完
 
丸趣
版權聲明:本站原創(chuàng)文章,由 丸趣 2023-08-04發(fā)表,共計13808字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網(wǎng)絡搜集發(fā)布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 宝丰县| 安阳县| 平邑县| 溧阳市| 清苑县| 桃园县| 佛教| 西畴县| 永济市| 右玉县| 清水河县| 田阳县| 乾安县| 蒙阴县| 东海县| 平远县| 石狮市| 合肥市| 绥宁县| 阳春市| 罗定市| 西城区| 威海市| 潮州市| 鄄城县| 南江县| 鱼台县| 兴安盟| 新宾| 红桥区| 芮城县| 安庆市| 界首市| 马鞍山市| 区。| 西畴县| 彭水| 永宁县| 吉水县| 怀集县| 九江县|