从 K8S 的 Cloud Provider 到 CCM 的演进之路

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: Kubernetes 是一个云原生平台,但为了让 Kubernetes 能够更好地运行在公有云平台上,能够灵活地使用、管理云上其他的基础资源和基础服务,云厂商需要实现自己的适配器。本文详细解读了 Kubernetes 从 Cloud Provider 到 Cloud Controller Mananger(CCM) 的演变过程及其实现细节,希望有助于大家更好地在公有云平台上构建基于 Kubernetes 的容器服务。

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 中删除。

  • Route Controller:用来配置 Node 的路由。Kubernetes 容器网络基本原则 [每个 Pod 都拥有一个独立的 IP 地址(IP per Pod),而且假定所有的 Pod 都在一个可以直接连通的、扁平的网络空间中。而在云上,Node 的基础设施是由云厂商提供的,所以 Route Controller 需要调用 Cloud Provider 来配置云上的 Node 的底层路由。]

  • 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:

    本文转自掘金-从 K8S 的 Cloud Provider 到 CCM 的演进之路

    相关实践学习
    深入解析Docker容器化技术
    Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
    相关文章
    |
    前端开发 JavaScript 机器人
    从头搭建一个在线聊天室(一)
    从头搭建一个在线聊天室(一)
    213 0
    |
    算法 Java 计算机视觉
    JavaOpenCV相似度计算基础教程
    JavaOpenCV是一个基于开放源代码的计算机视觉库,它可以实现许多计算机视觉任务,如图像处理、物体识别和图像相似度计算等。本教程旨在向您介绍JavaOpenCV中的相似度计算基础,帮助您理解如何使用该库计算图像之间的相似度
    479 0
    |
    存储 Dragonfly 缓存
    Nydus:开源的下一代容器镜像加速服务
    让更多的容器用户能够体验到容器快速启动和安全加载方面的能力。
    7755 0
    Nydus:开源的下一代容器镜像加速服务
    |
    9月前
    |
    运维 Kubernetes Java
    阿里云容器计算服务ACS ,更普惠易用、更柔性、更弹性的容器算力
    ACS是阿里云容器服务团队推出的一款面向Serverless场景的子产品,基于K8s界面提供符合容器规范的CPU及GPU算力资源。ACS采用Serverless形态,用户无需关注底层节点及集群运维,按需申请使用,秒级按量付费。该服务旨在打造更普惠易用、更柔性、更弹性的新一代容器算力,简化企业上云门槛,加速业务创新。ACS支持多种业务场景,提供通用型、性能型及BestEffort算力质量,帮助客户更从容应对流量变化,降低综合成本。
    |
    Kubernetes 容器 Perl
    【kubernetes】解决: kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = faile...
    【kubernetes】解决: kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = faile...
    16355 0
    |
    7月前
    |
    关系型数据库 MySQL
    图解MySQL【日志】——磁盘 I/O 次数过高时优化的办法
    当 MySQL 磁盘 I/O 次数过高时,可通过调整参数优化。控制刷盘时机以降低频率:组提交参数 `binlog_group_commit_sync_delay` 和 `binlog_group_commit_sync_no_delay_count` 调整等待时间和事务数量;`sync_binlog=N` 设置 write 和 fsync 频率,`innodb_flush_log_at_trx_commit=2` 使提交时只写入 Redo Log 文件,由 OS 择机持久化,但两者在 OS 崩溃时有丢失数据风险。
    178 3
    |
    10月前
    |
    安全 关系型数据库 MySQL
    【赵渝强老师】MySQL的连接方式
    本文介绍了MySQL数据库服务器启动后的三种连接方式:本地连接、远程连接和安全连接。详细步骤包括使用root用户登录、修改密码、创建新用户、授权及配置SSL等。并附有视频讲解,帮助读者更好地理解和操作。
    1085 1
    |
    消息中间件 存储 物联网
    RocketMQ 之 IoT 消息解析:物联网需要的消息技术
    RocketMQ 5.0 是为应对物联网(IoT)场景而发布的云原生消息中间件,旨在解决 IoT 中大规模设备连接、数据处理和边缘计算的需求。
    1430 106
    |
    异构计算
    无影云电脑产品使用之购买什么配置可以玩黑神话悟空游戏?
    本文汇总了关于阿里云无影云电脑的常见问题及解答,包括所需配置以运行《黑神话:悟空》游戏、不同版本显卡型号、电竞模式库存情况及如何查看云电脑的使用情况等。提供了多个详细解答链接,帮助用户更好地了解和使用无影云电脑。
    |
    存储 Kubernetes 调度
    在K8S中,什么是PV和PVC?
    在K8S中,什么是PV和PVC?