从 K8S 的 Cloud Provider 到 CCM 的演进之路
Posted K8sMeetup
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从 K8S 的 Cloud Provider 到 CCM 的演进之路相关的知识,希望对你有一定的参考价值。
| 为 | 容 | 器 | 技 | 术 | 而 | 生 |
编辑:小君君
Kubernetes 是一个云原生平台,但为了让 Kubernetes 能够更好地运行在公有云平台上,能够灵活地使用、管理云上其他的基础资源和基础服务,云厂商需要实现自己的适配器。本文详细解读了 Kubernetes 从 Cloud Provider 到 Cloud Controller Mananger(CCM) 的演变过程及其实现细节,希望有助于大家更好地在公有云平台上构建基于 Kubernetes 的容器服务。
Cloud Provider 背景概要
基于 Kubernetes 的容器云
容器云最主要的功能是帮助用户把所有的应用以容器的形式在集群中跑起来。目前很多的容器云平台通过 Docker 及 Kubernetes 等技术给应用提供运行平台,从而实现运维自动化、快速部署应用、弹性伸缩和动态调整应用环境资源,提高研发运营效率。
Cloud Provider 与云厂商
为了更好地让 Kubernetes 在公有云平台上运行,并且提供容器云服务,云厂商需要实现自己的 Cloud Provider,即实现:
cloudprovider.Interface(https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/cloud.go)。
它是 Kubernetes 中开放给云厂商的通用接口,便于 Kubernetes 自动管理和利用云服务商提供的资源,这些资源包括虚拟机资源、负载均衡服务、弹性公网 IP、存储服务等。
如下图所示,Kubernetes 核心库内置了很多主流云厂商的实现,包括 AWS、GCE、Azure:
Cloud Provider 的重构之路
近几年来, Kubernetes 逐渐成为在私有云、公有云和混合云环境中大规模部署容器化应用的事实标准,以至于越来越多的云厂商加入了进来,而 Cloud Provider 的实现也越来越多。
作为在 Kubernetes 核心库中的代码,这必将影响其快速更新和迭代。 所以产生了把 Cloud Provider 移出 Kubernetes 核心库并进行重构的提案(Refactor Cloud Provider out of Kubernetes Core)。
在 Kubernetes v1.6,引入了 Cloud Controller Manager(CCM),目的就是最终替代 Cloud Provider。截止到最新的 Kubernetes v1.11,还是处于 beta 阶段。
Cloud Provider 解析
Cloud Provider 的作用
在 Kubernetes 中有三个组件对 Cloud Provider 有依赖,分别是:
kube-controller-manager
kubelet
kube-apiserver
这三个组件对 Cloud Provider 的依赖部分会最终编译进相应的二进制中,详细的依赖关系图如下所示:
kube-controller-manager 对于 Cloud Provider 的依赖
kube-controller-manager 对 Cloud Provider 的依赖分布在四个 Controller 中。
Node Controller:Node Controller 使用 Cloud Provider 来检查 Node 是否已经在云上被删除了。如果 Cloud Provider 返回有 Node 被删除,那么 Node Controller 立马就会把此 Node 从 Kubernetes 中删除。
Service Controller:Service Controller 不光维护了当前可用 Node 的列表,而且它同时负责创建、删除、更新类型是 LoadBalancer 的 Service、使用云厂商额外提供的负载均衡服务、弹性公网 IP 等。
PersistentVolumeLabel Controller:PersistentVolumeLabel Controller 使用 Cloud Provider 来创建、删除、挂载、卸载 Node 上的卷,这是因为卷也是云厂商额外提供的云存储服务。
kubelet 对于 Cloud Provider 的依赖
kubelet 中的 Node Status 使用 Cloud Provider 来获得 Node 的信息。包括:
nodename:运行 kubelet 的节点名字
InstanceID, ProviderID, ExternalID, Zone Info(在初始化 kubelet 的时候需要)
周期性同步的 Node 的 IP
kube-apiserver 对于 Cloud Provider 的依赖
kube-apiserver 使用 Cloud Provider 来给所有 Node 派发 SSH Keys。
Cloud Provider 的设计
云厂商在实现自己的 Cloud Provider 时只需要实现 cloudprovider.Interface 即可,如下:
在此重点阐述两个比较重要的接口 LoadBalancer() 与 Routes()。
LoadBalancer() 的接口设计
LoadBalancer() 接口用来为 kube-controller-manager 的 Service Controller 服务,接口说明如下:
Routes() 的接口设计
Routes() 接口用来为 kube-controller-manager 的 Route Controller 服务,接口说明如下:
Cloud Provider 的演变之路
从 Kubernetes v1.6 开始,Kubernetes 的编译产物中多了一个二进制:cloud-controller manager,它就是用来替代 Cloud Provider 。
因为原先的 Cloud Provider 与 Mater 中的组件 kube-controller-manager、kube-apiserver 以及 Node 中的组件 kubelet 耦合很紧密,所以这三个组件也需要进行重构。
kube-controller-manager 的重构策略
kube-controller-manager 中有四个 controller 与 Cloud Provider 相关,相应的重构策略如下:
Route Controller
移入 CCM,并在相应的 controller loop 中运行。
Service Controller
移入 CCM,并在相应的 controller loop 中运行。
PersistentVolumeLabel Controller
移入 CCM,并在相应的 controller loop 中运行。
Node Controller
在 CCM 中增加新 controller:Cloud Node Controller。
Cloud Node Controller 除了实现原来 Node Controller 的功能外,增加新功能:
CIDR 的管理
监控节点的状态
节点 Pod 的驱逐策略
kube-apiserver 的重构策略
对于 kube-apiserver 使用 Cloud Provider 的两个功能:
分发 SSH Keys
移入 CCM
对于 PV 的 Admission Controller
在 kubelet 中实现
kubelet的重构策略
kubelet 需要增加一个新功能:在 CCM 还未初始化 kubelet 所在节点时,需标记此节点类似“ NotReady ”的状态,防止 scheduler 调度 Pod 到此节点时产生一系列错误。此功能通过给节点加上如下 Taints 并在 CCM 初始化后删去此 Taints 来实现:
Cloud Controller Manager 解析
Cloud Controller Manager 架构
按照上述方法进行重构后,新的模块 Cloud Controller Manager 将作为一个新的组件直接部署在集群内,如下图所示:
CCM 组件内各小模块的功能与原先 Cloud Provider 的差不多(见第二部分对 Cloud Provider 的解析)。
对于云厂商来说,需要:
实现 cloudprovider.Interface 接口的功能,这部分在 Cloud Provider 中已经都实现,直接迁移便可。
实现自己的 Cloud Controller Manager,并在部署 Kubernetes 时,把 CCM 按要求部署在集群内(部署时的注意事项及部署参考实践见第五部分)。
Cloud Controller Manager 实现举例
Cloud Controller Manager 实现举例如下:
Cloud Controller Manager 的部署
总体要求
云厂商提供给 CCM 的 API 需要有认证鉴权机制,防止恶意行为的发生;
因为 CCM 运行在集群内,所以需要 RBAC 规则去跟 kube-apiserver 进行通讯;
为了提高 CCM 的可用,可选择主功能。
K8S 相关组件的启动配置变化
将 Cloud Provider 改为 CCM 后,相关组件启动的配置需要修改。
kube-controller-manager 启动配置变化
不指定 cloud-provider。
kube-apiserver 启动配置变化
不指定 cloud-provider
在 admission-control 中删去 PersistentVolumeLabel
admission-control 中增加 Initializers
runtime-config 中增加 admissionregistration.k8s.io/v1alpha1
kubelet 启动配置变化
指定 cloud-provider=external,在 kubelet 被调度之前需要被 CCM 初始化。(Node 会被打上 Taints:node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule)
启动 CCM 举例
启用 initializers 并添加 InitializerConifguration
CCM 为了给 PV 打标签需要:
启用 initializers
(https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#enable-initializers-alpha-feature)
添加 InitializerConifguration:persistent-volume-label-initializer-config.yaml 如下:
创建 CCM 的 RBAC
启动 CCM
可以通过 DaemonSet 或者 Deployment 的方式启动 CCM:
参考文献:
1.https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/
2.https://github.com/kubernetes/community/blob/master/contributors/design-proposals/cloud-provider/cloud-provider-refactoring.md
3.https://kubernetes.io/docs/concepts/cluster-administration/cloud-providers/
作者简介:
毛宏斌,百度高级研发工程师,从事百度云容器引擎。
欢迎投稿
如果你对 Kubernetes 技术有深入解读,如果你对行业潮流有独到的见解,如果你只是单纯的有话要说,赶紧发邮件到 tougao@k8smeetup.com 来投稿吧。也许你与行业 KOL 只差这一封邮件……
邮件请附:
100 字左右的个人简介
可附个人技术博客或 GitHub 主页
作者福利:
「K8sMeetup 中国社区」全渠道推广
线下 Meetup 讲师优先候选人
线上课堂讲师优先候选人
金牌作者私享群
社区年度大会、KubeCon 大会门票福利
——K8sMeetup 中国社区
推荐阅读:
END
以上是关于从 K8S 的 Cloud Provider 到 CCM 的演进之路的主要内容,如果未能解决你的问题,请参考以下文章
kubernetes cloud-provider for aliyun