<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何為 Kubernetes 定制特性

          共 16690字,需瀏覽 34分鐘

           ·

          2021-04-24 21:12

          Kubernetes 是非常復(fù)雜的集群編排系統(tǒng),然而哪怕包含豐富的功能和特性,因?yàn)槿萜鞯恼{(diào)度和管理本身就有較高的復(fù)雜性,所以它無(wú)法滿足所有場(chǎng)景下的需求。雖然 Kubernetes 能夠解決大多數(shù)場(chǎng)景中的常見(jiàn)問(wèn)題,但是為了實(shí)現(xiàn)更加靈活的策略,我們需要使用 Kubernetes 提供的擴(kuò)展能力實(shí)現(xiàn)特定目的。

          每個(gè)項(xiàng)目在不同的周期會(huì)著眼于不同的特性,我們可以將項(xiàng)目的演進(jìn)過(guò)程簡(jiǎn)單分成三個(gè)不同的階段:

          • 最小可用:項(xiàng)目在早期更傾向于解決通用的、常見(jiàn)的問(wèn)題,給出開(kāi)箱即用的解決方案以吸引用戶,這時(shí)代碼庫(kù)的規(guī)模還相對(duì)比較小,提供的功能較為有限,能夠覆蓋領(lǐng)域內(nèi) 90% 的場(chǎng)景;
          • 功能完善:隨著項(xiàng)目得到更多的使用者和支持者,社區(qū)會(huì)不斷實(shí)現(xiàn)相對(duì)重要的功能,社區(qū)治理和自動(dòng)化工具也逐漸變得完善,能夠解決覆蓋內(nèi) 95% 的場(chǎng)景;
          • 擴(kuò)展能力:因?yàn)轫?xiàng)目的社區(qū)變得完善,代碼庫(kù)變得逐漸龐大,項(xiàng)目的每個(gè)變動(dòng)都會(huì)影響下游的開(kāi)發(fā)者,任何新功能的加入都需要社區(qū)成員的討論和審批,這時(shí)社區(qū)會(huì)選擇增強(qiáng)項(xiàng)目的擴(kuò)展性,讓使用者能夠?yàn)樽约旱膱?chǎng)景定制需求,能夠解決覆蓋內(nèi) 99% 的場(chǎng)景;
          圖 1 - 開(kāi)源項(xiàng)目的演進(jìn)

          從 90%、95% 到 99%,每個(gè)步驟都需要社區(qū)成員花費(fèi)很多精力,但是哪怕提供了較好的擴(kuò)展性也無(wú)法解決領(lǐng)域內(nèi)的全部問(wèn)題,在一些極端場(chǎng)景下仍然需要維護(hù)自己的分支或者另起爐灶滿足業(yè)務(wù)上的需求。

          然而無(wú)論是維護(hù)自己的分支,還是另起爐灶都會(huì)帶來(lái)較高的開(kāi)發(fā)和維護(hù)成本,這需要結(jié)合實(shí)際需求進(jìn)行抉擇。但是能夠利用項(xiàng)目提供的配置能力和擴(kuò)展能力就可以明顯地降低定制化的開(kāi)發(fā)成本,而我們今天要梳理的就是 Kubernetes 的可擴(kuò)展性。

          擴(kuò)展接口

          API 服務(wù)器是 Kubernetes 中的核心組件,它承擔(dān)著集群中資源讀寫的重任,雖然社區(qū)提供的資源和接口可以滿足大多數(shù)的日常需求,但是我們?nèi)匀粫?huì)有一些場(chǎng)景需要擴(kuò)展 API 服務(wù)器的能力,這一節(jié)簡(jiǎn)單介紹幾個(gè)擴(kuò)展該服務(wù)的方法。

          自定義資源

          自定義資源(Custom Resource Definition、CRD)應(yīng)該是 Kubernetes 最常見(jiàn)的擴(kuò)展方式[^1],它是擴(kuò)展 Kubernetes API 的方式之一。Kubernetes 的 API 就是我們向集群提交的 YAML,系統(tǒng)中的各個(gè)組件會(huì)根據(jù)提交的 YAML 啟動(dòng)應(yīng)用、創(chuàng)建網(wǎng)絡(luò)路由規(guī)則以及運(yùn)行工作負(fù)載。

          apiVersion: v1
          kind: Pod
          metadata:
            name: static-web
            labels:
              role: myrole
          spec:
            containers:
              - name: web
                image: nginx
                ports:
                  - name: web
                    containerPort: 80
                    protocol: TCP

          Pod、Service 以及 Ingress 都是 Kubernetes 對(duì)外暴露的接口,當(dāng)我們?cè)诩褐刑峤簧鲜?YAML 時(shí),Kubernetes 中的控制器會(huì)根據(jù)配置創(chuàng)建滿足條件的容器。

          apiVersion: apiextensions.k8s.io/v1
          kind: CustomResourceDefinition
          metadata:
            name: crontabs.stable.example.com
          spec:
            group: stable.example.com
            versions:
              - name: v1
                served: true
                storage: true
                schema:
                  openAPIV3Schema:
                    type: object
                    properties:
                      spec:
                        type: object
                        properties:
                          cronSpec:
                            type: string
                          image:
                            type: string
                          replicas:
                            type: integer
            scope: Namespaced
            names:
              plural: crontabs
              singular: crontab
              kind: CronTab
              shortNames:
              - ct

          除了這些系統(tǒng)內(nèi)置的 API 之外,想要實(shí)現(xiàn)定制的接口就需要使用 CRD,然而 CRD 僅僅是實(shí)現(xiàn)自定義資源的冰山一角,因?yàn)樗欢x了資源中的字段,我們還需要遵循 Kubernetes 的控制器模式,實(shí)現(xiàn)消費(fèi) CRD 的 Operator,通過(guò)組合 Kubernetes 提供的資源實(shí)現(xiàn)更復(fù)雜、更高級(jí)的功能。

          圖 2 - Kubernetes API 模塊化設(shè)計(jì)

          如上圖所示,Kubernetes 中的控制器等組件會(huì)消費(fèi) DeploymentStatefulSet 等資源,而用戶自定義的 CRD 會(huì)由自己實(shí)現(xiàn)的控制器消費(fèi),這種設(shè)計(jì)極大地降低了系統(tǒng)之間各個(gè)模塊的耦合,讓不同模塊可以無(wú)縫協(xié)作。當(dāng)我們想要讓 Kubernetes 集群提供更加復(fù)雜的功能時(shí),選擇 CRD 和控制器是首先需要考慮的方法,這種方式與現(xiàn)有的功能耦合性非常低,同時(shí)也具有較強(qiáng)的靈活性,但是在定義接口時(shí)應(yīng)該遵循社區(qū) API 的最佳實(shí)踐設(shè)計(jì)出優(yōu)雅的接口[^2]。

          聚合層

          Kubernetes API 聚合層是 v1.7 版本實(shí)現(xiàn)的功能,它的目的是將單體的 API 服務(wù)器拆分成多個(gè)聚合服務(wù),每個(gè)開(kāi)發(fā)者都能夠?qū)崿F(xiàn)聚合 API 服務(wù)暴露它們需要的接口,這個(gè)過(guò)程不需要重新編譯 Kubernetes 的任何代碼[^3]。

          圖 3 - Kubernetes API 聚合

          當(dāng)我們需要在集群中加入新的 API 聚合服務(wù)時(shí),需要提交一個(gè) APIService 資源,這個(gè)資源描述了接口所屬的組、版本號(hào)以及處理該接口的服務(wù),下面是 Kubernetes 社區(qū)中 metrics-server 服務(wù)對(duì)應(yīng)的 APIService

          apiVersion: apiregistration.k8s.io/v1
          kind: APIService
          metadata:
            name: v1beta1.metrics.k8s.io
          spec:
            service:
              name: metrics-server
              namespace: kube-system
            group: metrics.k8s.io
            version: v1beta1
            insecureSkipTLSVerify: true
            groupPriorityMinimum: 100
            versionPriority: 100

          如果我們將上述資源提交到 Kubernetes 集群中后,用戶在訪問(wèn) API 服務(wù)器的 /apis/metrics.k8s.io/v1beta1 路徑時(shí),會(huì)被轉(zhuǎn)發(fā)到集群中的 metrics-server.kube-system.svc 服務(wù)上。

          與應(yīng)用范圍很廣的 CRD 相比,API 聚合機(jī)制在項(xiàng)目中比較少見(jiàn),它的主要目的還是擴(kuò)展 API 服務(wù)器,而大多數(shù)的集群都不會(huì)有類似的需求,在這里也就不過(guò)多介紹了。

          準(zhǔn)入控制

          Kubernetes 的準(zhǔn)入控制機(jī)制可以修改和驗(yàn)證即將被 API 服務(wù)器持久化的資源,API 服務(wù)器收到的全部寫請(qǐng)求都會(huì)經(jīng)過(guò)如下所示的階段持久化到 etcd 中[^4]:

          圖 4 - Kubernetes 準(zhǔn)入控制

          Kubernetes 的代碼倉(cāng)庫(kù)中包含 20 多個(gè)準(zhǔn)入控制插件[^5],我們以 TaintNodesByCondition 插件[^6]為例簡(jiǎn)單介紹一下它們的實(shí)現(xiàn)原理:

          func (p *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
           if a.GetResource().GroupResource() != nodeResource || a.GetSubresource() != "" {
            return nil
           }

           node, ok := a.GetObject().(*api.Node)
           if !ok {
            return admission.NewForbidden(a, fmt.Errorf("unexpected type %T", a.GetObject()))
           }

           addNotReadyTaint(node)
           return nil
          }

          所有的準(zhǔn)入控制插件都可以實(shí)現(xiàn)上述的 Admit 方法修改即將提交到存儲(chǔ)中的資源,也就是上面提到的 Mutating 修改階段,這段代碼會(huì)為所有傳入節(jié)點(diǎn)加上 NotReady 污點(diǎn)保證節(jié)點(diǎn)在更新期間不會(huì)有任務(wù)調(diào)度到該節(jié)點(diǎn)上;除了 Admit 方法之外,插件還可以實(shí)現(xiàn) Validate 方法驗(yàn)證傳入資源的合法性。

          在 Kubernetes 實(shí)現(xiàn)自定義的準(zhǔn)入控制器相對(duì)比較復(fù)雜,我們需要構(gòu)建一個(gè)實(shí)現(xiàn)準(zhǔn)入控制接口的 API 服務(wù)并將該 API 服務(wù)通過(guò) MutatingWebhookConfigurationValidatingWebhookConfiguration 兩種資源將服務(wù)的地址和接口注冊(cè)到集群中,而 Kubernetes 的 API 服務(wù)器會(huì)在修改資源時(shí)調(diào)用 WebhookConfiguration 中定義的服務(wù)修改和驗(yàn)證資源。Kubernetes 社區(qū)中的比較熱門的服務(wù)網(wǎng)格 Istio 就利用該特性實(shí)現(xiàn)了一些功能[^7]。

          容器接口

          Kubernetes 作為容器編排系統(tǒng),它的主要邏輯還是調(diào)度和管理集群中運(yùn)行的容器,雖然它不需要從零開(kāi)始實(shí)現(xiàn)新的容器運(yùn)行時(shí),但是因?yàn)榫W(wǎng)絡(luò)和存儲(chǔ)等模塊是容器運(yùn)行的必需品,所以它要與這些模塊打交道。Kubernetes 選擇的方式是設(shè)計(jì)網(wǎng)絡(luò)、存儲(chǔ)和運(yùn)行時(shí)接口隔離實(shí)現(xiàn)細(xì)節(jié),自己把精力放在容器編排上,讓第三方社區(qū)實(shí)現(xiàn)這些復(fù)雜而且極具專業(yè)性的模塊。

          網(wǎng)絡(luò)插件

          容器網(wǎng)絡(luò)接口(Container Network Interface、CNI)包含一組用于開(kāi)發(fā)插件去配置 Linux 容器中網(wǎng)卡的接口和框架。CNI 僅會(huì)關(guān)注容器的網(wǎng)絡(luò)連通性并在容器刪除時(shí)回收所有分配的網(wǎng)絡(luò)資源[^8]。

          圖 5 - 容器網(wǎng)絡(luò)接口

          CNI 插件雖然與 Kubernetes 有密切的關(guān)系,但是不同的容器管理系統(tǒng)都可以使用 CNI 插件來(lái)創(chuàng)建和管理網(wǎng)絡(luò),例如:mesos、Cloud Foundry 等。

          所有的 CNI 插件都應(yīng)該實(shí)現(xiàn)包含 ADD、DELCHECK 操作的二進(jìn)制可執(zhí)行文件,容器管理系統(tǒng)會(huì)執(zhí)行二進(jìn)制文件來(lái)創(chuàng)建網(wǎng)絡(luò)[^9]。

          在 Kubernetes 中,無(wú)論使用哪種網(wǎng)絡(luò)插件都需要遵循它的網(wǎng)絡(luò)模型,除了每個(gè) Pod 都需要有獨(dú)立的 IP 地址之外,Kubernetes 還對(duì)網(wǎng)絡(luò)模型做出了以下的需求:

          • 任意節(jié)點(diǎn)上的 Pod 在不使用 NAT 的情況下都訪問(wèn)到所有節(jié)點(diǎn)上的所有 Pod;
          • 節(jié)點(diǎn)上的 Kubelet 和守護(hù)進(jìn)程等服務(wù)可以訪問(wèn)節(jié)點(diǎn)上的其他 Pod;
          type CNI interface {
           AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
           CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
           DelNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
           GetNetworkListCachedResult(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
           GetNetworkListCachedConfig(net *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error)

           AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
           CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
           DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
           GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
           GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error)

           ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
           ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
          }

          開(kāi)發(fā) CNI 插件對(duì)于多數(shù)工程師來(lái)說(shuō)都非常遙遠(yuǎn),在正常情況下,我們只需要在一些常見(jiàn)的開(kāi)源框架中根據(jù)需求做出選擇,例如:Flannel、Calico 和 Cilium 等,當(dāng)集群的規(guī)模變得非常龐大時(shí),也自然會(huì)有網(wǎng)絡(luò)工程師與 Kubernetes 開(kāi)發(fā)者配合開(kāi)發(fā)相應(yīng)的插件。

          存儲(chǔ)插件

          容器存儲(chǔ)接口(Container Storage Interface、CSI)是 Kubernetes 在 v1.9 引入的新特性,該特性在 v1.13 中達(dá)到穩(wěn)定,目前常見(jiàn)的容器編排系統(tǒng) Kubernetes、Cloud Foundry、Mesos 和 Nomad 都選擇使用該接口擴(kuò)展集群中容器的存儲(chǔ)能力。

          圖 6 - 容器存儲(chǔ)接口

          CSI 是在容器編排系統(tǒng)向容器化的工作負(fù)載暴露塊存儲(chǔ)和文件存儲(chǔ)的標(biāo)準(zhǔn),第三方的存儲(chǔ)提供商可以通過(guò)實(shí)現(xiàn) CSI 插件在 Kubernetes 集群中提供新的存儲(chǔ)[^11]。

          Kubernetes 的開(kāi)發(fā)團(tuán)隊(duì)在 CSI 的文檔中給出了開(kāi)發(fā)和部署 CSI 插件的最佳實(shí)踐[^12],其中最主要的工作是創(chuàng)建實(shí)現(xiàn) Identity、Node 和可選的 Controller 接口的容器化應(yīng)用,并通過(guò)官方的 sanity 包測(cè)試 CSI 插件的合法性,需要實(shí)現(xiàn)的接口都定義在 CSI 的規(guī)格文檔中[^13]。

          service Identity {
          rpc GetPluginInfo(GetPluginInfoRequest)
          returns (GetPluginInfoResponse) {}

          rpc GetPluginCapabilities(GetPluginCapabilitiesRequest)
          returns (GetPluginCapabilitiesResponse) {}

          rpc Probe (ProbeRequest)
          returns (ProbeResponse) {}
          }

          service Controller {
          ...
          }

          service Node {
          ...
          }

          CSI 的規(guī)格文檔非常復(fù)雜,除了詳細(xì)地定義了不同接口的請(qǐng)求和響應(yīng)參數(shù)。它還定義不同接口在出現(xiàn)相應(yīng)錯(cuò)誤時(shí)應(yīng)該返回的 gRPC 錯(cuò)誤碼,開(kāi)發(fā)者想要實(shí)現(xiàn)一個(gè)完全遵循 CSI 接口的插件還是很麻煩的。

          Kubernetes 在較早的版本中分別接入了不同的云廠商的接口,其中包括 Google PD、AWS、Azure 以及 OpenStack,但是隨著 CSI 接口的成熟,社區(qū)未來(lái)會(huì)在上游移除云廠商特定的實(shí)現(xiàn),減少上游的維護(hù)成本,也能加快各個(gè)廠商自身存儲(chǔ)的迭代和支持[^14]。

          運(yùn)行時(shí)接口

          容器運(yùn)行時(shí)接口(Container Runtime Interface、CRI)是一系列用于管理容器運(yùn)行時(shí)和鏡像的 gRPC 接口,它是 Kubernetes 在 v1.5 中引入的新接口,Kubelet 可以通過(guò)它使用不同的容器運(yùn)行時(shí)。

          圖 7 - CRI 和容器運(yùn)行時(shí)

          CRI 主要定義的是一組 gRPC 方法,我們能在規(guī)格文檔中找到 RuntimeServiceImageService 兩個(gè)服務(wù)[^15],它們的名字很好地解釋了各自的作用:

          service RuntimeService {
          rpc Version(VersionRequest) returns (VersionResponse) {}

          rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
          rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
          rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
          rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}
          rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}

          rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
          rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
          rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
          rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}
          rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
          rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}
          rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}
          rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {}

          rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}
          rpc Exec(ExecRequest) returns (ExecResponse) {}
          rpc Attach(AttachRequest) returns (AttachResponse) {}
          rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}

          ...
          }

          service ImageService {
          rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}
          rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {}
          rpc PullImage(PullImageRequest) returns (PullImageResponse) {}
          rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {}
          rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {}
          }

          容器運(yùn)行時(shí)的接口相對(duì)比較簡(jiǎn)單,上面的這些接口不僅暴露了 Pod 沙箱管理、容器管理以及命令執(zhí)行和端口轉(zhuǎn)發(fā)等功能,還包含用于管理鏡像的多個(gè)接口,容器運(yùn)行時(shí)只要實(shí)現(xiàn)上面的二三十個(gè)方法可以為 Kubelet 提供服務(wù)。

          設(shè)備插件

          CPU、內(nèi)存、磁盤是主機(jī)上常見(jiàn)的資源,然而隨著大數(shù)據(jù)、機(jī)器學(xué)習(xí)和硬件的發(fā)展,部分場(chǎng)景可能需要異構(gòu)的計(jì)算資源,例如:GPU、FPGA 等設(shè)備。異構(gòu)資源的出現(xiàn)不僅需要節(jié)點(diǎn)代理 Kubelet 的支持,還需要調(diào)度器的配合,為了良好的兼容后出現(xiàn)的不同計(jì)算設(shè)備,Kubernetes 社區(qū)在上游引入了設(shè)備插件(Device Plugin)用于支持多種類型資源的調(diào)度和分配[^16]。

          圖 8 - 設(shè)備插件概述

          設(shè)備插件是獨(dú)立在 Kubelet 之外單獨(dú)運(yùn)行的服務(wù),它通過(guò) Kubelet 暴露的 Registration 服務(wù)注冊(cè)自己的相關(guān)信息并實(shí)現(xiàn) DevicePlugin 服務(wù)用于訂閱和分配自定義的設(shè)備[^17]。

          service Registration {
          rpc Register(RegisterRequest) returns (Empty) {}
          }

          service DevicePlugin {
          rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
          rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
          rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
          rpc GetPreferredAllocation(PreferredAllocationRequest) returns (PreferredAllocationResponse) {}
          rpc PreStartContainer(PreStartContainerRequest) returns (PreStartContainerResponse) {}
          }

          當(dāng)設(shè)備插件剛剛啟動(dòng)時(shí),它會(huì)調(diào)用 Kubelet 的注冊(cè)接口傳入自己的版本號(hào)、Unix 套接字和資源名,例如:nvidia.com/gpu;Kubelet 會(huì)通過(guò) Unix 套接字與設(shè)備插件通信,它會(huì)通過(guò) ListAndWatch 接口持續(xù)獲得設(shè)備中資源的最新?tīng)顟B(tài),并在 Pod 申請(qǐng)資源時(shí)通過(guò) Allocate 接口分配資源。設(shè)備插件的實(shí)現(xiàn)邏輯相對(duì)比較簡(jiǎn)單,感興趣的讀者可以研究 Nvidia GPU 插件的實(shí)現(xiàn)原理[^18]。

          調(diào)度框架

          調(diào)度器是 Kubernetes 中的核心組件之一,它的主要作用是在 Kubernetes 集群中的一組節(jié)點(diǎn)中為工作負(fù)載做出最優(yōu)的調(diào)度決策,不同場(chǎng)景下的調(diào)度需求往往都是很復(fù)雜的,然而調(diào)度器在 Kubernetes 項(xiàng)目早期并不支持易用的擴(kuò)展能力,僅支持調(diào)度器擴(kuò)展(Extender)這種比較難用的方法。

          Kubernetes 從 v1.15 引入的調(diào)度框架才是今天比較主流的調(diào)度器擴(kuò)展技術(shù),通過(guò)在 Kubernetes 調(diào)度器的內(nèi)部抽象出關(guān)鍵的擴(kuò)展點(diǎn)(Extension Point)并通過(guò)插件的方式在擴(kuò)展點(diǎn)上改變調(diào)度器做出的調(diào)度決策[^19]。

          圖 9 - 調(diào)度框架擴(kuò)展點(diǎn)

          目前的調(diào)度框架總共支持 11 個(gè)不同的擴(kuò)展點(diǎn),每個(gè)擴(kuò)展點(diǎn)都對(duì)應(yīng) Kubernetes 調(diào)度器中定義的接口,這里僅展示 FilterPluginScorePlugin 兩個(gè)常見(jiàn)接口中的方法[^20]:

          type FilterPlugin interface {
           Plugin
           Filter(ctx context.Context, state *CycleState, pod *v1.Pod, nodeInfo *NodeInfo) *Status
          }

          type ScoreExtensions interface {
           NormalizeScore(ctx context.Context, state *CycleState, p *v1.Pod, scores NodeScoreList) *Status
          }

          type ScorePlugin interface {
           Plugin
           Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (int64, *Status)
           ScoreExtensions() ScoreExtensions
          }

          調(diào)度框架的出現(xiàn)讓實(shí)現(xiàn)復(fù)雜的調(diào)度策略和調(diào)度算法變得更加容易,社區(qū)通過(guò)調(diào)度框架替代更早的謂詞和優(yōu)先級(jí)并實(shí)現(xiàn)了協(xié)作式調(diào)度、基于容量調(diào)度等功能更強(qiáng)大的插件[^21]。雖然今天的調(diào)度框架已經(jīng)變得非常靈活,但是串行的調(diào)度器可能無(wú)法滿足大集群的調(diào)度需求,而 Kubernetes 目前也很難實(shí)現(xiàn)多調(diào)度器,不知道未來(lái)是否會(huì)提供更靈活的接口。

          總結(jié)

          Kubernetes 從 2014 年發(fā)布至今已經(jīng)過(guò)去將近 7 年了,從一個(gè)最小可用的編排系統(tǒng)到今天的龐然大物,社區(qū)的每個(gè)代碼貢獻(xiàn)者和成員都有責(zé)任。從這篇文章中,我們可以看到隨著 Kubernetes 項(xiàng)目的演進(jìn)方向,社區(qū)越來(lái)越關(guān)注系統(tǒng)的可擴(kuò)展性,通過(guò)設(shè)計(jì)接口、移除第三方代碼降低社區(qū)成員的負(fù)擔(dān),讓 Kubernetes 能夠更專注于容器的編排和調(diào)度。

          [^1]: Custom Resources · Kubernetes https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/

          [^2]: API Conventions · Kubernetes Community https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md

          [^3]: Aggregated API Servers · Kubernetes Community https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md

          [^4]: Using Admission Controllers https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/

          [^5]: kubernetes/plugin/pkg/admission/ · Kubernetes https://github.com/kubernetes/kubernetes/tree/master/plugin/pkg/admission

          [^6]: kubernetes/plugin/pkg/admission/nodetaint/admission.go · Kubernetes https://github.com/kubernetes/kubernetes/blob/master/plugin/pkg/admission/nodetaint/admission.go

          [^7]: Dynamic Admission Webhooks Overview https://istio.io/latest/docs/ops/configuration/mesh/webhook/

          [^8]: CNI - the Container Network Interface cni https://github.com/containernetworking/cni

          [^9]: Container Network Interface Specification https://github.com/containernetworking/cni/blob/master/SPEC.md

          [^10]: cni/libcni/api.go · containernetworking/cni https://github.com/containernetworking/cni/blob/master/libcni/api.go

          [^11]: Kubernetes Container Storage Interface (CSI) Documentation https://kubernetes-csi.github.io/docs/#kubernetes-container-storage-interface-csi-documentation

          [^12]: Recommended Mechanism (for Developing and Deploying a CSI driver for Kubernetes) https://kubernetes-csi.github.io/docs/#recommended-mechanism-for-developing-and-deploying-a-csi-driver-for-kubernetes

          [^13]: RPC Interface · Container Storage Interface (CSI) https://github.com/container-storage-interface/spec/blob/master/spec.md#rpc-interface

          [^14]: In-tree Storage Plugin to CSI Migration Design Doc https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/csi-migration.md

          [^15]: Container Runtime Interface (CRI) – a plugin interface which enables kubelet to use a wide variety of container runtimes. https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1/api.proto

          [^16]: Device Plugins https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/

          [^17]: API Specification · Device Manager Proposal https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resource-management/device-plugin.md#api-specification

          [^18]: k8s-device-plugin https://github.com/NVIDIA/k8s-device-plugin

          [^19]: Scheduling Framework https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/624-scheduling-framework

          [^20]: kubernetes/pkg/scheduler/framework/interface.go https://github.com/kubernetes/kubernetes/blob/master/pkg/scheduler/framework/interface.go

          [^21]: Repository for out-of-tree scheduler plugins based on scheduler framework. https://github.com/kubernetes-sigs/scheduler-plugins

          瀏覽 64
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  阴茎插入阴道内的欧美视频网站 | 免费操网站久久久久 | 99成人视频免费观看 | 丁香激情婷婷午夜版 | 免费黄片网站在线观看 |