K8S Internals 系列第五期
容器编排之争在 Kubernetes 一统天下场面造成后,K8S 成为了云原生时代的新一代操作系统。K8S 让所有变得简略了,但本身逐步变得越来越简单。【K8S Internals 系列专栏】围绕 K8S 生态的诸多方面,将由博云容器云研发团队定期分享无关调度、平安、网络、性能、存储、利用场景等热点话题。心愿大家在享受 K8S 带来的高效便当的同时,又能够如庖丁解牛般领略其内核运行机制的魅力。
本文将联合 CNCF 社区中面向多集群治理的 Cluster API 我的项目,来和大家谈谈 K8S 集群的治理形式。
1. 为什么抉择 Cluster API?
Kubernetes 曾经成为云原生容器平台的事实标准,越来越多不同行业的企事业单位开始将业务从传统的物理机、虚拟机迁徙过去。利用 Kubernetes 让利用治理变得既快又稳,同时降低成本。在这个过程中,一个企业外部建设了数量不少的 K8S 集群,这些集群的部署形式、版本、配置参数、业务部署都不尽相同。能够说,在 K8S 带来便捷高效的同时,如何治理这些 K8S 集群也成为了不可疏忽的问题,例如:如何装置部署 Kubernetes 集群、如何治理多个 Kubernetes 集群、异构集群如何治理、集群如何降级扩容、集群的配置参数如何标准的变更?一系列灵魂提问成了不少企业的痛楚。
联合 CNCF 社区中面向多集群治理的 Cluster API 我的项目,咱们来和大家谈谈社区的解决方案。
Cluster API 由 Kubernetes 特地兴趣小组 Cluster Lifecycle 发动,旨在提供 K8S 即服务能力。用 Kubernetes 的能力治理 Kubernetes,用 Kubernetes 的形式提供 Kubernetes 集群生命周期治理,并且反对治理集群相干的基础设施(虚拟机、网络、负载均衡器、VPC 等)。通过以上种种形式,让 K8S 基础设施的生命周期治理也变得十分云原生化。
看到这里,相熟 Kubernetes 的小伙伴们必定心想:用 cluster API 我的项目,是不是只用提交一个 yaml 就好了?没错就是这样。Cluster API 提供了申明式的集群治理形式。那么比照之前集群的部署形式又有什么区别呢?以应用 Kubernetes 的官网部署工具 kubeadm 为例,请看下图。
应用或部署过 Kubernetes 集群的小伙伴们晓得,Kubernetes 集群依赖于几个组件协同工作能力失常运行,对这些组件的部署往往吓退了很多人,kubeadm 的呈现很大水平加重了这一痛楚,并且对集群反复部署的问题也给出了一个很好的答案。不过正如上图所示,简直每一步都须要人工手动操作,部署人员辗转多台服务器之间反复着雷同的操作。同时面对日益增长的集群环境,kubeadm 并没有解决如何对本人已部署的集群进行治理。
除此之外还包含以下问题:
- 如何针对异构集群统一地配置机器、负载均衡器、VPC 等?
- 如何自动化治理集群生命周期,包含降级和集群删除?
- 如何扩大并治理任意数量的集群?
Cluster API 给出了答案,通过申明式的构建具备 Kubernetes 格调的 API,实现诸如集群主动创立、配置和治理等性能。同时反对您应用不同的基础设施提供商以及疏导程序提供商来构建治理您的集群。
2. Cluster API 架构
(图源 Cluster API 官方网站)
Management Cluster
Cluster API 工作的集群,该集群往往通过 kind 等工具生成,在该集群上运行着一个或多个基础设施提供程序,并保留着 Cluster API 相干的 CRD 资源。是负责管理工作集群生命周期的集群。
Target Cluster
工作集群,由治理集群创立并治理其生命周期。
Infrastructure provider
基础设施提供商,工作集群基础设施的理论提供者(如 AWS、Azure 和 Google 等),由各大厂商实现,但须要遵循 Cluster API 的标准去实现相应的接口和逻辑。
Control plane provider
管制立体提供者,负责 Target Cluster 管制立体的节点生成,Cluster API 默认应用 kubeadm 疏导管制立体。对于不同厂商可实现适配本人的管制立体疏导程序。
Bootstrap Provider
疏导程序提供者,负责集群证书生成,初始化管制立体,并管制其余节点(管制立体和工作节点)退出集群。Cluster API 默认应用基于 kubeadm 的疏导程序。对于不同厂商可实现适配本人的节点疏导程序。
Custom Resources
自定义资源,Cluster API 提供并依赖于几个自定义资源:Machine、MachineDeployment、MachineSet、Cluster。作为厂商,在实现本人的 provider 时该当遵循这些自定义资源标准。
3. Cluster API 资源介绍
咱们以 kubeadm-control-plane-provider(Control plane provider)、kubeadm-bootstrap-provider(bootstrap-provider)以及 cluster-api-provider-docker(Infrastructure Provider)组件,资源版本 v1beta1 为例,梳理一下 Cluster API 的自定义资源关系图。
在 Cluster API 中对于工作集群的管制立体节点和工作节点的管制是独立离开的,由此对应的资源关系又可划分为管制立体节点机器关系和工作节点机器关系。
管制立体节点机器关系图
对于 kubeadm-control-plane-provider,工作集群管制立体节点由 KubeadmControlplane 资源管制。该资源间接管制了一组 Machine 资源,每一个 Machine 资源又别离关联了一个 DockerMachine 和 KubeadmBootstrapConfig 资源。对于使用者来说理论工作集群中的一个管制立体节点都在治理集群中以一个 Machine 资源的模式存在,KubeadmControlplane 则是整个工作集群管制立体节点的体现。即每个理论的管制立体节点及其对应的疏导配置都在治理集群中以资源的模式存在,治理集群通过管制这些资源,最终由基础设施提供者(如 cluster-api-provider-docker)作用到理论的节点或基础设施之上。
工作节点机器关系图
相比于管制立体节点机器的关系图,工作节点机器的关系图更为简单。这是因为 Cluster API 对于工作节点机器的治理应用了相似 Kubernetes 中 Deployment 的 MachineDeployment,由 MachineDeployment 治理一组 MachineSet,再由 MachineSet 治理一组 Machine。和管制立体节点机器关系中所述统一,每个理论的控工作节点及其对应的疏导配置都在治理集群中以资源的模式存在,治理集群通过管制这些资源,最终由基础设施提供者(如 cluster-api-provider-docker)作用到理论的节点或基础设施之上。
资源介绍
上面咱们对波及到的具体资源做一些简略介绍。ClusterCluster 资源是整个工作集群在治理集群中以资源模式的存在。在对工作集群生命周期过程中,尤其是在工作集群部署阶段中,兼具部署状态收集的性能。通过查看 Cluster 资源状态便可掌控整个工作集群部署状态。同时在其资源字段中对整个工作集群的集群网络进行了配置。
关键字段展现:
spec.ClusterNetwork
type ClusterNetwork struct {
// APIServerPort specifies the port the API Server should bind to.
// Defaults to 6443.
// +optional
APIServerPort *int32 `json:"apiServerPort,omitempty"`
// The network ranges from which service VIPs are allocated.
// +optional
Services *NetworkRanges `json:"services,omitempty"`
// The network ranges from which Pod networks are allocated.
// +optional
Pods *NetworkRanges `json:"pods,omitempty"`
// Domain name for services.
// +optional
ServiceDomain string `json:"serviceDomain,omitempty"`
}
- Machine Deployment
MachineDeployment 的工作形式与 Kubernetes Deployment 相似。MachineDeployment 通过对 2 个 MachineSet(旧的和新的)进行更改来协调对 Machine Spec 的更改。
关键字段展现:
spec.ClusterName
// ClusterName is the name of the Cluster this object belongs to.
// +kubebuilder:validation:MinLength=1
ClusterName string `json:"clusterName"`
spec.Replicas
Replicas 就像 Kubernetes Deployment 那样定义冀望的 Pod 正本数定义冀望的 Machine 数量。
// Number of desired machines. Defaults to 1.
// This is a pointer to distinguish between explicit zero and not specified.
// +optional
// +kubebuilder:default=1
Replicas *int32 `json:"replicas,omitempty"`
spec.Selector
匹配具备对应 lable 的 Machine。
// Label selector for machines. Existing MachineSets whose machines are
// selected by this will be the ones affected by this deployment.
// It must match the machine template's labels.
Selector metav1.LabelSelector `json:"selector"`
spec.Template 创立 Machine 的模板,此处不展现,请持续向下看 Machine 资源介绍。
spec.Strategy
Machine 更新策略,默认为滚动更新(RollingUpdate),可选策略 RollingUpdate;OnDelete。
type MachineDeploymentStrategy struct {
// Type of deployment.
// Default is RollingUpdate.
// +kubebuilder:validation:Enum=RollingUpdate;OnDelete
// +optional
Type MachineDeploymentStrategyType `json:"type,omitempty"`
// Rolling update config params. Present only if
// MachineDeploymentStrategyType = RollingUpdate.
// +optional
RollingUpdate *MachineRollingUpdateDeployment `json:"rollingUpdate,omitempty"`
}
- MachineSet
MachineSet 的目标是保护在任何给定工夫运行的一组稳固的 Machine。但并不是间接独立应用,而是与 MachineDeployment 一起工作,由 Machine Deployments 来协调其状态。
关键字段展现:
spec.ClusterName
// ClusterName is the name of the Cluster this object belongs to.
// +kubebuilder:validation:MinLength=1
ClusterName string `json:"clusterName"`
spec.Replicas
// Replicas is the number of desired replicas.
// This is a pointer to distinguish between explicit zero and unspecified.
// Defaults to 1.
// +optional
// +kubebuilder:default=1
Replicas *int32 `json:"replicas,omitempty"`
sepc.DeletePolicy
当缩减节点时删除节点的策略,默认为随机(Random),可选 Random;Newest;Oldest。
// DeletePolicy defines the policy used to identify nodes to delete when downscaling.
// Defaults to "Random". Valid values are "Random,"Newest","Oldest"
// +kubebuilder:validation:Enum=Random;Newest;Oldest
// +optional
DeletePolicy string `json:"deletePolicy,omitempty"`
spec.Selector
// Selector is a label query over machines that should match the replica count.
// Label keys and values that must match in order to be controlled by this MachineSet.
// It must match the machine template's labels.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
Selector metav1.LabelSelector `json:"selector"`
spec.Template
创立 Machine 的模板,此处不展现,请持续向下看 Machine 资源介绍。
- Machine
Machine 是具体工作集群中具体节点在治理集群以资源模式的存在,当一个 Machine 被删除或创立,对应的工作集群的节点也会随之被删除或创立。如果 Machine 资源的字段被批改,那么控制器将会创立新的 Machine 对旧的 Machine 进行替换。
关键字段展现:
spec.ClusterName
// ClusterName is the name of the Cluster this object belongs to.
// +kubebuilder:validation:MinLength=1
ClusterName string `json:"clusterName"`
spec.Bootstrap
关联的疏导程序资源,对于 kubeadm-bootstrap-provider,关联的是 kubeadmBootstrapConfig。其中 DataSecretName 将会被存储 Bootstrap data 的 secret 的 name 填充。
// Bootstrap encapsulates fields to configure the Machine’s bootstrapping mechanism.
type Bootstrap struct {
// ConfigRef is a reference to a bootstrap provider-specific resource
// that holds configuration details. The reference is optional to
// allow users/operators to specify Bootstrap.DataSecretName without
// the need of a controller.
// +optional
ConfigRef *corev1.ObjectReference `json:"configRef,omitempty"`
// DataSecretName is the name of the secret that stores the bootstrap data script.
// If nil, the Machine should remain in the Pending state.
// +optional
DataSecretName *string `json:"dataSecretName,omitempty"`
}
spec.Infrastructure
Ref 关联基础设施提供程序,Machine 所有字段定义以及疏导工作都由基础设施提供者实现
// InfrastructureRef is a required reference to a custom resource
// offered by an infrastructure provider.
InfrastructureRef corev1.ObjectReference `json:"infrastructureRef"`
spec.Version
Vesion 定义了对应工作集群节点上所须要装置的 Kubernetes 版本
// Version defines the desired Kubernetes version.
// This field is meant to be optionally used by bootstrap providers.
// +optional
Version *string `json:"version,omitempty"`
spec.ProviderID
此字段与此 Machine 对应的工作集群 node 对象上的 ProviderID 统一,通过此字段匹配工作集群 node 对象,并通过工作集群的 API Server 对 node 对象进行拜访以及管制。
// ProviderID is the identification ID of the machine provided by the provider.
// This field must match the provider ID as seen on the node object corresponding to this machine.
// This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler
// with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out
// machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a
// generic out-of-tree provider for autoscaler, this field is required by autoscaler to be
// able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver
// and then a comparison is done to find out unregistered machines and are marked for delete.
// This field will be set by the actuators and consumed by higher level entities like autoscaler that will
// be interfacing with cluster-api as generic provider.
// +optional
ProviderID *string `json:"providerID,omitempty"`
4. 结束语
Cluster API 是一个非常优良的我的项目,从工作集群的部署到伸缩、删除和降级都有十分好的体验(提交 yaml 而后期待 Cluster API 实现工作)。无论您是在何种基础设施上搭建集群,都能在社区找到适合您的 provider。又或者您想自建 provider 适配,只需遵循 Cluster API 的 provider 标准便可疾速编写出您的定制程序。
下一篇,咱们将带您深刻理解 Cluster API 的运行原理。